This is the minimal fix for stable, I'll send cleanups later. Commit 854a6ed56839 ("signal: Add restore_user_sigmask()") introduced the visible change which breaks user-space: a signal temporary unblocked by set_user_sigmask() can be delivered even if the caller returns success or timeout. Change restore_user_sigmask() to accept the additional "interrupted" argument which should be used instead of signal_pending() check, and update the callers. Eric said: : For clarity. I don't think this is required by posix, or fundamentally to : remove the races in select. It is what linux has always done and we have : applications who care so I agree this fix is needed. : : Further in any case where the semantic change that this patch rolls back : (aka where allowing a signal to be delivered and the select like call to : complete) would be advantage we can do as well if not better by using : signalfd. : : Michael is there any chance we can get this guarantee of the linux : implementation of pselect and friends clearly documented. The guarantee : that if the system call completes successfully we are guaranteed that no : signal that is unblocked by using sigmask will be delivered?
Unified · Split
| @@ -2095,6 +2095,7 @@ SYSCALL_DEFINE6(io_pgetevents, · 2094 unmodified lines | |||
| 2095 | struct __aio_sigset ksig = { NULL, }; | 2095 | struct __aio_sigset ksig = { NULL, }; |
| 2096 | sigset_t ksigmask, sigsaved; | 2096 | sigset_t ksigmask, sigsaved; |
| 2097 | struct timespec64 ts; | 2097 | struct timespec64 ts; |
| 2098 | bool interrupted; | ||
| 2098 | int ret; | 2099 | int ret; |
| 2099 | 2100 | ||
| 2100 | if (timeout && unlikely(get_timespec64(&ts, timeout))) | 2101 | if (timeout && unlikely(get_timespec64(&ts, timeout))) |
| @@ -2108,8 +2109,10 @@ SYSCALL_DEFINE6(io_pgetevents, · 7 unmodified lines | |||
| 2108 | return ret; | 2109 | return ret; |
| 2109 | 2110 | ||
| 2110 | ret = do_io_getevents(ctx_id, min_nr, nr, events, timeout ? &ts : NULL); | 2111 | ret = do_io_getevents(ctx_id, min_nr, nr, events, timeout ? &ts : NULL); |
| 2111 | restore_user_sigmask(ksig.sigmask, &sigsaved); | 2112 | |
| 2112 | if (signal_pending(current) && !ret) | 2113 | interrupted = signal_pending(current); |
| 2114 | restore_user_sigmask(ksig.sigmask, &sigsaved, interrupted); | ||
| 2115 | if (interrupted && !ret) | ||
| 2113 | ret = -ERESTARTNOHAND; | 2116 | ret = -ERESTARTNOHAND; |
| 2114 | 2117 | ||
| 2115 | return ret; | 2118 | return ret; |
| @@ -2128,6 +2131,7 @@ SYSCALL_DEFINE6(io_pgetevents_time32, · 12 unmodified lines | |||
| 2128 | struct __aio_sigset ksig = { NULL, }; | 2131 | struct __aio_sigset ksig = { NULL, }; |
| 2129 | sigset_t ksigmask, sigsaved; | 2132 | sigset_t ksigmask, sigsaved; |
| 2130 | struct timespec64 ts; | 2133 | struct timespec64 ts; |
| 2134 | bool interrupted; | ||
| 2131 | int ret; | 2135 | int ret; |
| 2132 | 2136 | ||
| 2133 | if (timeout && unlikely(get_old_timespec32(&ts, timeout))) | 2137 | if (timeout && unlikely(get_old_timespec32(&ts, timeout))) |
| @@ -2142,8 +2146,10 @@ SYSCALL_DEFINE6(io_pgetevents_time32, · 8 unmodified lines | |||
| 2142 | return ret; | 2146 | return ret; |
| 2143 | 2147 | ||
| 2144 | ret = do_io_getevents(ctx_id, min_nr, nr, events, timeout ? &ts : NULL); | 2148 | ret = do_io_getevents(ctx_id, min_nr, nr, events, timeout ? &ts : NULL); |
| 2145 | restore_user_sigmask(ksig.sigmask, &sigsaved); | 2149 | |
| 2146 | if (signal_pending(current) && !ret) | 2150 | interrupted = signal_pending(current); |
| 2151 | restore_user_sigmask(ksig.sigmask, &sigsaved, interrupted); | ||
| 2152 | if (interrupted && !ret) | ||
| 2147 | ret = -ERESTARTNOHAND; | 2153 | ret = -ERESTARTNOHAND; |
| 2148 | 2154 | ||
| 2149 | return ret; | 2155 | return ret; |
| @@ -2193,6 +2199,7 @@ COMPAT_SYSCALL_DEFINE6(io_pgetevents, · 43 unmodified lines | |||
| 2193 | struct __compat_aio_sigset ksig = { NULL, }; | 2199 | struct __compat_aio_sigset ksig = { NULL, }; |
| 2194 | sigset_t ksigmask, sigsaved; | 2200 | sigset_t ksigmask, sigsaved; |
| 2195 | struct timespec64 t; | 2201 | struct timespec64 t; |
| 2202 | bool interrupted; | ||
| 2196 | int ret; | 2203 | int ret; |
| 2197 | 2204 | ||
| 2198 | if (timeout && get_old_timespec32(&t, timeout)) | 2205 | if (timeout && get_old_timespec32(&t, timeout)) |
| @@ -2206,8 +2213,10 @@ COMPAT_SYSCALL_DEFINE6(io_pgetevents, · 7 unmodified lines | |||
| 2206 | return ret; | 2213 | return ret; |
| 2207 | 2214 | ||
| 2208 | ret = do_io_getevents(ctx_id, min_nr, nr, events, timeout ? &t : NULL); | 2215 | ret = do_io_getevents(ctx_id, min_nr, nr, events, timeout ? &t : NULL); |
| 2209 | restore_user_sigmask(ksig.sigmask, &sigsaved); | 2216 | |
| 2210 | if (signal_pending(current) && !ret) | 2217 | interrupted = signal_pending(current); |
| 2218 | restore_user_sigmask(ksig.sigmask, &sigsaved, interrupted); | ||
| 2219 | if (interrupted && !ret) | ||
| 2211 | ret = -ERESTARTNOHAND; | 2220 | ret = -ERESTARTNOHAND; |
| 2212 | 2221 | ||
| 2213 | return ret; | 2222 | return ret; |
| @@ -2226,6 +2235,7 @@ COMPAT_SYSCALL_DEFINE6(io_pgetevents_time64, · 12 unmodified lines | |||
| 2226 | struct __compat_aio_sigset ksig = { NULL, }; | 2235 | struct __compat_aio_sigset ksig = { NULL, }; |
| 2227 | sigset_t ksigmask, sigsaved; | 2236 | sigset_t ksigmask, sigsaved; |
| 2228 | struct timespec64 t; | 2237 | struct timespec64 t; |
| 2238 | bool interrupted; | ||
| 2229 | int ret; | 2239 | int ret; |
| 2230 | 2240 | ||
| 2231 | if (timeout && get_timespec64(&t, timeout)) | 2241 | if (timeout && get_timespec64(&t, timeout)) |
| @@ -2239,8 +2249,10 @@ COMPAT_SYSCALL_DEFINE6(io_pgetevents_time64, · 7 unmodified lines | |||
| 2239 | return ret; | 2249 | return ret; |
| 2240 | 2250 | ||
| 2241 | ret = do_io_getevents(ctx_id, min_nr, nr, events, timeout ? &t : NULL); | 2251 | ret = do_io_getevents(ctx_id, min_nr, nr, events, timeout ? &t : NULL); |
| 2242 | restore_user_sigmask(ksig.sigmask, &sigsaved); | 2252 | |
| 2243 | if (signal_pending(current) && !ret) | 2253 | interrupted = signal_pending(current); |
| 2254 | restore_user_sigmask(ksig.sigmask, &sigsaved, interrupted); | ||
| 2255 | if (interrupted && !ret) | ||
| 2244 | ret = -ERESTARTNOHAND; | 2256 | ret = -ERESTARTNOHAND; |
| 2245 | 2257 | ||
| 2246 | return ret; | 2258 | return ret; |
| @@ -2325,7 +2325,7 @@ SYSCALL_DEFINE6(epoll_pwait, int, epfd, struct epoll_event __user *, events, · 2324 unmodified lines | |||
| 2325 | 2325 | ||
| 2326 | error = do_epoll_wait(epfd, events, maxevents, timeout); | 2326 | error = do_epoll_wait(epfd, events, maxevents, timeout); |
| 2327 | 2327 | ||
| 2328 | restore_user_sigmask(sigmask, &sigsaved); | 2328 | restore_user_sigmask(sigmask, &sigsaved, error == -EINTR); |
| 2329 | 2329 | ||
| 2330 | return error; | 2330 | return error; |
| 2331 | } | 2331 | } |
| @@ -2350,7 +2350,7 @@ COMPAT_SYSCALL_DEFINE6(epoll_pwait, int, epfd, · 18 unmodified lines | |||
| 2350 | 2350 | ||
| 2351 | err = do_epoll_wait(epfd, events, maxevents, timeout); | 2351 | err = do_epoll_wait(epfd, events, maxevents, timeout); |
| 2352 | 2352 | ||
| 2353 | restore_user_sigmask(sigmask, &sigsaved); | 2353 | restore_user_sigmask(sigmask, &sigsaved, err == -EINTR); |
| 2354 | 2354 | ||
| 2355 | return err; | 2355 | return err; |
| 2356 | } | 2356 | } |
| @@ -2201,11 +2201,12 @@ static int io_cqring_wait(struct io_ring_ctx *ctx, int min_events, · 2200 unmodified lines | |||
| 2201 | } | 2201 | } |
| 2202 | 2202 | ||
| 2203 | ret = wait_event_interruptible(ctx->wait, io_cqring_events(ring) >= min_events); | 2203 | ret = wait_event_interruptible(ctx->wait, io_cqring_events(ring) >= min_events); |
| 2204 | if (ret == -ERESTARTSYS) | ||
| 2205 | ret = -EINTR; | ||
| 2206 | 2204 | ||
| 2207 | if (sig) | 2205 | if (sig) |
| 2208 | restore_user_sigmask(sig, &sigsaved); | 2206 | restore_user_sigmask(sig, &sigsaved, ret == -ERESTARTSYS); |
| 2207 | |||
| 2208 | if (ret == -ERESTARTSYS) | ||
| 2209 | ret = -EINTR; | ||
| 2209 | 2210 | ||
| 2210 | return READ_ONCE(ring->r.head) == READ_ONCE(ring->r.tail) ? ret : 0; | 2211 | return READ_ONCE(ring->r.head) == READ_ONCE(ring->r.tail) ? ret : 0; |
| 2211 | } | 2212 | } |
| @@ -758,10 +758,9 @@ static long do_pselect(int n, fd_set __user *inp, fd_set __user *outp, · 757 unmodified lines | |||
| 758 | return ret; | 758 | return ret; |
| 759 | 759 | ||
| 760 | ret = core_sys_select(n, inp, outp, exp, to); | 760 | ret = core_sys_select(n, inp, outp, exp, to); |
| 761 | restore_user_sigmask(sigmask, &sigsaved, ret == -ERESTARTNOHAND); | ||
| 761 | ret = poll_select_copy_remaining(&end_time, tsp, type, ret); | 762 | ret = poll_select_copy_remaining(&end_time, tsp, type, ret); |
| 762 | 763 | ||
| 763 | restore_user_sigmask(sigmask, &sigsaved); | ||
| 764 | |||
| 765 | return ret; | 764 | return ret; |
| 766 | } | 765 | } |
| 767 | 766 | ||
| @@ -1106,8 +1105,7 @@ SYSCALL_DEFINE5(ppoll, struct pollfd __user *, ufds, unsigned int, nfds, · 338 unmodified lines | |||
| 1106 | 1105 | ||
| 1107 | ret = do_sys_poll(ufds, nfds, to); | 1106 | ret = do_sys_poll(ufds, nfds, to); |
| 1108 | 1107 | ||
| 1109 | restore_user_sigmask(sigmask, &sigsaved); | 1108 | restore_user_sigmask(sigmask, &sigsaved, ret == -EINTR); |
| 1110 | |||
| 1111 | /* We can restart this syscall, usually */ | 1109 | /* We can restart this syscall, usually */ |
| 1112 | if (ret == -EINTR) | 1110 | if (ret == -EINTR) |
| 1113 | ret = -ERESTARTNOHAND; | 1111 | ret = -ERESTARTNOHAND; |
| @@ -1142,8 +1140,7 @@ SYSCALL_DEFINE5(ppoll_time32, struct pollfd __user *, ufds, unsigned int, nfds, · 28 unmodified lines | |||
| 1142 | 1140 | ||
| 1143 | ret = do_sys_poll(ufds, nfds, to); | 1141 | ret = do_sys_poll(ufds, nfds, to); |
| 1144 | 1142 | ||
| 1145 | restore_user_sigmask(sigmask, &sigsaved); | 1143 | restore_user_sigmask(sigmask, &sigsaved, ret == -EINTR); |
| 1146 | |||
| 1147 | /* We can restart this syscall, usually */ | 1144 | /* We can restart this syscall, usually */ |
| 1148 | if (ret == -EINTR) | 1145 | if (ret == -EINTR) |
| 1149 | ret = -ERESTARTNOHAND; | 1146 | ret = -ERESTARTNOHAND; |
| @@ -1350,10 +1347,9 @@ static long do_compat_pselect(int n, compat_ulong_t __user *inp, · 200 unmodified lines | |||
| 1350 | return ret; | 1347 | return ret; |
| 1351 | 1348 | ||
| 1352 | ret = compat_core_sys_select(n, inp, outp, exp, to); | 1349 | ret = compat_core_sys_select(n, inp, outp, exp, to); |
| 1350 | restore_user_sigmask(sigmask, &sigsaved, ret == -ERESTARTNOHAND); | ||
| 1353 | ret = poll_select_copy_remaining(&end_time, tsp, type, ret); | 1351 | ret = poll_select_copy_remaining(&end_time, tsp, type, ret); |
| 1354 | 1352 | ||
| 1355 | restore_user_sigmask(sigmask, &sigsaved); | ||
| 1356 | |||
| 1357 | return ret; | 1353 | return ret; |
| 1358 | } | 1354 | } |
| 1359 | 1355 | ||
| @@ -1425,8 +1421,7 @@ COMPAT_SYSCALL_DEFINE5(ppoll_time32, struct pollfd __user *, ufds, · 65 unmodified lines | |||
| 1425 | 1421 | ||
| 1426 | ret = do_sys_poll(ufds, nfds, to); | 1422 | ret = do_sys_poll(ufds, nfds, to); |
| 1427 | 1423 | ||
| 1428 | restore_user_sigmask(sigmask, &sigsaved); | 1424 | restore_user_sigmask(sigmask, &sigsaved, ret == -EINTR); |
| 1429 | |||
| 1430 | /* We can restart this syscall, usually */ | 1425 | /* We can restart this syscall, usually */ |
| 1431 | if (ret == -EINTR) | 1426 | if (ret == -EINTR) |
| 1432 | ret = -ERESTARTNOHAND; | 1427 | ret = -ERESTARTNOHAND; |
| @@ -1461,8 +1456,7 @@ COMPAT_SYSCALL_DEFINE5(ppoll_time64, struct pollfd __user *, ufds, · 28 unmodified lines | |||
| 1461 | 1456 | ||
| 1462 | ret = do_sys_poll(ufds, nfds, to); | 1457 | ret = do_sys_poll(ufds, nfds, to); |
| 1463 | 1458 | ||
| 1464 | restore_user_sigmask(sigmask, &sigsaved); | 1459 | restore_user_sigmask(sigmask, &sigsaved, ret == -EINTR); |
| 1465 | |||
| 1466 | /* We can restart this syscall, usually */ | 1460 | /* We can restart this syscall, usually */ |
| 1467 | if (ret == -EINTR) | 1461 | if (ret == -EINTR) |
| 1468 | ret = -ERESTARTNOHAND; | 1462 | ret = -ERESTARTNOHAND; |
| @@ -276,7 +276,7 @@ extern int sigprocmask(int, sigset_t *, sigset_t *); · 275 unmodified lines | |||
| 276 | extern int set_user_sigmask(const sigset_t __user *usigmask, sigset_t *set, | 276 | extern int set_user_sigmask(const sigset_t __user *usigmask, sigset_t *set, |
| 277 | sigset_t *oldset, size_t sigsetsize); | 277 | sigset_t *oldset, size_t sigsetsize); |
| 278 | extern void restore_user_sigmask(const void __user *usigmask, | 278 | extern void restore_user_sigmask(const void __user *usigmask, |
| 279 | sigset_t *sigsaved); | 279 | sigset_t *sigsaved, bool interrupted); |
| 280 | extern void set_current_blocked(sigset_t *); | 280 | extern void set_current_blocked(sigset_t *); |
| 281 | extern void __set_current_blocked(const sigset_t *); | 281 | extern void __set_current_blocked(const sigset_t *); |
| 282 | extern int show_unhandled_signals; | 282 | extern int show_unhandled_signals; |
| @@ -2912,7 +2912,8 @@ EXPORT_SYMBOL(set_compat_user_sigmask); · 2911 unmodified lines | |||
| 2912 | * This is useful for syscalls such as ppoll, pselect, io_pgetevents and | 2912 | * This is useful for syscalls such as ppoll, pselect, io_pgetevents and |
| 2913 | * epoll_pwait where a new sigmask is passed in from userland for the syscalls. | 2913 | * epoll_pwait where a new sigmask is passed in from userland for the syscalls. |
| 2914 | */ | 2914 | */ |
| 2915 | void restore_user_sigmask(const void __user *usigmask, sigset_t *sigsaved) | 2915 | void restore_user_sigmask(const void __user *usigmask, sigset_t *sigsaved, |
| 2916 | bool interrupted) | ||
| 2916 | { | 2917 | { |
| 2917 | 2918 | ||
| 2918 | if (!usigmask) | 2919 | if (!usigmask) |
| @@ -2922,7 +2923,7 @@ void restore_user_sigmask(const void __user *usigmask, sigset_t *sigsaved) · 3 unmodified lines | |||
| 2922 | * Restoring sigmask here can lead to delivering signals that the above | 2923 | * Restoring sigmask here can lead to delivering signals that the above |
| 2923 | * syscalls are intended to block because of the sigmask passed in. | 2924 | * syscalls are intended to block because of the sigmask passed in. |
| 2924 | */ | 2925 | */ |
| 2925 | if (signal_pending(current)) { | 2926 | if (interrupted) { |
| 2926 | current->saved_sigmask = *sigsaved; | 2927 | current->saved_sigmask = *sigsaved; |
| 2927 | set_restore_sigmask(); | 2928 | set_restore_sigmask(); |
| 2928 | return; | 2929 | return; |