On Sun, Nov 12, 2017 at 08:19:42PM +0100, Otto Moerbeek wrote: > On Sun, Nov 12, 2017 at 08:12:26PM +0100, Mark Kettenis wrote: > > > > Date: Sun, 12 Nov 2017 19:54:24 +0100 > > > From: Otto Moerbeek <o...@drijf.net> > > > > > > On Sun, Nov 12, 2017 at 06:29:38PM +0100, Bruno Haible wrote: > > > > > > > >Synopsis: file timestamps wrap around > > > > >Category: <PR category (one line)> > > > > >Environment: > > > > System : OpenBSD 6.0 > > > > Details : OpenBSD 6.0 (GENERIC) #1917: Tue Jul 26 12:48:33 > > > > MDT 2016 > > > > > > > > dera...@i386.openbsd.org:/usr/src/sys/arch/i386/compile/GENERIC > > > > > > > > Architecture: OpenBSD.i386 > > > > Machine : i386 > > > > >Description: > > > > > > > > Use of 'touch', the kernel's file system, and the 'ls' program produces > > > > unintended time stamps. Time stamps that were meant to be in the past > > > > come out as time stamps in the future, and vice versa. > > > > > > > > >How-To-Repeat: > > > > > > > > $ export TZ=UTC0 > > > > > > > > $ touch -t 190101010000 in > > > > $ ls -l in > > > > -rw-r--r-- 1 bruno bruno 0 Feb 6 2037 in > > > > $ ls -lT in > > > > -rw-r--r-- 1 bruno bruno 0 Feb 6 06:28:16 2037 in > > > > > > > > $ touch -t 203801190314.08 in2 > > > > $ ls -l in2 > > > > -rw-r--r-- 1 bruno bruno 0 Dec 13 1901 in2 > > > > $ ls -lT in2 > > > > -rw-r--r-- 1 bruno bruno 0 Dec 13 20:45:52 1901 in2 > > > > > > > > $ touch -t 210602070628.15 in3 > > > > $ ls -l in3 > > > > -rw-r--r-- 1 bruno bruno 0 Dec 31 1969 in3 > > > > $ ls -lT in3 > > > > -rw-r--r-- 1 bruno bruno 0 Dec 31 23:59:59 in3 > > > > > > > > Credit for these instructions goes to Paul Eggert. > > > > https://lists.gnu.org/archive/html/bug-gzip/2017-11/msg00020.html > > > > > > > > >Fix: > > > > > > > > The 'touch' program should properly validate its input, and reject > > > > time stamps that it or the kernel's file system cannot handle. > > > > See https://cwe.mitre.org/data/definitions/20.html > > > > > > OpenBSD uses ffs1 by default. I suppose that is waht you call the > > > "kernel filesystem". If you would have ran you test cases using an > > > ffs2 filesystem it would have worked as expected: > > > > > > -rw-r--r-- 1 otto wheel 0 Jan 1 1901 in > > > -rw-r--r-- 1 otto wheel 0 Jan 19 2038 in2 > > > -rw-r--r-- 1 otto wheel 0 Feb 7 2106 in3 > > > > > > As for the general case, for timestamps before 1970, we *are* allowed > > > to have implementation defined behaviour. Posix says: > > > > > > "If the resulting time precedes the Epoch, the behavior is > > > implementation-defined. If the time cannot be represented as the > > > file's timestamp, touch shall exit immediately with an error status." > > > > > > For timestamps from 2038 the big problem is that implementing this is > > > a challange, since the kernel (let alone touch(1)) does not know the > > > filesystem's timestamp limitations in all cases. Things especially > > > become hairy in the case of network file systems. > > > > It certainly doesn't make sense to have touch(1) do the checks. > > > > Note that POSIX says that futimens(2) shall faill if: > > > > [EINVAL] > > A new file timestamp would be a value whose tv_sec component is > > not a value supported by the file system. > > > > which is something we don't implement for the filesystems where it > > matters. Also note that NFSv3 still uses 32 bits for storing the > > timestamp so there wil;l be issues regardless of the underlying > > filesystem. > > One thing to consider: touch first creates a file using > open(...O_CREAT...) and then sets it's timestamp using futimens(2). > That means that we can only determine something went wrong after the > fact and if there's would be an error we end up with a file with the > wrong filestamp. > > -Otto
to be more explicit: a conforming implementation of touch(1) should have knowledge of the filesystem, since Posix claims that touch(1) should do the validation taking into account the filesystem limitations. If we do not want to do that and rely on futimens(2) to detect the error cases, we have cases where we end up with wrong timestamp because of the two-stelp way of doing things. We could delete delete the file with the wrong filestamp on error, but that is a race condition I would not like to have. -Otto