diff options
Diffstat (limited to 'kernel/signal.c')
-rw-r--r-- | kernel/signal.c | 38 |
1 files changed, 20 insertions, 18 deletions
diff --git a/kernel/signal.c b/kernel/signal.c index 6b982f2cf524..1814e68e4de3 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
@@ -423,7 +423,7 @@ still_pending: | |||
423 | */ | 423 | */ |
424 | info->si_signo = sig; | 424 | info->si_signo = sig; |
425 | info->si_errno = 0; | 425 | info->si_errno = 0; |
426 | info->si_code = 0; | 426 | info->si_code = SI_USER; |
427 | info->si_pid = 0; | 427 | info->si_pid = 0; |
428 | info->si_uid = 0; | 428 | info->si_uid = 0; |
429 | } | 429 | } |
@@ -607,6 +607,17 @@ static int rm_from_queue(unsigned long mask, struct sigpending *s) | |||
607 | return 1; | 607 | return 1; |
608 | } | 608 | } |
609 | 609 | ||
610 | static inline int is_si_special(const struct siginfo *info) | ||
611 | { | ||
612 | return info <= SEND_SIG_FORCED; | ||
613 | } | ||
614 | |||
615 | static inline bool si_fromuser(const struct siginfo *info) | ||
616 | { | ||
617 | return info == SEND_SIG_NOINFO || | ||
618 | (!is_si_special(info) && SI_FROMUSER(info)); | ||
619 | } | ||
620 | |||
610 | /* | 621 | /* |
611 | * Bad permissions for sending the signal | 622 | * Bad permissions for sending the signal |
612 | * - the caller must hold at least the RCU read lock | 623 | * - the caller must hold at least the RCU read lock |
@@ -621,7 +632,7 @@ static int check_kill_permission(int sig, struct siginfo *info, | |||
621 | if (!valid_signal(sig)) | 632 | if (!valid_signal(sig)) |
622 | return -EINVAL; | 633 | return -EINVAL; |
623 | 634 | ||
624 | if (info != SEND_SIG_NOINFO && (is_si_special(info) || SI_FROMKERNEL(info))) | 635 | if (!si_fromuser(info)) |
625 | return 0; | 636 | return 0; |
626 | 637 | ||
627 | error = audit_signal_info(sig, t); /* Let audit system see the signal */ | 638 | error = audit_signal_info(sig, t); /* Let audit system see the signal */ |
@@ -949,9 +960,8 @@ static int send_signal(int sig, struct siginfo *info, struct task_struct *t, | |||
949 | int from_ancestor_ns = 0; | 960 | int from_ancestor_ns = 0; |
950 | 961 | ||
951 | #ifdef CONFIG_PID_NS | 962 | #ifdef CONFIG_PID_NS |
952 | if (!is_si_special(info) && SI_FROMUSER(info) && | 963 | from_ancestor_ns = si_fromuser(info) && |
953 | task_pid_nr_ns(current, task_active_pid_ns(t)) <= 0) | 964 | !task_pid_nr_ns(current, task_active_pid_ns(t)); |
954 | from_ancestor_ns = 1; | ||
955 | #endif | 965 | #endif |
956 | 966 | ||
957 | return __send_signal(sig, info, t, group, from_ancestor_ns); | 967 | return __send_signal(sig, info, t, group, from_ancestor_ns); |
@@ -1052,12 +1062,6 @@ force_sig_info(int sig, struct siginfo *info, struct task_struct *t) | |||
1052 | return ret; | 1062 | return ret; |
1053 | } | 1063 | } |
1054 | 1064 | ||
1055 | void | ||
1056 | force_sig_specific(int sig, struct task_struct *t) | ||
1057 | { | ||
1058 | force_sig_info(sig, SEND_SIG_FORCED, t); | ||
1059 | } | ||
1060 | |||
1061 | /* | 1065 | /* |
1062 | * Nuke all other threads in the group. | 1066 | * Nuke all other threads in the group. |
1063 | */ | 1067 | */ |
@@ -1186,8 +1190,7 @@ int kill_pid_info_as_uid(int sig, struct siginfo *info, struct pid *pid, | |||
1186 | goto out_unlock; | 1190 | goto out_unlock; |
1187 | } | 1191 | } |
1188 | pcred = __task_cred(p); | 1192 | pcred = __task_cred(p); |
1189 | if ((info == SEND_SIG_NOINFO || | 1193 | if (si_fromuser(info) && |
1190 | (!is_si_special(info) && SI_FROMUSER(info))) && | ||
1191 | euid != pcred->suid && euid != pcred->uid && | 1194 | euid != pcred->suid && euid != pcred->uid && |
1192 | uid != pcred->suid && uid != pcred->uid) { | 1195 | uid != pcred->suid && uid != pcred->uid) { |
1193 | ret = -EPERM; | 1196 | ret = -EPERM; |
@@ -1837,11 +1840,6 @@ relock: | |||
1837 | 1840 | ||
1838 | for (;;) { | 1841 | for (;;) { |
1839 | struct k_sigaction *ka; | 1842 | struct k_sigaction *ka; |
1840 | |||
1841 | if (unlikely(signal->group_stop_count > 0) && | ||
1842 | do_signal_stop(0)) | ||
1843 | goto relock; | ||
1844 | |||
1845 | /* | 1843 | /* |
1846 | * Tracing can induce an artifical signal and choose sigaction. | 1844 | * Tracing can induce an artifical signal and choose sigaction. |
1847 | * The return value in @signr determines the default action, | 1845 | * The return value in @signr determines the default action, |
@@ -1853,6 +1851,10 @@ relock: | |||
1853 | if (unlikely(signr != 0)) | 1851 | if (unlikely(signr != 0)) |
1854 | ka = return_ka; | 1852 | ka = return_ka; |
1855 | else { | 1853 | else { |
1854 | if (unlikely(signal->group_stop_count > 0) && | ||
1855 | do_signal_stop(0)) | ||
1856 | goto relock; | ||
1857 | |||
1856 | signr = dequeue_signal(current, ¤t->blocked, | 1858 | signr = dequeue_signal(current, ¤t->blocked, |
1857 | info); | 1859 | info); |
1858 | 1860 | ||