[patch for 2.6.26 4/4] vfs: utimensat(): fix write access check for futimens()

Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]
From: Linux Kernel Mailing List
Date: Sunday, June 29, 2008 - 12:59 pm

Gitweb:     http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=c70f84...
Commit:     c70f84417429f41519be0197a1092a53c2201f47
Parent:     4cca92264e61a90b43fc4e076cd25b7f4e16dc61
Author:     Michael Kerrisk <mtk.manpages@googlemail.com>
AuthorDate: Mon Jun 9 21:16:09 2008 -0700
Committer:  Al Viro <viro@zeniv.linux.org.uk>
CommitDate: Mon Jun 23 08:43:52 2008 -0400

    [patch for 2.6.26 4/4] vfs: utimensat(): fix write access check for futimens()
    
    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.
    Miklos also pointed out a simplification that could be
    made to my first version of this patch, since the checks
    for the pathname and file descriptor cases can now be
    conflated.
    
    Acked-by: Miklos Szeredi <miklos@szeredi.hu>
    Cc: Al Viro <viro@zeniv.linux.org.uk>
    Cc: Ulrich Drepper <drepper@redhat.com>
    Signed-off-by: Michael Kerrisk <mtk.manpages@gmail.com>
    Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
    Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 fs/utimes.c |   11 +++--------
 1 files changed, 3 insertions(+), 8 deletions(-)

diff --git a/fs/utimes.c b/fs/utimes.c
index 118d1c3..b6b664e 100644
--- a/fs/utimes.c
+++ b/fs/utimes.c
@@ -148,14 +148,9 @@ long do_utimes(int dfd, char __user *filename, struct timespec *times, int flags
 			goto mnt_drop_write_and_out;
 
 		if (!is_owner_or_cap(inode)) {
-			if (f) {
-				if (!(f->f_mode & FMODE_WRITE))
-					goto mnt_drop_write_and_out;
-			} else {
-				error = vfs_permission(&nd, MAY_WRITE);
-				if (error)
-					goto mnt_drop_write_and_out;
-			}
+			error = permission(inode, MAY_WRITE, NULL);
+			if (error)
+				goto mnt_drop_write_and_out;
 		}
 	}
 	mutex_lock(&inode->i_mutex);
--
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]

Messages in current thread:
[patch for 2.6.26 4/4] vfs: utimensat(): fix write access ..., Linux Kernel Mailing ..., (Sun Jun 29, 12:59 pm)