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) |