diff options
| author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2015-02-10 14:35:36 -0500 |
|---|---|---|
| committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2015-02-10 14:35:36 -0500 |
| commit | 4ba24fef3eb3b142197135223b90ced2f319cd53 (patch) | |
| tree | a20c125b27740ec7b4c761b11d801108e1b316b2 /kernel/signal.c | |
| parent | 47c1ffb2b6b630894e9a16442611c056ab21c057 (diff) | |
| parent | 98a4a59ee31a12105a2b84f5b8b515ac2cb208ef (diff) | |
Merge branch 'next' into for-linus
Prepare first round of input updates for 3.20.
Diffstat (limited to 'kernel/signal.c')
| -rw-r--r-- | kernel/signal.c | 46 |
1 files changed, 29 insertions, 17 deletions
diff --git a/kernel/signal.c b/kernel/signal.c index 8f0876f9f6dd..16a305295256 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
| @@ -1275,7 +1275,17 @@ struct sighand_struct *__lock_task_sighand(struct task_struct *tsk, | |||
| 1275 | local_irq_restore(*flags); | 1275 | local_irq_restore(*flags); |
| 1276 | break; | 1276 | break; |
| 1277 | } | 1277 | } |
| 1278 | 1278 | /* | |
| 1279 | * This sighand can be already freed and even reused, but | ||
| 1280 | * we rely on SLAB_DESTROY_BY_RCU and sighand_ctor() which | ||
| 1281 | * initializes ->siglock: this slab can't go away, it has | ||
| 1282 | * the same object type, ->siglock can't be reinitialized. | ||
| 1283 | * | ||
| 1284 | * We need to ensure that tsk->sighand is still the same | ||
| 1285 | * after we take the lock, we can race with de_thread() or | ||
| 1286 | * __exit_signal(). In the latter case the next iteration | ||
| 1287 | * must see ->sighand == NULL. | ||
| 1288 | */ | ||
| 1279 | spin_lock(&sighand->siglock); | 1289 | spin_lock(&sighand->siglock); |
| 1280 | if (likely(sighand == tsk->sighand)) { | 1290 | if (likely(sighand == tsk->sighand)) { |
| 1281 | rcu_read_unlock(); | 1291 | rcu_read_unlock(); |
| @@ -1331,23 +1341,21 @@ int kill_pid_info(int sig, struct siginfo *info, struct pid *pid) | |||
| 1331 | int error = -ESRCH; | 1341 | int error = -ESRCH; |
| 1332 | struct task_struct *p; | 1342 | struct task_struct *p; |
| 1333 | 1343 | ||
| 1334 | rcu_read_lock(); | 1344 | for (;;) { |
| 1335 | retry: | 1345 | rcu_read_lock(); |
| 1336 | p = pid_task(pid, PIDTYPE_PID); | 1346 | p = pid_task(pid, PIDTYPE_PID); |
| 1337 | if (p) { | 1347 | if (p) |
| 1338 | error = group_send_sig_info(sig, info, p); | 1348 | error = group_send_sig_info(sig, info, p); |
| 1339 | if (unlikely(error == -ESRCH)) | 1349 | rcu_read_unlock(); |
| 1340 | /* | 1350 | if (likely(!p || error != -ESRCH)) |
| 1341 | * The task was unhashed in between, try again. | 1351 | return error; |
| 1342 | * If it is dead, pid_task() will return NULL, | ||
| 1343 | * if we race with de_thread() it will find the | ||
| 1344 | * new leader. | ||
| 1345 | */ | ||
| 1346 | goto retry; | ||
| 1347 | } | ||
| 1348 | rcu_read_unlock(); | ||
| 1349 | 1352 | ||
| 1350 | return error; | 1353 | /* |
| 1354 | * The task was unhashed in between, try again. If it | ||
| 1355 | * is dead, pid_task() will return NULL, if we race with | ||
| 1356 | * de_thread() it will find the new leader. | ||
| 1357 | */ | ||
| 1358 | } | ||
| 1351 | } | 1359 | } |
| 1352 | 1360 | ||
| 1353 | int kill_proc_info(int sig, struct siginfo *info, pid_t pid) | 1361 | int kill_proc_info(int sig, struct siginfo *info, pid_t pid) |
| @@ -2748,6 +2756,10 @@ int copy_siginfo_to_user(siginfo_t __user *to, const siginfo_t *from) | |||
| 2748 | if (from->si_code == BUS_MCEERR_AR || from->si_code == BUS_MCEERR_AO) | 2756 | if (from->si_code == BUS_MCEERR_AR || from->si_code == BUS_MCEERR_AO) |
| 2749 | err |= __put_user(from->si_addr_lsb, &to->si_addr_lsb); | 2757 | err |= __put_user(from->si_addr_lsb, &to->si_addr_lsb); |
| 2750 | #endif | 2758 | #endif |
| 2759 | #ifdef SEGV_BNDERR | ||
| 2760 | err |= __put_user(from->si_lower, &to->si_lower); | ||
| 2761 | err |= __put_user(from->si_upper, &to->si_upper); | ||
| 2762 | #endif | ||
| 2751 | break; | 2763 | break; |
| 2752 | case __SI_CHLD: | 2764 | case __SI_CHLD: |
| 2753 | err |= __put_user(from->si_pid, &to->si_pid); | 2765 | err |= __put_user(from->si_pid, &to->si_pid); |
