aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/signal.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/signal.c')
-rw-r--r--kernel/signal.c22
1 files changed, 18 insertions, 4 deletions
diff --git a/kernel/signal.c b/kernel/signal.c
index 906ae5a1779c..4e3cff10fdce 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -637,7 +637,7 @@ static inline bool si_fromuser(const struct siginfo *info)
637 637
638/* 638/*
639 * Bad permissions for sending the signal 639 * Bad permissions for sending the signal
640 * - the caller must hold at least the RCU read lock 640 * - the caller must hold the RCU read lock
641 */ 641 */
642static int check_kill_permission(int sig, struct siginfo *info, 642static int check_kill_permission(int sig, struct siginfo *info,
643 struct task_struct *t) 643 struct task_struct *t)
@@ -1105,7 +1105,8 @@ int zap_other_threads(struct task_struct *p)
1105 return count; 1105 return count;
1106} 1106}
1107 1107
1108struct sighand_struct *lock_task_sighand(struct task_struct *tsk, unsigned long *flags) 1108struct sighand_struct *__lock_task_sighand(struct task_struct *tsk,
1109 unsigned long *flags)
1109{ 1110{
1110 struct sighand_struct *sighand; 1111 struct sighand_struct *sighand;
1111 1112
@@ -1127,11 +1128,14 @@ struct sighand_struct *lock_task_sighand(struct task_struct *tsk, unsigned long
1127 1128
1128/* 1129/*
1129 * send signal info to all the members of a group 1130 * send signal info to all the members of a group
1130 * - the caller must hold the RCU read lock at least
1131 */ 1131 */
1132int group_send_sig_info(int sig, struct siginfo *info, struct task_struct *p) 1132int group_send_sig_info(int sig, struct siginfo *info, struct task_struct *p)
1133{ 1133{
1134 int ret = check_kill_permission(sig, info, p); 1134 int ret;
1135
1136 rcu_read_lock();
1137 ret = check_kill_permission(sig, info, p);
1138 rcu_read_unlock();
1135 1139
1136 if (!ret && sig) 1140 if (!ret && sig)
1137 ret = do_send_sig_info(sig, info, p, true); 1141 ret = do_send_sig_info(sig, info, p, true);
@@ -1614,6 +1618,8 @@ static int sigkill_pending(struct task_struct *tsk)
1614 * is gone, we keep current->exit_code unless clear_code. 1618 * is gone, we keep current->exit_code unless clear_code.
1615 */ 1619 */
1616static void ptrace_stop(int exit_code, int clear_code, siginfo_t *info) 1620static void ptrace_stop(int exit_code, int clear_code, siginfo_t *info)
1621 __releases(&current->sighand->siglock)
1622 __acquires(&current->sighand->siglock)
1617{ 1623{
1618 if (arch_ptrace_stop_needed(exit_code, info)) { 1624 if (arch_ptrace_stop_needed(exit_code, info)) {
1619 /* 1625 /*
@@ -2212,6 +2218,14 @@ int copy_siginfo_to_user(siginfo_t __user *to, siginfo_t *from)
2212#ifdef __ARCH_SI_TRAPNO 2218#ifdef __ARCH_SI_TRAPNO
2213 err |= __put_user(from->si_trapno, &to->si_trapno); 2219 err |= __put_user(from->si_trapno, &to->si_trapno);
2214#endif 2220#endif
2221#ifdef BUS_MCEERR_AO
2222 /*
2223 * Other callers might not initialize the si_lsb field,
2224 * so check explicitely for the right codes here.
2225 */
2226 if (from->si_code == BUS_MCEERR_AR || from->si_code == BUS_MCEERR_AO)
2227 err |= __put_user(from->si_addr_lsb, &to->si_addr_lsb);
2228#endif
2215 break; 2229 break;
2216 case __SI_CHLD: 2230 case __SI_CHLD:
2217 err |= __put_user(from->si_pid, &to->si_pid); 2231 err |= __put_user(from->si_pid, &to->si_pid);