* [PATCH 00/23] y2038 cleanups @ 2019-11-08 21:02 Arnd Bergmann 2019-11-08 21:12 ` [PATCH 10/23] y2038: uapi: change __kernel_time_t to __kernel_old_time_t Arnd Bergmann ` (4 more replies) 0 siblings, 5 replies; 19+ messages in thread From: Arnd Bergmann @ 2019-11-08 21:02 UTC (permalink / raw) To: y2038 Cc: linux-kernel, Arnd Bergmann, rth, tony.luck, paul.burton, green.hu, deller, mpe, davem, tglx, x86, jdike, richard, viro, bcrl, john.stultz, sboyd, rostedt, vincenzo.frascino, paul, sds, eparis, peterz, will, deepa.kernel, christian, heiko.carstens, christophe.leroy, ebiederm, linux-alpha, linux-ia64, linux-mips, linux-parisc, linuxppc-dev, sparclinux, linux-um, linux-fsdevel This is a series of cleanups for the y2038 work, mostly intended for namespace cleaning: the kernel defines the traditional time_t, timeval and timespec types that often lead to y2038-unsafe code. Even though the unsafe usage is mostly gone from the kernel, having the types and associated functions around means that we can still grow new users, and that we may be missing conversions to safe types that actually matter. As there is no rush on any of these patches, I would either queue them up in linux-next through my y2038 branch, or Thomas could add them to the tip tree if he wants. As mentioned in another series, this is part of a larger effort to fix all the remaining bits and pieces that are not completed yet from the y2038 conversion, and the full set can be found at: https://git.kernel.org/pub/scm/linux/kernel/git/arnd/playground.git/log/?h=y2038-endgame Maintainers, please review and provide Acks. Let me know if you have any opinion on whether we should do the include last two patches of this series or not. Arnd Arnd Bergmann (23): y2038: remove CONFIG_64BIT_TIME y2038: add __kernel_old_timespec and __kernel_old_time_t y2038: vdso: change timeval to __kernel_old_timeval y2038: vdso: change timespec to __kernel_old_timespec y2038: vdso: change time_t to __kernel_old_time_t y2038: vdso: nds32: open-code timespec_add_ns() y2038: vdso: powerpc: avoid timespec references y2038: ipc: remove __kernel_time_t reference from headers y2038: stat: avoid 'time_t' in 'struct stat' y2038: uapi: change __kernel_time_t to __kernel_old_time_t y2038: rusage: use __kernel_old_timeval y2038: syscalls: change remaining timeval to __kernel_old_timeval y2038: socket: remove timespec reference in timestamping y2038: make ns_to_compat_timeval use __kernel_old_timeval y2038: elfcore: Use __kernel_old_timeval for process times y2038: timerfd: Use timespec64 internally y2038: time: avoid timespec usage in settimeofday() y2038: itimer: compat handling to itimer.c y2038: use compat_{get,set}_itimer on alpha y2038: move itimer reset into itimer.c y2038: itimer: change implementation to timespec64 [RFC] y2038: itimer: use ktime_t internally y2038: allow disabling time32 system calls arch/Kconfig | 11 +- arch/alpha/kernel/osf_sys.c | 67 +----- arch/alpha/kernel/syscalls/syscall.tbl | 4 +- arch/ia64/kernel/asm-offsets.c | 2 +- arch/mips/include/uapi/asm/msgbuf.h | 6 +- arch/mips/include/uapi/asm/sembuf.h | 4 +- arch/mips/include/uapi/asm/shmbuf.h | 6 +- arch/mips/include/uapi/asm/stat.h | 16 +- arch/mips/kernel/binfmt_elfn32.c | 4 +- arch/mips/kernel/binfmt_elfo32.c | 4 +- arch/nds32/kernel/vdso/gettimeofday.c | 61 +++-- arch/parisc/include/uapi/asm/msgbuf.h | 6 +- arch/parisc/include/uapi/asm/sembuf.h | 4 +- arch/parisc/include/uapi/asm/shmbuf.h | 6 +- arch/powerpc/include/asm/asm-prototypes.h | 3 +- arch/powerpc/include/asm/vdso_datapage.h | 6 +- arch/powerpc/include/uapi/asm/msgbuf.h | 6 +- arch/powerpc/include/uapi/asm/sembuf.h | 4 +- arch/powerpc/include/uapi/asm/shmbuf.h | 6 +- arch/powerpc/include/uapi/asm/stat.h | 2 +- arch/powerpc/kernel/asm-offsets.c | 18 +- arch/powerpc/kernel/syscalls.c | 4 +- arch/powerpc/kernel/time.c | 5 +- arch/powerpc/kernel/vdso32/gettimeofday.S | 6 +- arch/powerpc/kernel/vdso64/gettimeofday.S | 8 +- arch/sparc/include/uapi/asm/msgbuf.h | 6 +- arch/sparc/include/uapi/asm/sembuf.h | 4 +- arch/sparc/include/uapi/asm/shmbuf.h | 6 +- arch/sparc/include/uapi/asm/stat.h | 24 +- arch/sparc/vdso/vclock_gettime.c | 36 +-- arch/x86/entry/vdso/vclock_gettime.c | 6 +- arch/x86/entry/vsyscall/vsyscall_64.c | 4 +- arch/x86/include/uapi/asm/msgbuf.h | 6 +- arch/x86/include/uapi/asm/sembuf.h | 4 +- arch/x86/include/uapi/asm/shmbuf.h | 6 +- arch/x86/um/vdso/um_vdso.c | 12 +- fs/aio.c | 2 +- fs/binfmt_elf.c | 12 +- fs/binfmt_elf_fdpic.c | 12 +- fs/compat_binfmt_elf.c | 4 +- fs/select.c | 10 +- fs/timerfd.c | 14 +- fs/utimes.c | 8 +- include/linux/compat.h | 19 +- include/linux/syscalls.h | 16 +- include/linux/time.h | 9 +- include/linux/time32.h | 2 +- include/linux/types.h | 2 +- include/trace/events/timer.h | 29 +-- include/uapi/asm-generic/msgbuf.h | 12 +- include/uapi/asm-generic/posix_types.h | 1 + include/uapi/asm-generic/sembuf.h | 7 +- include/uapi/asm-generic/shmbuf.h | 12 +- include/uapi/linux/cyclades.h | 6 +- include/uapi/linux/elfcore.h | 8 +- include/uapi/linux/errqueue.h | 7 + include/uapi/linux/msg.h | 6 +- include/uapi/linux/ppp_defs.h | 4 +- include/uapi/linux/resource.h | 4 +- include/uapi/linux/sem.h | 4 +- include/uapi/linux/shm.h | 6 +- include/uapi/linux/time.h | 6 +- include/uapi/linux/time_types.h | 5 + include/uapi/linux/utime.h | 4 +- ipc/syscall.c | 2 +- kernel/compat.c | 24 -- kernel/power/power.h | 2 +- kernel/sys.c | 4 +- kernel/sys_ni.c | 23 ++ kernel/time/hrtimer.c | 2 +- kernel/time/itimer.c | 280 ++++++++++++++-------- kernel/time/time.c | 32 ++- lib/vdso/gettimeofday.c | 4 +- net/core/scm.c | 6 +- net/socket.c | 2 +- security/selinux/hooks.c | 10 +- 76 files changed, 501 insertions(+), 504 deletions(-) -- 2.20.0 Cc: rth@twiddle.net Cc: tony.luck@intel.com Cc: paul.burton@mips.com Cc: green.hu@gmail.com Cc: deller@gmx.de Cc: mpe@ellerman.id.au Cc: davem@davemloft.net Cc: tglx@linutronix.de Cc: x86@kernel.org Cc: jdike@addtoit.com Cc: richard@nod.at Cc: viro@zeniv.linux.org.uk Cc: bcrl@kvack.org Cc: john.stultz@linaro.org Cc: sboyd@kernel.org Cc: rostedt@goodmis.org Cc: arnd@arndb.de Cc: vincenzo.frascino@arm.com Cc: paul@paul-moore.com Cc: sds@tycho.nsa.gov Cc: eparis@parisplace.org Cc: peterz@infradead.org Cc: will@kernel.org Cc: deepa.kernel@gmail.com Cc: christian@brauner.io Cc: heiko.carstens@de.ibm.com Cc: christophe.leroy@c-s.fr Cc: ebiederm@xmission.com Cc: linux-kernel@vger.kernel.org Cc: linux-alpha@vger.kernel.org> Cc: linux-ia64@vger.kernel.org> Cc: linux-mips@vger.kernel.org> Cc: linux-parisc@vger.kernel.org> Cc: linuxppc-dev@lists.ozlabs.org> Cc: sparclinux@vger.kernel.org> Cc: linux-um@lists.infradead.org> Cc: linux-fsdevel@vger.kernel.org> Cc: linux-aio@kvack.org> Cc: linux-api@vger.kernel.org> Cc: linux-arch@vger.kernel.org> Cc: netdev@vger.kernel.org> Cc: selinux@vger.kernel.org> -- To unsubscribe, send a message with 'unsubscribe linux-aio' in the body to majordomo@kvack.org. For more info on Linux AIO, see: http://www.kvack.org/aio/ Don't email: <a href=mailto:"aart@kvack.org">aart@kvack.org</a> ^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 10/23] y2038: uapi: change __kernel_time_t to __kernel_old_time_t 2019-11-08 21:02 [PATCH 00/23] y2038 cleanups Arnd Bergmann @ 2019-11-08 21:12 ` Arnd Bergmann 2019-11-09 19:03 ` Deepa Dinamani 2019-11-11 12:38 ` Christian Brauner 2019-11-08 21:12 ` [PATCH 12/23] y2038: syscalls: change remaining timeval to __kernel_old_timeval Arnd Bergmann ` (3 subsequent siblings) 4 siblings, 2 replies; 19+ messages in thread From: Arnd Bergmann @ 2019-11-08 21:12 UTC (permalink / raw) To: y2038, John Stultz, Thomas Gleixner Cc: linux-kernel, Arnd Bergmann, Stephen Boyd, David Howells, Al Viro, Deepa Dinamani, Christian Brauner, linux-api This is mainly a patch for clarification, and to let us remove the time_t definition from the kernel to prevent new users from creeping in that might not be y2038-safe. All remaining uses of 'time_t' or '__kernel_time_t' are part of the user API that cannot be changed by that either have a replacement or that do not suffer from the y2038 overflow. Signed-off-by: Arnd Bergmann <arnd@arndb.de> --- include/linux/syscalls.h | 4 ++-- include/linux/time32.h | 2 +- include/linux/types.h | 2 +- include/uapi/linux/cyclades.h | 6 +++--- include/uapi/linux/msg.h | 6 +++--- include/uapi/linux/ppp_defs.h | 4 ++-- include/uapi/linux/sem.h | 4 ++-- include/uapi/linux/shm.h | 6 +++--- include/uapi/linux/time.h | 6 +++--- include/uapi/linux/time_types.h | 4 ++-- include/uapi/linux/utime.h | 4 ++-- kernel/time/time.c | 6 +++--- 12 files changed, 27 insertions(+), 27 deletions(-) diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index f7c561c4dcdd..2f27bc9d5ef0 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -1076,7 +1076,7 @@ asmlinkage long sys_fadvise64(int fd, loff_t offset, size_t len, int advice); asmlinkage long sys_alarm(unsigned int seconds); asmlinkage long sys_getpgrp(void); asmlinkage long sys_pause(void); -asmlinkage long sys_time(time_t __user *tloc); +asmlinkage long sys_time(__kernel_old_time_t __user *tloc); asmlinkage long sys_time32(old_time32_t __user *tloc); #ifdef __ARCH_WANT_SYS_UTIME asmlinkage long sys_utime(char __user *filename, @@ -1116,7 +1116,7 @@ asmlinkage long sys_sysfs(int option, asmlinkage long sys_fork(void); /* obsolete: kernel/time/time.c */ -asmlinkage long sys_stime(time_t __user *tptr); +asmlinkage long sys_stime(__kernel_old_time_t __user *tptr); asmlinkage long sys_stime32(old_time32_t __user *tptr); /* obsolete: kernel/signal.c */ diff --git a/include/linux/time32.h b/include/linux/time32.h index 0a1f302a1753..cad4c3186002 100644 --- a/include/linux/time32.h +++ b/include/linux/time32.h @@ -12,7 +12,7 @@ #include <linux/time64.h> #include <linux/timex.h> -#define TIME_T_MAX (time_t)((1UL << ((sizeof(time_t) << 3) - 1)) - 1) +#define TIME_T_MAX (__kernel_old_time_t)((1UL << ((sizeof(__kernel_old_time_t) << 3) - 1)) - 1) typedef s32 old_time32_t; diff --git a/include/linux/types.h b/include/linux/types.h index 05030f608be3..e32c1180b742 100644 --- a/include/linux/types.h +++ b/include/linux/types.h @@ -67,7 +67,7 @@ typedef __kernel_ptrdiff_t ptrdiff_t; #ifndef _TIME_T #define _TIME_T -typedef __kernel_time_t time_t; +typedef __kernel_old_time_t time_t; #endif #ifndef _CLOCK_T diff --git a/include/uapi/linux/cyclades.h b/include/uapi/linux/cyclades.h index 8279bc3d60ca..fc0add2194a9 100644 --- a/include/uapi/linux/cyclades.h +++ b/include/uapi/linux/cyclades.h @@ -83,9 +83,9 @@ struct cyclades_monitor { * open) */ struct cyclades_idle_stats { - __kernel_time_t in_use; /* Time device has been in use (secs) */ - __kernel_time_t recv_idle; /* Time since last char received (secs) */ - __kernel_time_t xmit_idle; /* Time since last char transmitted (secs) */ + __kernel_old_time_t in_use; /* Time device has been in use (secs) */ + __kernel_old_time_t recv_idle; /* Time since last char received (secs) */ + __kernel_old_time_t xmit_idle; /* Time since last char transmitted (secs) */ unsigned long recv_bytes; /* Bytes received */ unsigned long xmit_bytes; /* Bytes transmitted */ unsigned long overruns; /* Input overruns */ diff --git a/include/uapi/linux/msg.h b/include/uapi/linux/msg.h index e4a0d9a9a9e8..01ee8d54c1c8 100644 --- a/include/uapi/linux/msg.h +++ b/include/uapi/linux/msg.h @@ -19,9 +19,9 @@ struct msqid_ds { struct ipc_perm msg_perm; struct msg *msg_first; /* first message on queue,unused */ struct msg *msg_last; /* last message in queue,unused */ - __kernel_time_t msg_stime; /* last msgsnd time */ - __kernel_time_t msg_rtime; /* last msgrcv time */ - __kernel_time_t msg_ctime; /* last change time */ + __kernel_old_time_t msg_stime; /* last msgsnd time */ + __kernel_old_time_t msg_rtime; /* last msgrcv time */ + __kernel_old_time_t msg_ctime; /* last change time */ unsigned long msg_lcbytes; /* Reuse junk fields for 32 bit */ unsigned long msg_lqbytes; /* ditto */ unsigned short msg_cbytes; /* current number of bytes on queue */ diff --git a/include/uapi/linux/ppp_defs.h b/include/uapi/linux/ppp_defs.h index 0039fa39a358..20286bd90ab5 100644 --- a/include/uapi/linux/ppp_defs.h +++ b/include/uapi/linux/ppp_defs.h @@ -148,8 +148,8 @@ struct ppp_comp_stats { * based on the libc time_t. */ struct ppp_idle { - __kernel_time_t xmit_idle; /* time since last NP packet sent */ - __kernel_time_t recv_idle; /* time since last NP packet received */ + __kernel_old_time_t xmit_idle; /* time since last NP packet sent */ + __kernel_old_time_t recv_idle; /* time since last NP packet received */ }; struct ppp_idle32 { diff --git a/include/uapi/linux/sem.h b/include/uapi/linux/sem.h index 39a1876f039e..75aa3b273cd9 100644 --- a/include/uapi/linux/sem.h +++ b/include/uapi/linux/sem.h @@ -24,8 +24,8 @@ /* Obsolete, used only for backwards compatibility and libc5 compiles */ struct semid_ds { struct ipc_perm sem_perm; /* permissions .. see ipc.h */ - __kernel_time_t sem_otime; /* last semop time */ - __kernel_time_t sem_ctime; /* create/last semctl() time */ + __kernel_old_time_t sem_otime; /* last semop time */ + __kernel_old_time_t sem_ctime; /* create/last semctl() time */ struct sem *sem_base; /* ptr to first semaphore in array */ struct sem_queue *sem_pending; /* pending operations to be processed */ struct sem_queue **sem_pending_last; /* last pending operation */ diff --git a/include/uapi/linux/shm.h b/include/uapi/linux/shm.h index 6507ad0afc81..8d1f17a4e08e 100644 --- a/include/uapi/linux/shm.h +++ b/include/uapi/linux/shm.h @@ -28,9 +28,9 @@ struct shmid_ds { struct ipc_perm shm_perm; /* operation perms */ int shm_segsz; /* size of segment (bytes) */ - __kernel_time_t shm_atime; /* last attach time */ - __kernel_time_t shm_dtime; /* last detach time */ - __kernel_time_t shm_ctime; /* last change time */ + __kernel_old_time_t shm_atime; /* last attach time */ + __kernel_old_time_t shm_dtime; /* last detach time */ + __kernel_old_time_t shm_ctime; /* last change time */ __kernel_ipc_pid_t shm_cpid; /* pid of creator */ __kernel_ipc_pid_t shm_lpid; /* pid of last operator */ unsigned short shm_nattch; /* no. of current attaches */ diff --git a/include/uapi/linux/time.h b/include/uapi/linux/time.h index 958932effc5e..a655aa28dc6e 100644 --- a/include/uapi/linux/time.h +++ b/include/uapi/linux/time.h @@ -8,13 +8,13 @@ #ifndef _STRUCT_TIMESPEC #define _STRUCT_TIMESPEC struct timespec { - __kernel_time_t tv_sec; /* seconds */ - long tv_nsec; /* nanoseconds */ + __kernel_old_time_t tv_sec; /* seconds */ + long tv_nsec; /* nanoseconds */ }; #endif struct timeval { - __kernel_time_t tv_sec; /* seconds */ + __kernel_old_time_t tv_sec; /* seconds */ __kernel_suseconds_t tv_usec; /* microseconds */ }; diff --git a/include/uapi/linux/time_types.h b/include/uapi/linux/time_types.h index 60b37f29842d..074e391d73a1 100644 --- a/include/uapi/linux/time_types.h +++ b/include/uapi/linux/time_types.h @@ -29,8 +29,8 @@ struct __kernel_old_timeval { #endif struct __kernel_old_timespec { - __kernel_time_t tv_sec; /* seconds */ - long tv_nsec; /* nanoseconds */ + __kernel_old_time_t tv_sec; /* seconds */ + long tv_nsec; /* nanoseconds */ }; struct __kernel_sock_timeval { diff --git a/include/uapi/linux/utime.h b/include/uapi/linux/utime.h index fd9aa26b6860..bc8f13e81d6e 100644 --- a/include/uapi/linux/utime.h +++ b/include/uapi/linux/utime.h @@ -5,8 +5,8 @@ #include <linux/types.h> struct utimbuf { - __kernel_time_t actime; - __kernel_time_t modtime; + __kernel_old_time_t actime; + __kernel_old_time_t modtime; }; #endif diff --git a/kernel/time/time.c b/kernel/time/time.c index ddbddf504c23..7eba7c9a7e3e 100644 --- a/kernel/time/time.c +++ b/kernel/time/time.c @@ -59,9 +59,9 @@ EXPORT_SYMBOL(sys_tz); * why not move it into the appropriate arch directory (for those * architectures that need it). */ -SYSCALL_DEFINE1(time, time_t __user *, tloc) +SYSCALL_DEFINE1(time, __kernel_old_time_t __user *, tloc) { - time_t i = (time_t)ktime_get_real_seconds(); + __kernel_old_time_t i = (__kernel_old_time_t)ktime_get_real_seconds(); if (tloc) { if (put_user(i,tloc)) @@ -78,7 +78,7 @@ SYSCALL_DEFINE1(time, time_t __user *, tloc) * architectures that need it). */ -SYSCALL_DEFINE1(stime, time_t __user *, tptr) +SYSCALL_DEFINE1(stime, __kernel_old_time_t __user *, tptr) { struct timespec64 tv; int err; -- 2.20.0 ^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCH 10/23] y2038: uapi: change __kernel_time_t to __kernel_old_time_t 2019-11-08 21:12 ` [PATCH 10/23] y2038: uapi: change __kernel_time_t to __kernel_old_time_t Arnd Bergmann @ 2019-11-09 19:03 ` Deepa Dinamani 2019-11-11 12:38 ` Christian Brauner 1 sibling, 0 replies; 19+ messages in thread From: Deepa Dinamani @ 2019-11-09 19:03 UTC (permalink / raw) To: Arnd Bergmann Cc: y2038 Mailman List, John Stultz, Thomas Gleixner, Linux Kernel Mailing List, Stephen Boyd, David Howells, Al Viro, Christian Brauner, Linux API Acked-by: Deepa Dinamani <deepa.kernel@gmail.com> ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 10/23] y2038: uapi: change __kernel_time_t to __kernel_old_time_t 2019-11-08 21:12 ` [PATCH 10/23] y2038: uapi: change __kernel_time_t to __kernel_old_time_t Arnd Bergmann 2019-11-09 19:03 ` Deepa Dinamani @ 2019-11-11 12:38 ` Christian Brauner 1 sibling, 0 replies; 19+ messages in thread From: Christian Brauner @ 2019-11-11 12:38 UTC (permalink / raw) To: Arnd Bergmann Cc: y2038, John Stultz, Thomas Gleixner, linux-kernel, Stephen Boyd, David Howells, Al Viro, Deepa Dinamani, Christian Brauner, linux-api On Fri, Nov 08, 2019 at 10:12:09PM +0100, Arnd Bergmann wrote: > This is mainly a patch for clarification, and to let us remove > the time_t definition from the kernel to prevent new users from > creeping in that might not be y2038-safe. > > All remaining uses of 'time_t' or '__kernel_time_t' are part of > the user API that cannot be changed by that either have a > replacement or that do not suffer from the y2038 overflow. > > Signed-off-by: Arnd Bergmann <arnd@arndb.de> Acked-by: Christian Brauner <christian.brauner@ubuntu.com> ^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 12/23] y2038: syscalls: change remaining timeval to __kernel_old_timeval 2019-11-08 21:02 [PATCH 00/23] y2038 cleanups Arnd Bergmann 2019-11-08 21:12 ` [PATCH 10/23] y2038: uapi: change __kernel_time_t to __kernel_old_time_t Arnd Bergmann @ 2019-11-08 21:12 ` Arnd Bergmann 2019-11-11 12:44 ` Christian Brauner 2019-11-13 22:39 ` Rafael J. Wysocki 2019-11-08 21:12 ` [PATCH 17/23] y2038: time: avoid timespec usage in settimeofday() Arnd Bergmann ` (2 subsequent siblings) 4 siblings, 2 replies; 19+ messages in thread From: Arnd Bergmann @ 2019-11-08 21:12 UTC (permalink / raw) To: y2038, Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, Alexander Viro, Rafael J. Wysocki, Pavel Machek, Len Brown, John Stultz, Thomas Gleixner Cc: linux-kernel, Arnd Bergmann, Stephen Boyd, Christian Brauner, linuxppc-dev, linux-fsdevel, linux-api, linux-pm All of the remaining syscalls that pass a timeval (gettimeofday, utime, futimesat) can trivially be changed to pass a __kernel_old_timeval instead, which has a compatible layout, but avoids ambiguity with the timeval type in user space. Signed-off-by: Arnd Bergmann <arnd@arndb.de> --- arch/powerpc/include/asm/asm-prototypes.h | 3 ++- arch/powerpc/kernel/syscalls.c | 4 ++-- fs/select.c | 10 +++++----- fs/utimes.c | 8 ++++---- include/linux/syscalls.h | 10 +++++----- kernel/power/power.h | 2 +- kernel/time/time.c | 2 +- 7 files changed, 20 insertions(+), 19 deletions(-) diff --git a/arch/powerpc/include/asm/asm-prototypes.h b/arch/powerpc/include/asm/asm-prototypes.h index 8561498e653c..2c25dc079cb9 100644 --- a/arch/powerpc/include/asm/asm-prototypes.h +++ b/arch/powerpc/include/asm/asm-prototypes.h @@ -92,7 +92,8 @@ long sys_swapcontext(struct ucontext __user *old_ctx, long sys_debug_setcontext(struct ucontext __user *ctx, int ndbg, struct sig_dbg_op __user *dbg); int -ppc_select(int n, fd_set __user *inp, fd_set __user *outp, fd_set __user *exp, struct timeval __user *tvp); +ppc_select(int n, fd_set __user *inp, fd_set __user *outp, fd_set __user *exp, + struct __kernel_old_timeval __user *tvp); unsigned long __init early_init(unsigned long dt_ptr); void __init machine_init(u64 dt_ptr); #endif diff --git a/arch/powerpc/kernel/syscalls.c b/arch/powerpc/kernel/syscalls.c index 3bfb3888e897..078608ec2e92 100644 --- a/arch/powerpc/kernel/syscalls.c +++ b/arch/powerpc/kernel/syscalls.c @@ -79,7 +79,7 @@ SYSCALL_DEFINE6(mmap, unsigned long, addr, size_t, len, * sys_select() with the appropriate args. -- Cort */ int -ppc_select(int n, fd_set __user *inp, fd_set __user *outp, fd_set __user *exp, struct timeval __user *tvp) +ppc_select(int n, fd_set __user *inp, fd_set __user *outp, fd_set __user *exp, struct __kernel_old_timeval __user *tvp) { if ( (unsigned long)n >= 4096 ) { @@ -89,7 +89,7 @@ ppc_select(int n, fd_set __user *inp, fd_set __user *outp, fd_set __user *exp, s || __get_user(inp, ((fd_set __user * __user *)(buffer+1))) || __get_user(outp, ((fd_set __user * __user *)(buffer+2))) || __get_user(exp, ((fd_set __user * __user *)(buffer+3))) - || __get_user(tvp, ((struct timeval __user * __user *)(buffer+4)))) + || __get_user(tvp, ((struct __kernel_old_timeval __user * __user *)(buffer+4)))) return -EFAULT; } return sys_select(n, inp, outp, exp, tvp); diff --git a/fs/select.c b/fs/select.c index 53a0c149f528..11d0285d46b7 100644 --- a/fs/select.c +++ b/fs/select.c @@ -321,7 +321,7 @@ static int poll_select_finish(struct timespec64 *end_time, switch (pt_type) { case PT_TIMEVAL: { - struct timeval rtv; + struct __kernel_old_timeval rtv; if (sizeof(rtv) > sizeof(rtv.tv_sec) + sizeof(rtv.tv_usec)) memset(&rtv, 0, sizeof(rtv)); @@ -698,10 +698,10 @@ int core_sys_select(int n, fd_set __user *inp, fd_set __user *outp, } static int kern_select(int n, fd_set __user *inp, fd_set __user *outp, - fd_set __user *exp, struct timeval __user *tvp) + fd_set __user *exp, struct __kernel_old_timeval __user *tvp) { struct timespec64 end_time, *to = NULL; - struct timeval tv; + struct __kernel_old_timeval tv; int ret; if (tvp) { @@ -720,7 +720,7 @@ static int kern_select(int n, fd_set __user *inp, fd_set __user *outp, } SYSCALL_DEFINE5(select, int, n, fd_set __user *, inp, fd_set __user *, outp, - fd_set __user *, exp, struct timeval __user *, tvp) + fd_set __user *, exp, struct __kernel_old_timeval __user *, tvp) { return kern_select(n, inp, outp, exp, tvp); } @@ -810,7 +810,7 @@ SYSCALL_DEFINE6(pselect6_time32, int, n, fd_set __user *, inp, fd_set __user *, struct sel_arg_struct { unsigned long n; fd_set __user *inp, *outp, *exp; - struct timeval __user *tvp; + struct __kernel_old_timeval __user *tvp; }; SYSCALL_DEFINE1(old_select, struct sel_arg_struct __user *, arg) diff --git a/fs/utimes.c b/fs/utimes.c index 1ba3f7883870..c952b6b3d8a0 100644 --- a/fs/utimes.c +++ b/fs/utimes.c @@ -161,9 +161,9 @@ SYSCALL_DEFINE4(utimensat, int, dfd, const char __user *, filename, * utimensat() instead. */ static long do_futimesat(int dfd, const char __user *filename, - struct timeval __user *utimes) + struct __kernel_old_timeval __user *utimes) { - struct timeval times[2]; + struct __kernel_old_timeval times[2]; struct timespec64 tstimes[2]; if (utimes) { @@ -190,13 +190,13 @@ static long do_futimesat(int dfd, const char __user *filename, SYSCALL_DEFINE3(futimesat, int, dfd, const char __user *, filename, - struct timeval __user *, utimes) + struct __kernel_old_timeval __user *, utimes) { return do_futimesat(dfd, filename, utimes); } SYSCALL_DEFINE2(utimes, char __user *, filename, - struct timeval __user *, utimes) + struct __kernel_old_timeval __user *, utimes) { return do_futimesat(AT_FDCWD, filename, utimes); } diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 2f27bc9d5ef0..e665920fa359 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -51,7 +51,7 @@ struct statx; struct __sysctl_args; struct sysinfo; struct timespec; -struct timeval; +struct __kernel_old_timeval; struct __kernel_timex; struct timezone; struct tms; @@ -732,7 +732,7 @@ asmlinkage long sys_prctl(int option, unsigned long arg2, unsigned long arg3, asmlinkage long sys_getcpu(unsigned __user *cpu, unsigned __user *node, struct getcpu_cache __user *cache); /* kernel/time.c */ -asmlinkage long sys_gettimeofday(struct timeval __user *tv, +asmlinkage long sys_gettimeofday(struct __kernel_old_timeval __user *tv, struct timezone __user *tz); asmlinkage long sys_settimeofday(struct timeval __user *tv, struct timezone __user *tz); @@ -1082,9 +1082,9 @@ asmlinkage long sys_time32(old_time32_t __user *tloc); asmlinkage long sys_utime(char __user *filename, struct utimbuf __user *times); asmlinkage long sys_utimes(char __user *filename, - struct timeval __user *utimes); + struct __kernel_old_timeval __user *utimes); asmlinkage long sys_futimesat(int dfd, const char __user *filename, - struct timeval __user *utimes); + struct __kernel_old_timeval __user *utimes); #endif asmlinkage long sys_futimesat_time32(unsigned int dfd, const char __user *filename, @@ -1098,7 +1098,7 @@ asmlinkage long sys_getdents(unsigned int fd, struct linux_dirent __user *dirent, unsigned int count); asmlinkage long sys_select(int n, fd_set __user *inp, fd_set __user *outp, - fd_set __user *exp, struct timeval __user *tvp); + fd_set __user *exp, struct __kernel_old_timeval __user *tvp); asmlinkage long sys_poll(struct pollfd __user *ufds, unsigned int nfds, int timeout); asmlinkage long sys_epoll_wait(int epfd, struct epoll_event __user *events, diff --git a/kernel/power/power.h b/kernel/power/power.h index 44bee462ff57..7cdc64dc2373 100644 --- a/kernel/power/power.h +++ b/kernel/power/power.h @@ -179,7 +179,7 @@ extern void swsusp_close(fmode_t); extern int swsusp_unmark(void); #endif -struct timeval; +struct __kernel_old_timeval; /* kernel/power/swsusp.c */ extern void swsusp_show_speed(ktime_t, ktime_t, unsigned int, char *); diff --git a/kernel/time/time.c b/kernel/time/time.c index 7eba7c9a7e3e..bc114f0be8f1 100644 --- a/kernel/time/time.c +++ b/kernel/time/time.c @@ -137,7 +137,7 @@ SYSCALL_DEFINE1(stime32, old_time32_t __user *, tptr) #endif /* __ARCH_WANT_SYS_TIME32 */ #endif -SYSCALL_DEFINE2(gettimeofday, struct timeval __user *, tv, +SYSCALL_DEFINE2(gettimeofday, struct __kernel_old_timeval __user *, tv, struct timezone __user *, tz) { if (likely(tv != NULL)) { -- 2.20.0 ^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCH 12/23] y2038: syscalls: change remaining timeval to __kernel_old_timeval 2019-11-08 21:12 ` [PATCH 12/23] y2038: syscalls: change remaining timeval to __kernel_old_timeval Arnd Bergmann @ 2019-11-11 12:44 ` Christian Brauner 2019-11-13 22:39 ` Rafael J. Wysocki 1 sibling, 0 replies; 19+ messages in thread From: Christian Brauner @ 2019-11-11 12:44 UTC (permalink / raw) To: Arnd Bergmann Cc: Len Brown, linux-pm, y2038, Benjamin Herrenschmidt, Rafael J. Wysocki, linux-kernel, Stephen Boyd, Paul Mackerras, Alexander Viro, Pavel Machek, Michael Ellerman, linux-fsdevel, John Stultz, Thomas Gleixner, linux-api, linuxppc-dev, Christian Brauner On Fri, Nov 08, 2019 at 10:12:11PM +0100, Arnd Bergmann wrote: > All of the remaining syscalls that pass a timeval (gettimeofday, utime, > futimesat) can trivially be changed to pass a __kernel_old_timeval > instead, which has a compatible layout, but avoids ambiguity with > the timeval type in user space. > > Signed-off-by: Arnd Bergmann <arnd@arndb.de> Seems reasonable. Acked-by: Christian Brauner <christian.brauner@ubuntu.com> _______________________________________________ Y2038 mailing list Y2038@lists.linaro.org https://lists.linaro.org/mailman/listinfo/y2038 ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 12/23] y2038: syscalls: change remaining timeval to __kernel_old_timeval 2019-11-08 21:12 ` [PATCH 12/23] y2038: syscalls: change remaining timeval to __kernel_old_timeval Arnd Bergmann 2019-11-11 12:44 ` Christian Brauner @ 2019-11-13 22:39 ` Rafael J. Wysocki 1 sibling, 0 replies; 19+ messages in thread From: Rafael J. Wysocki @ 2019-11-13 22:39 UTC (permalink / raw) To: Arnd Bergmann Cc: y2038, Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, Alexander Viro, Pavel Machek, Len Brown, John Stultz, Thomas Gleixner, linux-kernel, Stephen Boyd, Christian Brauner, linuxppc-dev, linux-fsdevel, linux-api, linux-pm On Friday, November 8, 2019 10:12:11 PM CET Arnd Bergmann wrote: > All of the remaining syscalls that pass a timeval (gettimeofday, utime, > futimesat) can trivially be changed to pass a __kernel_old_timeval > instead, which has a compatible layout, but avoids ambiguity with > the timeval type in user space. > > Signed-off-by: Arnd Bergmann <arnd@arndb.de> For the change in power/power.h Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> > --- > arch/powerpc/include/asm/asm-prototypes.h | 3 ++- > arch/powerpc/kernel/syscalls.c | 4 ++-- > fs/select.c | 10 +++++----- > fs/utimes.c | 8 ++++---- > include/linux/syscalls.h | 10 +++++----- > kernel/power/power.h | 2 +- > kernel/time/time.c | 2 +- > 7 files changed, 20 insertions(+), 19 deletions(-) > > diff --git a/arch/powerpc/include/asm/asm-prototypes.h b/arch/powerpc/include/asm/asm-prototypes.h > index 8561498e653c..2c25dc079cb9 100644 > --- a/arch/powerpc/include/asm/asm-prototypes.h > +++ b/arch/powerpc/include/asm/asm-prototypes.h > @@ -92,7 +92,8 @@ long sys_swapcontext(struct ucontext __user *old_ctx, > long sys_debug_setcontext(struct ucontext __user *ctx, > int ndbg, struct sig_dbg_op __user *dbg); > int > -ppc_select(int n, fd_set __user *inp, fd_set __user *outp, fd_set __user *exp, struct timeval __user *tvp); > +ppc_select(int n, fd_set __user *inp, fd_set __user *outp, fd_set __user *exp, > + struct __kernel_old_timeval __user *tvp); > unsigned long __init early_init(unsigned long dt_ptr); > void __init machine_init(u64 dt_ptr); > #endif > diff --git a/arch/powerpc/kernel/syscalls.c b/arch/powerpc/kernel/syscalls.c > index 3bfb3888e897..078608ec2e92 100644 > --- a/arch/powerpc/kernel/syscalls.c > +++ b/arch/powerpc/kernel/syscalls.c > @@ -79,7 +79,7 @@ SYSCALL_DEFINE6(mmap, unsigned long, addr, size_t, len, > * sys_select() with the appropriate args. -- Cort > */ > int > -ppc_select(int n, fd_set __user *inp, fd_set __user *outp, fd_set __user *exp, struct timeval __user *tvp) > +ppc_select(int n, fd_set __user *inp, fd_set __user *outp, fd_set __user *exp, struct __kernel_old_timeval __user *tvp) > { > if ( (unsigned long)n >= 4096 ) > { > @@ -89,7 +89,7 @@ ppc_select(int n, fd_set __user *inp, fd_set __user *outp, fd_set __user *exp, s > || __get_user(inp, ((fd_set __user * __user *)(buffer+1))) > || __get_user(outp, ((fd_set __user * __user *)(buffer+2))) > || __get_user(exp, ((fd_set __user * __user *)(buffer+3))) > - || __get_user(tvp, ((struct timeval __user * __user *)(buffer+4)))) > + || __get_user(tvp, ((struct __kernel_old_timeval __user * __user *)(buffer+4)))) > return -EFAULT; > } > return sys_select(n, inp, outp, exp, tvp); > diff --git a/fs/select.c b/fs/select.c > index 53a0c149f528..11d0285d46b7 100644 > --- a/fs/select.c > +++ b/fs/select.c > @@ -321,7 +321,7 @@ static int poll_select_finish(struct timespec64 *end_time, > switch (pt_type) { > case PT_TIMEVAL: > { > - struct timeval rtv; > + struct __kernel_old_timeval rtv; > > if (sizeof(rtv) > sizeof(rtv.tv_sec) + sizeof(rtv.tv_usec)) > memset(&rtv, 0, sizeof(rtv)); > @@ -698,10 +698,10 @@ int core_sys_select(int n, fd_set __user *inp, fd_set __user *outp, > } > > static int kern_select(int n, fd_set __user *inp, fd_set __user *outp, > - fd_set __user *exp, struct timeval __user *tvp) > + fd_set __user *exp, struct __kernel_old_timeval __user *tvp) > { > struct timespec64 end_time, *to = NULL; > - struct timeval tv; > + struct __kernel_old_timeval tv; > int ret; > > if (tvp) { > @@ -720,7 +720,7 @@ static int kern_select(int n, fd_set __user *inp, fd_set __user *outp, > } > > SYSCALL_DEFINE5(select, int, n, fd_set __user *, inp, fd_set __user *, outp, > - fd_set __user *, exp, struct timeval __user *, tvp) > + fd_set __user *, exp, struct __kernel_old_timeval __user *, tvp) > { > return kern_select(n, inp, outp, exp, tvp); > } > @@ -810,7 +810,7 @@ SYSCALL_DEFINE6(pselect6_time32, int, n, fd_set __user *, inp, fd_set __user *, > struct sel_arg_struct { > unsigned long n; > fd_set __user *inp, *outp, *exp; > - struct timeval __user *tvp; > + struct __kernel_old_timeval __user *tvp; > }; > > SYSCALL_DEFINE1(old_select, struct sel_arg_struct __user *, arg) > diff --git a/fs/utimes.c b/fs/utimes.c > index 1ba3f7883870..c952b6b3d8a0 100644 > --- a/fs/utimes.c > +++ b/fs/utimes.c > @@ -161,9 +161,9 @@ SYSCALL_DEFINE4(utimensat, int, dfd, const char __user *, filename, > * utimensat() instead. > */ > static long do_futimesat(int dfd, const char __user *filename, > - struct timeval __user *utimes) > + struct __kernel_old_timeval __user *utimes) > { > - struct timeval times[2]; > + struct __kernel_old_timeval times[2]; > struct timespec64 tstimes[2]; > > if (utimes) { > @@ -190,13 +190,13 @@ static long do_futimesat(int dfd, const char __user *filename, > > > SYSCALL_DEFINE3(futimesat, int, dfd, const char __user *, filename, > - struct timeval __user *, utimes) > + struct __kernel_old_timeval __user *, utimes) > { > return do_futimesat(dfd, filename, utimes); > } > > SYSCALL_DEFINE2(utimes, char __user *, filename, > - struct timeval __user *, utimes) > + struct __kernel_old_timeval __user *, utimes) > { > return do_futimesat(AT_FDCWD, filename, utimes); > } > diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h > index 2f27bc9d5ef0..e665920fa359 100644 > --- a/include/linux/syscalls.h > +++ b/include/linux/syscalls.h > @@ -51,7 +51,7 @@ struct statx; > struct __sysctl_args; > struct sysinfo; > struct timespec; > -struct timeval; > +struct __kernel_old_timeval; > struct __kernel_timex; > struct timezone; > struct tms; > @@ -732,7 +732,7 @@ asmlinkage long sys_prctl(int option, unsigned long arg2, unsigned long arg3, > asmlinkage long sys_getcpu(unsigned __user *cpu, unsigned __user *node, struct getcpu_cache __user *cache); > > /* kernel/time.c */ > -asmlinkage long sys_gettimeofday(struct timeval __user *tv, > +asmlinkage long sys_gettimeofday(struct __kernel_old_timeval __user *tv, > struct timezone __user *tz); > asmlinkage long sys_settimeofday(struct timeval __user *tv, > struct timezone __user *tz); > @@ -1082,9 +1082,9 @@ asmlinkage long sys_time32(old_time32_t __user *tloc); > asmlinkage long sys_utime(char __user *filename, > struct utimbuf __user *times); > asmlinkage long sys_utimes(char __user *filename, > - struct timeval __user *utimes); > + struct __kernel_old_timeval __user *utimes); > asmlinkage long sys_futimesat(int dfd, const char __user *filename, > - struct timeval __user *utimes); > + struct __kernel_old_timeval __user *utimes); > #endif > asmlinkage long sys_futimesat_time32(unsigned int dfd, > const char __user *filename, > @@ -1098,7 +1098,7 @@ asmlinkage long sys_getdents(unsigned int fd, > struct linux_dirent __user *dirent, > unsigned int count); > asmlinkage long sys_select(int n, fd_set __user *inp, fd_set __user *outp, > - fd_set __user *exp, struct timeval __user *tvp); > + fd_set __user *exp, struct __kernel_old_timeval __user *tvp); > asmlinkage long sys_poll(struct pollfd __user *ufds, unsigned int nfds, > int timeout); > asmlinkage long sys_epoll_wait(int epfd, struct epoll_event __user *events, > diff --git a/kernel/power/power.h b/kernel/power/power.h > index 44bee462ff57..7cdc64dc2373 100644 > --- a/kernel/power/power.h > +++ b/kernel/power/power.h > @@ -179,7 +179,7 @@ extern void swsusp_close(fmode_t); > extern int swsusp_unmark(void); > #endif > > -struct timeval; > +struct __kernel_old_timeval; > /* kernel/power/swsusp.c */ > extern void swsusp_show_speed(ktime_t, ktime_t, unsigned int, char *); > > diff --git a/kernel/time/time.c b/kernel/time/time.c > index 7eba7c9a7e3e..bc114f0be8f1 100644 > --- a/kernel/time/time.c > +++ b/kernel/time/time.c > @@ -137,7 +137,7 @@ SYSCALL_DEFINE1(stime32, old_time32_t __user *, tptr) > #endif /* __ARCH_WANT_SYS_TIME32 */ > #endif > > -SYSCALL_DEFINE2(gettimeofday, struct timeval __user *, tv, > +SYSCALL_DEFINE2(gettimeofday, struct __kernel_old_timeval __user *, tv, > struct timezone __user *, tz) > { > if (likely(tv != NULL)) { > ^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 17/23] y2038: time: avoid timespec usage in settimeofday() 2019-11-08 21:02 [PATCH 00/23] y2038 cleanups Arnd Bergmann 2019-11-08 21:12 ` [PATCH 10/23] y2038: uapi: change __kernel_time_t to __kernel_old_time_t Arnd Bergmann 2019-11-08 21:12 ` [PATCH 12/23] y2038: syscalls: change remaining timeval to __kernel_old_timeval Arnd Bergmann @ 2019-11-08 21:12 ` Arnd Bergmann 2019-11-13 21:53 ` Thomas Gleixner 2019-11-14 23:01 ` Abel Vesa 2019-11-08 21:12 ` [PATCH 23/23] y2038: allow disabling time32 system calls Arnd Bergmann 2019-11-13 21:40 ` [PATCH 00/23] y2038 cleanups Arnd Bergmann 4 siblings, 2 replies; 19+ messages in thread From: Arnd Bergmann @ 2019-11-08 21:12 UTC (permalink / raw) To: y2038, John Stultz, Thomas Gleixner Cc: linux-kernel, Arnd Bergmann, Stephen Boyd, David Howells, Al Viro, Deepa Dinamani, Christian Brauner, Jens Axboe, Ingo Molnar, Corey Minyard, zhengbin, Li RongQing, linux-api The compat_get_timeval() and timeval_valid() interfaces are deprecated and getting removed along with the definition of struct timeval itself. Change the two implementations of the settimeofday() system call to open-code these helpers and completely avoid references to timeval. Signed-off-by: Arnd Bergmann <arnd@arndb.de> --- include/linux/syscalls.h | 2 +- kernel/time/time.c | 20 +++++++++----------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index e665920fa359..d0391cc2dae9 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -734,7 +734,7 @@ asmlinkage long sys_getcpu(unsigned __user *cpu, unsigned __user *node, struct g /* kernel/time.c */ asmlinkage long sys_gettimeofday(struct __kernel_old_timeval __user *tv, struct timezone __user *tz); -asmlinkage long sys_settimeofday(struct timeval __user *tv, +asmlinkage long sys_settimeofday(struct __kernel_old_timeval __user *tv, struct timezone __user *tz); asmlinkage long sys_adjtimex(struct __kernel_timex __user *txc_p); asmlinkage long sys_adjtimex_time32(struct old_timex32 __user *txc_p); diff --git a/kernel/time/time.c b/kernel/time/time.c index bc114f0be8f1..6bfbe640fd3b 100644 --- a/kernel/time/time.c +++ b/kernel/time/time.c @@ -196,22 +196,21 @@ int do_sys_settimeofday64(const struct timespec64 *tv, const struct timezone *tz return 0; } -SYSCALL_DEFINE2(settimeofday, struct timeval __user *, tv, +SYSCALL_DEFINE2(settimeofday, struct __kernel_old_timeval __user *, tv, struct timezone __user *, tz) { struct timespec64 new_ts; - struct timeval user_tv; struct timezone new_tz; if (tv) { - if (copy_from_user(&user_tv, tv, sizeof(*tv))) + if (get_user(new_ts.tv_sec, &tv->tv_sec) || + get_user(new_ts.tv_nsec, &tv->tv_usec)) return -EFAULT; - if (!timeval_valid(&user_tv)) + if (tv->tv_usec > USEC_PER_SEC) return -EINVAL; - new_ts.tv_sec = user_tv.tv_sec; - new_ts.tv_nsec = user_tv.tv_usec * NSEC_PER_USEC; + new_ts.tv_nsec *= NSEC_PER_USEC; } if (tz) { if (copy_from_user(&new_tz, tz, sizeof(*tz))) @@ -245,18 +244,17 @@ COMPAT_SYSCALL_DEFINE2(settimeofday, struct old_timeval32 __user *, tv, struct timezone __user *, tz) { struct timespec64 new_ts; - struct timeval user_tv; struct timezone new_tz; if (tv) { - if (compat_get_timeval(&user_tv, tv)) + if (get_user(new_ts.tv_sec, &tv->tv_sec) || + get_user(new_ts.tv_nsec, &tv->tv_usec)) return -EFAULT; - if (!timeval_valid(&user_tv)) + if (new_ts.tv_nsec > USEC_PER_SEC) return -EINVAL; - new_ts.tv_sec = user_tv.tv_sec; - new_ts.tv_nsec = user_tv.tv_usec * NSEC_PER_USEC; + new_ts.tv_nsec *= NSEC_PER_USEC; } if (tz) { if (copy_from_user(&new_tz, tz, sizeof(*tz))) -- 2.20.0 ^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCH 17/23] y2038: time: avoid timespec usage in settimeofday() 2019-11-08 21:12 ` [PATCH 17/23] y2038: time: avoid timespec usage in settimeofday() Arnd Bergmann @ 2019-11-13 21:53 ` Thomas Gleixner 2019-11-14 11:06 ` Arnd Bergmann 2019-11-14 23:01 ` Abel Vesa 1 sibling, 1 reply; 19+ messages in thread From: Thomas Gleixner @ 2019-11-13 21:53 UTC (permalink / raw) To: Arnd Bergmann Cc: y2038, John Stultz, linux-kernel, Stephen Boyd, David Howells, Al Viro, Deepa Dinamani, Christian Brauner, Jens Axboe, Ingo Molnar, Corey Minyard, zhengbin, Li RongQing, linux-api On Fri, 8 Nov 2019, Arnd Bergmann wrote: > -SYSCALL_DEFINE2(settimeofday, struct timeval __user *, tv, > +SYSCALL_DEFINE2(settimeofday, struct __kernel_old_timeval __user *, tv, > struct timezone __user *, tz) > { > struct timespec64 new_ts; > - struct timeval user_tv; > struct timezone new_tz; > > if (tv) { > - if (copy_from_user(&user_tv, tv, sizeof(*tv))) > + if (get_user(new_ts.tv_sec, &tv->tv_sec) || > + get_user(new_ts.tv_nsec, &tv->tv_usec)) > return -EFAULT; How is that supposed to be correct on a 32bit kernel? > > - if (!timeval_valid(&user_tv)) > + if (tv->tv_usec > USEC_PER_SEC) > return -EINVAL; That's incomplete: static inline bool timeval_valid(const struct timeval *tv) { /* Dates before 1970 are bogus */ if (tv->tv_sec < 0) return false; /* Can't have more microseconds then a second */ if (tv->tv_usec < 0 || tv->tv_usec >= USEC_PER_SEC) return false; return true; } > > - new_ts.tv_sec = user_tv.tv_sec; > - new_ts.tv_nsec = user_tv.tv_usec * NSEC_PER_USEC; > + new_ts.tv_nsec *= NSEC_PER_USEC; > } > if (tz) { > if (copy_from_user(&new_tz, tz, sizeof(*tz))) > @@ -245,18 +244,17 @@ COMPAT_SYSCALL_DEFINE2(settimeofday, struct old_timeval32 __user *, tv, > struct timezone __user *, tz) > { > struct timespec64 new_ts; > - struct timeval user_tv; > struct timezone new_tz; > > if (tv) { > - if (compat_get_timeval(&user_tv, tv)) > + if (get_user(new_ts.tv_sec, &tv->tv_sec) || > + get_user(new_ts.tv_nsec, &tv->tv_usec)) > return -EFAULT; > > - if (!timeval_valid(&user_tv)) > + if (new_ts.tv_nsec > USEC_PER_SEC) > return -EINVAL; Ditto. Thanks, tglx ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 17/23] y2038: time: avoid timespec usage in settimeofday() 2019-11-13 21:53 ` Thomas Gleixner @ 2019-11-14 11:06 ` Arnd Bergmann 2019-11-14 14:04 ` Thomas Gleixner 0 siblings, 1 reply; 19+ messages in thread From: Arnd Bergmann @ 2019-11-14 11:06 UTC (permalink / raw) To: Thomas Gleixner Cc: Jens Axboe, Corey Minyard, y2038 Mailman List, Linux API, linux-kernel@vger.kernel.org, Li RongQing, David Howells, Stephen Boyd, zhengbin, John Stultz, Al Viro, Ingo Molnar, Christian Brauner, Deepa Dinamani On Wed, Nov 13, 2019 at 10:53 PM Thomas Gleixner <tglx@linutronix.de> wrote: > > On Fri, 8 Nov 2019, Arnd Bergmann wrote: > > -SYSCALL_DEFINE2(settimeofday, struct timeval __user *, tv, > > +SYSCALL_DEFINE2(settimeofday, struct __kernel_old_timeval __user *, tv, > > struct timezone __user *, tz) > > { > > struct timespec64 new_ts; > > - struct timeval user_tv; > > struct timezone new_tz; > > > > if (tv) { > > - if (copy_from_user(&user_tv, tv, sizeof(*tv))) > > + if (get_user(new_ts.tv_sec, &tv->tv_sec) || > > + get_user(new_ts.tv_nsec, &tv->tv_usec)) > > return -EFAULT; > > How is that supposed to be correct on a 32bit kernel? I don't see the problem you are referring to. This should behave the same way on a 32-bit kernel and on a 64-bit kernel, sign-extending the tv_sec field, and copying the user tv_usec field into the kernel tv_nsec, to be multiplied by 1000 a few lines later. Am I missing something? > > - if (!timeval_valid(&user_tv)) > > + if (tv->tv_usec > USEC_PER_SEC) > > return -EINVAL; > > That's incomplete: > > static inline bool timeval_valid(const struct timeval *tv) > { > /* Dates before 1970 are bogus */ > if (tv->tv_sec < 0) > return false; > > /* Can't have more microseconds then a second */ > if (tv->tv_usec < 0 || tv->tv_usec >= USEC_PER_SEC) > return false; > > return true; > } My idea was to not duplicate the range check that is done in do_sys_settimeofday64() and again in do_settimeofday64: if (!timespec64_valid_settod(ts)) return -EINVAL; The only check we should need in addition to this is to ensure that passing an invalid tv_usec number doesn't become an unexpectedly valid tv_nsec after the multiplication. I agree the patch looks like I'm missing a check here, but the code after the patch appears clear enough to me. Arnd _______________________________________________ Y2038 mailing list Y2038@lists.linaro.org https://lists.linaro.org/mailman/listinfo/y2038 ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 17/23] y2038: time: avoid timespec usage in settimeofday() 2019-11-14 11:06 ` Arnd Bergmann @ 2019-11-14 14:04 ` Thomas Gleixner 2019-11-14 14:35 ` Arnd Bergmann 0 siblings, 1 reply; 19+ messages in thread From: Thomas Gleixner @ 2019-11-14 14:04 UTC (permalink / raw) To: Arnd Bergmann Cc: Jens Axboe, Corey Minyard, y2038 Mailman List, Linux API, linux-kernel@vger.kernel.org, Li RongQing, David Howells, Stephen Boyd, zhengbin, John Stultz, Al Viro, Ingo Molnar, Christian Brauner, Deepa Dinamani On Thu, 14 Nov 2019, Arnd Bergmann wrote: > On Wed, Nov 13, 2019 at 10:53 PM Thomas Gleixner <tglx@linutronix.de> wrote: > > > > On Fri, 8 Nov 2019, Arnd Bergmann wrote: > > > -SYSCALL_DEFINE2(settimeofday, struct timeval __user *, tv, > > > +SYSCALL_DEFINE2(settimeofday, struct __kernel_old_timeval __user *, tv, > > > struct timezone __user *, tz) > > > { > > > struct timespec64 new_ts; > > > - struct timeval user_tv; > > > struct timezone new_tz; > > > > > > if (tv) { > > > - if (copy_from_user(&user_tv, tv, sizeof(*tv))) > > > + if (get_user(new_ts.tv_sec, &tv->tv_sec) || > > > + get_user(new_ts.tv_nsec, &tv->tv_usec)) > > > return -EFAULT; > > > > How is that supposed to be correct on a 32bit kernel? > > I don't see the problem you are referring to. This should behave the > same way on a 32-bit kernel and on a 64-bit kernel, sign-extending > the tv_sec field, and copying the user tv_usec field into the > kernel tv_nsec, to be multiplied by 1000 a few lines later. You're right. Tired brain failed to see the implicit sign extension in get_user(). > Am I missing something? No. > > > - if (!timeval_valid(&user_tv)) > > > + if (tv->tv_usec > USEC_PER_SEC) > > > return -EINVAL; > > > > That's incomplete: > > > > static inline bool timeval_valid(const struct timeval *tv) > > { > > /* Dates before 1970 are bogus */ > > if (tv->tv_sec < 0) > > return false; > > > > /* Can't have more microseconds then a second */ > > if (tv->tv_usec < 0 || tv->tv_usec >= USEC_PER_SEC) > > return false; > > > > return true; > > } > > My idea was to not duplicate the range check that is done > in do_sys_settimeofday64() and again in do_settimeofday64: > > if (!timespec64_valid_settod(ts)) > return -EINVAL; > > The only check we should need in addition to this is to ensure > that passing an invalid tv_usec number doesn't become an > unexpectedly valid tv_nsec after the multiplication. Right, but please add a proper comment as you/we are going to scratch heads 4 weeks from now when staring at that check and wondering why it is incomplete. Thanks, tglx _______________________________________________ Y2038 mailing list Y2038@lists.linaro.org https://lists.linaro.org/mailman/listinfo/y2038 ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 17/23] y2038: time: avoid timespec usage in settimeofday() 2019-11-14 14:04 ` Thomas Gleixner @ 2019-11-14 14:35 ` Arnd Bergmann 0 siblings, 0 replies; 19+ messages in thread From: Arnd Bergmann @ 2019-11-14 14:35 UTC (permalink / raw) To: Thomas Gleixner Cc: y2038 Mailman List, John Stultz, linux-kernel@vger.kernel.org, Stephen Boyd, David Howells, Al Viro, Deepa Dinamani, Christian Brauner, Jens Axboe, Ingo Molnar, Corey Minyard, zhengbin, Li RongQing, Linux API On Thu, Nov 14, 2019 at 3:04 PM Thomas Gleixner <tglx@linutronix.de> wrote: > On Thu, 14 Nov 2019, Arnd Bergmann wrote: > > On Wed, Nov 13, 2019 at 10:53 PM Thomas Gleixner <tglx@linutronix.de> wrote: > > > > My idea was to not duplicate the range check that is done > > in do_sys_settimeofday64() and again in do_settimeofday64: > > > > if (!timespec64_valid_settod(ts)) > > return -EINVAL; > > > > The only check we should need in addition to this is to ensure > > that passing an invalid tv_usec number doesn't become an > > unexpectedly valid tv_nsec after the multiplication. > > Right, but please add a proper comment as you/we are going to scratch heads > 4 weeks from now when staring at that check and wondering why it is > incomplete. Ok, done. I had just uploaded the branch with the fixup for the __user pointer access in the same patch, but that version had introduced another typo. I hope the version I uploaded now has all known issues addressed for tomorrow's linux-next. Arnd ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 17/23] y2038: time: avoid timespec usage in settimeofday() 2019-11-08 21:12 ` [PATCH 17/23] y2038: time: avoid timespec usage in settimeofday() Arnd Bergmann 2019-11-13 21:53 ` Thomas Gleixner @ 2019-11-14 23:01 ` Abel Vesa 2019-11-15 7:58 ` Arnd Bergmann 1 sibling, 1 reply; 19+ messages in thread From: Abel Vesa @ 2019-11-14 23:01 UTC (permalink / raw) To: Arnd Bergmann Cc: y2038, John Stultz, Thomas Gleixner, linux-kernel, Stephen Boyd, David Howells, Al Viro, Deepa Dinamani, Christian Brauner, Jens Axboe, Ingo Molnar, Corey Minyard, zhengbin, Li RongQing, linux-api On 19-11-08 22:12:16, Arnd Bergmann wrote: > The compat_get_timeval() and timeval_valid() interfaces > are deprecated and getting removed along with the definition > of struct timeval itself. > > Change the two implementations of the settimeofday() > system call to open-code these helpers and completely > avoid references to timeval. > I get the following rcu stalls due to this patch on riscv64 (on qemu): [root@riscv ~]# uname -a Linux riscv 5.4.0-rc6-00018-gadde74306a4b #112 SMP Fri Nov 15 00:46:20 EET 2019 riscv64 riscv64 riscv64 GNU/Linux [root@riscv ~]# [ 420.135710] rcu: INFO: rcu_sched self-detected stall on CPU [ 420.136839] rcu: 3-....: (99702 ticks this GP) idle=482/1/0x4000000000000002 softirq=3322/3322 fqs=48784 [ 420.138917] (t=99768 jiffies g=4985 q=8343) [ 420.139772] Task dump for CPU 3: [ 420.140236] rdate R running task 0 254 1 0x00000008 [ 420.142226] Call Trace: [ 420.142791] [<ffffffe000037954>] walk_stackframe+0x0/0xa6 [ 420.143911] [<ffffffe000037aba>] show_stack+0x2a/0x34 [ 420.145010] [<ffffffe0000569c8>] sched_show_task+0xf0/0x116 [ 420.145996] [<ffffffe00005b502>] dump_cpu_task+0x3e/0x48 [ 420.147073] [<ffffffe000084e5e>] rcu_dump_cpu_stacks+0x7c/0xb4 [ 420.148243] [<ffffffe0000842f6>] rcu_sched_clock_irq+0x3d6/0x582 [ 420.149349] [<ffffffe0000897b4>] update_process_times+0x1e/0x42 [ 420.150306] [<ffffffe000093a34>] tick_sched_handle.isra.0+0x2a/0x3a [ 420.150997] [<ffffffe000093ce8>] tick_sched_timer+0x4e/0x92 [ 420.151603] [<ffffffe000089eb6>] __hrtimer_run_queues+0xae/0x108 [ 420.152639] [<ffffffe00008a5ac>] hrtimer_interrupt+0xca/0x1d4 [ 420.153629] [<ffffffe0004de564>] riscv_timer_interrupt+0x32/0x3a [ 420.154629] [<ffffffe000612ad4>] do_IRQ+0xa4/0xb8 [ 420.155294] [<ffffffe000036814>] ret_from_exception+0x0/0xc [ 420.156073] [<ffffffe000036814>] ret_from_exception+0x0/0xc [ 451.556189] rcu: INFO: rcu_sched detected expedited stalls on CPUs/tasks: { 3-... } 100725 jiffies s: 53 root: 0x8/. [ 451.558689] rcu: blocking rcu_node structures: [ 451.559501] Task dump for CPU 3: [ 451.560518] rdate R running task 0 254 1 0x00000008 [ 451.561396] Call Trace: [ 451.561675] [<ffffffe00060ed48>] __schedule+0x158/0x36a [ 483.147733] rcu: INFO: rcu_sched self-detected stall on CPU [ 483.148723] rcu: 3-....: (115448 ticks this GP) idle=482/1/0x4000000000000002 softirq=3322/3322 fqs=56510 [ 483.150220] (t=115521 jiffies g=4985 q=8400) [ 483.150885] Task dump for CPU 3: [ 483.151392] rdate R running task 0 254 1 0x00000008 [ 483.152321] Call Trace: [ 483.152755] [<ffffffe000037954>] walk_stackframe+0x0/0xa6 [ 483.153600] [<ffffffe000037aba>] show_stack+0x2a/0x34 [ 483.154428] [<ffffffe0000569c8>] sched_show_task+0xf0/0x116 [ 483.155325] [<ffffffe00005b502>] dump_cpu_task+0x3e/0x48 [ 483.156199] [<ffffffe000084e5e>] rcu_dump_cpu_stacks+0x7c/0xb4 [ 483.157163] [<ffffffe0000842f6>] rcu_sched_clock_irq+0x3d6/0x582 [ 483.158166] [<ffffffe0000897b4>] update_process_times+0x1e/0x42 [ 483.159257] [<ffffffe000093a34>] tick_sched_handle.isra.0+0x2a/0x3a [ 483.160240] [<ffffffe000093ce8>] tick_sched_timer+0x4e/0x92 [ 483.160992] [<ffffffe000089eb6>] __hrtimer_run_queues+0xae/0x108 [ 483.161881] [<ffffffe00008a5ac>] hrtimer_interrupt+0xca/0x1d4 [ 483.162778] [<ffffffe0004de564>] riscv_timer_interrupt+0x32/0x3a [ 483.163542] [<ffffffe000612ad4>] do_IRQ+0xa4/0xb8 [ 483.164241] [<ffffffe000036814>] ret_from_exception+0x0/0xc [ 483.165108] [<ffffffe000036814>] ret_from_exception+0x0/0xc [ 515.044254] rcu: INFO: rcu_sched detected expedited stalls on CPUs/tasks: { 3-... } 116597 jiffies s: 53 root: 0x8/. [ 515.046221] rcu: blocking rcu_node structures: [ 515.046799] Task dump for CPU 3: [ 515.047180] rdate R running task 0 254 1 0x00000008 [ 515.048476] Call Trace: [ 515.048895] [<ffffffe00060ed48>] __schedule+0x158/0x36a I will dig up some more into this tomorrow since it's way past by midnight here. > Signed-off-by: Arnd Bergmann <arnd@arndb.de> > --- > include/linux/syscalls.h | 2 +- > kernel/time/time.c | 20 +++++++++----------- > 2 files changed, 10 insertions(+), 12 deletions(-) > > diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h > index e665920fa359..d0391cc2dae9 100644 > --- a/include/linux/syscalls.h > +++ b/include/linux/syscalls.h > @@ -734,7 +734,7 @@ asmlinkage long sys_getcpu(unsigned __user *cpu, unsigned __user *node, struct g > /* kernel/time.c */ > asmlinkage long sys_gettimeofday(struct __kernel_old_timeval __user *tv, > struct timezone __user *tz); > -asmlinkage long sys_settimeofday(struct timeval __user *tv, > +asmlinkage long sys_settimeofday(struct __kernel_old_timeval __user *tv, > struct timezone __user *tz); > asmlinkage long sys_adjtimex(struct __kernel_timex __user *txc_p); > asmlinkage long sys_adjtimex_time32(struct old_timex32 __user *txc_p); > diff --git a/kernel/time/time.c b/kernel/time/time.c > index bc114f0be8f1..6bfbe640fd3b 100644 > --- a/kernel/time/time.c > +++ b/kernel/time/time.c > @@ -196,22 +196,21 @@ int do_sys_settimeofday64(const struct timespec64 *tv, const struct timezone *tz > return 0; > } > > -SYSCALL_DEFINE2(settimeofday, struct timeval __user *, tv, > +SYSCALL_DEFINE2(settimeofday, struct __kernel_old_timeval __user *, tv, > struct timezone __user *, tz) > { > struct timespec64 new_ts; > - struct timeval user_tv; > struct timezone new_tz; > > if (tv) { > - if (copy_from_user(&user_tv, tv, sizeof(*tv))) > + if (get_user(new_ts.tv_sec, &tv->tv_sec) || > + get_user(new_ts.tv_nsec, &tv->tv_usec)) > return -EFAULT; > > - if (!timeval_valid(&user_tv)) > + if (tv->tv_usec > USEC_PER_SEC) > return -EINVAL; > > - new_ts.tv_sec = user_tv.tv_sec; > - new_ts.tv_nsec = user_tv.tv_usec * NSEC_PER_USEC; > + new_ts.tv_nsec *= NSEC_PER_USEC; > } > if (tz) { > if (copy_from_user(&new_tz, tz, sizeof(*tz))) > @@ -245,18 +244,17 @@ COMPAT_SYSCALL_DEFINE2(settimeofday, struct old_timeval32 __user *, tv, > struct timezone __user *, tz) > { > struct timespec64 new_ts; > - struct timeval user_tv; > struct timezone new_tz; > > if (tv) { > - if (compat_get_timeval(&user_tv, tv)) > + if (get_user(new_ts.tv_sec, &tv->tv_sec) || > + get_user(new_ts.tv_nsec, &tv->tv_usec)) > return -EFAULT; > > - if (!timeval_valid(&user_tv)) > + if (new_ts.tv_nsec > USEC_PER_SEC) > return -EINVAL; > > - new_ts.tv_sec = user_tv.tv_sec; > - new_ts.tv_nsec = user_tv.tv_usec * NSEC_PER_USEC; > + new_ts.tv_nsec *= NSEC_PER_USEC; > } > if (tz) { > if (copy_from_user(&new_tz, tz, sizeof(*tz))) > -- > 2.20.0 > ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 17/23] y2038: time: avoid timespec usage in settimeofday() 2019-11-14 23:01 ` Abel Vesa @ 2019-11-15 7:58 ` Arnd Bergmann 2019-11-15 10:27 ` Rasmus Villemoes 0 siblings, 1 reply; 19+ messages in thread From: Arnd Bergmann @ 2019-11-15 7:58 UTC (permalink / raw) To: Abel Vesa Cc: y2038 Mailman List, John Stultz, Thomas Gleixner, linux-kernel@vger.kernel.org, Stephen Boyd, David Howells, Al Viro, Deepa Dinamani, Christian Brauner, Jens Axboe, Ingo Molnar, Corey Minyard, zhengbin, Li RongQing, Linux API On Fri, Nov 15, 2019 at 12:01 AM Abel Vesa <abelvesa@linux.com> wrote: > > On 19-11-08 22:12:16, Arnd Bergmann wrote: > > The compat_get_timeval() and timeval_valid() interfaces > > are deprecated and getting removed along with the definition > > of struct timeval itself. > > > > Change the two implementations of the settimeofday() > > system call to open-code these helpers and completely > > avoid references to timeval. > > I'm not sure how we get to the RCU stall, but this is almost certainly another symptom of a typo I had introduced in the patch, which others have also reported. This is the the fix in today's linux-next: --- a/kernel/time/time.c +++ b/kernel/time/time.c @@ -207,7 +207,7 @@ SYSCALL_DEFINE2(settimeofday, struct __kernel_old_timeval __user *, tv, get_user(new_ts.tv_nsec, &tv->tv_usec)) return -EFAULT; - if (tv->tv_usec > USEC_PER_SEC) + if (new_ts->tv_usec > USEC_PER_SEC) return -EINVAL; new_ts.tv_nsec *= NSEC_PER_USEC; Arnd > I get the following rcu stalls due to this patch on riscv64 (on qemu): > > [root@riscv ~]# uname -a > Linux riscv 5.4.0-rc6-00018-gadde74306a4b #112 SMP Fri Nov 15 00:46:20 EET 2019 riscv64 riscv64 riscv64 GNU/Linux > [root@riscv ~]# [ 420.135710] rcu: INFO: rcu_sched self-detected stall > on CPU > [ 420.136839] rcu: 3-....: (99702 ticks this GP) idle=482/1/0x4000000000000002 softirq=3322/3322 fqs=48784 > [ 420.138917] (t=99768 jiffies g=4985 q=8343) > [ 420.139772] Task dump for CPU 3: > [ 420.140236] rdate R running task 0 254 1 0x00000008 > [ 420.142226] Call Trace: > [ 420.142791] [<ffffffe000037954>] walk_stackframe+0x0/0xa6 > [ 420.143911] [<ffffffe000037aba>] show_stack+0x2a/0x34 > [ 420.145010] [<ffffffe0000569c8>] sched_show_task+0xf0/0x116 > [ 420.145996] [<ffffffe00005b502>] dump_cpu_task+0x3e/0x48 > [ 420.147073] [<ffffffe000084e5e>] rcu_dump_cpu_stacks+0x7c/0xb4 > [ 420.148243] [<ffffffe0000842f6>] rcu_sched_clock_irq+0x3d6/0x582 > [ 420.149349] [<ffffffe0000897b4>] update_process_times+0x1e/0x42 > [ 420.150306] [<ffffffe000093a34>] tick_sched_handle.isra.0+0x2a/0x3a > [ 420.150997] [<ffffffe000093ce8>] tick_sched_timer+0x4e/0x92 > [ 420.151603] [<ffffffe000089eb6>] __hrtimer_run_queues+0xae/0x108 > [ 420.152639] [<ffffffe00008a5ac>] hrtimer_interrupt+0xca/0x1d4 > [ 420.153629] [<ffffffe0004de564>] riscv_timer_interrupt+0x32/0x3a > [ 420.154629] [<ffffffe000612ad4>] do_IRQ+0xa4/0xb8 > [ 420.155294] [<ffffffe000036814>] ret_from_exception+0x0/0xc > [ 420.156073] [<ffffffe000036814>] ret_from_exception+0x0/0xc ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 17/23] y2038: time: avoid timespec usage in settimeofday() 2019-11-15 7:58 ` Arnd Bergmann @ 2019-11-15 10:27 ` Rasmus Villemoes 2019-11-15 13:50 ` Arnd Bergmann 0 siblings, 1 reply; 19+ messages in thread From: Rasmus Villemoes @ 2019-11-15 10:27 UTC (permalink / raw) To: Arnd Bergmann, Abel Vesa Cc: y2038 Mailman List, John Stultz, Thomas Gleixner, linux-kernel@vger.kernel.org, Stephen Boyd, David Howells, Al Viro, Deepa Dinamani, Christian Brauner, Jens Axboe, Ingo Molnar, Corey Minyard, zhengbin, Li RongQing, Linux API On 15/11/2019 08.58, Arnd Bergmann wrote: > On Fri, Nov 15, 2019 at 12:01 AM Abel Vesa <abelvesa@linux.com> wrote: >> >> On 19-11-08 22:12:16, Arnd Bergmann wrote: >>> The compat_get_timeval() and timeval_valid() interfaces >>> are deprecated and getting removed along with the definition >>> of struct timeval itself. >>> >>> Change the two implementations of the settimeofday() >>> system call to open-code these helpers and completely >>> avoid references to timeval. >>> > > I'm not sure how we get to the RCU stall, but this is almost certainly another > symptom of a typo I had introduced in the patch, which others have also > reported. This is the the fix in today's linux-next: > > --- a/kernel/time/time.c > +++ b/kernel/time/time.c > @@ -207,7 +207,7 @@ SYSCALL_DEFINE2(settimeofday, struct > __kernel_old_timeval __user *, tv, > get_user(new_ts.tv_nsec, &tv->tv_usec)) > return -EFAULT; > > - if (tv->tv_usec > USEC_PER_SEC) > + if (new_ts->tv_usec > USEC_PER_SEC) > return -EINVAL; Hopefully not :) > new_ts.tv_nsec *= NSEC_PER_USEC; So the actual patch in next-20191115 does - if (copy_from_user(&user_tv, tv, sizeof(*tv))) + if (get_user(new_ts.tv_sec, &tv->tv_sec) || + get_user(new_ts.tv_nsec, &tv->tv_usec)) return -EFAULT; - if (!timeval_valid(&user_tv)) + if (new_ts.tv_nsec > USEC_PER_SEC) return -EINVAL; - new_ts.tv_sec = user_tv.tv_sec; - new_ts.tv_nsec = user_tv.tv_usec * NSEC_PER_USEC; + new_ts.tv_nsec *= NSEC_PER_USEC; But removing the "user value is < 0" check, relying on the timespec value being rejected later, is wrong: 1000=8*125. Multiplying by 8 always gives a value with the low three bits clear, multiplying by 125 is reversible. So you can take any target value with the three low bits clear, logic shift right by 3, multiply by 0x1cac083126e978d5 , and flip the top three bits as you wish to generate 8 pre-images of that target value. Four of those will be negative. A trivial example is 0x80..000 (aka LONG_MIN) and its cousins 0xa0..000, 0xc0..000, 0xe0..000 which all become 0 and thus accepted after multiplying by NSEC_PER_USEC. But also -858989233 (or -3689348814741906097 if long is 64 bit) become 4226200 which isn't even a multiple of 1000 - there's 500M examples to choose from :) I'm pretty sure it doesn't generate worse code, gcc is smart enough to compile "foo > BAR || foo < 0" as if it was written "(unsigned version of foo)foo > BAR". And while a value of USEC_PER_SEC itself will not overflow and then be rejeted because the real comparison done later is ">= NSEC_PER_SEC", I think it's clearer to say "foo >= USEC_PER_SEC || foo < 0) just so the same pattern is used. Rasmus ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 17/23] y2038: time: avoid timespec usage in settimeofday() 2019-11-15 10:27 ` Rasmus Villemoes @ 2019-11-15 13:50 ` Arnd Bergmann 0 siblings, 0 replies; 19+ messages in thread From: Arnd Bergmann @ 2019-11-15 13:50 UTC (permalink / raw) To: Rasmus Villemoes Cc: Abel Vesa, y2038 Mailman List, John Stultz, Thomas Gleixner, linux-kernel@vger.kernel.org, Stephen Boyd, David Howells, Al Viro, Deepa Dinamani, Christian Brauner, Jens Axboe, Ingo Molnar, Corey Minyard, zhengbin, Li RongQing, Linux API On Fri, Nov 15, 2019 at 11:27 AM Rasmus Villemoes <linux@rasmusvillemoes.dk> wrote: > On 15/11/2019 08.58, Arnd Bergmann wrote: > > On Fri, Nov 15, 2019 at 12:01 AM Abel Vesa <abelvesa@linux.com> wrote: > >> > > --- a/kernel/time/time.c > > +++ b/kernel/time/time.c > > @@ -207,7 +207,7 @@ SYSCALL_DEFINE2(settimeofday, struct > > __kernel_old_timeval __user *, tv, > > get_user(new_ts.tv_nsec, &tv->tv_usec)) > > return -EFAULT; > > > > - if (tv->tv_usec > USEC_PER_SEC) > > + if (new_ts->tv_usec > USEC_PER_SEC) > > return -EINVAL; > > Hopefully not :) No, I misquoted from a fix that I had temporarily applied, not the version in linux-next. > > > new_ts.tv_nsec *= NSEC_PER_USEC; > > So the actual patch in next-20191115 does > > - if (copy_from_user(&user_tv, tv, sizeof(*tv))) > + if (get_user(new_ts.tv_sec, &tv->tv_sec) || > + get_user(new_ts.tv_nsec, &tv->tv_usec)) > return -EFAULT; > > - if (!timeval_valid(&user_tv)) > + if (new_ts.tv_nsec > USEC_PER_SEC) > return -EINVAL; > > - new_ts.tv_sec = user_tv.tv_sec; > - new_ts.tv_nsec = user_tv.tv_usec * NSEC_PER_USEC; > + new_ts.tv_nsec *= NSEC_PER_USEC; > > But removing the "user value is < 0" check, relying on the timespec > value being rejected later, is wrong You are right of course, so many ways to get this one line wrong... Pushed more more update to the branch now. Thanks for the careful review! Arnd ^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 23/23] y2038: allow disabling time32 system calls 2019-11-08 21:02 [PATCH 00/23] y2038 cleanups Arnd Bergmann ` (2 preceding siblings ...) 2019-11-08 21:12 ` [PATCH 17/23] y2038: time: avoid timespec usage in settimeofday() Arnd Bergmann @ 2019-11-08 21:12 ` Arnd Bergmann 2019-11-11 12:31 ` Christian Brauner 2019-11-13 21:40 ` [PATCH 00/23] y2038 cleanups Arnd Bergmann 4 siblings, 1 reply; 19+ messages in thread From: Arnd Bergmann @ 2019-11-08 21:12 UTC (permalink / raw) To: y2038 Cc: linux-kernel, Arnd Bergmann, Ingo Molnar, Peter Zijlstra, Thomas Gleixner, Geert Uytterhoeven, Christian Brauner, linux-api At the moment, the compilation of the old time32 system calls depends purely on the architecture. As systems with new libc based on 64-bit time_t are getting deployed, even architectures that previously supported these (notably x86-32 and arm32 but also many others) no longer depend on them, and removing them from a kernel image results in a smaller kernel binary, the same way we can leave out many other optional system calls. More importantly, on an embedded system that needs to keep working beyond year 2038, any user space program calling these system calls is likely a bug, so removing them from the kernel image does provide an extra debugging help for finding broken applications. I've gone back and forth on hiding this option unless CONFIG_EXPERT is set. This version leaves it visible based on the logic that eventually it will be turned off indefinitely. Signed-off-by: Arnd Bergmann <arnd@arndb.de> --- arch/Kconfig | 3 ++- kernel/sys_ni.c | 23 +++++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/arch/Kconfig b/arch/Kconfig index 0e1fded2940e..1203955ed4d0 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -797,7 +797,8 @@ config COMPAT_OLD_SIGACTION bool config COMPAT_32BIT_TIME - def_bool !64BIT || COMPAT + bool "Provide system calls for 32-bit time_t" + default !64BIT || COMPAT help This enables 32 bit time_t support in addition to 64 bit time_t support. This is relevant on all 32-bit architectures, and 64-bit architectures diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c index 34b76895b81e..3b69a560a7ac 100644 --- a/kernel/sys_ni.c +++ b/kernel/sys_ni.c @@ -410,6 +410,29 @@ COND_SYSCALL(send); COND_SYSCALL(bdflush); COND_SYSCALL(uselib); +/* optional: time32 */ +COND_SYSCALL(time32); +COND_SYSCALL(stime32); +COND_SYSCALL(utime32); +COND_SYSCALL(adjtimex_time32); +COND_SYSCALL(sched_rr_get_interval_time32); +COND_SYSCALL(nanosleep_time32); +COND_SYSCALL(rt_sigtimedwait_time32); +COND_SYSCALL_COMPAT(rt_sigtimedwait_time32); +COND_SYSCALL(timer_settime32); +COND_SYSCALL(timer_gettime32); +COND_SYSCALL(clock_settime32); +COND_SYSCALL(clock_gettime32); +COND_SYSCALL(clock_getres_time32); +COND_SYSCALL(clock_nanosleep_time32); +COND_SYSCALL(utimes_time32); +COND_SYSCALL(futimesat_time32); +COND_SYSCALL(pselect6_time32); +COND_SYSCALL_COMPAT(pselect6_time32); +COND_SYSCALL(ppoll_time32); +COND_SYSCALL_COMPAT(ppoll_time32); +COND_SYSCALL(utimensat_time32); +COND_SYSCALL(clock_adjtime32); /* * The syscalls below are not found in include/uapi/asm-generic/unistd.h -- 2.20.0 ^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCH 23/23] y2038: allow disabling time32 system calls 2019-11-08 21:12 ` [PATCH 23/23] y2038: allow disabling time32 system calls Arnd Bergmann @ 2019-11-11 12:31 ` Christian Brauner 0 siblings, 0 replies; 19+ messages in thread From: Christian Brauner @ 2019-11-11 12:31 UTC (permalink / raw) To: Arnd Bergmann Cc: y2038, linux-kernel, Ingo Molnar, Peter Zijlstra, Thomas Gleixner, Geert Uytterhoeven, Christian Brauner, linux-api On Fri, Nov 08, 2019 at 10:12:22PM +0100, Arnd Bergmann wrote: > At the moment, the compilation of the old time32 system calls depends > purely on the architecture. As systems with new libc based on 64-bit > time_t are getting deployed, even architectures that previously supported > these (notably x86-32 and arm32 but also many others) no longer depend on > them, and removing them from a kernel image results in a smaller kernel > binary, the same way we can leave out many other optional system calls. > > More importantly, on an embedded system that needs to keep working > beyond year 2038, any user space program calling these system calls > is likely a bug, so removing them from the kernel image does provide > an extra debugging help for finding broken applications. > > I've gone back and forth on hiding this option unless CONFIG_EXPERT > is set. This version leaves it visible based on the logic that > eventually it will be turned off indefinitely. > > Signed-off-by: Arnd Bergmann <arnd@arndb.de> Acked-by: Christian Brauner <christian.brauner@ubuntu.com> ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 00/23] y2038 cleanups 2019-11-08 21:02 [PATCH 00/23] y2038 cleanups Arnd Bergmann ` (3 preceding siblings ...) 2019-11-08 21:12 ` [PATCH 23/23] y2038: allow disabling time32 system calls Arnd Bergmann @ 2019-11-13 21:40 ` Arnd Bergmann 4 siblings, 0 replies; 19+ messages in thread From: Arnd Bergmann @ 2019-11-13 21:40 UTC (permalink / raw) To: y2038 Mailman List Cc: linux-kernel@vger.kernel.org, Richard Henderson, Tony Luck, Paul Burton, Greentime Hu, Helge Deller, Michael Ellerman, David Miller, Thomas Gleixner, the arch/x86 maintainers, Jeff Dike, Richard Weinberger, Al Viro, Benjamin LaHaise, John Stultz, Stephen Boyd, Steven Rostedt, Vincenzo Frascino, Paul Moore, Stephen Smalley On Fri, Nov 8, 2019 at 10:04 PM Arnd Bergmann <arnd@arndb.de> wrote: > > This is a series of cleanups for the y2038 work, mostly intended > for namespace cleaning: the kernel defines the traditional > time_t, timeval and timespec types that often lead to y2038-unsafe > code. Even though the unsafe usage is mostly gone from the kernel, > having the types and associated functions around means that we > can still grow new users, and that we may be missing conversions > to safe types that actually matter. > > As there is no rush on any of these patches, I would either > queue them up in linux-next through my y2038 branch, or > Thomas could add them to the tip tree if he wants. > > As mentioned in another series, this is part of a larger > effort to fix all the remaining bits and pieces that are > not completed yet from the y2038 conversion, and the full > set can be found at: > > https://git.kernel.org/pub/scm/linux/kernel/git/arnd/playground.git/log/?h=y2038-endgame > > Maintainers, please review and provide Acks. > > Let me know if you have any opinion on whether we should do > the include last two patches of this series or not. > > Arnd > > Arnd Bergmann (23): > y2038: remove CONFIG_64BIT_TIME > y2038: add __kernel_old_timespec and __kernel_old_time_t > y2038: vdso: change timeval to __kernel_old_timeval > y2038: vdso: change timespec to __kernel_old_timespec > y2038: vdso: change time_t to __kernel_old_time_t > y2038: vdso: nds32: open-code timespec_add_ns() > y2038: vdso: powerpc: avoid timespec references > y2038: ipc: remove __kernel_time_t reference from headers > y2038: stat: avoid 'time_t' in 'struct stat' > y2038: uapi: change __kernel_time_t to __kernel_old_time_t > y2038: rusage: use __kernel_old_timeval > y2038: syscalls: change remaining timeval to __kernel_old_timeval > y2038: socket: remove timespec reference in timestamping > y2038: make ns_to_compat_timeval use __kernel_old_timeval > y2038: elfcore: Use __kernel_old_timeval for process times > y2038: timerfd: Use timespec64 internally > y2038: time: avoid timespec usage in settimeofday() > y2038: itimer: compat handling to itimer.c > y2038: use compat_{get,set}_itimer on alpha > y2038: move itimer reset into itimer.c > y2038: itimer: change implementation to timespec64 > [RFC] y2038: itimer: use ktime_t internally > y2038: allow disabling time32 system calls I've dropped the "[RFC] y2038: itimer: use ktime_t internally" patch for the moment, and added two other patches from other series: y2038: remove CONFIG_64BIT_TIME y2038: socket: use __kernel_old_timespec instead of timespec Tentatively pushed out the patches with the Acks I have received so far to my y2038 branch on git.kernel.org so it gets included in linux-next. If I hear no complaints, I'll send a pull request for the merge window, along with the compat-ioctl series I have already queued up in the same branch. Arnd ^ permalink raw reply [flat|nested] 19+ messages in thread
end of thread, other threads:[~2019-11-15 13:50 UTC | newest] Thread overview: 19+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2019-11-08 21:02 [PATCH 00/23] y2038 cleanups Arnd Bergmann 2019-11-08 21:12 ` [PATCH 10/23] y2038: uapi: change __kernel_time_t to __kernel_old_time_t Arnd Bergmann 2019-11-09 19:03 ` Deepa Dinamani 2019-11-11 12:38 ` Christian Brauner 2019-11-08 21:12 ` [PATCH 12/23] y2038: syscalls: change remaining timeval to __kernel_old_timeval Arnd Bergmann 2019-11-11 12:44 ` Christian Brauner 2019-11-13 22:39 ` Rafael J. Wysocki 2019-11-08 21:12 ` [PATCH 17/23] y2038: time: avoid timespec usage in settimeofday() Arnd Bergmann 2019-11-13 21:53 ` Thomas Gleixner 2019-11-14 11:06 ` Arnd Bergmann 2019-11-14 14:04 ` Thomas Gleixner 2019-11-14 14:35 ` Arnd Bergmann 2019-11-14 23:01 ` Abel Vesa 2019-11-15 7:58 ` Arnd Bergmann 2019-11-15 10:27 ` Rasmus Villemoes 2019-11-15 13:50 ` Arnd Bergmann 2019-11-08 21:12 ` [PATCH 23/23] y2038: allow disabling time32 system calls Arnd Bergmann 2019-11-11 12:31 ` Christian Brauner 2019-11-13 21:40 ` [PATCH 00/23] y2038 cleanups Arnd Bergmann
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).