History

signal: remove the wrong signal_pending() check in restore_user_sigmask()

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?

Oleg Nesterov committed 7 years ago

Commit 97abc881 parent 867bfa46 files · +36 −28Browse files

Unified · Split

6 files
  1. fs/aio.c +20 −8
  2. fs/eventpoll.c +2 −2
  3. fs/io_uring.c +4 −3
  4. fs/select.c +6 −12
  5. include/linux/signal.h +1 −1
  6. kernel/signal.c +3 −2
fs/aio.c+20−8
@@ -2095,6 +2095,7 @@ SYSCALL_DEFINE6(io_pgetevents, · 2094 unmodified lines
20952095 struct __aio_sigset ksig = { NULL, };
20962096 sigset_t ksigmask, sigsaved;
20972097 struct timespec64 ts;
2098+ bool interrupted;
20982099 int ret;
20992100
21002101 if (timeout && unlikely(get_timespec64(&ts, timeout)))
@@ -2108,8 +2109,10 @@ SYSCALL_DEFINE6(io_pgetevents, · 7 unmodified lines
21082109 return ret;
21092110
21102111 ret = do_io_getevents(ctx_id, min_nr, nr, events, timeout ? &ts : NULL);
2111− restore_user_sigmask(ksig.sigmask, &sigsaved);
2112− if (signal_pending(current) && !ret)
2112+
2113+ interrupted = signal_pending(current);
2114+ restore_user_sigmask(ksig.sigmask, &sigsaved, interrupted);
2115+ if (interrupted && !ret)
21132116 ret = -ERESTARTNOHAND;
21142117
21152118 return ret;
@@ -2128,6 +2131,7 @@ SYSCALL_DEFINE6(io_pgetevents_time32, · 12 unmodified lines
21282131 struct __aio_sigset ksig = { NULL, };
21292132 sigset_t ksigmask, sigsaved;
21302133 struct timespec64 ts;
2134+ bool interrupted;
21312135 int ret;
21322136
21332137 if (timeout && unlikely(get_old_timespec32(&ts, timeout)))
@@ -2142,8 +2146,10 @@ SYSCALL_DEFINE6(io_pgetevents_time32, · 8 unmodified lines
21422146 return ret;
21432147
21442148 ret = do_io_getevents(ctx_id, min_nr, nr, events, timeout ? &ts : NULL);
2145− restore_user_sigmask(ksig.sigmask, &sigsaved);
2146− if (signal_pending(current) && !ret)
2149+
2150+ interrupted = signal_pending(current);
2151+ restore_user_sigmask(ksig.sigmask, &sigsaved, interrupted);
2152+ if (interrupted && !ret)
21472153 ret = -ERESTARTNOHAND;
21482154
21492155 return ret;
@@ -2193,6 +2199,7 @@ COMPAT_SYSCALL_DEFINE6(io_pgetevents, · 43 unmodified lines
21932199 struct __compat_aio_sigset ksig = { NULL, };
21942200 sigset_t ksigmask, sigsaved;
21952201 struct timespec64 t;
2202+ bool interrupted;
21962203 int ret;
21972204
21982205 if (timeout && get_old_timespec32(&t, timeout))
@@ -2206,8 +2213,10 @@ COMPAT_SYSCALL_DEFINE6(io_pgetevents, · 7 unmodified lines
22062213 return ret;
22072214
22082215 ret = do_io_getevents(ctx_id, min_nr, nr, events, timeout ? &t : NULL);
2209− restore_user_sigmask(ksig.sigmask, &sigsaved);
2210− if (signal_pending(current) && !ret)
2216+
2217+ interrupted = signal_pending(current);
2218+ restore_user_sigmask(ksig.sigmask, &sigsaved, interrupted);
2219+ if (interrupted && !ret)
22112220 ret = -ERESTARTNOHAND;
22122221
22132222 return ret;
@@ -2226,6 +2235,7 @@ COMPAT_SYSCALL_DEFINE6(io_pgetevents_time64, · 12 unmodified lines
22262235 struct __compat_aio_sigset ksig = { NULL, };
22272236 sigset_t ksigmask, sigsaved;
22282237 struct timespec64 t;
2238+ bool interrupted;
22292239 int ret;
22302240
22312241 if (timeout && get_timespec64(&t, timeout))
@@ -2239,8 +2249,10 @@ COMPAT_SYSCALL_DEFINE6(io_pgetevents_time64, · 7 unmodified lines
22392249 return ret;
22402250
22412251 ret = do_io_getevents(ctx_id, min_nr, nr, events, timeout ? &t : NULL);
2242− restore_user_sigmask(ksig.sigmask, &sigsaved);
2243− if (signal_pending(current) && !ret)
2252+
2253+ interrupted = signal_pending(current);
2254+ restore_user_sigmask(ksig.sigmask, &sigsaved, interrupted);
2255+ if (interrupted && !ret)
22442256 ret = -ERESTARTNOHAND;
22452257
22462258 return ret;
fs/eventpoll.c+2−2
@@ -2325,7 +2325,7 @@ SYSCALL_DEFINE6(epoll_pwait, int, epfd, struct epoll_event __user *, events, · 2324 unmodified lines
23252325
23262326 error = do_epoll_wait(epfd, events, maxevents, timeout);
23272327
2328− restore_user_sigmask(sigmask, &sigsaved);
2328+ restore_user_sigmask(sigmask, &sigsaved, error == -EINTR);
23292329
23302330 return error;
23312331 }
@@ -2350,7 +2350,7 @@ COMPAT_SYSCALL_DEFINE6(epoll_pwait, int, epfd, · 18 unmodified lines
23502350
23512351 err = do_epoll_wait(epfd, events, maxevents, timeout);
23522352
2353− restore_user_sigmask(sigmask, &sigsaved);
2353+ restore_user_sigmask(sigmask, &sigsaved, err == -EINTR);
23542354
23552355 return err;
23562356 }
fs/io_uring.c+4−3
@@ -2201,11 +2201,12 @@ static int io_cqring_wait(struct io_ring_ctx *ctx, int min_events, · 2200 unmodified lines
22012201 }
22022202
22032203 ret = wait_event_interruptible(ctx->wait, io_cqring_events(ring) >= min_events);
2204− if (ret == -ERESTARTSYS)
2205− ret = -EINTR;
22062204
22072205 if (sig)
2208− restore_user_sigmask(sig, &sigsaved);
2206+ restore_user_sigmask(sig, &sigsaved, ret == -ERESTARTSYS);
2207+
2208+ if (ret == -ERESTARTSYS)
2209+ ret = -EINTR;
22092210
22102211 return READ_ONCE(ring->r.head) == READ_ONCE(ring->r.tail) ? ret : 0;
22112212 }
fs/select.c+6−12
@@ -758,10 +758,9 @@ static long do_pselect(int n, fd_set __user *inp, fd_set __user *outp, · 757 unmodified lines
758758 return ret;
759759
760760 ret = core_sys_select(n, inp, outp, exp, to);
761+ restore_user_sigmask(sigmask, &sigsaved, ret == -ERESTARTNOHAND);
761762 ret = poll_select_copy_remaining(&end_time, tsp, type, ret);
762763
763− restore_user_sigmask(sigmask, &sigsaved);
764−
765764 return ret;
766765 }
767766
@@ -1106,8 +1105,7 @@ SYSCALL_DEFINE5(ppoll, struct pollfd __user *, ufds, unsigned int, nfds, · 338 unmodified lines
11061105
11071106 ret = do_sys_poll(ufds, nfds, to);
11081107
1109− restore_user_sigmask(sigmask, &sigsaved);
1110−
1108+ restore_user_sigmask(sigmask, &sigsaved, ret == -EINTR);
11111109 /* We can restart this syscall, usually */
11121110 if (ret == -EINTR)
11131111 ret = -ERESTARTNOHAND;
@@ -1142,8 +1140,7 @@ SYSCALL_DEFINE5(ppoll_time32, struct pollfd __user *, ufds, unsigned int, nfds, · 28 unmodified lines
11421140
11431141 ret = do_sys_poll(ufds, nfds, to);
11441142
1145− restore_user_sigmask(sigmask, &sigsaved);
1146−
1143+ restore_user_sigmask(sigmask, &sigsaved, ret == -EINTR);
11471144 /* We can restart this syscall, usually */
11481145 if (ret == -EINTR)
11491146 ret = -ERESTARTNOHAND;
@@ -1350,10 +1347,9 @@ static long do_compat_pselect(int n, compat_ulong_t __user *inp, · 200 unmodified lines
13501347 return ret;
13511348
13521349 ret = compat_core_sys_select(n, inp, outp, exp, to);
1350+ restore_user_sigmask(sigmask, &sigsaved, ret == -ERESTARTNOHAND);
13531351 ret = poll_select_copy_remaining(&end_time, tsp, type, ret);
13541352
1355− restore_user_sigmask(sigmask, &sigsaved);
1356−
13571353 return ret;
13581354 }
13591355
@@ -1425,8 +1421,7 @@ COMPAT_SYSCALL_DEFINE5(ppoll_time32, struct pollfd __user *, ufds, · 65 unmodified lines
14251421
14261422 ret = do_sys_poll(ufds, nfds, to);
14271423
1428− restore_user_sigmask(sigmask, &sigsaved);
1429−
1424+ restore_user_sigmask(sigmask, &sigsaved, ret == -EINTR);
14301425 /* We can restart this syscall, usually */
14311426 if (ret == -EINTR)
14321427 ret = -ERESTARTNOHAND;
@@ -1461,8 +1456,7 @@ COMPAT_SYSCALL_DEFINE5(ppoll_time64, struct pollfd __user *, ufds, · 28 unmodified lines
14611456
14621457 ret = do_sys_poll(ufds, nfds, to);
14631458
1464− restore_user_sigmask(sigmask, &sigsaved);
1465−
1459+ restore_user_sigmask(sigmask, &sigsaved, ret == -EINTR);
14661460 /* We can restart this syscall, usually */
14671461 if (ret == -EINTR)
14681462 ret = -ERESTARTNOHAND;
include/linux/signal.h+1−1
@@ -276,7 +276,7 @@ extern int sigprocmask(int, sigset_t *, sigset_t *); · 275 unmodified lines
276276 extern int set_user_sigmask(const sigset_t __user *usigmask, sigset_t *set,
277277 sigset_t *oldset, size_t sigsetsize);
278278 extern void restore_user_sigmask(const void __user *usigmask,
279− sigset_t *sigsaved);
279+ sigset_t *sigsaved, bool interrupted);
280280 extern void set_current_blocked(sigset_t *);
281281 extern void __set_current_blocked(const sigset_t *);
282282 extern int show_unhandled_signals;
kernel/signal.c+3−2
@@ -2912,7 +2912,8 @@ EXPORT_SYMBOL(set_compat_user_sigmask); · 2911 unmodified lines
29122912 * This is useful for syscalls such as ppoll, pselect, io_pgetevents and
29132913 * epoll_pwait where a new sigmask is passed in from userland for the syscalls.
29142914 */
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)
29162917 {
29172918
29182919 if (!usigmask)
@@ -2922,7 +2923,7 @@ void restore_user_sigmask(const void __user *usigmask, sigset_t *sigsaved) · 3 unmodified lines
29222923 * Restoring sigmask here can lead to delivering signals that the above
29232924 * syscalls are intended to block because of the sigmask passed in.
29242925 */
2925− if (signal_pending(current)) {
2926+ if (interrupted) {
29262927 current->saved_sigmask = *sigsaved;
29272928 set_restore_sigmask();
29282929 return;