X-Git-Url: http://pilppa.org/gitweb/?a=blobdiff_plain;f=fs%2Futimes.c;h=b9912ecbee241231ca0b776d9131af1e2643d80a;hb=c7a6cbc01b955906e64f06ad2364098260c7341d;hp=480f7c8c29da13ee10941f5cf5e560faffbde0a6;hpb=eedab661a51966c454e38c17266a531aa58b4a98;p=linux-2.6-omap-h63xx.git diff --git a/fs/utimes.c b/fs/utimes.c index 480f7c8c29d..b9912ecbee2 100644 --- a/fs/utimes.c +++ b/fs/utimes.c @@ -38,6 +38,14 @@ asmlinkage long sys_utime(char __user *filename, struct utimbuf __user *times) #endif +static bool nsec_valid(long nsec) +{ + if (nsec == UTIME_OMIT || nsec == UTIME_NOW) + return true; + + return nsec >= 0 && nsec <= 999999999; +} + /* If times==NULL, set access and modification to current time, * must be owner or have write permission. * Else, update from *times, must be owner or super user. @@ -52,6 +60,11 @@ long do_utimes(int dfd, char __user *filename, struct timespec *times, int flags struct file *f = NULL; error = -EINVAL; + if (times && (!nsec_valid(times[0].tv_nsec) || + !nsec_valid(times[1].tv_nsec))) { + goto out; + } + if (flags & ~AT_SYMLINK_NOFOLLOW) goto out; @@ -106,9 +119,16 @@ long do_utimes(int dfd, char __user *filename, struct timespec *times, int flags if (IS_IMMUTABLE(inode)) goto dput_and_out; - if (current->fsuid != inode->i_uid && - (error = vfs_permission(&nd, MAY_WRITE)) != 0) - goto dput_and_out; + if (!is_owner_or_cap(inode)) { + if (f) { + if (!(f->f_mode & FMODE_WRITE)) + goto dput_and_out; + } else { + error = vfs_permission(&nd, MAY_WRITE); + if (error) + goto dput_and_out; + } + } } mutex_lock(&inode->i_mutex); error = notify_change(dentry, &newattrs);