History

utimes: Make utimes y2038 safe

struct timespec is not y2038 safe on 32 bit machines. Replace timespec with y2038 safe struct timespec64. Note that the patch only changes the internals without modifying the syscall interfaces. This will be part of a separate series.

Deepa Dinamani committed 9 years ago

Commit aaed2dd1 parent 7ff28193 files · +14 −13Browse files

Unified · Split

3 files
  1. fs/utimes.c +12 −11
  2. include/linux/time.h +1 −1
  3. init/initramfs.c +1 −1
fs/utimes.c+12−11
@@ -22,7 +22,7 @@ · 21 unmodified lines
2222 */
2323 SYSCALL_DEFINE2(utime, char __user *, filename, struct utimbuf __user *, times)
2424 {
25− struct timespec tv[2];
25+ struct timespec64 tv[2];
2626
2727 if (times) {
2828 if (get_user(tv[0].tv_sec, &times->actime) ||
@@ -44,7 +44,7 @@ static bool nsec_valid(long nsec) · 15 unmodified lines
4444 return nsec >= 0 && nsec <= 999999999;
4545 }
4646
47−static int utimes_common(const struct path *path, struct timespec *times)
47+static int utimes_common(const struct path *path, struct timespec64 *times)
4848 {
4949 int error;
5050 struct iattr newattrs;
@@ -115,7 +115,7 @@ out: · 64 unmodified lines
115115 * must be owner or have write permission.
116116 * Else, update from *times, must be owner or super user.
117117 */
118−long do_utimes(int dfd, const char __user *filename, struct timespec *times,
118+long do_utimes(int dfd, const char __user *filename, struct timespec64 *times,
119119 int flags)
120120 {
121121 int error = -EINVAL;
@@ -167,10 +167,11 @@ out: · 45 unmodified lines
167167 SYSCALL_DEFINE4(utimensat, int, dfd, const char __user *, filename,
168168 struct timespec __user *, utimes, int, flags)
169169 {
170− struct timespec tstimes[2];
170+ struct timespec64 tstimes[2];
171171
172172 if (utimes) {
173− if (copy_from_user(&tstimes, utimes, sizeof(tstimes)))
173+ if ((get_timespec64(&tstimes[0], &utimes[0]) ||
174+ get_timespec64(&tstimes[1], &utimes[1])))
174175 return -EFAULT;
175176
176177 /* Nothing to do, we must not even check the path. */
@@ -186,7 +187,7 @@ SYSCALL_DEFINE3(futimesat, int, dfd, const char __user *, filename, · 9 unmodified lines
186187 struct timeval __user *, utimes)
187188 {
188189 struct timeval times[2];
189− struct timespec tstimes[2];
190+ struct timespec64 tstimes[2];
190191
191192 if (utimes) {
192193 if (copy_from_user(&times, utimes, sizeof(times)))
@@ -224,7 +225,7 @@ SYSCALL_DEFINE2(utimes, char __user *, filename, · 31 unmodified lines
224225 COMPAT_SYSCALL_DEFINE2(utime, const char __user *, filename,
225226 struct compat_utimbuf __user *, t)
226227 {
227− struct timespec tv[2];
228+ struct timespec64 tv[2];
228229
229230 if (t) {
230231 if (get_user(tv[0].tv_sec, &t->actime) ||
@@ -238,11 +239,11 @@ COMPAT_SYSCALL_DEFINE2(utime, const char __user *, filename, · 7 unmodified lines
238239
239240 COMPAT_SYSCALL_DEFINE4(utimensat, unsigned int, dfd, const char __user *, filename, struct compat_timespec __user *, t, int, flags)
240241 {
241− struct timespec tv[2];
242+ struct timespec64 tv[2];
242243
243244 if (t) {
244− if (compat_get_timespec(&tv[0], &t[0]) ||
245− compat_get_timespec(&tv[1], &t[1]))
245+ if (compat_get_timespec64(&tv[0], &t[0]) ||
246+ compat_get_timespec64(&tv[1], &t[1]))
246247 return -EFAULT;
247248
248249 if (tv[0].tv_nsec == UTIME_OMIT && tv[1].tv_nsec == UTIME_OMIT)
@@ -253,7 +254,7 @@ COMPAT_SYSCALL_DEFINE4(utimensat, unsigned int, dfd, const char __user *, filena · 4 unmodified lines
253254
254255 COMPAT_SYSCALL_DEFINE3(futimesat, unsigned int, dfd, const char __user *, filename, struct compat_timeval __user *, t)
255256 {
256− struct timespec tv[2];
257+ struct timespec64 tv[2];
257258
258259 if (t) {
259260 if (get_user(tv[0].tv_sec, &t[0].tv_sec) ||
include/linux/time.h+1−1
@@ -178,7 +178,7 @@ extern int do_setitimer(int which, struct itimerval *value, · 177 unmodified lines
178178 struct itimerval *ovalue);
179179 extern int do_getitimer(int which, struct itimerval *value);
180180
181−extern long do_utimes(int dfd, const char __user *filename, struct timespec *times, int flags);
181+extern long do_utimes(int dfd, const char __user *filename, struct timespec64 *times, int flags);
182182
183183 /*
184184 * Similar to the struct tm in userspace <time.h>, but it needs to be here so
init/initramfs.c+1−1
@@ -110,7 +110,7 @@ static void __init free_hash(void) · 109 unmodified lines
110110
111111 static long __init do_utime(char *filename, time_t mtime)
112112 {
113− struct timespec t[2];
113+ struct timespec64 t[2];
114114
115115 t[0].tv_sec = mtime;
116116 t[0].tv_nsec = 0;