[PATCH] utimensat() non-conformances and fixes

Previous thread: inotify SIGIO documentation for inotify.7 man page by Michael Kerrisk on Monday, April 7, 2008 - 6:16 pm. (2 messages)

Next thread: [PATCH 1/1 resend][PPC] replace logical by bitand in pci_process_ISA_OF_ranges(), arch/powerpc/kernel/isa-bridge.c by Roel Kluin on Monday, April 7, 2008 - 6:26 pm. (3 messages)
To: Ulrich Drepper <drepper@...>
Cc: Andrew Morton <akpm@...>, lkml <linux-kernel@...>, <linux-man@...>
Date: Monday, April 7, 2008 - 6:18 pm

Ulrich,

While writing a man page for utimensat(2) and futimens(3), I think I've
found a few bugs in the utimensat() system call (i.e., non-conformances
with either the specification in the draft POSIX.1-200x revision or
traditional Linux behavior).

int utimensat(int dirfd, const char *pathname,
const struct timespec times[2], int flags);

1. The draft POSIX.1-200x specification for utimensat() says that if a
times[n].tv_nsec field is UTIME_OMIT or UTIME_NOW, then the value in the
corresponding tv_sec field is ignored. However the current Linux
implementation requires the tv_sec value to be zero (or the EINVAL error
results). This requirement should be removed.

2. The POSIX.1 draft says that to do anything other than setting both
timestamps to a time other than the current time (i.e., times is not NULL,
and both tv_nsec fields are not UTIME_NOW and both tv_nsec fields are not
UTIME_OMIT -- see lines 32400 to 32403 of draft 5 of the spec), either: the
caller's effective user ID must match the owner of the file; or the caller
must have appropriate privileges. If this condition is violated, then the
error EPERM results. However, the current implementation does not generate
EPERM if one tv_nsec field is UTIME_NOW while the other is UTIME_OMIT -- it
should give this error for that case.

3. Traditionally, utime()/utimes() gives the error EACCES for the case
where the timestamp pointer argument is NULL (i.e., set both timestamps to
the current time), and the file is owned by a user other than the effective
UID of the caller, and the file is not writable by the effective UID of the
program. utimensat() also gives this error in the same case. However, in
the same circumstances, when utimensat() is given a 'times' array in which
both tv_nsec fields are UTIME_NOW, which provides equivalent functionality
to specifying 'times' as NULL, the call succeeds. I think that it should fail
with the error EACCES in this case.

4. A further bug relates to tradition...

To: <mtk.manpages@...>
Cc: <linux-fsdevel@...>, <drepper@...>, <akpm@...>, <linux-kernel@...>, <linux-man@...>
Date: Wednesday, April 23, 2008 - 5:37 am

[Please, please, please always CC linux-fsdevel on VFS related work.

This seems wrong. Why exactly was this change made?

Setting the time to inode->i_atime is *not* the same as not setting
the time. For some filesystems i_atime is just a cached value, that
may or may not match the actual last access time. For those

So this is a no-op? In which case this check could be moved to the
top of the function to just return zero.

--

To: Michael Kerrisk <mtk.manpages@...>
Cc: Andrew Morton <akpm@...>, lkml <linux-kernel@...>, <linux-man@...>
Date: Monday, April 21, 2008 - 2:20 am

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

This is probably a necessary change. Non-synchronized changes might be

Is this something I changed? I doubt I added this.

- --
➧ Ulrich Drepper ➧ Red Hat, Inc. ➧ 444 Castro St ➧ Mountain View, CA ❖
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org

iEYEARECAAYFAkgMMjsACgkQ2ijCOnn/RHT9dwCgxhprkeAg86sW11ilKtHaVYtO
Ae0An18utIREI/MnfwPO5HixxZbJz7zD
=hrvK
-----END PGP SIGNATURE-----
--

To: Ulrich Drepper <drepper@...>
Cc: Andrew Morton <akpm@...>, lkml <linux-kernel@...>, <linux-man@...>
Date: Monday, April 21, 2008 - 11:41 am

My only real objection to the implemented behavior is that it doesn't
follow the spec. It doesn't seem unreasonable to change the spec
here. Or is it already too late for that? (I suppose it may well

Well, I just went away and tested yet again, and utime[s]() with a
NULL second argument gives the behavior I describe (and always did) --
and utimensat() should behave the same way for the
(times == NULL && times[0].tv_nsec == UTIME_NOW && times[1].tv_nsec ==
UTIME_NOW)
case, but does not.

Cheers,

Michael

--
Michael Kerrisk
Maintainer of the Linux man-pages project
http://www.kernel.org/doc/man-pages/
Want to report a man-pages bug? Look here:
http://www.kernel.org/doc/man-pages/reporting_bugs.html
--

To: Ulrich Drepper <drepper@...>
Cc: Andrew Morton <akpm@...>, lkml <linux-kernel@...>, <linux-man@...>
Date: Thursday, April 17, 2008 - 2:06 pm

Ulrich,

Ping! Could you please review this patch.

Cheers,

Michael

On Tue, Apr 8, 2008 at 12:18 AM, Michael Kerrisk

--
Michael Kerrisk
Maintainer of the Linux man-pages project
http://www.kernel.org/doc/man-pages/
Want to report a man-pages bug? Look here:
http://www.kernel.org/doc/man-pages/reporting_bugs.html
--

Previous thread: inotify SIGIO documentation for inotify.7 man page by Michael Kerrisk on Monday, April 7, 2008 - 6:16 pm. (2 messages)

Next thread: [PATCH 1/1 resend][PPC] replace logical by bitand in pci_process_ISA_OF_ranges(), arch/powerpc/kernel/isa-bridge.c by Roel Kluin on Monday, April 7, 2008 - 6:26 pm. (3 messages)