> The POSIX.1 draft spec for futimens()/utimensat() says: > > Only a process with the effective user ID equal to the > user ID of the file, *or with write access to the file*, > or with appropriate privileges may use futimens() or > utimensat() with a null pointer as the times argument > or with both tv_nsec fields set to the special value > UTIME_NOW. > > The important piece here is "with write access to the file", and > this matters for futimens(), which deals with an argument that > is a file descriptor referring to the file whose timestamps are > being updated, The standard is saying that the "writability" > check is based on the file permissions, not the access mode with > which the file is opened. (This behavior is consistent with the > semantics of FreeBSD's futimes().) However, Linux is currently > doing the latter -- futimens(fd, times) is a library > function implemented as > > utimensat(fd, NULL, times, 0) > > and within the utimensat() implementation we have the code: > > f = fget(dfd); // dfd is 'fd' > ... > if (f) { > if (!(f->f_mode & FMODE_WRITE)) > goto mnt_drop_write_and_out; > > The check should instead be based on the file permissions. > > Thanks to Miklos for pointing out how to do this check. > > CC: Miklos Szeredi <miklos@xxxxxxxxxx> > CC: Al Viro <viro@xxxxxxxxxxxxxxxxxx> > CC: Ulrich Drepper <drepper@xxxxxxxxxx> > Signed-off-by: Michael Kerrisk <mtk.manpages@xxxxxxxxx> > > --- linux-2.6.26-rc4/fs/utimes.c 2008-06-03 23:13:31.000000000 +0200 > +++ linux-2.6.26-rc4-utimensat-fix-v4/fs/utimes.c 2008-06-03 23:15:12.000000000 +0200 > @@ -137,7 +137,8 @@ > > if (!is_owner_or_cap(inode)) { > if (f) { > - if (!(f->f_mode & FMODE_WRITE)) > + error = permission(inode, MAY_WRITE, NULL); > + if (error) > goto mnt_drop_write_and_out; > } else { > error = vfs_permission(&nd, MAY_WRITE); At which point the "if (f)" and the "else" branches become equivalent (the nameidata isn't interesting in the other case either). So that could be written as: if (!is_owner_or_cap(inode)) { error = permission(inode, MAY_WRITE, NULL); if (error) goto mnt_drop_write_and_out; } Miklos -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html