summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiklos Szeredi <mszeredi@suse.cz>2007-10-16 23:27:07 -0700
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-17 08:42:52 -0700
commit043f46f6151df2c518988b5e41376e42491257b5 (patch)
tree036f75b27d139408da721aaa75ed41a9b737a83d
parent995e4286a047b32aebf8ce540908edb7fbd93f76 (diff)
VFS: check nanoseconds in utimensat
utimensat() (and possibly other callers of do_utimes()) didn't check if the nanosecond value was within the allowed range. Signed-off-by: Miklos Szeredi <mszeredi@suse.cz> Cc: Ulrich Drepper <drepper@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--fs/utimes.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/fs/utimes.c b/fs/utimes.c
index 682eb63b20a..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;