lkml.org 
[lkml]   [2007]   [Nov]   [1]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Subject[PATCH 13/27] r-o-bind-mounts-elevate-write-count-for-do_utimes
    From
    Date

    Now includes fix for oops seen by akpm.

    "never let a libc developer write your kernel code" - hch

    "nor, apparently, a kernel developer" - akpm

    Acked-by: Christoph Hellwig <hch@infradead.org>
    Signed-off-by: Dave Hansen <haveblue@us.ibm.com>
    Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
    Cc: Christoph Hellwig <hch@lst.de>
    Cc: Valdis Kletnieks <Valdis.Kletnieks@vt.edu>
    Cc: Balbir Singh <balbir@in.ibm.com>
    Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
    ---

    linux-2.6.git-dave/fs/utimes.c | 18 ++++++++++++------
    1 file changed, 12 insertions(+), 6 deletions(-)

    diff -puN fs/utimes.c~r-o-bind-mounts-elevate-write-count-for-do_utimes fs/utimes.c
    --- linux-2.6.git/fs/utimes.c~r-o-bind-mounts-elevate-write-count-for-do_utimes 2007-11-01 14:46:13.000000000 -0700
    +++ linux-2.6.git-dave/fs/utimes.c 2007-11-01 14:46:13.000000000 -0700
    @@ -2,6 +2,7 @@
    #include <linux/file.h>
    #include <linux/fs.h>
    #include <linux/linkage.h>
    +#include <linux/mount.h>
    #include <linux/namei.h>
    #include <linux/sched.h>
    #include <linux/stat.h>
    @@ -58,6 +59,7 @@ long do_utimes(int dfd, char __user *fil
    struct inode *inode;
    struct iattr newattrs;
    struct file *f = NULL;
    + struct vfsmount *mnt;

    error = -EINVAL;
    if (times && (!nsec_valid(times[0].tv_nsec) ||
    @@ -78,18 +80,20 @@ long do_utimes(int dfd, char __user *fil
    if (!f)
    goto out;
    dentry = f->f_path.dentry;
    + mnt = f->f_path.mnt;
    } else {
    error = __user_walk_fd(dfd, filename, (flags & AT_SYMLINK_NOFOLLOW) ? 0 : LOOKUP_FOLLOW, &nd);
    if (error)
    goto out;

    dentry = nd.dentry;
    + mnt = nd.mnt;
    }

    inode = dentry->d_inode;

    - error = -EROFS;
    - if (IS_RDONLY(inode))
    + error = mnt_want_write(mnt);
    + if (error)
    goto dput_and_out;

    /* Don't worry, the checks are done in inode_change_ok() */
    @@ -97,7 +101,7 @@ long do_utimes(int dfd, char __user *fil
    if (times) {
    error = -EPERM;
    if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
    - goto dput_and_out;
    + goto mnt_drop_write_and_out;

    if (times[0].tv_nsec == UTIME_OMIT)
    newattrs.ia_valid &= ~ATTR_ATIME;
    @@ -117,22 +121,24 @@ long do_utimes(int dfd, char __user *fil
    } else {
    error = -EACCES;
    if (IS_IMMUTABLE(inode))
    - goto dput_and_out;
    + goto mnt_drop_write_and_out;

    if (!is_owner_or_cap(inode)) {
    if (f) {
    if (!(f->f_mode & FMODE_WRITE))
    - goto dput_and_out;
    + goto mnt_drop_write_and_out;
    } else {
    error = vfs_permission(&nd, MAY_WRITE);
    if (error)
    - goto dput_and_out;
    + goto mnt_drop_write_and_out;
    }
    }
    }
    mutex_lock(&inode->i_mutex);
    error = notify_change(dentry, &newattrs);
    mutex_unlock(&inode->i_mutex);
    +mnt_drop_write_and_out:
    + mnt_drop_write(mnt);
    dput_and_out:
    if (f)
    fput(f);
    _
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/
    \
     
     \ /
      Last update: 2007-11-02 00:17    [W:0.024 / U:0.444 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site