diff options
author | Arnd Bergmann <arnd@arndb.de> | 2018-04-18 07:42:25 -0400 |
---|---|---|
committer | Arnd Bergmann <arnd@arndb.de> | 2018-08-29 09:42:24 -0400 |
commit | c2e6c8567acdba8db1055b242c34ceb123c6a253 (patch) | |
tree | c68fc623710d64f681bcd1b90965f69a757e64ba /net/socket.c | |
parent | 474b9c777b20b8340a6ee0f7ba6ebbd6a4bf47e2 (diff) |
y2038: socket: Change recvmmsg to use __kernel_timespec
This converts the recvmmsg() system call in all its variations to use
'timespec64' internally for its timeout, and have a __kernel_timespec64
argument in the native entry point. This lets us change the type to use
64-bit time_t at a later point while using the 32-bit compat system call
emulation for existing user space.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'net/socket.c')
-rw-r--r-- | net/socket.c | 18 |
1 files changed, 8 insertions, 10 deletions
diff --git a/net/socket.c b/net/socket.c index e6945e318f02..b9d71b503720 100644 --- a/net/socket.c +++ b/net/socket.c | |||
@@ -2340,7 +2340,7 @@ SYSCALL_DEFINE3(recvmsg, int, fd, struct user_msghdr __user *, msg, | |||
2340 | */ | 2340 | */ |
2341 | 2341 | ||
2342 | int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, | 2342 | int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, |
2343 | unsigned int flags, struct timespec *timeout) | 2343 | unsigned int flags, struct timespec64 *timeout) |
2344 | { | 2344 | { |
2345 | int fput_needed, err, datagrams; | 2345 | int fput_needed, err, datagrams; |
2346 | struct socket *sock; | 2346 | struct socket *sock; |
@@ -2405,8 +2405,7 @@ int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, | |||
2405 | 2405 | ||
2406 | if (timeout) { | 2406 | if (timeout) { |
2407 | ktime_get_ts64(&timeout64); | 2407 | ktime_get_ts64(&timeout64); |
2408 | *timeout = timespec64_to_timespec( | 2408 | *timeout = timespec64_sub(end_time, timeout64); |
2409 | timespec64_sub(end_time, timeout64)); | ||
2410 | if (timeout->tv_sec < 0) { | 2409 | if (timeout->tv_sec < 0) { |
2411 | timeout->tv_sec = timeout->tv_nsec = 0; | 2410 | timeout->tv_sec = timeout->tv_nsec = 0; |
2412 | break; | 2411 | break; |
@@ -2452,10 +2451,10 @@ out_put: | |||
2452 | 2451 | ||
2453 | static int do_sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, | 2452 | static int do_sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, |
2454 | unsigned int vlen, unsigned int flags, | 2453 | unsigned int vlen, unsigned int flags, |
2455 | struct timespec __user *timeout) | 2454 | struct __kernel_timespec __user *timeout) |
2456 | { | 2455 | { |
2457 | int datagrams; | 2456 | int datagrams; |
2458 | struct timespec timeout_sys; | 2457 | struct timespec64 timeout_sys; |
2459 | 2458 | ||
2460 | if (flags & MSG_CMSG_COMPAT) | 2459 | if (flags & MSG_CMSG_COMPAT) |
2461 | return -EINVAL; | 2460 | return -EINVAL; |
@@ -2463,13 +2462,12 @@ static int do_sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, | |||
2463 | if (!timeout) | 2462 | if (!timeout) |
2464 | return __sys_recvmmsg(fd, mmsg, vlen, flags, NULL); | 2463 | return __sys_recvmmsg(fd, mmsg, vlen, flags, NULL); |
2465 | 2464 | ||
2466 | if (copy_from_user(&timeout_sys, timeout, sizeof(timeout_sys))) | 2465 | if (get_timespec64(&timeout_sys, timeout)) |
2467 | return -EFAULT; | 2466 | return -EFAULT; |
2468 | 2467 | ||
2469 | datagrams = __sys_recvmmsg(fd, mmsg, vlen, flags, &timeout_sys); | 2468 | datagrams = __sys_recvmmsg(fd, mmsg, vlen, flags, &timeout_sys); |
2470 | 2469 | ||
2471 | if (datagrams > 0 && | 2470 | if (datagrams > 0 && put_timespec64(&timeout_sys, timeout)) |
2472 | copy_to_user(timeout, &timeout_sys, sizeof(timeout_sys))) | ||
2473 | datagrams = -EFAULT; | 2471 | datagrams = -EFAULT; |
2474 | 2472 | ||
2475 | return datagrams; | 2473 | return datagrams; |
@@ -2477,7 +2475,7 @@ static int do_sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, | |||
2477 | 2475 | ||
2478 | SYSCALL_DEFINE5(recvmmsg, int, fd, struct mmsghdr __user *, mmsg, | 2476 | SYSCALL_DEFINE5(recvmmsg, int, fd, struct mmsghdr __user *, mmsg, |
2479 | unsigned int, vlen, unsigned int, flags, | 2477 | unsigned int, vlen, unsigned int, flags, |
2480 | struct timespec __user *, timeout) | 2478 | struct __kernel_timespec __user *, timeout) |
2481 | { | 2479 | { |
2482 | return do_sys_recvmmsg(fd, mmsg, vlen, flags, timeout); | 2480 | return do_sys_recvmmsg(fd, mmsg, vlen, flags, timeout); |
2483 | } | 2481 | } |
@@ -2601,7 +2599,7 @@ SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args) | |||
2601 | break; | 2599 | break; |
2602 | case SYS_RECVMMSG: | 2600 | case SYS_RECVMMSG: |
2603 | err = do_sys_recvmmsg(a0, (struct mmsghdr __user *)a1, a[2], | 2601 | err = do_sys_recvmmsg(a0, (struct mmsghdr __user *)a1, a[2], |
2604 | a[3], (struct timespec __user *)a[4]); | 2602 | a[3], (struct __kernel_timespec __user *)a[4]); |
2605 | break; | 2603 | break; |
2606 | case SYS_ACCEPT4: | 2604 | case SYS_ACCEPT4: |
2607 | err = __sys_accept4(a0, (struct sockaddr __user *)a1, | 2605 | err = __sys_accept4(a0, (struct sockaddr __user *)a1, |