Skip to content

Commit 6b2912c

Browse files
committed
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace
Pull signal fixes from Eric Biederman: "This contains four small fixes for signal handling. A missing range check, a regression fix, prioritizing signals we have already started a signal group exit for, and better detection of synchronous signals. The confused decision of which signals to handle failed spectacularly when a timer was pointed at SIGBUS and the stack overflowed. Resulting in an unkillable process in an infinite loop instead of a SIGSEGV and core dump" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace: signal: Better detection of synchronous signals signal: Always notice exiting tasks signal: Always attempt to allocate siginfo for SIGSTOP signal: Make siginmask safe when passed a signal of 0
2 parents 3b6e820 + 7146db3 commit 6b2912c

File tree

2 files changed

+60
-5
lines changed

2 files changed

+60
-5
lines changed

include/linux/signal.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -392,7 +392,7 @@ extern bool unhandled_signal(struct task_struct *tsk, int sig);
392392
#endif
393393

394394
#define siginmask(sig, mask) \
395-
((sig) < SIGRTMIN && (rt_sigmask(sig) & (mask)))
395+
((sig) > 0 && (sig) < SIGRTMIN && (rt_sigmask(sig) & (mask)))
396396

397397
#define SIG_KERNEL_ONLY_MASK (\
398398
rt_sigmask(SIGKILL) | rt_sigmask(SIGSTOP))

kernel/signal.c

Lines changed: 59 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -688,6 +688,48 @@ int dequeue_signal(struct task_struct *tsk, sigset_t *mask, kernel_siginfo_t *in
688688
}
689689
EXPORT_SYMBOL_GPL(dequeue_signal);
690690

691+
static int dequeue_synchronous_signal(kernel_siginfo_t *info)
692+
{
693+
struct task_struct *tsk = current;
694+
struct sigpending *pending = &tsk->pending;
695+
struct sigqueue *q, *sync = NULL;
696+
697+
/*
698+
* Might a synchronous signal be in the queue?
699+
*/
700+
if (!((pending->signal.sig[0] & ~tsk->blocked.sig[0]) & SYNCHRONOUS_MASK))
701+
return 0;
702+
703+
/*
704+
* Return the first synchronous signal in the queue.
705+
*/
706+
list_for_each_entry(q, &pending->list, list) {
707+
/* Synchronous signals have a postive si_code */
708+
if ((q->info.si_code > SI_USER) &&
709+
(sigmask(q->info.si_signo) & SYNCHRONOUS_MASK)) {
710+
sync = q;
711+
goto next;
712+
}
713+
}
714+
return 0;
715+
next:
716+
/*
717+
* Check if there is another siginfo for the same signal.
718+
*/
719+
list_for_each_entry_continue(q, &pending->list, list) {
720+
if (q->info.si_signo == sync->info.si_signo)
721+
goto still_pending;
722+
}
723+
724+
sigdelset(&pending->signal, sync->info.si_signo);
725+
recalc_sigpending();
726+
still_pending:
727+
list_del_init(&sync->list);
728+
copy_siginfo(info, &sync->info);
729+
__sigqueue_free(sync);
730+
return info->si_signo;
731+
}
732+
691733
/*
692734
* Tell a process that it has a new active signal..
693735
*
@@ -1057,10 +1099,9 @@ static int __send_signal(int sig, struct kernel_siginfo *info, struct task_struc
10571099

10581100
result = TRACE_SIGNAL_DELIVERED;
10591101
/*
1060-
* Skip useless siginfo allocation for SIGKILL SIGSTOP,
1061-
* and kernel threads.
1102+
* Skip useless siginfo allocation for SIGKILL and kernel threads.
10621103
*/
1063-
if (sig_kernel_only(sig) || (t->flags & PF_KTHREAD))
1104+
if ((sig == SIGKILL) || (t->flags & PF_KTHREAD))
10641105
goto out_set;
10651106

10661107
/*
@@ -2394,6 +2435,11 @@ bool get_signal(struct ksignal *ksig)
23942435
goto relock;
23952436
}
23962437

2438+
/* Has this task already been marked for death? */
2439+
ksig->info.si_signo = signr = SIGKILL;
2440+
if (signal_group_exit(signal))
2441+
goto fatal;
2442+
23972443
for (;;) {
23982444
struct k_sigaction *ka;
23992445

@@ -2407,7 +2453,15 @@ bool get_signal(struct ksignal *ksig)
24072453
goto relock;
24082454
}
24092455

2410-
signr = dequeue_signal(current, &current->blocked, &ksig->info);
2456+
/*
2457+
* Signals generated by the execution of an instruction
2458+
* need to be delivered before any other pending signals
2459+
* so that the instruction pointer in the signal stack
2460+
* frame points to the faulting instruction.
2461+
*/
2462+
signr = dequeue_synchronous_signal(&ksig->info);
2463+
if (!signr)
2464+
signr = dequeue_signal(current, &current->blocked, &ksig->info);
24112465

24122466
if (!signr)
24132467
break; /* will return 0 */
@@ -2489,6 +2543,7 @@ bool get_signal(struct ksignal *ksig)
24892543
continue;
24902544
}
24912545

2546+
fatal:
24922547
spin_unlock_irq(&sighand->siglock);
24932548

24942549
/*

0 commit comments

Comments
 (0)