Commit aaed2dd8 authored by Deepa Dinamani's avatar Deepa Dinamani Committed by Al Viro

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.
Signed-off-by: default avatarDeepa Dinamani <deepa.kernel@gmail.com>
Reviewed-by: default avatarArnd Bergmann <arnd@arndb.de>
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 7ff2819e
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
*/ */
SYSCALL_DEFINE2(utime, char __user *, filename, struct utimbuf __user *, times) SYSCALL_DEFINE2(utime, char __user *, filename, struct utimbuf __user *, times)
{ {
struct timespec tv[2]; struct timespec64 tv[2];
if (times) { if (times) {
if (get_user(tv[0].tv_sec, &times->actime) || if (get_user(tv[0].tv_sec, &times->actime) ||
...@@ -44,7 +44,7 @@ static bool nsec_valid(long nsec) ...@@ -44,7 +44,7 @@ static bool nsec_valid(long nsec)
return nsec >= 0 && nsec <= 999999999; return nsec >= 0 && nsec <= 999999999;
} }
static int utimes_common(const struct path *path, struct timespec *times) static int utimes_common(const struct path *path, struct timespec64 *times)
{ {
int error; int error;
struct iattr newattrs; struct iattr newattrs;
...@@ -115,7 +115,7 @@ static int utimes_common(const struct path *path, struct timespec *times) ...@@ -115,7 +115,7 @@ static int utimes_common(const struct path *path, struct timespec *times)
* must be owner or have write permission. * must be owner or have write permission.
* Else, update from *times, must be owner or super user. * Else, update from *times, must be owner or super user.
*/ */
long do_utimes(int dfd, const char __user *filename, struct timespec *times, long do_utimes(int dfd, const char __user *filename, struct timespec64 *times,
int flags) int flags)
{ {
int error = -EINVAL; int error = -EINVAL;
...@@ -167,10 +167,11 @@ long do_utimes(int dfd, const char __user *filename, struct timespec *times, ...@@ -167,10 +167,11 @@ long do_utimes(int dfd, const char __user *filename, struct timespec *times,
SYSCALL_DEFINE4(utimensat, int, dfd, const char __user *, filename, SYSCALL_DEFINE4(utimensat, int, dfd, const char __user *, filename,
struct timespec __user *, utimes, int, flags) struct timespec __user *, utimes, int, flags)
{ {
struct timespec tstimes[2]; struct timespec64 tstimes[2];
if (utimes) { if (utimes) {
if (copy_from_user(&tstimes, utimes, sizeof(tstimes))) if ((get_timespec64(&tstimes[0], &utimes[0]) ||
get_timespec64(&tstimes[1], &utimes[1])))
return -EFAULT; return -EFAULT;
/* Nothing to do, we must not even check the path. */ /* Nothing to do, we must not even check the path. */
...@@ -186,7 +187,7 @@ SYSCALL_DEFINE3(futimesat, int, dfd, const char __user *, filename, ...@@ -186,7 +187,7 @@ SYSCALL_DEFINE3(futimesat, int, dfd, const char __user *, filename,
struct timeval __user *, utimes) struct timeval __user *, utimes)
{ {
struct timeval times[2]; struct timeval times[2];
struct timespec tstimes[2]; struct timespec64 tstimes[2];
if (utimes) { if (utimes) {
if (copy_from_user(&times, utimes, sizeof(times))) if (copy_from_user(&times, utimes, sizeof(times)))
...@@ -224,7 +225,7 @@ SYSCALL_DEFINE2(utimes, char __user *, filename, ...@@ -224,7 +225,7 @@ SYSCALL_DEFINE2(utimes, char __user *, filename,
COMPAT_SYSCALL_DEFINE2(utime, const char __user *, filename, COMPAT_SYSCALL_DEFINE2(utime, const char __user *, filename,
struct compat_utimbuf __user *, t) struct compat_utimbuf __user *, t)
{ {
struct timespec tv[2]; struct timespec64 tv[2];
if (t) { if (t) {
if (get_user(tv[0].tv_sec, &t->actime) || if (get_user(tv[0].tv_sec, &t->actime) ||
...@@ -238,11 +239,11 @@ COMPAT_SYSCALL_DEFINE2(utime, const char __user *, filename, ...@@ -238,11 +239,11 @@ COMPAT_SYSCALL_DEFINE2(utime, const char __user *, filename,
COMPAT_SYSCALL_DEFINE4(utimensat, unsigned int, dfd, const char __user *, filename, struct compat_timespec __user *, t, int, flags) COMPAT_SYSCALL_DEFINE4(utimensat, unsigned int, dfd, const char __user *, filename, struct compat_timespec __user *, t, int, flags)
{ {
struct timespec tv[2]; struct timespec64 tv[2];
if (t) { if (t) {
if (compat_get_timespec(&tv[0], &t[0]) || if (compat_get_timespec64(&tv[0], &t[0]) ||
compat_get_timespec(&tv[1], &t[1])) compat_get_timespec64(&tv[1], &t[1]))
return -EFAULT; return -EFAULT;
if (tv[0].tv_nsec == UTIME_OMIT && tv[1].tv_nsec == UTIME_OMIT) 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 ...@@ -253,7 +254,7 @@ COMPAT_SYSCALL_DEFINE4(utimensat, unsigned int, dfd, const char __user *, filena
COMPAT_SYSCALL_DEFINE3(futimesat, unsigned int, dfd, const char __user *, filename, struct compat_timeval __user *, t) COMPAT_SYSCALL_DEFINE3(futimesat, unsigned int, dfd, const char __user *, filename, struct compat_timeval __user *, t)
{ {
struct timespec tv[2]; struct timespec64 tv[2];
if (t) { if (t) {
if (get_user(tv[0].tv_sec, &t[0].tv_sec) || if (get_user(tv[0].tv_sec, &t[0].tv_sec) ||
......
...@@ -178,7 +178,7 @@ extern int do_setitimer(int which, struct itimerval *value, ...@@ -178,7 +178,7 @@ extern int do_setitimer(int which, struct itimerval *value,
struct itimerval *ovalue); struct itimerval *ovalue);
extern int do_getitimer(int which, struct itimerval *value); extern int do_getitimer(int which, struct itimerval *value);
extern long do_utimes(int dfd, const char __user *filename, struct timespec *times, int flags); extern long do_utimes(int dfd, const char __user *filename, struct timespec64 *times, int flags);
/* /*
* Similar to the struct tm in userspace <time.h>, but it needs to be here so * Similar to the struct tm in userspace <time.h>, but it needs to be here so
......
...@@ -110,7 +110,7 @@ static void __init free_hash(void) ...@@ -110,7 +110,7 @@ static void __init free_hash(void)
static long __init do_utime(char *filename, time_t mtime) static long __init do_utime(char *filename, time_t mtime)
{ {
struct timespec t[2]; struct timespec64 t[2];
t[0].tv_sec = mtime; t[0].tv_sec = mtime;
t[0].tv_nsec = 0; t[0].tv_nsec = 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment