Skip to content

Commit c2e6c85

Browse files
committed
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 <[email protected]>
1 parent 474b9c7 commit c2e6c85

File tree

4 files changed

+14
-16
lines changed

4 files changed

+14
-16
lines changed

include/linux/socket.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@ struct ucred {
348348
extern int move_addr_to_kernel(void __user *uaddr, int ulen, struct sockaddr_storage *kaddr);
349349
extern int put_cmsg(struct msghdr*, int level, int type, int len, void *data);
350350

351-
struct timespec;
351+
struct timespec64;
352352

353353
/* The __sys_...msg variants allow MSG_CMSG_COMPAT iff
354354
* forbid_cmsg_compat==false
@@ -358,7 +358,7 @@ extern long __sys_recvmsg(int fd, struct user_msghdr __user *msg,
358358
extern long __sys_sendmsg(int fd, struct user_msghdr __user *msg,
359359
unsigned int flags, bool forbid_cmsg_compat);
360360
extern int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,
361-
unsigned int flags, struct timespec *timeout);
361+
unsigned int flags, struct timespec64 *timeout);
362362
extern int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg,
363363
unsigned int vlen, unsigned int flags,
364364
bool forbid_cmsg_compat);

include/linux/syscalls.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -830,7 +830,7 @@ asmlinkage long sys_perf_event_open(
830830
asmlinkage long sys_accept4(int, struct sockaddr __user *, int __user *, int);
831831
asmlinkage long sys_recvmmsg(int fd, struct mmsghdr __user *msg,
832832
unsigned int vlen, unsigned flags,
833-
struct timespec __user *timeout);
833+
struct __kernel_timespec __user *timeout);
834834

835835
asmlinkage long sys_wait4(pid_t pid, int __user *stat_addr,
836836
int options, struct rusage __user *ru);

net/compat.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -815,18 +815,18 @@ static int __compat_sys_recvmmsg(int fd, struct compat_mmsghdr __user *mmsg,
815815
struct old_timespec32 __user *timeout)
816816
{
817817
int datagrams;
818-
struct timespec ktspec;
818+
struct timespec64 ktspec;
819819

820820
if (timeout == NULL)
821821
return __sys_recvmmsg(fd, (struct mmsghdr __user *)mmsg, vlen,
822822
flags | MSG_CMSG_COMPAT, NULL);
823823

824-
if (compat_get_timespec(&ktspec, timeout))
824+
if (compat_get_timespec64(&ktspec, timeout))
825825
return -EFAULT;
826826

827827
datagrams = __sys_recvmmsg(fd, (struct mmsghdr __user *)mmsg, vlen,
828828
flags | MSG_CMSG_COMPAT, &ktspec);
829-
if (datagrams > 0 && compat_put_timespec(&ktspec, timeout))
829+
if (datagrams > 0 && compat_put_timespec64(&ktspec, timeout))
830830
datagrams = -EFAULT;
831831

832832
return datagrams;

net/socket.c

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2340,7 +2340,7 @@ SYSCALL_DEFINE3(recvmsg, int, fd, struct user_msghdr __user *, msg,
23402340
*/
23412341

23422342
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)
23442344
{
23452345
int fput_needed, err, datagrams;
23462346
struct socket *sock;
@@ -2405,8 +2405,7 @@ int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,
24052405

24062406
if (timeout) {
24072407
ktime_get_ts64(&timeout64);
2408-
*timeout = timespec64_to_timespec(
2409-
timespec64_sub(end_time, timeout64));
2408+
*timeout = timespec64_sub(end_time, timeout64);
24102409
if (timeout->tv_sec < 0) {
24112410
timeout->tv_sec = timeout->tv_nsec = 0;
24122411
break;
@@ -2452,32 +2451,31 @@ int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,
24522451

24532452
static int do_sys_recvmmsg(int fd, struct mmsghdr __user *mmsg,
24542453
unsigned int vlen, unsigned int flags,
2455-
struct timespec __user *timeout)
2454+
struct __kernel_timespec __user *timeout)
24562455
{
24572456
int datagrams;
2458-
struct timespec timeout_sys;
2457+
struct timespec64 timeout_sys;
24592458

24602459
if (flags & MSG_CMSG_COMPAT)
24612460
return -EINVAL;
24622461

24632462
if (!timeout)
24642463
return __sys_recvmmsg(fd, mmsg, vlen, flags, NULL);
24652464

2466-
if (copy_from_user(&timeout_sys, timeout, sizeof(timeout_sys)))
2465+
if (get_timespec64(&timeout_sys, timeout))
24672466
return -EFAULT;
24682467

24692468
datagrams = __sys_recvmmsg(fd, mmsg, vlen, flags, &timeout_sys);
24702469

2471-
if (datagrams > 0 &&
2472-
copy_to_user(timeout, &timeout_sys, sizeof(timeout_sys)))
2470+
if (datagrams > 0 && put_timespec64(&timeout_sys, timeout))
24732471
datagrams = -EFAULT;
24742472

24752473
return datagrams;
24762474
}
24772475

24782476
SYSCALL_DEFINE5(recvmmsg, int, fd, struct mmsghdr __user *, mmsg,
24792477
unsigned int, vlen, unsigned int, flags,
2480-
struct timespec __user *, timeout)
2478+
struct __kernel_timespec __user *, timeout)
24812479
{
24822480
return do_sys_recvmmsg(fd, mmsg, vlen, flags, timeout);
24832481
}
@@ -2601,7 +2599,7 @@ SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args)
26012599
break;
26022600
case SYS_RECVMMSG:
26032601
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]);
26052603
break;
26062604
case SYS_ACCEPT4:
26072605
err = __sys_accept4(a0, (struct sockaddr __user *)a1,

0 commit comments

Comments
 (0)