aboutsummaryrefslogtreecommitdiffstats
path: root/fs/select.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/select.c')
-rw-r--r--fs/select.c69
1 files changed, 27 insertions, 42 deletions
diff --git a/fs/select.c b/fs/select.c
index c6362e38ae92..6de493bb42a4 100644
--- a/fs/select.c
+++ b/fs/select.c
@@ -1,3 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * This file contains the procedures for the handling of select and poll 3 * This file contains the procedures for the handling of select and poll
3 * 4 *
@@ -291,8 +292,7 @@ static int poll_select_copy_remaining(struct timespec64 *end_time,
291 void __user *p, 292 void __user *p,
292 int timeval, int ret) 293 int timeval, int ret)
293{ 294{
294 struct timespec64 rts64; 295 struct timespec64 rts;
295 struct timespec rts;
296 struct timeval rtv; 296 struct timeval rtv;
297 297
298 if (!p) 298 if (!p)
@@ -305,23 +305,22 @@ static int poll_select_copy_remaining(struct timespec64 *end_time,
305 if (!end_time->tv_sec && !end_time->tv_nsec) 305 if (!end_time->tv_sec && !end_time->tv_nsec)
306 return ret; 306 return ret;
307 307
308 ktime_get_ts64(&rts64); 308 ktime_get_ts64(&rts);
309 rts64 = timespec64_sub(*end_time, rts64); 309 rts = timespec64_sub(*end_time, rts);
310 if (rts64.tv_sec < 0) 310 if (rts.tv_sec < 0)
311 rts64.tv_sec = rts64.tv_nsec = 0; 311 rts.tv_sec = rts.tv_nsec = 0;
312 312
313 rts = timespec64_to_timespec(rts64);
314 313
315 if (timeval) { 314 if (timeval) {
316 if (sizeof(rtv) > sizeof(rtv.tv_sec) + sizeof(rtv.tv_usec)) 315 if (sizeof(rtv) > sizeof(rtv.tv_sec) + sizeof(rtv.tv_usec))
317 memset(&rtv, 0, sizeof(rtv)); 316 memset(&rtv, 0, sizeof(rtv));
318 rtv.tv_sec = rts64.tv_sec; 317 rtv.tv_sec = rts.tv_sec;
319 rtv.tv_usec = rts64.tv_nsec / NSEC_PER_USEC; 318 rtv.tv_usec = rts.tv_nsec / NSEC_PER_USEC;
320 319
321 if (!copy_to_user(p, &rtv, sizeof(rtv))) 320 if (!copy_to_user(p, &rtv, sizeof(rtv)))
322 return ret; 321 return ret;
323 322
324 } else if (!copy_to_user(p, &rts, sizeof(rts))) 323 } else if (!put_timespec64(&rts, p))
325 return ret; 324 return ret;
326 325
327 /* 326 /*
@@ -704,17 +703,15 @@ static long do_pselect(int n, fd_set __user *inp, fd_set __user *outp,
704 const sigset_t __user *sigmask, size_t sigsetsize) 703 const sigset_t __user *sigmask, size_t sigsetsize)
705{ 704{
706 sigset_t ksigmask, sigsaved; 705 sigset_t ksigmask, sigsaved;
707 struct timespec ts; 706 struct timespec64 ts, end_time, *to = NULL;
708 struct timespec64 ts64, end_time, *to = NULL;
709 int ret; 707 int ret;
710 708
711 if (tsp) { 709 if (tsp) {
712 if (copy_from_user(&ts, tsp, sizeof(ts))) 710 if (get_timespec64(&ts, tsp))
713 return -EFAULT; 711 return -EFAULT;
714 ts64 = timespec_to_timespec64(ts);
715 712
716 to = &end_time; 713 to = &end_time;
717 if (poll_select_set_timeout(to, ts64.tv_sec, ts64.tv_nsec)) 714 if (poll_select_set_timeout(to, ts.tv_sec, ts.tv_nsec))
718 return -EINVAL; 715 return -EINVAL;
719 } 716 }
720 717
@@ -1051,12 +1048,11 @@ SYSCALL_DEFINE5(ppoll, struct pollfd __user *, ufds, unsigned int, nfds,
1051 size_t, sigsetsize) 1048 size_t, sigsetsize)
1052{ 1049{
1053 sigset_t ksigmask, sigsaved; 1050 sigset_t ksigmask, sigsaved;
1054 struct timespec ts; 1051 struct timespec64 ts, end_time, *to = NULL;
1055 struct timespec64 end_time, *to = NULL;
1056 int ret; 1052 int ret;
1057 1053
1058 if (tsp) { 1054 if (tsp) {
1059 if (copy_from_user(&ts, tsp, sizeof(ts))) 1055 if (get_timespec64(&ts, tsp))
1060 return -EFAULT; 1056 return -EFAULT;
1061 1057
1062 to = &end_time; 1058 to = &end_time;
@@ -1102,10 +1098,10 @@ SYSCALL_DEFINE5(ppoll, struct pollfd __user *, ufds, unsigned int, nfds,
1102#define __COMPAT_NFDBITS (8 * sizeof(compat_ulong_t)) 1098#define __COMPAT_NFDBITS (8 * sizeof(compat_ulong_t))
1103 1099
1104static 1100static
1105int compat_poll_select_copy_remaining(struct timespec *end_time, void __user *p, 1101int compat_poll_select_copy_remaining(struct timespec64 *end_time, void __user *p,
1106 int timeval, int ret) 1102 int timeval, int ret)
1107{ 1103{
1108 struct timespec ts; 1104 struct timespec64 ts;
1109 1105
1110 if (!p) 1106 if (!p)
1111 return ret; 1107 return ret;
@@ -1117,8 +1113,8 @@ int compat_poll_select_copy_remaining(struct timespec *end_time, void __user *p,
1117 if (!end_time->tv_sec && !end_time->tv_nsec) 1113 if (!end_time->tv_sec && !end_time->tv_nsec)
1118 return ret; 1114 return ret;
1119 1115
1120 ktime_get_ts(&ts); 1116 ktime_get_ts64(&ts);
1121 ts = timespec_sub(*end_time, ts); 1117 ts = timespec64_sub(*end_time, ts);
1122 if (ts.tv_sec < 0) 1118 if (ts.tv_sec < 0)
1123 ts.tv_sec = ts.tv_nsec = 0; 1119 ts.tv_sec = ts.tv_nsec = 0;
1124 1120
@@ -1131,12 +1127,7 @@ int compat_poll_select_copy_remaining(struct timespec *end_time, void __user *p,
1131 if (!copy_to_user(p, &rtv, sizeof(rtv))) 1127 if (!copy_to_user(p, &rtv, sizeof(rtv)))
1132 return ret; 1128 return ret;
1133 } else { 1129 } else {
1134 struct compat_timespec rts; 1130 if (!compat_put_timespec64(&ts, p))
1135
1136 rts.tv_sec = ts.tv_sec;
1137 rts.tv_nsec = ts.tv_nsec;
1138
1139 if (!copy_to_user(p, &rts, sizeof(rts)))
1140 return ret; 1131 return ret;
1141 } 1132 }
1142 /* 1133 /*
@@ -1194,7 +1185,7 @@ int compat_set_fd_set(unsigned long nr, compat_ulong_t __user *ufdset,
1194 */ 1185 */
1195static int compat_core_sys_select(int n, compat_ulong_t __user *inp, 1186static int compat_core_sys_select(int n, compat_ulong_t __user *inp,
1196 compat_ulong_t __user *outp, compat_ulong_t __user *exp, 1187 compat_ulong_t __user *outp, compat_ulong_t __user *exp,
1197 struct timespec *end_time) 1188 struct timespec64 *end_time)
1198{ 1189{
1199 fd_set_bits fds; 1190 fd_set_bits fds;
1200 void *bits; 1191 void *bits;
@@ -1267,7 +1258,7 @@ COMPAT_SYSCALL_DEFINE5(select, int, n, compat_ulong_t __user *, inp,
1267 compat_ulong_t __user *, outp, compat_ulong_t __user *, exp, 1258 compat_ulong_t __user *, outp, compat_ulong_t __user *, exp,
1268 struct compat_timeval __user *, tvp) 1259 struct compat_timeval __user *, tvp)
1269{ 1260{
1270 struct timespec end_time, *to = NULL; 1261 struct timespec64 end_time, *to = NULL;
1271 struct compat_timeval tv; 1262 struct compat_timeval tv;
1272 int ret; 1263 int ret;
1273 1264
@@ -1311,14 +1302,12 @@ static long do_compat_pselect(int n, compat_ulong_t __user *inp,
1311 struct compat_timespec __user *tsp, compat_sigset_t __user *sigmask, 1302 struct compat_timespec __user *tsp, compat_sigset_t __user *sigmask,
1312 compat_size_t sigsetsize) 1303 compat_size_t sigsetsize)
1313{ 1304{
1314 compat_sigset_t ss32;
1315 sigset_t ksigmask, sigsaved; 1305 sigset_t ksigmask, sigsaved;
1316 struct compat_timespec ts; 1306 struct timespec64 ts, end_time, *to = NULL;
1317 struct timespec end_time, *to = NULL;
1318 int ret; 1307 int ret;
1319 1308
1320 if (tsp) { 1309 if (tsp) {
1321 if (copy_from_user(&ts, tsp, sizeof(ts))) 1310 if (compat_get_timespec64(&ts, tsp))
1322 return -EFAULT; 1311 return -EFAULT;
1323 1312
1324 to = &end_time; 1313 to = &end_time;
@@ -1329,9 +1318,8 @@ static long do_compat_pselect(int n, compat_ulong_t __user *inp,
1329 if (sigmask) { 1318 if (sigmask) {
1330 if (sigsetsize != sizeof(compat_sigset_t)) 1319 if (sigsetsize != sizeof(compat_sigset_t))
1331 return -EINVAL; 1320 return -EINVAL;
1332 if (copy_from_user(&ss32, sigmask, sizeof(ss32))) 1321 if (get_compat_sigset(&ksigmask, sigmask))
1333 return -EFAULT; 1322 return -EFAULT;
1334 sigset_from_compat(&ksigmask, &ss32);
1335 1323
1336 sigdelsetmask(&ksigmask, sigmask(SIGKILL)|sigmask(SIGSTOP)); 1324 sigdelsetmask(&ksigmask, sigmask(SIGKILL)|sigmask(SIGSTOP));
1337 sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved); 1325 sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved);
@@ -1380,14 +1368,12 @@ COMPAT_SYSCALL_DEFINE5(ppoll, struct pollfd __user *, ufds,
1380 unsigned int, nfds, struct compat_timespec __user *, tsp, 1368 unsigned int, nfds, struct compat_timespec __user *, tsp,
1381 const compat_sigset_t __user *, sigmask, compat_size_t, sigsetsize) 1369 const compat_sigset_t __user *, sigmask, compat_size_t, sigsetsize)
1382{ 1370{
1383 compat_sigset_t ss32;
1384 sigset_t ksigmask, sigsaved; 1371 sigset_t ksigmask, sigsaved;
1385 struct compat_timespec ts; 1372 struct timespec64 ts, end_time, *to = NULL;
1386 struct timespec end_time, *to = NULL;
1387 int ret; 1373 int ret;
1388 1374
1389 if (tsp) { 1375 if (tsp) {
1390 if (copy_from_user(&ts, tsp, sizeof(ts))) 1376 if (compat_get_timespec64(&ts, tsp))
1391 return -EFAULT; 1377 return -EFAULT;
1392 1378
1393 to = &end_time; 1379 to = &end_time;
@@ -1398,9 +1384,8 @@ COMPAT_SYSCALL_DEFINE5(ppoll, struct pollfd __user *, ufds,
1398 if (sigmask) { 1384 if (sigmask) {
1399 if (sigsetsize != sizeof(compat_sigset_t)) 1385 if (sigsetsize != sizeof(compat_sigset_t))
1400 return -EINVAL; 1386 return -EINVAL;
1401 if (copy_from_user(&ss32, sigmask, sizeof(ss32))) 1387 if (get_compat_sigset(&ksigmask, sigmask))
1402 return -EFAULT; 1388 return -EFAULT;
1403 sigset_from_compat(&ksigmask, &ss32);
1404 1389
1405 sigdelsetmask(&ksigmask, sigmask(SIGKILL)|sigmask(SIGSTOP)); 1390 sigdelsetmask(&ksigmask, sigmask(SIGKILL)|sigmask(SIGSTOP));
1406 sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved); 1391 sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved);