diff options
Diffstat (limited to 'kernel/signal.c')
| -rw-r--r-- | kernel/signal.c | 23 |
1 files changed, 13 insertions, 10 deletions
diff --git a/kernel/signal.c b/kernel/signal.c index 825a3f24ad76..906ae5a1779c 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
| @@ -642,7 +642,7 @@ static inline bool si_fromuser(const struct siginfo *info) | |||
| 642 | static int check_kill_permission(int sig, struct siginfo *info, | 642 | static int check_kill_permission(int sig, struct siginfo *info, |
| 643 | struct task_struct *t) | 643 | struct task_struct *t) |
| 644 | { | 644 | { |
| 645 | const struct cred *cred = current_cred(), *tcred; | 645 | const struct cred *cred, *tcred; |
| 646 | struct pid *sid; | 646 | struct pid *sid; |
| 647 | int error; | 647 | int error; |
| 648 | 648 | ||
| @@ -656,8 +656,10 @@ static int check_kill_permission(int sig, struct siginfo *info, | |||
| 656 | if (error) | 656 | if (error) |
| 657 | return error; | 657 | return error; |
| 658 | 658 | ||
| 659 | cred = current_cred(); | ||
| 659 | tcred = __task_cred(t); | 660 | tcred = __task_cred(t); |
| 660 | if ((cred->euid ^ tcred->suid) && | 661 | if (!same_thread_group(current, t) && |
| 662 | (cred->euid ^ tcred->suid) && | ||
| 661 | (cred->euid ^ tcred->uid) && | 663 | (cred->euid ^ tcred->uid) && |
| 662 | (cred->uid ^ tcred->suid) && | 664 | (cred->uid ^ tcred->suid) && |
| 663 | (cred->uid ^ tcred->uid) && | 665 | (cred->uid ^ tcred->uid) && |
| @@ -1083,23 +1085,24 @@ force_sig_info(int sig, struct siginfo *info, struct task_struct *t) | |||
| 1083 | /* | 1085 | /* |
| 1084 | * Nuke all other threads in the group. | 1086 | * Nuke all other threads in the group. |
| 1085 | */ | 1087 | */ |
| 1086 | void zap_other_threads(struct task_struct *p) | 1088 | int zap_other_threads(struct task_struct *p) |
| 1087 | { | 1089 | { |
| 1088 | struct task_struct *t; | 1090 | struct task_struct *t = p; |
| 1091 | int count = 0; | ||
| 1089 | 1092 | ||
| 1090 | p->signal->group_stop_count = 0; | 1093 | p->signal->group_stop_count = 0; |
| 1091 | 1094 | ||
| 1092 | for (t = next_thread(p); t != p; t = next_thread(t)) { | 1095 | while_each_thread(p, t) { |
| 1093 | /* | 1096 | count++; |
| 1094 | * Don't bother with already dead threads | 1097 | |
| 1095 | */ | 1098 | /* Don't bother with already dead threads */ |
| 1096 | if (t->exit_state) | 1099 | if (t->exit_state) |
| 1097 | continue; | 1100 | continue; |
| 1098 | |||
| 1099 | /* SIGKILL will be handled before any pending SIGSTOP */ | ||
| 1100 | sigaddset(&t->pending.signal, SIGKILL); | 1101 | sigaddset(&t->pending.signal, SIGKILL); |
| 1101 | signal_wake_up(t, 1); | 1102 | signal_wake_up(t, 1); |
| 1102 | } | 1103 | } |
| 1104 | |||
| 1105 | return count; | ||
| 1103 | } | 1106 | } |
| 1104 | 1107 | ||
| 1105 | struct sighand_struct *lock_task_sighand(struct task_struct *tsk, unsigned long *flags) | 1108 | struct sighand_struct *lock_task_sighand(struct task_struct *tsk, unsigned long *flags) |
