Skip to content

Commit 5e6292c

Browse files
Matt Flemingtorvalds
authored andcommitted
signal: add block_sigmask() for adding sigmask to current->blocked
Abstract the code sequence for adding a signal handler's sa_mask to current->blocked because the sequence is identical for all architectures. Furthermore, in the past some architectures actually got this code wrong, so introduce a wrapper that all architectures can use. Signed-off-by: Matt Fleming <[email protected]> Signed-off-by: Oleg Nesterov <[email protected]> Cc: Thomas Gleixner <[email protected]> Cc: Ingo Molnar <[email protected]> Cc: H. Peter Anvin <[email protected]> Cc: Tejun Heo <[email protected]> Cc: "David S. Miller" <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent f350b17 commit 5e6292c

File tree

3 files changed

+23
-5
lines changed

3 files changed

+23
-5
lines changed

arch/x86/kernel/signal.c

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -682,7 +682,6 @@ static int
682682
handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
683683
struct pt_regs *regs)
684684
{
685-
sigset_t blocked;
686685
int ret;
687686

688687
/* Are we from a system call? */
@@ -733,10 +732,7 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
733732
*/
734733
regs->flags &= ~X86_EFLAGS_TF;
735734

736-
sigorsets(&blocked, &current->blocked, &ka->sa.sa_mask);
737-
if (!(ka->sa.sa_flags & SA_NODEFER))
738-
sigaddset(&blocked, sig);
739-
set_current_blocked(&blocked);
735+
block_sigmask(ka, sig);
740736

741737
tracehook_signal_handler(sig, info, ka, regs,
742738
test_thread_flag(TIF_SINGLESTEP));

include/linux/signal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,7 @@ extern void set_current_blocked(const sigset_t *);
254254
extern int show_unhandled_signals;
255255

256256
extern int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka, struct pt_regs *regs, void *cookie);
257+
extern void block_sigmask(struct k_sigaction *ka, int signr);
257258
extern void exit_signals(struct task_struct *tsk);
258259

259260
extern struct kmem_cache *sighand_cachep;

kernel/signal.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2318,6 +2318,27 @@ int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka,
23182318
return signr;
23192319
}
23202320

2321+
/**
2322+
* block_sigmask - add @ka's signal mask to current->blocked
2323+
* @ka: action for @signr
2324+
* @signr: signal that has been successfully delivered
2325+
*
2326+
* This function should be called when a signal has succesfully been
2327+
* delivered. It adds the mask of signals for @ka to current->blocked
2328+
* so that they are blocked during the execution of the signal
2329+
* handler. In addition, @signr will be blocked unless %SA_NODEFER is
2330+
* set in @ka->sa.sa_flags.
2331+
*/
2332+
void block_sigmask(struct k_sigaction *ka, int signr)
2333+
{
2334+
sigset_t blocked;
2335+
2336+
sigorsets(&blocked, &current->blocked, &ka->sa.sa_mask);
2337+
if (!(ka->sa.sa_flags & SA_NODEFER))
2338+
sigaddset(&blocked, signr);
2339+
set_current_blocked(&blocked);
2340+
}
2341+
23212342
/*
23222343
* It could be that complete_signal() picked us to notify about the
23232344
* group-wide signal. Other threads should be notified now to take

0 commit comments

Comments
 (0)