Skip to content

Commit 73ef4ae

Browse files
committed
signal: sigprocmask: narrow the scope of ->siglock
No functional changes, preparation to simplify the review of the next change. 1. We can read current->block lockless, nobody else can ever change this mask. 2. Calculate the resulting sigset_t outside of ->siglock into the temporary variable, then take ->siglock and change ->blocked. Also, kill the stale comment about BKL. Signed-off-by: Oleg Nesterov <oleg@redhat.com> Reviewed-by: Matt Fleming <matt.fleming@linux.intel.com> Acked-by: Tejun Heo <tj@kernel.org>
1 parent fec9993 commit 73ef4ae

File tree

1 file changed

+13
-16
lines changed

1 file changed

+13
-16
lines changed

kernel/signal.c

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2299,12 +2299,6 @@ long do_no_restart_syscall(struct restart_block *param)
22992299
return -EINTR;
23002300
}
23012301

2302-
/*
2303-
* We don't need to get the kernel lock - this is all local to this
2304-
* particular thread.. (and that's good, because this is _heavily_
2305-
* used by various programs)
2306-
*/
2307-
23082302
/*
23092303
* This is also useful for kernel threads that want to temporarily
23102304
* (or permanently) block certain signals.
@@ -2315,30 +2309,33 @@ long do_no_restart_syscall(struct restart_block *param)
23152309
*/
23162310
int sigprocmask(int how, sigset_t *set, sigset_t *oldset)
23172311
{
2318-
int error;
2312+
struct task_struct *tsk = current;
2313+
sigset_t newset;
23192314

2320-
spin_lock_irq(&current->sighand->siglock);
2315+
/* Lockless, only current can change ->blocked, never from irq */
23212316
if (oldset)
2322-
*oldset = current->blocked;
2317+
*oldset = tsk->blocked;
23232318

2324-
error = 0;
23252319
switch (how) {
23262320
case SIG_BLOCK:
2327-
sigorsets(&current->blocked, &current->blocked, set);
2321+
sigorsets(&newset, &tsk->blocked, set);
23282322
break;
23292323
case SIG_UNBLOCK:
2330-
signandsets(&current->blocked, &current->blocked, set);
2324+
signandsets(&newset, &tsk->blocked, set);
23312325
break;
23322326
case SIG_SETMASK:
2333-
current->blocked = *set;
2327+
newset = *set;
23342328
break;
23352329
default:
2336-
error = -EINVAL;
2330+
return -EINVAL;
23372331
}
2332+
2333+
spin_lock_irq(&tsk->sighand->siglock);
2334+
tsk->blocked = newset;
23382335
recalc_sigpending();
2339-
spin_unlock_irq(&current->sighand->siglock);
2336+
spin_unlock_irq(&tsk->sighand->siglock);
23402337

2341-
return error;
2338+
return 0;
23422339
}
23432340

23442341
/**

0 commit comments

Comments
 (0)