hc
2024-10-09 05e59e5fb0064c97a1c10921ecd549f2d4a58565
kernel/fs/select.c
....@@ -97,7 +97,7 @@
9797 struct poll_table_page {
9898 struct poll_table_page * next;
9999 struct poll_table_entry * entry;
100
- struct poll_table_entry entries[0];
100
+ struct poll_table_entry entries[];
101101 };
102102
103103 #define POLL_TABLE_FULL(table) \
....@@ -287,12 +287,20 @@
287287 return 0;
288288 }
289289
290
-static int poll_select_copy_remaining(struct timespec64 *end_time,
291
- void __user *p,
292
- int timeval, int ret)
290
+enum poll_time_type {
291
+ PT_TIMEVAL = 0,
292
+ PT_OLD_TIMEVAL = 1,
293
+ PT_TIMESPEC = 2,
294
+ PT_OLD_TIMESPEC = 3,
295
+};
296
+
297
+static int poll_select_finish(struct timespec64 *end_time,
298
+ void __user *p,
299
+ enum poll_time_type pt_type, int ret)
293300 {
294301 struct timespec64 rts;
295
- struct timeval rtv;
302
+
303
+ restore_saved_sigmask_unless(ret == -ERESTARTNOHAND);
296304
297305 if (!p)
298306 return ret;
....@@ -310,18 +318,40 @@
310318 rts.tv_sec = rts.tv_nsec = 0;
311319
312320
313
- if (timeval) {
314
- if (sizeof(rtv) > sizeof(rtv.tv_sec) + sizeof(rtv.tv_usec))
315
- memset(&rtv, 0, sizeof(rtv));
316
- rtv.tv_sec = rts.tv_sec;
317
- rtv.tv_usec = rts.tv_nsec / NSEC_PER_USEC;
321
+ switch (pt_type) {
322
+ case PT_TIMEVAL:
323
+ {
324
+ struct __kernel_old_timeval rtv;
318325
319
- if (!copy_to_user(p, &rtv, sizeof(rtv)))
326
+ if (sizeof(rtv) > sizeof(rtv.tv_sec) + sizeof(rtv.tv_usec))
327
+ memset(&rtv, 0, sizeof(rtv));
328
+ rtv.tv_sec = rts.tv_sec;
329
+ rtv.tv_usec = rts.tv_nsec / NSEC_PER_USEC;
330
+ if (!copy_to_user(p, &rtv, sizeof(rtv)))
331
+ return ret;
332
+ }
333
+ break;
334
+ case PT_OLD_TIMEVAL:
335
+ {
336
+ struct old_timeval32 rtv;
337
+
338
+ rtv.tv_sec = rts.tv_sec;
339
+ rtv.tv_usec = rts.tv_nsec / NSEC_PER_USEC;
340
+ if (!copy_to_user(p, &rtv, sizeof(rtv)))
341
+ return ret;
342
+ }
343
+ break;
344
+ case PT_TIMESPEC:
345
+ if (!put_timespec64(&rts, p))
320346 return ret;
321
-
322
- } else if (!put_timespec64(&rts, p))
323
- return ret;
324
-
347
+ break;
348
+ case PT_OLD_TIMESPEC:
349
+ if (!put_old_timespec32(&rts, p))
350
+ return ret;
351
+ break;
352
+ default:
353
+ BUG();
354
+ }
325355 /*
326356 * If an application puts its timeval in read-only memory, we
327357 * don't want the Linux-specific update to the timeval to
....@@ -353,9 +383,6 @@
353383 #define FDS_BYTES(nr) (FDS_LONGS(nr)*sizeof(long))
354384
355385 /*
356
- * We do a VERIFY_WRITE here even though we are only reading this time:
357
- * we'll write to it eventually..
358
- *
359386 * Use "unsigned long" accesses to let user-mode fd_set's be long-aligned.
360387 */
361388 static inline
....@@ -674,10 +701,10 @@
674701 }
675702
676703 static int kern_select(int n, fd_set __user *inp, fd_set __user *outp,
677
- fd_set __user *exp, struct timeval __user *tvp)
704
+ fd_set __user *exp, struct __kernel_old_timeval __user *tvp)
678705 {
679706 struct timespec64 end_time, *to = NULL;
680
- struct timeval tv;
707
+ struct __kernel_old_timeval tv;
681708 int ret;
682709
683710 if (tvp) {
....@@ -692,63 +719,48 @@
692719 }
693720
694721 ret = core_sys_select(n, inp, outp, exp, to);
695
- ret = poll_select_copy_remaining(&end_time, tvp, 1, ret);
696
-
697
- return ret;
722
+ return poll_select_finish(&end_time, tvp, PT_TIMEVAL, ret);
698723 }
699724
700725 SYSCALL_DEFINE5(select, int, n, fd_set __user *, inp, fd_set __user *, outp,
701
- fd_set __user *, exp, struct timeval __user *, tvp)
726
+ fd_set __user *, exp, struct __kernel_old_timeval __user *, tvp)
702727 {
703728 return kern_select(n, inp, outp, exp, tvp);
704729 }
705730
706731 static long do_pselect(int n, fd_set __user *inp, fd_set __user *outp,
707
- fd_set __user *exp, struct timespec __user *tsp,
708
- const sigset_t __user *sigmask, size_t sigsetsize)
732
+ fd_set __user *exp, void __user *tsp,
733
+ const sigset_t __user *sigmask, size_t sigsetsize,
734
+ enum poll_time_type type)
709735 {
710
- sigset_t ksigmask, sigsaved;
711736 struct timespec64 ts, end_time, *to = NULL;
712737 int ret;
713738
714739 if (tsp) {
715
- if (get_timespec64(&ts, tsp))
716
- return -EFAULT;
740
+ switch (type) {
741
+ case PT_TIMESPEC:
742
+ if (get_timespec64(&ts, tsp))
743
+ return -EFAULT;
744
+ break;
745
+ case PT_OLD_TIMESPEC:
746
+ if (get_old_timespec32(&ts, tsp))
747
+ return -EFAULT;
748
+ break;
749
+ default:
750
+ BUG();
751
+ }
717752
718753 to = &end_time;
719754 if (poll_select_set_timeout(to, ts.tv_sec, ts.tv_nsec))
720755 return -EINVAL;
721756 }
722757
723
- if (sigmask) {
724
- /* XXX: Don't preclude handling different sized sigset_t's. */
725
- if (sigsetsize != sizeof(sigset_t))
726
- return -EINVAL;
727
- if (copy_from_user(&ksigmask, sigmask, sizeof(ksigmask)))
728
- return -EFAULT;
729
-
730
- sigdelsetmask(&ksigmask, sigmask(SIGKILL)|sigmask(SIGSTOP));
731
- sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved);
732
- }
758
+ ret = set_user_sigmask(sigmask, sigsetsize);
759
+ if (ret)
760
+ return ret;
733761
734762 ret = core_sys_select(n, inp, outp, exp, to);
735
- ret = poll_select_copy_remaining(&end_time, tsp, 0, ret);
736
-
737
- if (ret == -ERESTARTNOHAND) {
738
- /*
739
- * Don't restore the signal mask yet. Let do_signal() deliver
740
- * the signal on the way back to userspace, before the signal
741
- * mask is restored.
742
- */
743
- if (sigmask) {
744
- memcpy(&current->saved_sigmask, &sigsaved,
745
- sizeof(sigsaved));
746
- set_restore_sigmask();
747
- }
748
- } else if (sigmask)
749
- sigprocmask(SIG_SETMASK, &sigsaved, NULL);
750
-
751
- return ret;
763
+ return poll_select_finish(&end_time, tsp, type, ret);
752764 }
753765
754766 /*
....@@ -757,29 +769,61 @@
757769 * which has a pointer to the sigset_t itself followed by a size_t containing
758770 * the sigset size.
759771 */
772
+struct sigset_argpack {
773
+ sigset_t __user *p;
774
+ size_t size;
775
+};
776
+
777
+static inline int get_sigset_argpack(struct sigset_argpack *to,
778
+ struct sigset_argpack __user *from)
779
+{
780
+ // the path is hot enough for overhead of copy_from_user() to matter
781
+ if (from) {
782
+ if (!user_read_access_begin(from, sizeof(*from)))
783
+ return -EFAULT;
784
+ unsafe_get_user(to->p, &from->p, Efault);
785
+ unsafe_get_user(to->size, &from->size, Efault);
786
+ user_read_access_end();
787
+ }
788
+ return 0;
789
+Efault:
790
+ user_access_end();
791
+ return -EFAULT;
792
+}
793
+
760794 SYSCALL_DEFINE6(pselect6, int, n, fd_set __user *, inp, fd_set __user *, outp,
761
- fd_set __user *, exp, struct timespec __user *, tsp,
795
+ fd_set __user *, exp, struct __kernel_timespec __user *, tsp,
762796 void __user *, sig)
763797 {
764
- size_t sigsetsize = 0;
765
- sigset_t __user *up = NULL;
798
+ struct sigset_argpack x = {NULL, 0};
766799
767
- if (sig) {
768
- if (!access_ok(VERIFY_READ, sig, sizeof(void *)+sizeof(size_t))
769
- || __get_user(up, (sigset_t __user * __user *)sig)
770
- || __get_user(sigsetsize,
771
- (size_t __user *)(sig+sizeof(void *))))
772
- return -EFAULT;
773
- }
800
+ if (get_sigset_argpack(&x, sig))
801
+ return -EFAULT;
774802
775
- return do_pselect(n, inp, outp, exp, tsp, up, sigsetsize);
803
+ return do_pselect(n, inp, outp, exp, tsp, x.p, x.size, PT_TIMESPEC);
776804 }
805
+
806
+#if defined(CONFIG_COMPAT_32BIT_TIME) && !defined(CONFIG_64BIT)
807
+
808
+SYSCALL_DEFINE6(pselect6_time32, int, n, fd_set __user *, inp, fd_set __user *, outp,
809
+ fd_set __user *, exp, struct old_timespec32 __user *, tsp,
810
+ void __user *, sig)
811
+{
812
+ struct sigset_argpack x = {NULL, 0};
813
+
814
+ if (get_sigset_argpack(&x, sig))
815
+ return -EFAULT;
816
+
817
+ return do_pselect(n, inp, outp, exp, tsp, x.p, x.size, PT_OLD_TIMESPEC);
818
+}
819
+
820
+#endif
777821
778822 #ifdef __ARCH_WANT_SYS_OLD_SELECT
779823 struct sel_arg_struct {
780824 unsigned long n;
781825 fd_set __user *inp, *outp, *exp;
782
- struct timeval __user *tvp;
826
+ struct __kernel_old_timeval __user *tvp;
783827 };
784828
785829 SYSCALL_DEFINE1(old_select, struct sel_arg_struct __user *, arg)
....@@ -795,7 +839,7 @@
795839 struct poll_list {
796840 struct poll_list *next;
797841 int len;
798
- struct pollfd entries[0];
842
+ struct pollfd entries[];
799843 };
800844
801845 #define POLLFD_PER_PAGE ((PAGE_SIZE-sizeof(struct poll_list)) / sizeof(struct pollfd))
....@@ -891,7 +935,7 @@
891935 if (!count) {
892936 count = wait->error;
893937 if (signal_pending(current))
894
- count = -EINTR;
938
+ count = -ERESTARTNOHAND;
895939 }
896940 if (count || timed_out)
897941 break;
....@@ -930,7 +974,7 @@
930974 struct timespec64 *end_time)
931975 {
932976 struct poll_wqueues table;
933
- int err = -EFAULT, fdcount, len, size;
977
+ int err = -EFAULT, fdcount, len;
934978 /* Allocate small arguments on the stack to save memory and be
935979 faster - use long to make sure the buffer is aligned properly
936980 on 64 bit archs to avoid unaligned access */
....@@ -958,8 +1002,8 @@
9581002 break;
9591003
9601004 len = min(todo, POLLFD_PER_PAGE);
961
- size = sizeof(struct poll_list) + sizeof(struct pollfd) * len;
962
- walk = walk->next = kmalloc(size, GFP_KERNEL);
1005
+ walk = walk->next = kmalloc(struct_size(walk, entries, len),
1006
+ GFP_KERNEL);
9631007 if (!walk) {
9641008 err = -ENOMEM;
9651009 goto out_fds;
....@@ -970,14 +1014,17 @@
9701014 fdcount = do_poll(head, &table, end_time);
9711015 poll_freewait(&table);
9721016
1017
+ if (!user_write_access_begin(ufds, nfds * sizeof(*ufds)))
1018
+ goto out_fds;
1019
+
9731020 for (walk = head; walk; walk = walk->next) {
9741021 struct pollfd *fds = walk->entries;
9751022 int j;
9761023
977
- for (j = 0; j < walk->len; j++, ufds++)
978
- if (__put_user(fds[j].revents, &ufds->revents))
979
- goto out_fds;
1024
+ for (j = walk->len; j; fds++, ufds++, j--)
1025
+ unsafe_put_user(fds->revents, &ufds->revents, Efault);
9801026 }
1027
+ user_write_access_end();
9811028
9821029 err = fdcount;
9831030 out_fds:
....@@ -989,6 +1036,11 @@
9891036 }
9901037
9911038 return err;
1039
+
1040
+Efault:
1041
+ user_write_access_end();
1042
+ err = -EFAULT;
1043
+ goto out_fds;
9921044 }
9931045
9941046 static long do_restart_poll(struct restart_block *restart_block)
....@@ -1006,7 +1058,7 @@
10061058
10071059 ret = do_sys_poll(ufds, nfds, to);
10081060
1009
- if (ret == -EINTR)
1061
+ if (ret == -ERESTARTNOHAND)
10101062 ret = set_restart_fn(restart_block, do_restart_poll);
10111063
10121064 return ret;
....@@ -1026,7 +1078,7 @@
10261078
10271079 ret = do_sys_poll(ufds, nfds, to);
10281080
1029
- if (ret == -EINTR) {
1081
+ if (ret == -ERESTARTNOHAND) {
10301082 struct restart_block *restart_block;
10311083
10321084 restart_block = &current->restart_block;
....@@ -1046,10 +1098,9 @@
10461098 }
10471099
10481100 SYSCALL_DEFINE5(ppoll, struct pollfd __user *, ufds, unsigned int, nfds,
1049
- struct timespec __user *, tsp, const sigset_t __user *, sigmask,
1101
+ struct __kernel_timespec __user *, tsp, const sigset_t __user *, sigmask,
10501102 size_t, sigsetsize)
10511103 {
1052
- sigset_t ksigmask, sigsaved;
10531104 struct timespec64 ts, end_time, *to = NULL;
10541105 int ret;
10551106
....@@ -1062,89 +1113,43 @@
10621113 return -EINVAL;
10631114 }
10641115
1065
- if (sigmask) {
1066
- /* XXX: Don't preclude handling different sized sigset_t's. */
1067
- if (sigsetsize != sizeof(sigset_t))
1068
- return -EINVAL;
1069
- if (copy_from_user(&ksigmask, sigmask, sizeof(ksigmask)))
1070
- return -EFAULT;
1071
-
1072
- sigdelsetmask(&ksigmask, sigmask(SIGKILL)|sigmask(SIGSTOP));
1073
- sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved);
1074
- }
1116
+ ret = set_user_sigmask(sigmask, sigsetsize);
1117
+ if (ret)
1118
+ return ret;
10751119
10761120 ret = do_sys_poll(ufds, nfds, to);
1077
-
1078
- /* We can restart this syscall, usually */
1079
- if (ret == -EINTR) {
1080
- /*
1081
- * Don't restore the signal mask yet. Let do_signal() deliver
1082
- * the signal on the way back to userspace, before the signal
1083
- * mask is restored.
1084
- */
1085
- if (sigmask) {
1086
- memcpy(&current->saved_sigmask, &sigsaved,
1087
- sizeof(sigsaved));
1088
- set_restore_sigmask();
1089
- }
1090
- ret = -ERESTARTNOHAND;
1091
- } else if (sigmask)
1092
- sigprocmask(SIG_SETMASK, &sigsaved, NULL);
1093
-
1094
- ret = poll_select_copy_remaining(&end_time, tsp, 0, ret);
1095
-
1096
- return ret;
1121
+ return poll_select_finish(&end_time, tsp, PT_TIMESPEC, ret);
10971122 }
1123
+
1124
+#if defined(CONFIG_COMPAT_32BIT_TIME) && !defined(CONFIG_64BIT)
1125
+
1126
+SYSCALL_DEFINE5(ppoll_time32, struct pollfd __user *, ufds, unsigned int, nfds,
1127
+ struct old_timespec32 __user *, tsp, const sigset_t __user *, sigmask,
1128
+ size_t, sigsetsize)
1129
+{
1130
+ struct timespec64 ts, end_time, *to = NULL;
1131
+ int ret;
1132
+
1133
+ if (tsp) {
1134
+ if (get_old_timespec32(&ts, tsp))
1135
+ return -EFAULT;
1136
+
1137
+ to = &end_time;
1138
+ if (poll_select_set_timeout(to, ts.tv_sec, ts.tv_nsec))
1139
+ return -EINVAL;
1140
+ }
1141
+
1142
+ ret = set_user_sigmask(sigmask, sigsetsize);
1143
+ if (ret)
1144
+ return ret;
1145
+
1146
+ ret = do_sys_poll(ufds, nfds, to);
1147
+ return poll_select_finish(&end_time, tsp, PT_OLD_TIMESPEC, ret);
1148
+}
1149
+#endif
10981150
10991151 #ifdef CONFIG_COMPAT
11001152 #define __COMPAT_NFDBITS (8 * sizeof(compat_ulong_t))
1101
-
1102
-static
1103
-int compat_poll_select_copy_remaining(struct timespec64 *end_time, void __user *p,
1104
- int timeval, int ret)
1105
-{
1106
- struct timespec64 ts;
1107
-
1108
- if (!p)
1109
- return ret;
1110
-
1111
- if (current->personality & STICKY_TIMEOUTS)
1112
- goto sticky;
1113
-
1114
- /* No update for zero timeout */
1115
- if (!end_time->tv_sec && !end_time->tv_nsec)
1116
- return ret;
1117
-
1118
- ktime_get_ts64(&ts);
1119
- ts = timespec64_sub(*end_time, ts);
1120
- if (ts.tv_sec < 0)
1121
- ts.tv_sec = ts.tv_nsec = 0;
1122
-
1123
- if (timeval) {
1124
- struct compat_timeval rtv;
1125
-
1126
- rtv.tv_sec = ts.tv_sec;
1127
- rtv.tv_usec = ts.tv_nsec / NSEC_PER_USEC;
1128
-
1129
- if (!copy_to_user(p, &rtv, sizeof(rtv)))
1130
- return ret;
1131
- } else {
1132
- if (!compat_put_timespec64(&ts, p))
1133
- return ret;
1134
- }
1135
- /*
1136
- * If an application puts its timeval in read-only memory, we
1137
- * don't want the Linux-specific update to the timeval to
1138
- * cause a fault after the select has completed
1139
- * successfully. However, because we're not updating the
1140
- * timeval, we can't restart the system call.
1141
- */
1142
-
1143
-sticky:
1144
- if (ret == -ERESTARTNOHAND)
1145
- ret = -EINTR;
1146
- return ret;
1147
-}
11481153
11491154 /*
11501155 * Ooo, nasty. We need here to frob 32-bit unsigned longs to
....@@ -1258,10 +1263,10 @@
12581263
12591264 static int do_compat_select(int n, compat_ulong_t __user *inp,
12601265 compat_ulong_t __user *outp, compat_ulong_t __user *exp,
1261
- struct compat_timeval __user *tvp)
1266
+ struct old_timeval32 __user *tvp)
12621267 {
12631268 struct timespec64 end_time, *to = NULL;
1264
- struct compat_timeval tv;
1269
+ struct old_timeval32 tv;
12651270 int ret;
12661271
12671272 if (tvp) {
....@@ -1276,14 +1281,12 @@
12761281 }
12771282
12781283 ret = compat_core_sys_select(n, inp, outp, exp, to);
1279
- ret = compat_poll_select_copy_remaining(&end_time, tvp, 1, ret);
1280
-
1281
- return ret;
1284
+ return poll_select_finish(&end_time, tvp, PT_OLD_TIMEVAL, ret);
12821285 }
12831286
12841287 COMPAT_SYSCALL_DEFINE5(select, int, n, compat_ulong_t __user *, inp,
12851288 compat_ulong_t __user *, outp, compat_ulong_t __user *, exp,
1286
- struct compat_timeval __user *, tvp)
1289
+ struct old_timeval32 __user *, tvp)
12871290 {
12881291 return do_compat_select(n, inp, outp, exp, tvp);
12891292 }
....@@ -1308,81 +1311,99 @@
13081311
13091312 static long do_compat_pselect(int n, compat_ulong_t __user *inp,
13101313 compat_ulong_t __user *outp, compat_ulong_t __user *exp,
1311
- struct compat_timespec __user *tsp, compat_sigset_t __user *sigmask,
1312
- compat_size_t sigsetsize)
1314
+ void __user *tsp, compat_sigset_t __user *sigmask,
1315
+ compat_size_t sigsetsize, enum poll_time_type type)
13131316 {
1314
- sigset_t ksigmask, sigsaved;
13151317 struct timespec64 ts, end_time, *to = NULL;
13161318 int ret;
13171319
13181320 if (tsp) {
1319
- if (compat_get_timespec64(&ts, tsp))
1320
- return -EFAULT;
1321
+ switch (type) {
1322
+ case PT_OLD_TIMESPEC:
1323
+ if (get_old_timespec32(&ts, tsp))
1324
+ return -EFAULT;
1325
+ break;
1326
+ case PT_TIMESPEC:
1327
+ if (get_timespec64(&ts, tsp))
1328
+ return -EFAULT;
1329
+ break;
1330
+ default:
1331
+ BUG();
1332
+ }
13211333
13221334 to = &end_time;
13231335 if (poll_select_set_timeout(to, ts.tv_sec, ts.tv_nsec))
13241336 return -EINVAL;
13251337 }
13261338
1327
- if (sigmask) {
1328
- if (sigsetsize != sizeof(compat_sigset_t))
1329
- return -EINVAL;
1330
- if (get_compat_sigset(&ksigmask, sigmask))
1331
- return -EFAULT;
1332
-
1333
- sigdelsetmask(&ksigmask, sigmask(SIGKILL)|sigmask(SIGSTOP));
1334
- sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved);
1335
- }
1339
+ ret = set_compat_user_sigmask(sigmask, sigsetsize);
1340
+ if (ret)
1341
+ return ret;
13361342
13371343 ret = compat_core_sys_select(n, inp, outp, exp, to);
1338
- ret = compat_poll_select_copy_remaining(&end_time, tsp, 0, ret);
1339
-
1340
- if (ret == -ERESTARTNOHAND) {
1341
- /*
1342
- * Don't restore the signal mask yet. Let do_signal() deliver
1343
- * the signal on the way back to userspace, before the signal
1344
- * mask is restored.
1345
- */
1346
- if (sigmask) {
1347
- memcpy(&current->saved_sigmask, &sigsaved,
1348
- sizeof(sigsaved));
1349
- set_restore_sigmask();
1350
- }
1351
- } else if (sigmask)
1352
- sigprocmask(SIG_SETMASK, &sigsaved, NULL);
1353
-
1354
- return ret;
1344
+ return poll_select_finish(&end_time, tsp, type, ret);
13551345 }
13561346
1357
-COMPAT_SYSCALL_DEFINE6(pselect6, int, n, compat_ulong_t __user *, inp,
1358
- compat_ulong_t __user *, outp, compat_ulong_t __user *, exp,
1359
- struct compat_timespec __user *, tsp, void __user *, sig)
1347
+struct compat_sigset_argpack {
1348
+ compat_uptr_t p;
1349
+ compat_size_t size;
1350
+};
1351
+static inline int get_compat_sigset_argpack(struct compat_sigset_argpack *to,
1352
+ struct compat_sigset_argpack __user *from)
13601353 {
1361
- compat_size_t sigsetsize = 0;
1362
- compat_uptr_t up = 0;
1363
-
1364
- if (sig) {
1365
- if (!access_ok(VERIFY_READ, sig,
1366
- sizeof(compat_uptr_t)+sizeof(compat_size_t)) ||
1367
- __get_user(up, (compat_uptr_t __user *)sig) ||
1368
- __get_user(sigsetsize,
1369
- (compat_size_t __user *)(sig+sizeof(up))))
1354
+ if (from) {
1355
+ if (!user_read_access_begin(from, sizeof(*from)))
13701356 return -EFAULT;
1357
+ unsafe_get_user(to->p, &from->p, Efault);
1358
+ unsafe_get_user(to->size, &from->size, Efault);
1359
+ user_read_access_end();
13711360 }
1372
- return do_compat_pselect(n, inp, outp, exp, tsp, compat_ptr(up),
1373
- sigsetsize);
1361
+ return 0;
1362
+Efault:
1363
+ user_access_end();
1364
+ return -EFAULT;
13741365 }
13751366
1376
-COMPAT_SYSCALL_DEFINE5(ppoll, struct pollfd __user *, ufds,
1377
- unsigned int, nfds, struct compat_timespec __user *, tsp,
1367
+COMPAT_SYSCALL_DEFINE6(pselect6_time64, int, n, compat_ulong_t __user *, inp,
1368
+ compat_ulong_t __user *, outp, compat_ulong_t __user *, exp,
1369
+ struct __kernel_timespec __user *, tsp, void __user *, sig)
1370
+{
1371
+ struct compat_sigset_argpack x = {0, 0};
1372
+
1373
+ if (get_compat_sigset_argpack(&x, sig))
1374
+ return -EFAULT;
1375
+
1376
+ return do_compat_pselect(n, inp, outp, exp, tsp, compat_ptr(x.p),
1377
+ x.size, PT_TIMESPEC);
1378
+}
1379
+
1380
+#if defined(CONFIG_COMPAT_32BIT_TIME)
1381
+
1382
+COMPAT_SYSCALL_DEFINE6(pselect6_time32, int, n, compat_ulong_t __user *, inp,
1383
+ compat_ulong_t __user *, outp, compat_ulong_t __user *, exp,
1384
+ struct old_timespec32 __user *, tsp, void __user *, sig)
1385
+{
1386
+ struct compat_sigset_argpack x = {0, 0};
1387
+
1388
+ if (get_compat_sigset_argpack(&x, sig))
1389
+ return -EFAULT;
1390
+
1391
+ return do_compat_pselect(n, inp, outp, exp, tsp, compat_ptr(x.p),
1392
+ x.size, PT_OLD_TIMESPEC);
1393
+}
1394
+
1395
+#endif
1396
+
1397
+#if defined(CONFIG_COMPAT_32BIT_TIME)
1398
+COMPAT_SYSCALL_DEFINE5(ppoll_time32, struct pollfd __user *, ufds,
1399
+ unsigned int, nfds, struct old_timespec32 __user *, tsp,
13781400 const compat_sigset_t __user *, sigmask, compat_size_t, sigsetsize)
13791401 {
1380
- sigset_t ksigmask, sigsaved;
13811402 struct timespec64 ts, end_time, *to = NULL;
13821403 int ret;
13831404
13841405 if (tsp) {
1385
- if (compat_get_timespec64(&ts, tsp))
1406
+ if (get_old_timespec32(&ts, tsp))
13861407 return -EFAULT;
13871408
13881409 to = &end_time;
....@@ -1390,36 +1411,38 @@
13901411 return -EINVAL;
13911412 }
13921413
1393
- if (sigmask) {
1394
- if (sigsetsize != sizeof(compat_sigset_t))
1395
- return -EINVAL;
1396
- if (get_compat_sigset(&ksigmask, sigmask))
1397
- return -EFAULT;
1398
-
1399
- sigdelsetmask(&ksigmask, sigmask(SIGKILL)|sigmask(SIGSTOP));
1400
- sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved);
1401
- }
1414
+ ret = set_compat_user_sigmask(sigmask, sigsetsize);
1415
+ if (ret)
1416
+ return ret;
14021417
14031418 ret = do_sys_poll(ufds, nfds, to);
1404
-
1405
- /* We can restart this syscall, usually */
1406
- if (ret == -EINTR) {
1407
- /*
1408
- * Don't restore the signal mask yet. Let do_signal() deliver
1409
- * the signal on the way back to userspace, before the signal
1410
- * mask is restored.
1411
- */
1412
- if (sigmask) {
1413
- memcpy(&current->saved_sigmask, &sigsaved,
1414
- sizeof(sigsaved));
1415
- set_restore_sigmask();
1416
- }
1417
- ret = -ERESTARTNOHAND;
1418
- } else if (sigmask)
1419
- sigprocmask(SIG_SETMASK, &sigsaved, NULL);
1420
-
1421
- ret = compat_poll_select_copy_remaining(&end_time, tsp, 0, ret);
1422
-
1423
- return ret;
1419
+ return poll_select_finish(&end_time, tsp, PT_OLD_TIMESPEC, ret);
14241420 }
14251421 #endif
1422
+
1423
+/* New compat syscall for 64 bit time_t*/
1424
+COMPAT_SYSCALL_DEFINE5(ppoll_time64, struct pollfd __user *, ufds,
1425
+ unsigned int, nfds, struct __kernel_timespec __user *, tsp,
1426
+ const compat_sigset_t __user *, sigmask, compat_size_t, sigsetsize)
1427
+{
1428
+ struct timespec64 ts, end_time, *to = NULL;
1429
+ int ret;
1430
+
1431
+ if (tsp) {
1432
+ if (get_timespec64(&ts, tsp))
1433
+ return -EFAULT;
1434
+
1435
+ to = &end_time;
1436
+ if (poll_select_set_timeout(to, ts.tv_sec, ts.tv_nsec))
1437
+ return -EINVAL;
1438
+ }
1439
+
1440
+ ret = set_compat_user_sigmask(sigmask, sigsetsize);
1441
+ if (ret)
1442
+ return ret;
1443
+
1444
+ ret = do_sys_poll(ufds, nfds, to);
1445
+ return poll_select_finish(&end_time, tsp, PT_TIMESPEC, ret);
1446
+}
1447
+
1448
+#endif