|
Message-ID: <20210708013943.GS13220@brightrain.aerifal.cx> Date: Wed, 7 Jul 2021 21:39:43 -0400 From: Rich Felker <dalias@...c.org> To: musl@...ts.openwall.com Subject: Re: [PATCH] fix fexecve fallback code when fd is negative On Wed, Jul 07, 2021 at 09:15:19PM -0300, Érico Nogueira wrote: > even though passing negative fd values to fexecve shouldn't happen on > the part of any application, if it does happen and the current kernel > doesn't implement SYS_execveat, musl will call execve on > "/proc/self/fd/(unsigned)fd", which might be an existing, unrelated, > file. > > this was introduced in commit c8c0844f7fbcb955848ca84432e5ffcf71f1cef1, > when fexecve started using __procfdname, which takes an unsigned integer > instead of signed one. > > this also fixes the POSIX-compliance of the function, since POSIX > specifies: > > The fexecve() function shall fail if: > > EBADF The fd argument is not a valid file descriptor open for > executing. > > this corner case was found while investigating usage of __procfdname. > all other cases are correct: > > - fchmod,fchdir,fchown -> will fail the direct syscall first > - fchmodat -> is in the *at family so fd can be -1, only uses procfdname with another fd > - fstatat -> checks for fd>=0 in the branch that uses procfdname > - ttyname_r -> fd goes through isatty() > --- > src/process/fexecve.c | 2 ++ > 1 file changed, 2 insertions(+) > > diff --git a/src/process/fexecve.c b/src/process/fexecve.c > index 554c1981..ab81b2d3 100644 > --- a/src/process/fexecve.c > +++ b/src/process/fexecve.c > @@ -8,6 +8,8 @@ int fexecve(int fd, char *const argv[], char *const envp[]) > { > int r = __syscall(SYS_execveat, fd, "", argv, envp, AT_EMPTY_PATH); > if (r != -ENOSYS) return __syscall_ret(r); > + else if (fd < 0) return __syscall_ret(-EBADF); > + > char buf[15 + 3*sizeof(int)]; > __procfdname(buf, fd); > execve(buf, argv, envp); > -- > 2.32.0 To document what we discussed on IRC, if x has type int and x<0, (unsigned)x > INT_MAX, so it cannot masquerade as a value in the range 0..INT_MAX (which a fd must be). This means the code is already working, and the line following the above context: if (errno == ENOENT) errno = EBADF; handles conversion to the expected error code. Rich
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.