y2038: rusage: use __kernel_old_timeval
authorArnd Bergmann <arnd@arndb.de>
Fri, 25 Oct 2019 20:46:48 +0000 (22:46 +0200)
committerArnd Bergmann <arnd@arndb.de>
Fri, 15 Nov 2019 13:38:29 +0000 (14:38 +0100)
There are two 'struct timeval' fields in 'struct rusage'.

Unfortunately the definition of timeval is now ambiguous when used in
user space with a libc that has a 64-bit time_t, and this also changes
the 'rusage' definition in user space in a way that is incompatible with
the system call interface.

While there is no good solution to avoid all ambiguity here, change
the definition in the kernel headers to be compatible with the kernel
ABI, using __kernel_old_timeval as an unambiguous base type.

In previous discussions, there was also a plan to add a replacement
for rusage based on 64-bit timestamps and nanosecond resolution,
i.e. 'struct __kernel_timespec'. I have patches for that as well,
if anyone thinks we should do that.

Reviewed-by: Cyrill Gorcunov <gorcunov@gmail.com>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
arch/alpha/kernel/osf_sys.c
include/uapi/linux/resource.h
kernel/sys.c

index bf497b8b0ec60ba4f31f34d67bd86ab89a173096..bbe7a0da6264f31a806d9315f18a8104afe67f12 100644 (file)
@@ -963,7 +963,7 @@ put_tv32(struct timeval32 __user *o, struct timespec64 *i)
 }
 
 static inline long
-put_tv_to_tv32(struct timeval32 __user *o, struct timeval *i)
+put_tv_to_tv32(struct timeval32 __user *o, struct __kernel_old_timeval *i)
 {
        return copy_to_user(o, &(struct timeval32){
                                .tv_sec = i->tv_sec,
index cc00fd07963179e58d7b7d6051a6dc1f0794aebd..74ef57b38f9f51f0d41011914d2dae44c0987256 100644 (file)
@@ -22,8 +22,8 @@
 #define        RUSAGE_THREAD   1               /* only the calling thread */
 
 struct rusage {
-       struct timeval ru_utime;        /* user time used */
-       struct timeval ru_stime;        /* system time used */
+       struct __kernel_old_timeval ru_utime;   /* user time used */
+       struct __kernel_old_timeval ru_stime;   /* system time used */
        __kernel_long_t ru_maxrss;      /* maximum resident set size */
        __kernel_long_t ru_ixrss;       /* integral shared memory size */
        __kernel_long_t ru_idrss;       /* integral unshared data size */
index a611d1d58c7d00525247edff32211cc9586f2c9e..d3aef31e24dca203d39ae59fcb0027a287fd8001 100644 (file)
@@ -1763,8 +1763,8 @@ void getrusage(struct task_struct *p, int who, struct rusage *r)
        unlock_task_sighand(p, &flags);
 
 out:
-       r->ru_utime = ns_to_timeval(utime);
-       r->ru_stime = ns_to_timeval(stime);
+       r->ru_utime = ns_to_kernel_old_timeval(utime);
+       r->ru_stime = ns_to_kernel_old_timeval(stime);
 
        if (who != RUSAGE_CHILDREN) {
                struct mm_struct *mm = get_task_mm(p);