aboutsummaryrefslogtreecommitdiffstats
path: root/fs/select.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-07-17 11:58:04 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2019-07-17 11:58:04 -0400
commit57a8ec387e1441ea5e1232bc0749fb99a8cba7e7 (patch)
treeb5fb03fc6bc5754de8b5b1f8b0e4f36d67c8315c /fs/select.c
parent0a8ad0ffa4d80a544f6cbff703bf6394339afcdf (diff)
parent43e11fa2d1d3b6e35629fa556eb7d571edba2010 (diff)
Merge branch 'akpm' (patches from Andrew)
Merge more updates from Andrew Morton: "VM: - z3fold fixes and enhancements by Henry Burns and Vitaly Wool - more accurate reclaimed slab caches calculations by Yafang Shao - fix MAP_UNINITIALIZED UAPI symbol to not depend on config, by Christoph Hellwig - !CONFIG_MMU fixes by Christoph Hellwig - new novmcoredd parameter to omit device dumps from vmcore, by Kairui Song - new test_meminit module for testing heap and pagealloc initialization, by Alexander Potapenko - ioremap improvements for huge mappings, by Anshuman Khandual - generalize kprobe page fault handling, by Anshuman Khandual - device-dax hotplug fixes and improvements, by Pavel Tatashin - enable synchronous DAX fault on powerpc, by Aneesh Kumar K.V - add pte_devmap() support for arm64, by Robin Murphy - unify locked_vm accounting with a helper, by Daniel Jordan - several misc fixes core/lib: - new typeof_member() macro including some users, by Alexey Dobriyan - make BIT() and GENMASK() available in asm, by Masahiro Yamada - changed LIST_POISON2 on x86_64 to 0xdead000000000122 for better code generation, by Alexey Dobriyan - rbtree code size optimizations, by Michel Lespinasse - convert struct pid count to refcount_t, by Joel Fernandes get_maintainer.pl: - add --no-moderated switch to skip moderated ML's, by Joe Perches misc: - ptrace PTRACE_GET_SYSCALL_INFO interface - coda updates - gdb scripts, various" [ Using merge message suggestion from Vlastimil Babka, with some editing - Linus ] * emailed patches from Andrew Morton <akpm@linux-foundation.org>: (100 commits) fs/select.c: use struct_size() in kmalloc() mm: add account_locked_vm utility function arm64: mm: implement pte_devmap support mm: introduce ARCH_HAS_PTE_DEVMAP mm: clean up is_device_*_page() definitions mm/mmap: move common defines to mman-common.h mm: move MAP_SYNC to asm-generic/mman-common.h device-dax: "Hotremove" persistent memory that is used like normal RAM mm/hotplug: make remove_memory() interface usable device-dax: fix memory and resource leak if hotplug fails include/linux/lz4.h: fix spelling and copy-paste errors in documentation ipc/mqueue.c: only perform resource calculation if user valid include/asm-generic/bug.h: fix "cut here" for WARN_ON for __WARN_TAINT architectures scripts/gdb: add helpers to find and list devices scripts/gdb: add lx-genpd-summary command drivers/pps/pps.c: clear offset flags in PPS_SETPARAMS ioctl kernel/pid.c: convert struct pid count to refcount_t drivers/rapidio/devices/rio_mport_cdev.c: NUL terminate some strings select: shift restore_saved_sigmask_unless() into poll_select_copy_remaining() select: change do_poll() to return -ERESTARTNOHAND rather than -EINTR ...
Diffstat (limited to 'fs/select.c')
-rw-r--r--fs/select.c96
1 files changed, 25 insertions, 71 deletions
diff --git a/fs/select.c b/fs/select.c
index a4d8f6e8b63c..53a0c149f528 100644
--- a/fs/select.c
+++ b/fs/select.c
@@ -294,12 +294,14 @@ enum poll_time_type {
294 PT_OLD_TIMESPEC = 3, 294 PT_OLD_TIMESPEC = 3,
295}; 295};
296 296
297static int poll_select_copy_remaining(struct timespec64 *end_time, 297static int poll_select_finish(struct timespec64 *end_time,
298 void __user *p, 298 void __user *p,
299 enum poll_time_type pt_type, int ret) 299 enum poll_time_type pt_type, int ret)
300{ 300{
301 struct timespec64 rts; 301 struct timespec64 rts;
302 302
303 restore_saved_sigmask_unless(ret == -ERESTARTNOHAND);
304
303 if (!p) 305 if (!p)
304 return ret; 306 return ret;
305 307
@@ -714,9 +716,7 @@ static int kern_select(int n, fd_set __user *inp, fd_set __user *outp,
714 } 716 }
715 717
716 ret = core_sys_select(n, inp, outp, exp, to); 718 ret = core_sys_select(n, inp, outp, exp, to);
717 ret = poll_select_copy_remaining(&end_time, tvp, PT_TIMEVAL, ret); 719 return poll_select_finish(&end_time, tvp, PT_TIMEVAL, ret);
718
719 return ret;
720} 720}
721 721
722SYSCALL_DEFINE5(select, int, n, fd_set __user *, inp, fd_set __user *, outp, 722SYSCALL_DEFINE5(select, int, n, fd_set __user *, inp, fd_set __user *, outp,
@@ -730,7 +730,6 @@ static long do_pselect(int n, fd_set __user *inp, fd_set __user *outp,
730 const sigset_t __user *sigmask, size_t sigsetsize, 730 const sigset_t __user *sigmask, size_t sigsetsize,
731 enum poll_time_type type) 731 enum poll_time_type type)
732{ 732{
733 sigset_t ksigmask, sigsaved;
734 struct timespec64 ts, end_time, *to = NULL; 733 struct timespec64 ts, end_time, *to = NULL;
735 int ret; 734 int ret;
736 735
@@ -753,15 +752,12 @@ static long do_pselect(int n, fd_set __user *inp, fd_set __user *outp,
753 return -EINVAL; 752 return -EINVAL;
754 } 753 }
755 754
756 ret = set_user_sigmask(sigmask, &ksigmask, &sigsaved, sigsetsize); 755 ret = set_user_sigmask(sigmask, sigsetsize);
757 if (ret) 756 if (ret)
758 return ret; 757 return ret;
759 758
760 ret = core_sys_select(n, inp, outp, exp, to); 759 ret = core_sys_select(n, inp, outp, exp, to);
761 restore_user_sigmask(sigmask, &sigsaved, ret == -ERESTARTNOHAND); 760 return poll_select_finish(&end_time, tsp, type, ret);
762 ret = poll_select_copy_remaining(&end_time, tsp, type, ret);
763
764 return ret;
765} 761}
766 762
767/* 763/*
@@ -926,7 +922,7 @@ static int do_poll(struct poll_list *list, struct poll_wqueues *wait,
926 if (!count) { 922 if (!count) {
927 count = wait->error; 923 count = wait->error;
928 if (signal_pending(current)) 924 if (signal_pending(current))
929 count = -EINTR; 925 count = -ERESTARTNOHAND;
930 } 926 }
931 if (count || timed_out) 927 if (count || timed_out)
932 break; 928 break;
@@ -965,7 +961,7 @@ static int do_sys_poll(struct pollfd __user *ufds, unsigned int nfds,
965 struct timespec64 *end_time) 961 struct timespec64 *end_time)
966{ 962{
967 struct poll_wqueues table; 963 struct poll_wqueues table;
968 int err = -EFAULT, fdcount, len, size; 964 int err = -EFAULT, fdcount, len;
969 /* Allocate small arguments on the stack to save memory and be 965 /* Allocate small arguments on the stack to save memory and be
970 faster - use long to make sure the buffer is aligned properly 966 faster - use long to make sure the buffer is aligned properly
971 on 64 bit archs to avoid unaligned access */ 967 on 64 bit archs to avoid unaligned access */
@@ -993,8 +989,8 @@ static int do_sys_poll(struct pollfd __user *ufds, unsigned int nfds,
993 break; 989 break;
994 990
995 len = min(todo, POLLFD_PER_PAGE); 991 len = min(todo, POLLFD_PER_PAGE);
996 size = sizeof(struct poll_list) + sizeof(struct pollfd) * len; 992 walk = walk->next = kmalloc(struct_size(walk, entries, len),
997 walk = walk->next = kmalloc(size, GFP_KERNEL); 993 GFP_KERNEL);
998 if (!walk) { 994 if (!walk) {
999 err = -ENOMEM; 995 err = -ENOMEM;
1000 goto out_fds; 996 goto out_fds;
@@ -1041,7 +1037,7 @@ static long do_restart_poll(struct restart_block *restart_block)
1041 1037
1042 ret = do_sys_poll(ufds, nfds, to); 1038 ret = do_sys_poll(ufds, nfds, to);
1043 1039
1044 if (ret == -EINTR) { 1040 if (ret == -ERESTARTNOHAND) {
1045 restart_block->fn = do_restart_poll; 1041 restart_block->fn = do_restart_poll;
1046 ret = -ERESTART_RESTARTBLOCK; 1042 ret = -ERESTART_RESTARTBLOCK;
1047 } 1043 }
@@ -1062,7 +1058,7 @@ SYSCALL_DEFINE3(poll, struct pollfd __user *, ufds, unsigned int, nfds,
1062 1058
1063 ret = do_sys_poll(ufds, nfds, to); 1059 ret = do_sys_poll(ufds, nfds, to);
1064 1060
1065 if (ret == -EINTR) { 1061 if (ret == -ERESTARTNOHAND) {
1066 struct restart_block *restart_block; 1062 struct restart_block *restart_block;
1067 1063
1068 restart_block = &current->restart_block; 1064 restart_block = &current->restart_block;
@@ -1086,7 +1082,6 @@ SYSCALL_DEFINE5(ppoll, struct pollfd __user *, ufds, unsigned int, nfds,
1086 struct __kernel_timespec __user *, tsp, const sigset_t __user *, sigmask, 1082 struct __kernel_timespec __user *, tsp, const sigset_t __user *, sigmask,
1087 size_t, sigsetsize) 1083 size_t, sigsetsize)
1088{ 1084{
1089 sigset_t ksigmask, sigsaved;
1090 struct timespec64 ts, end_time, *to = NULL; 1085 struct timespec64 ts, end_time, *to = NULL;
1091 int ret; 1086 int ret;
1092 1087
@@ -1099,20 +1094,12 @@ SYSCALL_DEFINE5(ppoll, struct pollfd __user *, ufds, unsigned int, nfds,
1099 return -EINVAL; 1094 return -EINVAL;
1100 } 1095 }
1101 1096
1102 ret = set_user_sigmask(sigmask, &ksigmask, &sigsaved, sigsetsize); 1097 ret = set_user_sigmask(sigmask, sigsetsize);
1103 if (ret) 1098 if (ret)
1104 return ret; 1099 return ret;
1105 1100
1106 ret = do_sys_poll(ufds, nfds, to); 1101 ret = do_sys_poll(ufds, nfds, to);
1107 1102 return poll_select_finish(&end_time, tsp, PT_TIMESPEC, ret);
1108 restore_user_sigmask(sigmask, &sigsaved, ret == -EINTR);
1109 /* We can restart this syscall, usually */
1110 if (ret == -EINTR)
1111 ret = -ERESTARTNOHAND;
1112
1113 ret = poll_select_copy_remaining(&end_time, tsp, PT_TIMESPEC, ret);
1114
1115 return ret;
1116} 1103}
1117 1104
1118#if defined(CONFIG_COMPAT_32BIT_TIME) && !defined(CONFIG_64BIT) 1105#if defined(CONFIG_COMPAT_32BIT_TIME) && !defined(CONFIG_64BIT)
@@ -1121,7 +1108,6 @@ SYSCALL_DEFINE5(ppoll_time32, struct pollfd __user *, ufds, unsigned int, nfds,
1121 struct old_timespec32 __user *, tsp, const sigset_t __user *, sigmask, 1108 struct old_timespec32 __user *, tsp, const sigset_t __user *, sigmask,
1122 size_t, sigsetsize) 1109 size_t, sigsetsize)
1123{ 1110{
1124 sigset_t ksigmask, sigsaved;
1125 struct timespec64 ts, end_time, *to = NULL; 1111 struct timespec64 ts, end_time, *to = NULL;
1126 int ret; 1112 int ret;
1127 1113
@@ -1134,20 +1120,12 @@ SYSCALL_DEFINE5(ppoll_time32, struct pollfd __user *, ufds, unsigned int, nfds,
1134 return -EINVAL; 1120 return -EINVAL;
1135 } 1121 }
1136 1122
1137 ret = set_user_sigmask(sigmask, &ksigmask, &sigsaved, sigsetsize); 1123 ret = set_user_sigmask(sigmask, sigsetsize);
1138 if (ret) 1124 if (ret)
1139 return ret; 1125 return ret;
1140 1126
1141 ret = do_sys_poll(ufds, nfds, to); 1127 ret = do_sys_poll(ufds, nfds, to);
1142 1128 return poll_select_finish(&end_time, tsp, PT_OLD_TIMESPEC, ret);
1143 restore_user_sigmask(sigmask, &sigsaved, ret == -EINTR);
1144 /* We can restart this syscall, usually */
1145 if (ret == -EINTR)
1146 ret = -ERESTARTNOHAND;
1147
1148 ret = poll_select_copy_remaining(&end_time, tsp, PT_OLD_TIMESPEC, ret);
1149
1150 return ret;
1151} 1129}
1152#endif 1130#endif
1153 1131
@@ -1284,9 +1262,7 @@ static int do_compat_select(int n, compat_ulong_t __user *inp,
1284 } 1262 }
1285 1263
1286 ret = compat_core_sys_select(n, inp, outp, exp, to); 1264 ret = compat_core_sys_select(n, inp, outp, exp, to);
1287 ret = poll_select_copy_remaining(&end_time, tvp, PT_OLD_TIMEVAL, ret); 1265 return poll_select_finish(&end_time, tvp, PT_OLD_TIMEVAL, ret);
1288
1289 return ret;
1290} 1266}
1291 1267
1292COMPAT_SYSCALL_DEFINE5(select, int, n, compat_ulong_t __user *, inp, 1268COMPAT_SYSCALL_DEFINE5(select, int, n, compat_ulong_t __user *, inp,
@@ -1319,7 +1295,6 @@ static long do_compat_pselect(int n, compat_ulong_t __user *inp,
1319 void __user *tsp, compat_sigset_t __user *sigmask, 1295 void __user *tsp, compat_sigset_t __user *sigmask,
1320 compat_size_t sigsetsize, enum poll_time_type type) 1296 compat_size_t sigsetsize, enum poll_time_type type)
1321{ 1297{
1322 sigset_t ksigmask, sigsaved;
1323 struct timespec64 ts, end_time, *to = NULL; 1298 struct timespec64 ts, end_time, *to = NULL;
1324 int ret; 1299 int ret;
1325 1300
@@ -1342,15 +1317,12 @@ static long do_compat_pselect(int n, compat_ulong_t __user *inp,
1342 return -EINVAL; 1317 return -EINVAL;
1343 } 1318 }
1344 1319
1345 ret = set_compat_user_sigmask(sigmask, &ksigmask, &sigsaved, sigsetsize); 1320 ret = set_compat_user_sigmask(sigmask, sigsetsize);
1346 if (ret) 1321 if (ret)
1347 return ret; 1322 return ret;
1348 1323
1349 ret = compat_core_sys_select(n, inp, outp, exp, to); 1324 ret = compat_core_sys_select(n, inp, outp, exp, to);
1350 restore_user_sigmask(sigmask, &sigsaved, ret == -ERESTARTNOHAND); 1325 return poll_select_finish(&end_time, tsp, type, ret);
1351 ret = poll_select_copy_remaining(&end_time, tsp, type, ret);
1352
1353 return ret;
1354} 1326}
1355 1327
1356COMPAT_SYSCALL_DEFINE6(pselect6_time64, int, n, compat_ulong_t __user *, inp, 1328COMPAT_SYSCALL_DEFINE6(pselect6_time64, int, n, compat_ulong_t __user *, inp,
@@ -1402,7 +1374,6 @@ COMPAT_SYSCALL_DEFINE5(ppoll_time32, struct pollfd __user *, ufds,
1402 unsigned int, nfds, struct old_timespec32 __user *, tsp, 1374 unsigned int, nfds, struct old_timespec32 __user *, tsp,
1403 const compat_sigset_t __user *, sigmask, compat_size_t, sigsetsize) 1375 const compat_sigset_t __user *, sigmask, compat_size_t, sigsetsize)
1404{ 1376{
1405 sigset_t ksigmask, sigsaved;
1406 struct timespec64 ts, end_time, *to = NULL; 1377 struct timespec64 ts, end_time, *to = NULL;
1407 int ret; 1378 int ret;
1408 1379
@@ -1415,20 +1386,12 @@ COMPAT_SYSCALL_DEFINE5(ppoll_time32, struct pollfd __user *, ufds,
1415 return -EINVAL; 1386 return -EINVAL;
1416 } 1387 }
1417 1388
1418 ret = set_compat_user_sigmask(sigmask, &ksigmask, &sigsaved, sigsetsize); 1389 ret = set_compat_user_sigmask(sigmask, sigsetsize);
1419 if (ret) 1390 if (ret)
1420 return ret; 1391 return ret;
1421 1392
1422 ret = do_sys_poll(ufds, nfds, to); 1393 ret = do_sys_poll(ufds, nfds, to);
1423 1394 return poll_select_finish(&end_time, tsp, PT_OLD_TIMESPEC, ret);
1424 restore_user_sigmask(sigmask, &sigsaved, ret == -EINTR);
1425 /* We can restart this syscall, usually */
1426 if (ret == -EINTR)
1427 ret = -ERESTARTNOHAND;
1428
1429 ret = poll_select_copy_remaining(&end_time, tsp, PT_OLD_TIMESPEC, ret);
1430
1431 return ret;
1432} 1395}
1433#endif 1396#endif
1434 1397
@@ -1437,7 +1400,6 @@ COMPAT_SYSCALL_DEFINE5(ppoll_time64, struct pollfd __user *, ufds,
1437 unsigned int, nfds, struct __kernel_timespec __user *, tsp, 1400 unsigned int, nfds, struct __kernel_timespec __user *, tsp,
1438 const compat_sigset_t __user *, sigmask, compat_size_t, sigsetsize) 1401 const compat_sigset_t __user *, sigmask, compat_size_t, sigsetsize)
1439{ 1402{
1440 sigset_t ksigmask, sigsaved;
1441 struct timespec64 ts, end_time, *to = NULL; 1403 struct timespec64 ts, end_time, *to = NULL;
1442 int ret; 1404 int ret;
1443 1405
@@ -1450,20 +1412,12 @@ COMPAT_SYSCALL_DEFINE5(ppoll_time64, struct pollfd __user *, ufds,
1450 return -EINVAL; 1412 return -EINVAL;
1451 } 1413 }
1452 1414
1453 ret = set_compat_user_sigmask(sigmask, &ksigmask, &sigsaved, sigsetsize); 1415 ret = set_compat_user_sigmask(sigmask, sigsetsize);
1454 if (ret) 1416 if (ret)
1455 return ret; 1417 return ret;
1456 1418
1457 ret = do_sys_poll(ufds, nfds, to); 1419 ret = do_sys_poll(ufds, nfds, to);
1458 1420 return poll_select_finish(&end_time, tsp, PT_TIMESPEC, ret);
1459 restore_user_sigmask(sigmask, &sigsaved, ret == -EINTR);
1460 /* We can restart this syscall, usually */
1461 if (ret == -EINTR)
1462 ret = -ERESTARTNOHAND;
1463
1464 ret = poll_select_copy_remaining(&end_time, tsp, PT_TIMESPEC, ret);
1465
1466 return ret;
1467} 1421}
1468 1422
1469#endif 1423#endif