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

move compat select-related syscalls to fs/select.c

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Al Viro e99ca56c 2611dc19

+419 -426
-368
fs/compat.c
··· 43 43 #include <linux/security.h> 44 44 #include <linux/highmem.h> 45 45 #include <linux/signal.h> 46 - #include <linux/poll.h> 47 46 #include <linux/mm.h> 48 47 #include <linux/fs_struct.h> 49 48 #include <linux/slab.h> ··· 922 923 COMPAT_SYSCALL_DEFINE4(openat, int, dfd, const char __user *, filename, int, flags, umode_t, mode) 923 924 { 924 925 return do_sys_open(dfd, filename, flags, mode); 925 - } 926 - 927 - #define __COMPAT_NFDBITS (8 * sizeof(compat_ulong_t)) 928 - 929 - static int poll_select_copy_remaining(struct timespec *end_time, void __user *p, 930 - int timeval, int ret) 931 - { 932 - struct timespec ts; 933 - 934 - if (!p) 935 - return ret; 936 - 937 - if (current->personality & STICKY_TIMEOUTS) 938 - goto sticky; 939 - 940 - /* No update for zero timeout */ 941 - if (!end_time->tv_sec && !end_time->tv_nsec) 942 - return ret; 943 - 944 - ktime_get_ts(&ts); 945 - ts = timespec_sub(*end_time, ts); 946 - if (ts.tv_sec < 0) 947 - ts.tv_sec = ts.tv_nsec = 0; 948 - 949 - if (timeval) { 950 - struct compat_timeval rtv; 951 - 952 - rtv.tv_sec = ts.tv_sec; 953 - rtv.tv_usec = ts.tv_nsec / NSEC_PER_USEC; 954 - 955 - if (!copy_to_user(p, &rtv, sizeof(rtv))) 956 - return ret; 957 - } else { 958 - struct compat_timespec rts; 959 - 960 - rts.tv_sec = ts.tv_sec; 961 - rts.tv_nsec = ts.tv_nsec; 962 - 963 - if (!copy_to_user(p, &rts, sizeof(rts))) 964 - return ret; 965 - } 966 - /* 967 - * If an application puts its timeval in read-only memory, we 968 - * don't want the Linux-specific update to the timeval to 969 - * cause a fault after the select has completed 970 - * successfully. However, because we're not updating the 971 - * timeval, we can't restart the system call. 972 - */ 973 - 974 - sticky: 975 - if (ret == -ERESTARTNOHAND) 976 - ret = -EINTR; 977 - return ret; 978 - } 979 - 980 - /* 981 - * Ooo, nasty. We need here to frob 32-bit unsigned longs to 982 - * 64-bit unsigned longs. 983 - */ 984 - static 985 - int compat_get_fd_set(unsigned long nr, compat_ulong_t __user *ufdset, 986 - unsigned long *fdset) 987 - { 988 - nr = DIV_ROUND_UP(nr, __COMPAT_NFDBITS); 989 - if (ufdset) { 990 - unsigned long odd; 991 - 992 - if (!access_ok(VERIFY_WRITE, ufdset, nr*sizeof(compat_ulong_t))) 993 - return -EFAULT; 994 - 995 - odd = nr & 1UL; 996 - nr &= ~1UL; 997 - while (nr) { 998 - unsigned long h, l; 999 - if (__get_user(l, ufdset) || __get_user(h, ufdset+1)) 1000 - return -EFAULT; 1001 - ufdset += 2; 1002 - *fdset++ = h << 32 | l; 1003 - nr -= 2; 1004 - } 1005 - if (odd && __get_user(*fdset, ufdset)) 1006 - return -EFAULT; 1007 - } else { 1008 - /* Tricky, must clear full unsigned long in the 1009 - * kernel fdset at the end, this makes sure that 1010 - * actually happens. 1011 - */ 1012 - memset(fdset, 0, ((nr + 1) & ~1)*sizeof(compat_ulong_t)); 1013 - } 1014 - return 0; 1015 - } 1016 - 1017 - static 1018 - int compat_set_fd_set(unsigned long nr, compat_ulong_t __user *ufdset, 1019 - unsigned long *fdset) 1020 - { 1021 - unsigned long odd; 1022 - nr = DIV_ROUND_UP(nr, __COMPAT_NFDBITS); 1023 - 1024 - if (!ufdset) 1025 - return 0; 1026 - 1027 - odd = nr & 1UL; 1028 - nr &= ~1UL; 1029 - while (nr) { 1030 - unsigned long h, l; 1031 - l = *fdset++; 1032 - h = l >> 32; 1033 - if (__put_user(l, ufdset) || __put_user(h, ufdset+1)) 1034 - return -EFAULT; 1035 - ufdset += 2; 1036 - nr -= 2; 1037 - } 1038 - if (odd && __put_user(*fdset, ufdset)) 1039 - return -EFAULT; 1040 - return 0; 1041 - } 1042 - 1043 - 1044 - /* 1045 - * This is a virtual copy of sys_select from fs/select.c and probably 1046 - * should be compared to it from time to time 1047 - */ 1048 - 1049 - /* 1050 - * We can actually return ERESTARTSYS instead of EINTR, but I'd 1051 - * like to be certain this leads to no problems. So I return 1052 - * EINTR just for safety. 1053 - * 1054 - * Update: ERESTARTSYS breaks at least the xview clock binary, so 1055 - * I'm trying ERESTARTNOHAND which restart only when you want to. 1056 - */ 1057 - int compat_core_sys_select(int n, compat_ulong_t __user *inp, 1058 - compat_ulong_t __user *outp, compat_ulong_t __user *exp, 1059 - struct timespec *end_time) 1060 - { 1061 - fd_set_bits fds; 1062 - void *bits; 1063 - int size, max_fds, ret = -EINVAL; 1064 - struct fdtable *fdt; 1065 - long stack_fds[SELECT_STACK_ALLOC/sizeof(long)]; 1066 - 1067 - if (n < 0) 1068 - goto out_nofds; 1069 - 1070 - /* max_fds can increase, so grab it once to avoid race */ 1071 - rcu_read_lock(); 1072 - fdt = files_fdtable(current->files); 1073 - max_fds = fdt->max_fds; 1074 - rcu_read_unlock(); 1075 - if (n > max_fds) 1076 - n = max_fds; 1077 - 1078 - /* 1079 - * We need 6 bitmaps (in/out/ex for both incoming and outgoing), 1080 - * since we used fdset we need to allocate memory in units of 1081 - * long-words. 1082 - */ 1083 - size = FDS_BYTES(n); 1084 - bits = stack_fds; 1085 - if (size > sizeof(stack_fds) / 6) { 1086 - bits = kmalloc(6 * size, GFP_KERNEL); 1087 - ret = -ENOMEM; 1088 - if (!bits) 1089 - goto out_nofds; 1090 - } 1091 - fds.in = (unsigned long *) bits; 1092 - fds.out = (unsigned long *) (bits + size); 1093 - fds.ex = (unsigned long *) (bits + 2*size); 1094 - fds.res_in = (unsigned long *) (bits + 3*size); 1095 - fds.res_out = (unsigned long *) (bits + 4*size); 1096 - fds.res_ex = (unsigned long *) (bits + 5*size); 1097 - 1098 - if ((ret = compat_get_fd_set(n, inp, fds.in)) || 1099 - (ret = compat_get_fd_set(n, outp, fds.out)) || 1100 - (ret = compat_get_fd_set(n, exp, fds.ex))) 1101 - goto out; 1102 - zero_fd_set(n, fds.res_in); 1103 - zero_fd_set(n, fds.res_out); 1104 - zero_fd_set(n, fds.res_ex); 1105 - 1106 - ret = do_select(n, &fds, end_time); 1107 - 1108 - if (ret < 0) 1109 - goto out; 1110 - if (!ret) { 1111 - ret = -ERESTARTNOHAND; 1112 - if (signal_pending(current)) 1113 - goto out; 1114 - ret = 0; 1115 - } 1116 - 1117 - if (compat_set_fd_set(n, inp, fds.res_in) || 1118 - compat_set_fd_set(n, outp, fds.res_out) || 1119 - compat_set_fd_set(n, exp, fds.res_ex)) 1120 - ret = -EFAULT; 1121 - out: 1122 - if (bits != stack_fds) 1123 - kfree(bits); 1124 - out_nofds: 1125 - return ret; 1126 - } 1127 - 1128 - COMPAT_SYSCALL_DEFINE5(select, int, n, compat_ulong_t __user *, inp, 1129 - compat_ulong_t __user *, outp, compat_ulong_t __user *, exp, 1130 - struct compat_timeval __user *, tvp) 1131 - { 1132 - struct timespec end_time, *to = NULL; 1133 - struct compat_timeval tv; 1134 - int ret; 1135 - 1136 - if (tvp) { 1137 - if (copy_from_user(&tv, tvp, sizeof(tv))) 1138 - return -EFAULT; 1139 - 1140 - to = &end_time; 1141 - if (poll_select_set_timeout(to, 1142 - tv.tv_sec + (tv.tv_usec / USEC_PER_SEC), 1143 - (tv.tv_usec % USEC_PER_SEC) * NSEC_PER_USEC)) 1144 - return -EINVAL; 1145 - } 1146 - 1147 - ret = compat_core_sys_select(n, inp, outp, exp, to); 1148 - ret = poll_select_copy_remaining(&end_time, tvp, 1, ret); 1149 - 1150 - return ret; 1151 - } 1152 - 1153 - struct compat_sel_arg_struct { 1154 - compat_ulong_t n; 1155 - compat_uptr_t inp; 1156 - compat_uptr_t outp; 1157 - compat_uptr_t exp; 1158 - compat_uptr_t tvp; 1159 - }; 1160 - 1161 - COMPAT_SYSCALL_DEFINE1(old_select, struct compat_sel_arg_struct __user *, arg) 1162 - { 1163 - struct compat_sel_arg_struct a; 1164 - 1165 - if (copy_from_user(&a, arg, sizeof(a))) 1166 - return -EFAULT; 1167 - return compat_sys_select(a.n, compat_ptr(a.inp), compat_ptr(a.outp), 1168 - compat_ptr(a.exp), compat_ptr(a.tvp)); 1169 - } 1170 - 1171 - static long do_compat_pselect(int n, compat_ulong_t __user *inp, 1172 - compat_ulong_t __user *outp, compat_ulong_t __user *exp, 1173 - struct compat_timespec __user *tsp, compat_sigset_t __user *sigmask, 1174 - compat_size_t sigsetsize) 1175 - { 1176 - compat_sigset_t ss32; 1177 - sigset_t ksigmask, sigsaved; 1178 - struct compat_timespec ts; 1179 - struct timespec end_time, *to = NULL; 1180 - int ret; 1181 - 1182 - if (tsp) { 1183 - if (copy_from_user(&ts, tsp, sizeof(ts))) 1184 - return -EFAULT; 1185 - 1186 - to = &end_time; 1187 - if (poll_select_set_timeout(to, ts.tv_sec, ts.tv_nsec)) 1188 - return -EINVAL; 1189 - } 1190 - 1191 - if (sigmask) { 1192 - if (sigsetsize != sizeof(compat_sigset_t)) 1193 - return -EINVAL; 1194 - if (copy_from_user(&ss32, sigmask, sizeof(ss32))) 1195 - return -EFAULT; 1196 - sigset_from_compat(&ksigmask, &ss32); 1197 - 1198 - sigdelsetmask(&ksigmask, sigmask(SIGKILL)|sigmask(SIGSTOP)); 1199 - sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved); 1200 - } 1201 - 1202 - ret = compat_core_sys_select(n, inp, outp, exp, to); 1203 - ret = poll_select_copy_remaining(&end_time, tsp, 0, ret); 1204 - 1205 - if (ret == -ERESTARTNOHAND) { 1206 - /* 1207 - * Don't restore the signal mask yet. Let do_signal() deliver 1208 - * the signal on the way back to userspace, before the signal 1209 - * mask is restored. 1210 - */ 1211 - if (sigmask) { 1212 - memcpy(&current->saved_sigmask, &sigsaved, 1213 - sizeof(sigsaved)); 1214 - set_restore_sigmask(); 1215 - } 1216 - } else if (sigmask) 1217 - sigprocmask(SIG_SETMASK, &sigsaved, NULL); 1218 - 1219 - return ret; 1220 - } 1221 - 1222 - COMPAT_SYSCALL_DEFINE6(pselect6, int, n, compat_ulong_t __user *, inp, 1223 - compat_ulong_t __user *, outp, compat_ulong_t __user *, exp, 1224 - struct compat_timespec __user *, tsp, void __user *, sig) 1225 - { 1226 - compat_size_t sigsetsize = 0; 1227 - compat_uptr_t up = 0; 1228 - 1229 - if (sig) { 1230 - if (!access_ok(VERIFY_READ, sig, 1231 - sizeof(compat_uptr_t)+sizeof(compat_size_t)) || 1232 - __get_user(up, (compat_uptr_t __user *)sig) || 1233 - __get_user(sigsetsize, 1234 - (compat_size_t __user *)(sig+sizeof(up)))) 1235 - return -EFAULT; 1236 - } 1237 - return do_compat_pselect(n, inp, outp, exp, tsp, compat_ptr(up), 1238 - sigsetsize); 1239 - } 1240 - 1241 - COMPAT_SYSCALL_DEFINE5(ppoll, struct pollfd __user *, ufds, 1242 - unsigned int, nfds, struct compat_timespec __user *, tsp, 1243 - const compat_sigset_t __user *, sigmask, compat_size_t, sigsetsize) 1244 - { 1245 - compat_sigset_t ss32; 1246 - sigset_t ksigmask, sigsaved; 1247 - struct compat_timespec ts; 1248 - struct timespec end_time, *to = NULL; 1249 - int ret; 1250 - 1251 - if (tsp) { 1252 - if (copy_from_user(&ts, tsp, sizeof(ts))) 1253 - return -EFAULT; 1254 - 1255 - to = &end_time; 1256 - if (poll_select_set_timeout(to, ts.tv_sec, ts.tv_nsec)) 1257 - return -EINVAL; 1258 - } 1259 - 1260 - if (sigmask) { 1261 - if (sigsetsize != sizeof(compat_sigset_t)) 1262 - return -EINVAL; 1263 - if (copy_from_user(&ss32, sigmask, sizeof(ss32))) 1264 - return -EFAULT; 1265 - sigset_from_compat(&ksigmask, &ss32); 1266 - 1267 - sigdelsetmask(&ksigmask, sigmask(SIGKILL)|sigmask(SIGSTOP)); 1268 - sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved); 1269 - } 1270 - 1271 - ret = do_sys_poll(ufds, nfds, to); 1272 - 1273 - /* We can restart this syscall, usually */ 1274 - if (ret == -EINTR) { 1275 - /* 1276 - * Don't restore the signal mask yet. Let do_signal() deliver 1277 - * the signal on the way back to userspace, before the signal 1278 - * mask is restored. 1279 - */ 1280 - if (sigmask) { 1281 - memcpy(&current->saved_sigmask, &sigsaved, 1282 - sizeof(sigsaved)); 1283 - set_restore_sigmask(); 1284 - } 1285 - ret = -ERESTARTNOHAND; 1286 - } else if (sigmask) 1287 - sigprocmask(SIG_SETMASK, &sigsaved, NULL); 1288 - 1289 - ret = poll_select_copy_remaining(&end_time, tsp, 0, ret); 1290 - 1291 - return ret; 1292 926 } 1293 927 1294 928 #ifdef CONFIG_FHANDLE
+419 -2
fs/select.c
··· 338 338 return ret; 339 339 } 340 340 341 + /* 342 + * Scalable version of the fd_set. 343 + */ 344 + 345 + typedef struct { 346 + unsigned long *in, *out, *ex; 347 + unsigned long *res_in, *res_out, *res_ex; 348 + } fd_set_bits; 349 + 350 + /* 351 + * How many longwords for "nr" bits? 352 + */ 353 + #define FDS_BITPERLONG (8*sizeof(long)) 354 + #define FDS_LONGS(nr) (((nr)+FDS_BITPERLONG-1)/FDS_BITPERLONG) 355 + #define FDS_BYTES(nr) (FDS_LONGS(nr)*sizeof(long)) 356 + 357 + /* 358 + * We do a VERIFY_WRITE here even though we are only reading this time: 359 + * we'll write to it eventually.. 360 + * 361 + * Use "unsigned long" accesses to let user-mode fd_set's be long-aligned. 362 + */ 363 + static inline 364 + int get_fd_set(unsigned long nr, void __user *ufdset, unsigned long *fdset) 365 + { 366 + nr = FDS_BYTES(nr); 367 + if (ufdset) 368 + return copy_from_user(fdset, ufdset, nr) ? -EFAULT : 0; 369 + 370 + memset(fdset, 0, nr); 371 + return 0; 372 + } 373 + 374 + static inline unsigned long __must_check 375 + set_fd_set(unsigned long nr, void __user *ufdset, unsigned long *fdset) 376 + { 377 + if (ufdset) 378 + return __copy_to_user(ufdset, fdset, FDS_BYTES(nr)); 379 + return 0; 380 + } 381 + 382 + static inline 383 + void zero_fd_set(unsigned long nr, unsigned long *fdset) 384 + { 385 + memset(fdset, 0, FDS_BYTES(nr)); 386 + } 387 + 341 388 #define FDS_IN(fds, n) (fds->in + n) 342 389 #define FDS_OUT(fds, n) (fds->out + n) 343 390 #define FDS_EX(fds, n) (fds->ex + n) ··· 448 401 wait->_key |= POLLOUT_SET; 449 402 } 450 403 451 - int do_select(int n, fd_set_bits *fds, struct timespec64 *end_time) 404 + static int do_select(int n, fd_set_bits *fds, struct timespec64 *end_time) 452 405 { 453 406 ktime_t expire, *to = NULL; 454 407 struct poll_wqueues table; ··· 928 881 #define N_STACK_PPS ((sizeof(stack_pps) - sizeof(struct poll_list)) / \ 929 882 sizeof(struct pollfd)) 930 883 931 - int do_sys_poll(struct pollfd __user *ufds, unsigned int nfds, 884 + static int do_sys_poll(struct pollfd __user *ufds, unsigned int nfds, 932 885 struct timespec64 *end_time) 933 886 { 934 887 struct poll_wqueues table; ··· 1100 1053 1101 1054 return ret; 1102 1055 } 1056 + 1057 + #ifdef CONFIG_COMPAT 1058 + #define __COMPAT_NFDBITS (8 * sizeof(compat_ulong_t)) 1059 + 1060 + static 1061 + int compat_poll_select_copy_remaining(struct timespec *end_time, void __user *p, 1062 + int timeval, int ret) 1063 + { 1064 + struct timespec ts; 1065 + 1066 + if (!p) 1067 + return ret; 1068 + 1069 + if (current->personality & STICKY_TIMEOUTS) 1070 + goto sticky; 1071 + 1072 + /* No update for zero timeout */ 1073 + if (!end_time->tv_sec && !end_time->tv_nsec) 1074 + return ret; 1075 + 1076 + ktime_get_ts(&ts); 1077 + ts = timespec_sub(*end_time, ts); 1078 + if (ts.tv_sec < 0) 1079 + ts.tv_sec = ts.tv_nsec = 0; 1080 + 1081 + if (timeval) { 1082 + struct compat_timeval rtv; 1083 + 1084 + rtv.tv_sec = ts.tv_sec; 1085 + rtv.tv_usec = ts.tv_nsec / NSEC_PER_USEC; 1086 + 1087 + if (!copy_to_user(p, &rtv, sizeof(rtv))) 1088 + return ret; 1089 + } else { 1090 + struct compat_timespec rts; 1091 + 1092 + rts.tv_sec = ts.tv_sec; 1093 + rts.tv_nsec = ts.tv_nsec; 1094 + 1095 + if (!copy_to_user(p, &rts, sizeof(rts))) 1096 + return ret; 1097 + } 1098 + /* 1099 + * If an application puts its timeval in read-only memory, we 1100 + * don't want the Linux-specific update to the timeval to 1101 + * cause a fault after the select has completed 1102 + * successfully. However, because we're not updating the 1103 + * timeval, we can't restart the system call. 1104 + */ 1105 + 1106 + sticky: 1107 + if (ret == -ERESTARTNOHAND) 1108 + ret = -EINTR; 1109 + return ret; 1110 + } 1111 + 1112 + /* 1113 + * Ooo, nasty. We need here to frob 32-bit unsigned longs to 1114 + * 64-bit unsigned longs. 1115 + */ 1116 + static 1117 + int compat_get_fd_set(unsigned long nr, compat_ulong_t __user *ufdset, 1118 + unsigned long *fdset) 1119 + { 1120 + nr = DIV_ROUND_UP(nr, __COMPAT_NFDBITS); 1121 + if (ufdset) { 1122 + unsigned long odd; 1123 + 1124 + if (!access_ok(VERIFY_WRITE, ufdset, nr*sizeof(compat_ulong_t))) 1125 + return -EFAULT; 1126 + 1127 + odd = nr & 1UL; 1128 + nr &= ~1UL; 1129 + while (nr) { 1130 + unsigned long h, l; 1131 + if (__get_user(l, ufdset) || __get_user(h, ufdset+1)) 1132 + return -EFAULT; 1133 + ufdset += 2; 1134 + *fdset++ = h << 32 | l; 1135 + nr -= 2; 1136 + } 1137 + if (odd && __get_user(*fdset, ufdset)) 1138 + return -EFAULT; 1139 + } else { 1140 + /* Tricky, must clear full unsigned long in the 1141 + * kernel fdset at the end, this makes sure that 1142 + * actually happens. 1143 + */ 1144 + memset(fdset, 0, ((nr + 1) & ~1)*sizeof(compat_ulong_t)); 1145 + } 1146 + return 0; 1147 + } 1148 + 1149 + static 1150 + int compat_set_fd_set(unsigned long nr, compat_ulong_t __user *ufdset, 1151 + unsigned long *fdset) 1152 + { 1153 + unsigned long odd; 1154 + nr = DIV_ROUND_UP(nr, __COMPAT_NFDBITS); 1155 + 1156 + if (!ufdset) 1157 + return 0; 1158 + 1159 + odd = nr & 1UL; 1160 + nr &= ~1UL; 1161 + while (nr) { 1162 + unsigned long h, l; 1163 + l = *fdset++; 1164 + h = l >> 32; 1165 + if (__put_user(l, ufdset) || __put_user(h, ufdset+1)) 1166 + return -EFAULT; 1167 + ufdset += 2; 1168 + nr -= 2; 1169 + } 1170 + if (odd && __put_user(*fdset, ufdset)) 1171 + return -EFAULT; 1172 + return 0; 1173 + } 1174 + 1175 + 1176 + /* 1177 + * This is a virtual copy of sys_select from fs/select.c and probably 1178 + * should be compared to it from time to time 1179 + */ 1180 + 1181 + /* 1182 + * We can actually return ERESTARTSYS instead of EINTR, but I'd 1183 + * like to be certain this leads to no problems. So I return 1184 + * EINTR just for safety. 1185 + * 1186 + * Update: ERESTARTSYS breaks at least the xview clock binary, so 1187 + * I'm trying ERESTARTNOHAND which restart only when you want to. 1188 + */ 1189 + static int compat_core_sys_select(int n, compat_ulong_t __user *inp, 1190 + compat_ulong_t __user *outp, compat_ulong_t __user *exp, 1191 + struct timespec *end_time) 1192 + { 1193 + fd_set_bits fds; 1194 + void *bits; 1195 + int size, max_fds, ret = -EINVAL; 1196 + struct fdtable *fdt; 1197 + long stack_fds[SELECT_STACK_ALLOC/sizeof(long)]; 1198 + 1199 + if (n < 0) 1200 + goto out_nofds; 1201 + 1202 + /* max_fds can increase, so grab it once to avoid race */ 1203 + rcu_read_lock(); 1204 + fdt = files_fdtable(current->files); 1205 + max_fds = fdt->max_fds; 1206 + rcu_read_unlock(); 1207 + if (n > max_fds) 1208 + n = max_fds; 1209 + 1210 + /* 1211 + * We need 6 bitmaps (in/out/ex for both incoming and outgoing), 1212 + * since we used fdset we need to allocate memory in units of 1213 + * long-words. 1214 + */ 1215 + size = FDS_BYTES(n); 1216 + bits = stack_fds; 1217 + if (size > sizeof(stack_fds) / 6) { 1218 + bits = kmalloc(6 * size, GFP_KERNEL); 1219 + ret = -ENOMEM; 1220 + if (!bits) 1221 + goto out_nofds; 1222 + } 1223 + fds.in = (unsigned long *) bits; 1224 + fds.out = (unsigned long *) (bits + size); 1225 + fds.ex = (unsigned long *) (bits + 2*size); 1226 + fds.res_in = (unsigned long *) (bits + 3*size); 1227 + fds.res_out = (unsigned long *) (bits + 4*size); 1228 + fds.res_ex = (unsigned long *) (bits + 5*size); 1229 + 1230 + if ((ret = compat_get_fd_set(n, inp, fds.in)) || 1231 + (ret = compat_get_fd_set(n, outp, fds.out)) || 1232 + (ret = compat_get_fd_set(n, exp, fds.ex))) 1233 + goto out; 1234 + zero_fd_set(n, fds.res_in); 1235 + zero_fd_set(n, fds.res_out); 1236 + zero_fd_set(n, fds.res_ex); 1237 + 1238 + ret = do_select(n, &fds, end_time); 1239 + 1240 + if (ret < 0) 1241 + goto out; 1242 + if (!ret) { 1243 + ret = -ERESTARTNOHAND; 1244 + if (signal_pending(current)) 1245 + goto out; 1246 + ret = 0; 1247 + } 1248 + 1249 + if (compat_set_fd_set(n, inp, fds.res_in) || 1250 + compat_set_fd_set(n, outp, fds.res_out) || 1251 + compat_set_fd_set(n, exp, fds.res_ex)) 1252 + ret = -EFAULT; 1253 + out: 1254 + if (bits != stack_fds) 1255 + kfree(bits); 1256 + out_nofds: 1257 + return ret; 1258 + } 1259 + 1260 + COMPAT_SYSCALL_DEFINE5(select, int, n, compat_ulong_t __user *, inp, 1261 + compat_ulong_t __user *, outp, compat_ulong_t __user *, exp, 1262 + struct compat_timeval __user *, tvp) 1263 + { 1264 + struct timespec end_time, *to = NULL; 1265 + struct compat_timeval tv; 1266 + int ret; 1267 + 1268 + if (tvp) { 1269 + if (copy_from_user(&tv, tvp, sizeof(tv))) 1270 + return -EFAULT; 1271 + 1272 + to = &end_time; 1273 + if (poll_select_set_timeout(to, 1274 + tv.tv_sec + (tv.tv_usec / USEC_PER_SEC), 1275 + (tv.tv_usec % USEC_PER_SEC) * NSEC_PER_USEC)) 1276 + return -EINVAL; 1277 + } 1278 + 1279 + ret = compat_core_sys_select(n, inp, outp, exp, to); 1280 + ret = compat_poll_select_copy_remaining(&end_time, tvp, 1, ret); 1281 + 1282 + return ret; 1283 + } 1284 + 1285 + struct compat_sel_arg_struct { 1286 + compat_ulong_t n; 1287 + compat_uptr_t inp; 1288 + compat_uptr_t outp; 1289 + compat_uptr_t exp; 1290 + compat_uptr_t tvp; 1291 + }; 1292 + 1293 + COMPAT_SYSCALL_DEFINE1(old_select, struct compat_sel_arg_struct __user *, arg) 1294 + { 1295 + struct compat_sel_arg_struct a; 1296 + 1297 + if (copy_from_user(&a, arg, sizeof(a))) 1298 + return -EFAULT; 1299 + return compat_sys_select(a.n, compat_ptr(a.inp), compat_ptr(a.outp), 1300 + compat_ptr(a.exp), compat_ptr(a.tvp)); 1301 + } 1302 + 1303 + static long do_compat_pselect(int n, compat_ulong_t __user *inp, 1304 + compat_ulong_t __user *outp, compat_ulong_t __user *exp, 1305 + struct compat_timespec __user *tsp, compat_sigset_t __user *sigmask, 1306 + compat_size_t sigsetsize) 1307 + { 1308 + compat_sigset_t ss32; 1309 + sigset_t ksigmask, sigsaved; 1310 + struct compat_timespec ts; 1311 + struct timespec end_time, *to = NULL; 1312 + int ret; 1313 + 1314 + if (tsp) { 1315 + if (copy_from_user(&ts, tsp, sizeof(ts))) 1316 + return -EFAULT; 1317 + 1318 + to = &end_time; 1319 + if (poll_select_set_timeout(to, ts.tv_sec, ts.tv_nsec)) 1320 + return -EINVAL; 1321 + } 1322 + 1323 + if (sigmask) { 1324 + if (sigsetsize != sizeof(compat_sigset_t)) 1325 + return -EINVAL; 1326 + if (copy_from_user(&ss32, sigmask, sizeof(ss32))) 1327 + return -EFAULT; 1328 + sigset_from_compat(&ksigmask, &ss32); 1329 + 1330 + sigdelsetmask(&ksigmask, sigmask(SIGKILL)|sigmask(SIGSTOP)); 1331 + sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved); 1332 + } 1333 + 1334 + ret = compat_core_sys_select(n, inp, outp, exp, to); 1335 + ret = compat_poll_select_copy_remaining(&end_time, tsp, 0, ret); 1336 + 1337 + if (ret == -ERESTARTNOHAND) { 1338 + /* 1339 + * Don't restore the signal mask yet. Let do_signal() deliver 1340 + * the signal on the way back to userspace, before the signal 1341 + * mask is restored. 1342 + */ 1343 + if (sigmask) { 1344 + memcpy(&current->saved_sigmask, &sigsaved, 1345 + sizeof(sigsaved)); 1346 + set_restore_sigmask(); 1347 + } 1348 + } else if (sigmask) 1349 + sigprocmask(SIG_SETMASK, &sigsaved, NULL); 1350 + 1351 + return ret; 1352 + } 1353 + 1354 + COMPAT_SYSCALL_DEFINE6(pselect6, int, n, compat_ulong_t __user *, inp, 1355 + compat_ulong_t __user *, outp, compat_ulong_t __user *, exp, 1356 + struct compat_timespec __user *, tsp, void __user *, sig) 1357 + { 1358 + compat_size_t sigsetsize = 0; 1359 + compat_uptr_t up = 0; 1360 + 1361 + if (sig) { 1362 + if (!access_ok(VERIFY_READ, sig, 1363 + sizeof(compat_uptr_t)+sizeof(compat_size_t)) || 1364 + __get_user(up, (compat_uptr_t __user *)sig) || 1365 + __get_user(sigsetsize, 1366 + (compat_size_t __user *)(sig+sizeof(up)))) 1367 + return -EFAULT; 1368 + } 1369 + return do_compat_pselect(n, inp, outp, exp, tsp, compat_ptr(up), 1370 + sigsetsize); 1371 + } 1372 + 1373 + COMPAT_SYSCALL_DEFINE5(ppoll, struct pollfd __user *, ufds, 1374 + unsigned int, nfds, struct compat_timespec __user *, tsp, 1375 + const compat_sigset_t __user *, sigmask, compat_size_t, sigsetsize) 1376 + { 1377 + compat_sigset_t ss32; 1378 + sigset_t ksigmask, sigsaved; 1379 + struct compat_timespec ts; 1380 + struct timespec end_time, *to = NULL; 1381 + int ret; 1382 + 1383 + if (tsp) { 1384 + if (copy_from_user(&ts, tsp, sizeof(ts))) 1385 + return -EFAULT; 1386 + 1387 + to = &end_time; 1388 + if (poll_select_set_timeout(to, ts.tv_sec, ts.tv_nsec)) 1389 + return -EINVAL; 1390 + } 1391 + 1392 + if (sigmask) { 1393 + if (sigsetsize != sizeof(compat_sigset_t)) 1394 + return -EINVAL; 1395 + if (copy_from_user(&ss32, sigmask, sizeof(ss32))) 1396 + return -EFAULT; 1397 + sigset_from_compat(&ksigmask, &ss32); 1398 + 1399 + sigdelsetmask(&ksigmask, sigmask(SIGKILL)|sigmask(SIGSTOP)); 1400 + sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved); 1401 + } 1402 + 1403 + 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; 1424 + } 1425 + #endif
-56
include/linux/poll.h
··· 98 98 ktime_t *expires, unsigned long slack); 99 99 extern u64 select_estimate_accuracy(struct timespec64 *tv); 100 100 101 - 102 - static inline int poll_schedule(struct poll_wqueues *pwq, int state) 103 - { 104 - return poll_schedule_timeout(pwq, state, NULL, 0); 105 - } 106 - 107 - /* 108 - * Scalable version of the fd_set. 109 - */ 110 - 111 - typedef struct { 112 - unsigned long *in, *out, *ex; 113 - unsigned long *res_in, *res_out, *res_ex; 114 - } fd_set_bits; 115 - 116 - /* 117 - * How many longwords for "nr" bits? 118 - */ 119 - #define FDS_BITPERLONG (8*sizeof(long)) 120 - #define FDS_LONGS(nr) (((nr)+FDS_BITPERLONG-1)/FDS_BITPERLONG) 121 - #define FDS_BYTES(nr) (FDS_LONGS(nr)*sizeof(long)) 122 - 123 - /* 124 - * We do a VERIFY_WRITE here even though we are only reading this time: 125 - * we'll write to it eventually.. 126 - * 127 - * Use "unsigned long" accesses to let user-mode fd_set's be long-aligned. 128 - */ 129 - static inline 130 - int get_fd_set(unsigned long nr, void __user *ufdset, unsigned long *fdset) 131 - { 132 - nr = FDS_BYTES(nr); 133 - if (ufdset) 134 - return copy_from_user(fdset, ufdset, nr) ? -EFAULT : 0; 135 - 136 - memset(fdset, 0, nr); 137 - return 0; 138 - } 139 - 140 - static inline unsigned long __must_check 141 - set_fd_set(unsigned long nr, void __user *ufdset, unsigned long *fdset) 142 - { 143 - if (ufdset) 144 - return __copy_to_user(ufdset, fdset, FDS_BYTES(nr)); 145 - return 0; 146 - } 147 - 148 - static inline 149 - void zero_fd_set(unsigned long nr, unsigned long *fdset) 150 - { 151 - memset(fdset, 0, FDS_BYTES(nr)); 152 - } 153 - 154 101 #define MAX_INT64_SECONDS (((s64)(~((u64)0)>>1)/HZ)-1) 155 102 156 - extern int do_select(int n, fd_set_bits *fds, struct timespec64 *end_time); 157 - extern int do_sys_poll(struct pollfd __user * ufds, unsigned int nfds, 158 - struct timespec64 *end_time); 159 103 extern int core_sys_select(int n, fd_set __user *inp, fd_set __user *outp, 160 104 fd_set __user *exp, struct timespec64 *end_time); 161 105