diff options
Diffstat (limited to 'fs/compat.c')
-rw-r--r-- | fs/compat.c | 43 |
1 files changed, 35 insertions, 8 deletions
diff --git a/fs/compat.c b/fs/compat.c index 9f6248dfd9d9..9cf75df9b2bb 100644 --- a/fs/compat.c +++ b/fs/compat.c | |||
@@ -77,30 +77,57 @@ int compat_printk(const char *fmt, ...) | |||
77 | */ | 77 | */ |
78 | asmlinkage long compat_sys_utime(char __user *filename, struct compat_utimbuf __user *t) | 78 | asmlinkage long compat_sys_utime(char __user *filename, struct compat_utimbuf __user *t) |
79 | { | 79 | { |
80 | struct timeval tv[2]; | 80 | struct timespec tv[2]; |
81 | 81 | ||
82 | if (t) { | 82 | if (t) { |
83 | if (get_user(tv[0].tv_sec, &t->actime) || | 83 | if (get_user(tv[0].tv_sec, &t->actime) || |
84 | get_user(tv[1].tv_sec, &t->modtime)) | 84 | get_user(tv[1].tv_sec, &t->modtime)) |
85 | return -EFAULT; | 85 | return -EFAULT; |
86 | tv[0].tv_usec = 0; | 86 | tv[0].tv_nsec = 0; |
87 | tv[1].tv_usec = 0; | 87 | tv[1].tv_nsec = 0; |
88 | } | 88 | } |
89 | return do_utimes(AT_FDCWD, filename, t ? tv : NULL); | 89 | return do_utimes(AT_FDCWD, filename, t ? tv : NULL, 0); |
90 | } | ||
91 | |||
92 | asmlinkage long compat_sys_utimensat(unsigned int dfd, char __user *filename, struct compat_timespec __user *t, int flags) | ||
93 | { | ||
94 | struct timespec tv[2]; | ||
95 | |||
96 | if (t) { | ||
97 | if (get_compat_timespec(&tv[0], &t[0]) || | ||
98 | get_compat_timespec(&tv[1], &t[1])) | ||
99 | return -EFAULT; | ||
100 | |||
101 | if ((tv[0].tv_nsec == UTIME_OMIT || tv[0].tv_nsec == UTIME_NOW) | ||
102 | && tv[0].tv_sec != 0) | ||
103 | return -EINVAL; | ||
104 | if ((tv[1].tv_nsec == UTIME_OMIT || tv[1].tv_nsec == UTIME_NOW) | ||
105 | && tv[1].tv_sec != 0) | ||
106 | return -EINVAL; | ||
107 | |||
108 | if (tv[0].tv_nsec == UTIME_OMIT && tv[1].tv_nsec == UTIME_OMIT) | ||
109 | return 0; | ||
110 | } | ||
111 | return do_utimes(dfd, filename, t ? tv : NULL, flags); | ||
90 | } | 112 | } |
91 | 113 | ||
92 | asmlinkage long compat_sys_futimesat(unsigned int dfd, char __user *filename, struct compat_timeval __user *t) | 114 | asmlinkage long compat_sys_futimesat(unsigned int dfd, char __user *filename, struct compat_timeval __user *t) |
93 | { | 115 | { |
94 | struct timeval tv[2]; | 116 | struct timespec tv[2]; |
95 | 117 | ||
96 | if (t) { | 118 | if (t) { |
97 | if (get_user(tv[0].tv_sec, &t[0].tv_sec) || | 119 | if (get_user(tv[0].tv_sec, &t[0].tv_sec) || |
98 | get_user(tv[0].tv_usec, &t[0].tv_usec) || | 120 | get_user(tv[0].tv_nsec, &t[0].tv_usec) || |
99 | get_user(tv[1].tv_sec, &t[1].tv_sec) || | 121 | get_user(tv[1].tv_sec, &t[1].tv_sec) || |
100 | get_user(tv[1].tv_usec, &t[1].tv_usec)) | 122 | get_user(tv[1].tv_nsec, &t[1].tv_usec)) |
101 | return -EFAULT; | 123 | return -EFAULT; |
124 | if (tv[0].tv_nsec >= 1000000 || tv[0].tv_nsec < 0 || | ||
125 | tv[1].tv_nsec >= 1000000 || tv[1].tv_nsec < 0) | ||
126 | return -EINVAL; | ||
127 | tv[0].tv_nsec *= 1000; | ||
128 | tv[1].tv_nsec *= 1000; | ||
102 | } | 129 | } |
103 | return do_utimes(dfd, filename, t ? tv : NULL); | 130 | return do_utimes(dfd, filename, t ? tv : NULL, 0); |
104 | } | 131 | } |
105 | 132 | ||
106 | asmlinkage long compat_sys_utimes(char __user *filename, struct compat_timeval __user *t) | 133 | asmlinkage long compat_sys_utimes(char __user *filename, struct compat_timeval __user *t) |