summaryrefslogtreecommitdiffstats
path: root/fs/select.c
diff options
context:
space:
mode:
authorDeepa Dinamani <deepa.kernel@gmail.com>2017-08-05 00:12:31 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2017-09-19 17:55:58 -0400
commit36819ad093e16a4b06c53f98d4a5afc55530bbcb (patch)
treeaa982a97ae10e3c3e4928517d4ed6c0de9a02558 /fs/select.c
parent176826af03666758c656dd27f098cc889b71638b (diff)
select: Use get/put_timespec64
Usage of these apis and their compat versions makes the syscalls: select family of syscalls and their compat implementations simpler. This is a preparatory patch to isolate data conversions to struct timespec64 at userspace boundaries. This helps contain the changes needed to transition to new y2038 safe types. Signed-off-by: Deepa Dinamani <deepa.kernel@gmail.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/select.c')
-rw-r--r--fs/select.c60
1 files changed, 24 insertions, 36 deletions
diff --git a/fs/select.c b/fs/select.c
index c6362e38ae92..20a7d061904f 100644
--- a/fs/select.c
+++ b/fs/select.c
@@ -291,8 +291,7 @@ static int poll_select_copy_remaining(struct timespec64 *end_time,
291 void __user *p, 291 void __user *p,
292 int timeval, int ret) 292 int timeval, int ret)
293{ 293{
294 struct timespec64 rts64; 294 struct timespec64 rts;
295 struct timespec rts;
296 struct timeval rtv; 295 struct timeval rtv;
297 296
298 if (!p) 297 if (!p)
@@ -305,23 +304,22 @@ static int poll_select_copy_remaining(struct timespec64 *end_time,
305 if (!end_time->tv_sec && !end_time->tv_nsec) 304 if (!end_time->tv_sec && !end_time->tv_nsec)
306 return ret; 305 return ret;
307 306
308 ktime_get_ts64(&rts64); 307 ktime_get_ts64(&rts);
309 rts64 = timespec64_sub(*end_time, rts64); 308 rts = timespec64_sub(*end_time, rts);
310 if (rts64.tv_sec < 0) 309 if (rts.tv_sec < 0)
311 rts64.tv_sec = rts64.tv_nsec = 0; 310 rts.tv_sec = rts.tv_nsec = 0;
312 311
313 rts = timespec64_to_timespec(rts64);
314 312
315 if (timeval) { 313 if (timeval) {
316 if (sizeof(rtv) > sizeof(rtv.tv_sec) + sizeof(rtv.tv_usec)) 314 if (sizeof(rtv) > sizeof(rtv.tv_sec) + sizeof(rtv.tv_usec))
317 memset(&rtv, 0, sizeof(rtv)); 315 memset(&rtv, 0, sizeof(rtv));
318 rtv.tv_sec = rts64.tv_sec; 316 rtv.tv_sec = rts.tv_sec;
319 rtv.tv_usec = rts64.tv_nsec / NSEC_PER_USEC; 317 rtv.tv_usec = rts.tv_nsec / NSEC_PER_USEC;
320 318
321 if (!copy_to_user(p, &rtv, sizeof(rtv))) 319 if (!copy_to_user(p, &rtv, sizeof(rtv)))
322 return ret; 320 return ret;
323 321
324 } else if (!copy_to_user(p, &rts, sizeof(rts))) 322 } else if (!put_timespec64(&rts, p))
325 return ret; 323 return ret;
326 324
327 /* 325 /*
@@ -704,17 +702,15 @@ static long do_pselect(int n, fd_set __user *inp, fd_set __user *outp,
704 const sigset_t __user *sigmask, size_t sigsetsize) 702 const sigset_t __user *sigmask, size_t sigsetsize)
705{ 703{
706 sigset_t ksigmask, sigsaved; 704 sigset_t ksigmask, sigsaved;
707 struct timespec ts; 705 struct timespec64 ts, end_time, *to = NULL;
708 struct timespec64 ts64, end_time, *to = NULL;
709 int ret; 706 int ret;
710 707
711 if (tsp) { 708 if (tsp) {
712 if (copy_from_user(&ts, tsp, sizeof(ts))) 709 if (get_timespec64(&ts, tsp))
713 return -EFAULT; 710 return -EFAULT;
714 ts64 = timespec_to_timespec64(ts);
715 711
716 to = &end_time; 712 to = &end_time;
717 if (poll_select_set_timeout(to, ts64.tv_sec, ts64.tv_nsec)) 713 if (poll_select_set_timeout(to, ts.tv_sec, ts.tv_nsec))
718 return -EINVAL; 714 return -EINVAL;
719 } 715 }
720 716
@@ -1051,12 +1047,11 @@ SYSCALL_DEFINE5(ppoll, struct pollfd __user *, ufds, unsigned int, nfds,
1051 size_t, sigsetsize) 1047 size_t, sigsetsize)
1052{ 1048{
1053 sigset_t ksigmask, sigsaved; 1049 sigset_t ksigmask, sigsaved;
1054 struct timespec ts; 1050 struct timespec64 ts, end_time, *to = NULL;
1055 struct timespec64 end_time, *to = NULL;
1056 int ret; 1051 int ret;
1057 1052
1058 if (tsp) { 1053 if (tsp) {
1059 if (copy_from_user(&ts, tsp, sizeof(ts))) 1054 if (get_timespec64(&ts, tsp))
1060 return -EFAULT; 1055 return -EFAULT;
1061 1056
1062 to = &end_time; 1057 to = &end_time;
@@ -1102,10 +1097,10 @@ SYSCALL_DEFINE5(ppoll, struct pollfd __user *, ufds, unsigned int, nfds,
1102#define __COMPAT_NFDBITS (8 * sizeof(compat_ulong_t)) 1097#define __COMPAT_NFDBITS (8 * sizeof(compat_ulong_t))
1103 1098
1104static 1099static
1105int compat_poll_select_copy_remaining(struct timespec *end_time, void __user *p, 1100int compat_poll_select_copy_remaining(struct timespec64 *end_time, void __user *p,
1106 int timeval, int ret) 1101 int timeval, int ret)
1107{ 1102{
1108 struct timespec ts; 1103 struct timespec64 ts;
1109 1104
1110 if (!p) 1105 if (!p)
1111 return ret; 1106 return ret;
@@ -1117,8 +1112,8 @@ int compat_poll_select_copy_remaining(struct timespec *end_time, void __user *p,
1117 if (!end_time->tv_sec && !end_time->tv_nsec) 1112 if (!end_time->tv_sec && !end_time->tv_nsec)
1118 return ret; 1113 return ret;
1119 1114
1120 ktime_get_ts(&ts); 1115 ktime_get_ts64(&ts);
1121 ts = timespec_sub(*end_time, ts); 1116 ts = timespec64_sub(*end_time, ts);
1122 if (ts.tv_sec < 0) 1117 if (ts.tv_sec < 0)
1123 ts.tv_sec = ts.tv_nsec = 0; 1118 ts.tv_sec = ts.tv_nsec = 0;
1124 1119
@@ -1131,12 +1126,7 @@ int compat_poll_select_copy_remaining(struct timespec *end_time, void __user *p,
1131 if (!copy_to_user(p, &rtv, sizeof(rtv))) 1126 if (!copy_to_user(p, &rtv, sizeof(rtv)))
1132 return ret; 1127 return ret;
1133 } else { 1128 } else {
1134 struct compat_timespec rts; 1129 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; 1130 return ret;
1141 } 1131 }
1142 /* 1132 /*
@@ -1194,7 +1184,7 @@ int compat_set_fd_set(unsigned long nr, compat_ulong_t __user *ufdset,
1194 */ 1184 */
1195static int compat_core_sys_select(int n, compat_ulong_t __user *inp, 1185static int compat_core_sys_select(int n, compat_ulong_t __user *inp,
1196 compat_ulong_t __user *outp, compat_ulong_t __user *exp, 1186 compat_ulong_t __user *outp, compat_ulong_t __user *exp,
1197 struct timespec *end_time) 1187 struct timespec64 *end_time)
1198{ 1188{
1199 fd_set_bits fds; 1189 fd_set_bits fds;
1200 void *bits; 1190 void *bits;
@@ -1267,7 +1257,7 @@ COMPAT_SYSCALL_DEFINE5(select, int, n, compat_ulong_t __user *, inp,
1267 compat_ulong_t __user *, outp, compat_ulong_t __user *, exp, 1257 compat_ulong_t __user *, outp, compat_ulong_t __user *, exp,
1268 struct compat_timeval __user *, tvp) 1258 struct compat_timeval __user *, tvp)
1269{ 1259{
1270 struct timespec end_time, *to = NULL; 1260 struct timespec64 end_time, *to = NULL;
1271 struct compat_timeval tv; 1261 struct compat_timeval tv;
1272 int ret; 1262 int ret;
1273 1263
@@ -1313,12 +1303,11 @@ static long do_compat_pselect(int n, compat_ulong_t __user *inp,
1313{ 1303{
1314 compat_sigset_t ss32; 1304 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;
@@ -1382,12 +1371,11 @@ COMPAT_SYSCALL_DEFINE5(ppoll, struct pollfd __user *, ufds,
1382{ 1371{
1383 compat_sigset_t ss32; 1372 compat_sigset_t ss32;
1384 sigset_t ksigmask, sigsaved; 1373 sigset_t ksigmask, sigsaved;
1385 struct compat_timespec ts; 1374 struct timespec64 ts, end_time, *to = NULL;
1386 struct timespec end_time, *to = NULL;
1387 int ret; 1375 int ret;
1388 1376
1389 if (tsp) { 1377 if (tsp) {
1390 if (copy_from_user(&ts, tsp, sizeof(ts))) 1378 if (compat_get_timespec64(&ts, tsp))
1391 return -EFAULT; 1379 return -EFAULT;
1392 1380
1393 to = &end_time; 1381 to = &end_time;