Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <20190324184255.GA18043@voyager>
Date: Sun, 24 Mar 2019 19:42:55 +0100
From: Markus Wichmann <nullplan@....net>
To: musl@...ts.openwall.com
Subject: Re: futimens on musl libc (fwd)

On Sun, Mar 24, 2019 at 10:21:18AM -0400, Rich Felker wrote:
> I think this needs action but I'm not clear what the exact mechanism
> is yet, so I'm forwarding to the list.
>
> ----- Forwarded message from Bruno Haible <bruno@...sp.org> -----
>
> From: Bruno Haible <bruno@...sp.org>
> To: bug-gnulib@....org, Rich Felker <dalias@...c.org>
> Subject: futimens on musl libc
> Date: Sat, 23 Mar 2019 21:40:33 +0100
> Message-ID: <4061903.SY8uJAIc8I@...ga>
>
> The gnulib configure test in m4/futimens.m4, when run on Alpine Linux 3.7,
> determines that the errno value is not as expected for a wrong fd.
>
> Let me document this in gnulib and update the cross-compilation guess
> accordingly.
>
> Rich, FYI: The test program is this one:
>
> #include <fcntl.h>
> #include <sys/stat.h>
> #include <unistd.h>
> #include <time.h>
> #include <errno.h>
> int main ()
> {
>       struct timespec ts[2];
>       int fd = creat ("conftest.file", 0600);
>       struct stat st;
>       if (fd < 0) return 1;
>       ts[0].tv_sec = 1;
>       ts[0].tv_nsec = UTIME_OMIT;
>       ts[1].tv_sec = 1;
>       ts[1].tv_nsec = UTIME_NOW;
>       errno = 0;
>       if (futimens (AT_FDCWD, NULL) == 0) return 2;
>       if (errno != EBADF) return 3;     /* <== It fails here */

Ah! There are multiple errors present in the call, but gnulib expects a
certain one of these to be returned.

futimens() should return EBADF for invalid FD, and EFAULT for invalid
buffer address (second argument, according to manpage). However, musl
implements futimens in terms of utimensat(), which just wraps a syscall
of the same name on recent kernels (i.e. there's an optional fallback
there that won't be used if the error from the first try isn't ENOSYS).

According to the manpage, utimensat() returns EFAULT for invalid buffer
address, and if the fd happens to be AT_FDCWD, but the path name is NULL
(which it is when the call comes in from futimens()).

POSIX is also rather clear on the matter:
|The futimens() function shall fail if:
|
|[EBADF]
|    The fd argument is not a valid file descriptor.

If the test program were patched to provide a propper buffer to
futimens(), musl's implementation would still return EFAULT instead of
the required EBADF. We might have to test for AT_FDCWD in futimens(),
before passing it on to utimensat(). Are there other special FDs we have
to consider?

Ciao,
Markus

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.