Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

compat: Use COMPAT_USE_64BIT_TIME in net/compat.c

Handle 64-bit time structures in the networking core compat code.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Cc: David S. Miller <davem@davemloft.net>

authored by

H. J. Lu and committed by
H. Peter Anvin
ee4fa23c da88cea1

+40 -25
+40 -25
net/compat.c
··· 219 219 220 220 int put_cmsg_compat(struct msghdr *kmsg, int level, int type, int len, void *data) 221 221 { 222 - struct compat_timeval ctv; 223 - struct compat_timespec cts[3]; 224 222 struct compat_cmsghdr __user *cm = (struct compat_cmsghdr __user *) kmsg->msg_control; 225 223 struct compat_cmsghdr cmhdr; 226 224 int cmlen; ··· 228 230 return 0; /* XXX: return error? check spec. */ 229 231 } 230 232 231 - if (level == SOL_SOCKET && type == SCM_TIMESTAMP) { 232 - struct timeval *tv = (struct timeval *)data; 233 - ctv.tv_sec = tv->tv_sec; 234 - ctv.tv_usec = tv->tv_usec; 235 - data = &ctv; 236 - len = sizeof(ctv); 237 - } 238 - if (level == SOL_SOCKET && 239 - (type == SCM_TIMESTAMPNS || type == SCM_TIMESTAMPING)) { 240 - int count = type == SCM_TIMESTAMPNS ? 1 : 3; 241 - int i; 242 - struct timespec *ts = (struct timespec *)data; 243 - for (i = 0; i < count; i++) { 244 - cts[i].tv_sec = ts[i].tv_sec; 245 - cts[i].tv_nsec = ts[i].tv_nsec; 233 + if (!COMPAT_USE_64BIT_TIME) { 234 + struct compat_timeval ctv; 235 + struct compat_timespec cts[3]; 236 + if (level == SOL_SOCKET && type == SCM_TIMESTAMP) { 237 + struct timeval *tv = (struct timeval *)data; 238 + ctv.tv_sec = tv->tv_sec; 239 + ctv.tv_usec = tv->tv_usec; 240 + data = &ctv; 241 + len = sizeof(ctv); 246 242 } 247 - data = &cts; 248 - len = sizeof(cts[0]) * count; 243 + if (level == SOL_SOCKET && 244 + (type == SCM_TIMESTAMPNS || type == SCM_TIMESTAMPING)) { 245 + int count = type == SCM_TIMESTAMPNS ? 1 : 3; 246 + int i; 247 + struct timespec *ts = (struct timespec *)data; 248 + for (i = 0; i < count; i++) { 249 + cts[i].tv_sec = ts[i].tv_sec; 250 + cts[i].tv_nsec = ts[i].tv_nsec; 251 + } 252 + data = &cts; 253 + len = sizeof(cts[0]) * count; 254 + } 249 255 } 250 256 251 257 cmlen = CMSG_COMPAT_LEN(len); ··· 456 454 457 455 int compat_sock_get_timestamp(struct sock *sk, struct timeval __user *userstamp) 458 456 { 459 - struct compat_timeval __user *ctv = 460 - (struct compat_timeval __user *) userstamp; 461 - int err = -ENOENT; 457 + struct compat_timeval __user *ctv; 458 + int err; 462 459 struct timeval tv; 463 460 461 + if (COMPAT_USE_64BIT_TIME) 462 + return sock_get_timestamp(sk, userstamp); 463 + 464 + ctv = (struct compat_timeval __user *) userstamp; 465 + err = -ENOENT; 464 466 if (!sock_flag(sk, SOCK_TIMESTAMP)) 465 467 sock_enable_timestamp(sk, SOCK_TIMESTAMP); 466 468 tv = ktime_to_timeval(sk->sk_stamp); ··· 484 478 485 479 int compat_sock_get_timestampns(struct sock *sk, struct timespec __user *userstamp) 486 480 { 487 - struct compat_timespec __user *ctv = 488 - (struct compat_timespec __user *) userstamp; 489 - int err = -ENOENT; 481 + struct compat_timespec __user *ctv; 482 + int err; 490 483 struct timespec ts; 491 484 485 + if (COMPAT_USE_64BIT_TIME) 486 + return sock_get_timestampns (sk, userstamp); 487 + 488 + ctv = (struct compat_timespec __user *) userstamp; 489 + err = -ENOENT; 492 490 if (!sock_flag(sk, SOCK_TIMESTAMP)) 493 491 sock_enable_timestamp(sk, SOCK_TIMESTAMP); 494 492 ts = ktime_to_timespec(sk->sk_stamp); ··· 776 766 { 777 767 int datagrams; 778 768 struct timespec ktspec; 769 + 770 + if (COMPAT_USE_64BIT_TIME) 771 + return __sys_recvmmsg(fd, (struct mmsghdr __user *)mmsg, vlen, 772 + flags | MSG_CMSG_COMPAT, 773 + (struct timespec *) timeout); 779 774 780 775 if (timeout == NULL) 781 776 return __sys_recvmmsg(fd, (struct mmsghdr __user *)mmsg, vlen,