Skip to contentSkip to conversation

New: prototype for execveat() in the documentation appears wrong

Bug 216876 Alejandro Colomar 2 participants 3 messages Jan 2, 2023 1 message not in the archive Man-pages: manual pages for Linux -- Sections 2, 3, 4, 5, and 7

lore
Share & tools
lore
#1 lore raw
In reply to a message not in the archive

Hi,

Quoted 28 lines · On 1/2/23 04:47, [email protected] wrote:

https://bugzilla.kernel.org/show_bug.cgi?id=216876

Bug ID: 216876
Summary: prototype for execveat() in the documentation appears
wrong
Product: Documentation
Version: unspecified
Hardware: All
OS: Linux
Status: NEW
Severity: low
Priority: P1
Component: man-pages
Assignee: [email protected]
Reporter: [email protected]
Regression: No

prototype for execveat() in the documentation is:

int execveat(int dirfd, const char *pathname,

                     const char *const argv[], const char *const envp[],
                     int flags);

This appears to be inconsistent with similar functions, other documentation, and my sources (latest Ubuntu distribution).

Quoted 5 lines

I think two of the "const" should be dropped so that we should have:

int execveat(int dirfd, const char *pathname,

                     char *const argv[], char *const envp[],
                     int flags);

Thanks for the report!

This was introduced in commit 71a25d4c79b1ccf538f6b813c834bbc4197f6370 "execveat.2: Fix prototype".

The reason is that the kernel uses the const:

alx@asus5775:~/src/linux/linux$ grepc execveat
./include/linux/compat.h:851:
asmlinkage long compat_sys_execveat(int dfd, const char __user *filename,
		     const compat_uptr_t __user *argv,
		     const compat_uptr_t __user *envp, int flags);

./include/linux/syscalls.h:1011:
asmlinkage long sys_execveat(int dfd, const char __user *filename,

			const char __user *const __user *argv,
			const char __user *const __user *envp, int flags);

./fs/exec.c:2096:
SYSCALL_DEFINE5(execveat,
int, fd, const char __user *, filename, const char __user *const __user *, argv, const char __user *const __user *, envp, int, flags)

{
	return do_execveat(fd,
			   getname_uflags(filename, flags),
			   argv, envp, flags);
}

./fs/exec.c:2115:
COMPAT_SYSCALL_DEFINE5(execveat, int, fd,
const char __user *, filename, const compat_uptr_t __user *, argv, const compat_uptr_t __user *, envp, int, flags)

{
	return compat_do_execveat(fd,
				  getname_uflags(filename, flags),
				  argv, envp, flags);
}

It seems that glibc added a wrapper recently, and I didn't check that the prototype changed:

alx@asus5775:~/src/gnu/glibc$ grepc execveat
./posix/unistd.h:300:
extern int execveat (int __fd, const char *__path, char *const __argv[],
                     char *const __envp[], int __flags)
    __THROW __nonnull ((2, 3));

./sysdeps/unix/sysv/linux/execveat.c:25:
int
execveat (int dirfd, const char *path, char *const argv[], char *const envp[],
int flags)
{
/* Avoid implicit array coercion in syscall macros. */
return INLINE_SYSCALL_CALL (execveat, dirfd, path, &argv[0], &envp[0],

			      flags);
}

I CCd glibc so that they can comment.

Cheers,

Alex

P.S.: There's some problem in bugzilla that it's not receiving my replies, so I CCed everyone involved so we can keep the discussion in the mailing list.

P.S.2: Ping, Konstantin, please check that.

Signature · 1 line
<http://www.alejandro-colomar.es/>
#2 lore raw

* Alejandro Colomar via Libc-alpha:

Quoted 17 lines

It seems that glibc added a wrapper recently, and I didn't check that the prototype changed:

alx@asus5775:~/src/gnu/glibc$ grepc execveat
./posix/unistd.h:300:
extern int execveat (int __fd, const char *__path, char *const __argv[],
                     char *const __envp[], int __flags)
    __THROW __nonnull ((2, 3));

./sysdeps/unix/sysv/linux/execveat.c:25:
int
execveat (int dirfd, const char *path, char *const argv[], char *const envp[],
int flags)
{
/* Avoid implicit array coercion in syscall macros. */
return INLINE_SYSCALL_CALL (execveat, dirfd, path, &argv[0], &envp[0],

Quoted 5 lines
			      flags);
}

I CCd glibc so that they can comment.

POSIX uses these types for fexecve and execve, and it seemed right to be consistent with that.

There are several more manual pages which do not specify the correct
prototype: open, openat, prctl. I have received compiler bug reports when people used function pointers modeled after the declarations of open and prctl in the manual pages because of the ABI mismatch with the glibc implementations. The execveat difference is harmless in comparison.

Thanks,
Florian

#3 lore raw

Hi Florian,

Quoted 28 lines · Florian Weimer

* Alejandro Colomar via Libc-alpha:

Quoted 14 lines

It seems that glibc added a wrapper recently, and I didn't check that the prototype changed:

alx@asus5775:~/src/gnu/glibc$ grepc execveat
./posix/unistd.h:300:
extern int execveat (int __fd, const char *__path, char *const __argv[],
                      char *const __envp[], int __flags)
     __THROW __nonnull ((2, 3));

./sysdeps/unix/sysv/linux/execveat.c:25:
int
execveat (int dirfd, const char *path, char *const argv[], char *const envp[],
int flags)

Quoted 8 lines
{
   /* Avoid implicit array coercion in syscall macros.  */
   return INLINE_SYSCALL_CALL (execveat, dirfd, path, &argv[0], &envp[0],
			      flags);
}

I CCd glibc so that they can comment.

POSIX uses these types for fexecve and execve, and it seemed right to be consistent with that.

Quoted 6 lines

There are several more manual pages which do not specify the correct
prototype: open, openat, prctl. I have received compiler bug reports when people used function pointers modeled after the declarations of open and prctl in the manual pages because of the ABI mismatch with the glibc implementations. The execveat difference is harmless in comparison.

That makes sense, and is what I guessed. I just wanted to make sure that it was intentional. I've updated the page to reflect the glibc wrapper.

Cheers,

Alex

Quoted 4 lines

Thanks,
Florian

Signature · 1 line
<http://www.alejandro-colomar.es/>