diff options
Diffstat (limited to 'kernel/signal.c')
-rw-r--r-- | kernel/signal.c | 100 |
1 files changed, 53 insertions, 47 deletions
diff --git a/kernel/signal.c b/kernel/signal.c index 17afcaf582d0..08dfbd748cd2 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/pid_namespace.h> | 29 | #include <linux/pid_namespace.h> |
30 | #include <linux/nsproxy.h> | 30 | #include <linux/nsproxy.h> |
31 | #include <linux/user_namespace.h> | 31 | #include <linux/user_namespace.h> |
32 | #include <linux/uprobes.h> | ||
32 | #define CREATE_TRACE_POINTS | 33 | #define CREATE_TRACE_POINTS |
33 | #include <trace/events/signal.h> | 34 | #include <trace/events/signal.h> |
34 | 35 | ||
@@ -160,7 +161,7 @@ void recalc_sigpending(void) | |||
160 | 161 | ||
161 | #define SYNCHRONOUS_MASK \ | 162 | #define SYNCHRONOUS_MASK \ |
162 | (sigmask(SIGSEGV) | sigmask(SIGBUS) | sigmask(SIGILL) | \ | 163 | (sigmask(SIGSEGV) | sigmask(SIGBUS) | sigmask(SIGILL) | \ |
163 | sigmask(SIGTRAP) | sigmask(SIGFPE)) | 164 | sigmask(SIGTRAP) | sigmask(SIGFPE) | sigmask(SIGSYS)) |
164 | 165 | ||
165 | int next_signal(struct sigpending *pending, sigset_t *mask) | 166 | int next_signal(struct sigpending *pending, sigset_t *mask) |
166 | { | 167 | { |
@@ -767,14 +768,13 @@ static int kill_ok_by_cred(struct task_struct *t) | |||
767 | const struct cred *cred = current_cred(); | 768 | const struct cred *cred = current_cred(); |
768 | const struct cred *tcred = __task_cred(t); | 769 | const struct cred *tcred = __task_cred(t); |
769 | 770 | ||
770 | if (cred->user->user_ns == tcred->user->user_ns && | 771 | if (uid_eq(cred->euid, tcred->suid) || |
771 | (cred->euid == tcred->suid || | 772 | uid_eq(cred->euid, tcred->uid) || |
772 | cred->euid == tcred->uid || | 773 | uid_eq(cred->uid, tcred->suid) || |
773 | cred->uid == tcred->suid || | 774 | uid_eq(cred->uid, tcred->uid)) |
774 | cred->uid == tcred->uid)) | ||
775 | return 1; | 775 | return 1; |
776 | 776 | ||
777 | if (ns_capable(tcred->user->user_ns, CAP_KILL)) | 777 | if (ns_capable(tcred->user_ns, CAP_KILL)) |
778 | return 1; | 778 | return 1; |
779 | 779 | ||
780 | return 0; | 780 | return 0; |
@@ -1020,15 +1020,6 @@ static inline int legacy_queue(struct sigpending *signals, int sig) | |||
1020 | return (sig < SIGRTMIN) && sigismember(&signals->signal, sig); | 1020 | return (sig < SIGRTMIN) && sigismember(&signals->signal, sig); |
1021 | } | 1021 | } |
1022 | 1022 | ||
1023 | /* | ||
1024 | * map the uid in struct cred into user namespace *ns | ||
1025 | */ | ||
1026 | static inline uid_t map_cred_ns(const struct cred *cred, | ||
1027 | struct user_namespace *ns) | ||
1028 | { | ||
1029 | return user_ns_map_uid(ns, cred, cred->uid); | ||
1030 | } | ||
1031 | |||
1032 | #ifdef CONFIG_USER_NS | 1023 | #ifdef CONFIG_USER_NS |
1033 | static inline void userns_fixup_signal_uid(struct siginfo *info, struct task_struct *t) | 1024 | static inline void userns_fixup_signal_uid(struct siginfo *info, struct task_struct *t) |
1034 | { | 1025 | { |
@@ -1038,8 +1029,10 @@ static inline void userns_fixup_signal_uid(struct siginfo *info, struct task_str | |||
1038 | if (SI_FROMKERNEL(info)) | 1029 | if (SI_FROMKERNEL(info)) |
1039 | return; | 1030 | return; |
1040 | 1031 | ||
1041 | info->si_uid = user_ns_map_uid(task_cred_xxx(t, user_ns), | 1032 | rcu_read_lock(); |
1042 | current_cred(), info->si_uid); | 1033 | info->si_uid = from_kuid_munged(task_cred_xxx(t, user_ns), |
1034 | make_kuid(current_user_ns(), info->si_uid)); | ||
1035 | rcu_read_unlock(); | ||
1043 | } | 1036 | } |
1044 | #else | 1037 | #else |
1045 | static inline void userns_fixup_signal_uid(struct siginfo *info, struct task_struct *t) | 1038 | static inline void userns_fixup_signal_uid(struct siginfo *info, struct task_struct *t) |
@@ -1106,7 +1099,7 @@ static int __send_signal(int sig, struct siginfo *info, struct task_struct *t, | |||
1106 | q->info.si_code = SI_USER; | 1099 | q->info.si_code = SI_USER; |
1107 | q->info.si_pid = task_tgid_nr_ns(current, | 1100 | q->info.si_pid = task_tgid_nr_ns(current, |
1108 | task_active_pid_ns(t)); | 1101 | task_active_pid_ns(t)); |
1109 | q->info.si_uid = current_uid(); | 1102 | q->info.si_uid = from_kuid_munged(current_user_ns(), current_uid()); |
1110 | break; | 1103 | break; |
1111 | case (unsigned long) SEND_SIG_PRIV: | 1104 | case (unsigned long) SEND_SIG_PRIV: |
1112 | q->info.si_signo = sig; | 1105 | q->info.si_signo = sig; |
@@ -1387,10 +1380,8 @@ static int kill_as_cred_perm(const struct cred *cred, | |||
1387 | struct task_struct *target) | 1380 | struct task_struct *target) |
1388 | { | 1381 | { |
1389 | const struct cred *pcred = __task_cred(target); | 1382 | const struct cred *pcred = __task_cred(target); |
1390 | if (cred->user_ns != pcred->user_ns) | 1383 | if (!uid_eq(cred->euid, pcred->suid) && !uid_eq(cred->euid, pcred->uid) && |
1391 | return 0; | 1384 | !uid_eq(cred->uid, pcred->suid) && !uid_eq(cred->uid, pcred->uid)) |
1392 | if (cred->euid != pcred->suid && cred->euid != pcred->uid && | ||
1393 | cred->uid != pcred->suid && cred->uid != pcred->uid) | ||
1394 | return 0; | 1385 | return 0; |
1395 | return 1; | 1386 | return 1; |
1396 | } | 1387 | } |
@@ -1665,21 +1656,20 @@ bool do_notify_parent(struct task_struct *tsk, int sig) | |||
1665 | info.si_signo = sig; | 1656 | info.si_signo = sig; |
1666 | info.si_errno = 0; | 1657 | info.si_errno = 0; |
1667 | /* | 1658 | /* |
1668 | * we are under tasklist_lock here so our parent is tied to | 1659 | * We are under tasklist_lock here so our parent is tied to |
1669 | * us and cannot exit and release its namespace. | 1660 | * us and cannot change. |
1670 | * | 1661 | * |
1671 | * the only it can is to switch its nsproxy with sys_unshare, | 1662 | * task_active_pid_ns will always return the same pid namespace |
1672 | * bu uncharing pid namespaces is not allowed, so we'll always | 1663 | * until a task passes through release_task. |
1673 | * see relevant namespace | ||
1674 | * | 1664 | * |
1675 | * write_lock() currently calls preempt_disable() which is the | 1665 | * write_lock() currently calls preempt_disable() which is the |
1676 | * same as rcu_read_lock(), but according to Oleg, this is not | 1666 | * same as rcu_read_lock(), but according to Oleg, this is not |
1677 | * correct to rely on this | 1667 | * correct to rely on this |
1678 | */ | 1668 | */ |
1679 | rcu_read_lock(); | 1669 | rcu_read_lock(); |
1680 | info.si_pid = task_pid_nr_ns(tsk, tsk->parent->nsproxy->pid_ns); | 1670 | info.si_pid = task_pid_nr_ns(tsk, task_active_pid_ns(tsk->parent)); |
1681 | info.si_uid = map_cred_ns(__task_cred(tsk), | 1671 | info.si_uid = from_kuid_munged(task_cred_xxx(tsk->parent, user_ns), |
1682 | task_cred_xxx(tsk->parent, user_ns)); | 1672 | task_uid(tsk)); |
1683 | rcu_read_unlock(); | 1673 | rcu_read_unlock(); |
1684 | 1674 | ||
1685 | info.si_utime = cputime_to_clock_t(tsk->utime + tsk->signal->utime); | 1675 | info.si_utime = cputime_to_clock_t(tsk->utime + tsk->signal->utime); |
@@ -1762,8 +1752,7 @@ static void do_notify_parent_cldstop(struct task_struct *tsk, | |||
1762 | */ | 1752 | */ |
1763 | rcu_read_lock(); | 1753 | rcu_read_lock(); |
1764 | info.si_pid = task_pid_nr_ns(tsk, parent->nsproxy->pid_ns); | 1754 | info.si_pid = task_pid_nr_ns(tsk, parent->nsproxy->pid_ns); |
1765 | info.si_uid = map_cred_ns(__task_cred(tsk), | 1755 | info.si_uid = from_kuid_munged(task_cred_xxx(parent, user_ns), task_uid(tsk)); |
1766 | task_cred_xxx(parent, user_ns)); | ||
1767 | rcu_read_unlock(); | 1756 | rcu_read_unlock(); |
1768 | 1757 | ||
1769 | info.si_utime = cputime_to_clock_t(tsk->utime); | 1758 | info.si_utime = cputime_to_clock_t(tsk->utime); |
@@ -1973,7 +1962,7 @@ static void ptrace_do_notify(int signr, int exit_code, int why) | |||
1973 | info.si_signo = signr; | 1962 | info.si_signo = signr; |
1974 | info.si_code = exit_code; | 1963 | info.si_code = exit_code; |
1975 | info.si_pid = task_pid_vnr(current); | 1964 | info.si_pid = task_pid_vnr(current); |
1976 | info.si_uid = current_uid(); | 1965 | info.si_uid = from_kuid_munged(current_user_ns(), current_uid()); |
1977 | 1966 | ||
1978 | /* Let the debugger run. */ | 1967 | /* Let the debugger run. */ |
1979 | ptrace_stop(exit_code, why, 1, &info); | 1968 | ptrace_stop(exit_code, why, 1, &info); |
@@ -2181,8 +2170,8 @@ static int ptrace_signal(int signr, siginfo_t *info, | |||
2181 | info->si_code = SI_USER; | 2170 | info->si_code = SI_USER; |
2182 | rcu_read_lock(); | 2171 | rcu_read_lock(); |
2183 | info->si_pid = task_pid_vnr(current->parent); | 2172 | info->si_pid = task_pid_vnr(current->parent); |
2184 | info->si_uid = map_cred_ns(__task_cred(current->parent), | 2173 | info->si_uid = from_kuid_munged(current_user_ns(), |
2185 | current_user_ns()); | 2174 | task_uid(current->parent)); |
2186 | rcu_read_unlock(); | 2175 | rcu_read_unlock(); |
2187 | } | 2176 | } |
2188 | 2177 | ||
@@ -2202,6 +2191,9 @@ int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka, | |||
2202 | struct signal_struct *signal = current->signal; | 2191 | struct signal_struct *signal = current->signal; |
2203 | int signr; | 2192 | int signr; |
2204 | 2193 | ||
2194 | if (unlikely(uprobe_deny_signal())) | ||
2195 | return 0; | ||
2196 | |||
2205 | relock: | 2197 | relock: |
2206 | /* | 2198 | /* |
2207 | * We'll jump back here after any time we were stopped in TASK_STOPPED. | 2199 | * We'll jump back here after any time we were stopped in TASK_STOPPED. |
@@ -2706,6 +2698,13 @@ int copy_siginfo_to_user(siginfo_t __user *to, siginfo_t *from) | |||
2706 | err |= __put_user(from->si_uid, &to->si_uid); | 2698 | err |= __put_user(from->si_uid, &to->si_uid); |
2707 | err |= __put_user(from->si_ptr, &to->si_ptr); | 2699 | err |= __put_user(from->si_ptr, &to->si_ptr); |
2708 | break; | 2700 | break; |
2701 | #ifdef __ARCH_SIGSYS | ||
2702 | case __SI_SYS: | ||
2703 | err |= __put_user(from->si_call_addr, &to->si_call_addr); | ||
2704 | err |= __put_user(from->si_syscall, &to->si_syscall); | ||
2705 | err |= __put_user(from->si_arch, &to->si_arch); | ||
2706 | break; | ||
2707 | #endif | ||
2709 | default: /* this is just in case for now ... */ | 2708 | default: /* this is just in case for now ... */ |
2710 | err |= __put_user(from->si_pid, &to->si_pid); | 2709 | err |= __put_user(from->si_pid, &to->si_pid); |
2711 | err |= __put_user(from->si_uid, &to->si_uid); | 2710 | err |= __put_user(from->si_uid, &to->si_uid); |
@@ -2828,7 +2827,7 @@ SYSCALL_DEFINE2(kill, pid_t, pid, int, sig) | |||
2828 | info.si_errno = 0; | 2827 | info.si_errno = 0; |
2829 | info.si_code = SI_USER; | 2828 | info.si_code = SI_USER; |
2830 | info.si_pid = task_tgid_vnr(current); | 2829 | info.si_pid = task_tgid_vnr(current); |
2831 | info.si_uid = current_uid(); | 2830 | info.si_uid = from_kuid_munged(current_user_ns(), current_uid()); |
2832 | 2831 | ||
2833 | return kill_something_info(sig, &info, pid); | 2832 | return kill_something_info(sig, &info, pid); |
2834 | } | 2833 | } |
@@ -2871,7 +2870,7 @@ static int do_tkill(pid_t tgid, pid_t pid, int sig) | |||
2871 | info.si_errno = 0; | 2870 | info.si_errno = 0; |
2872 | info.si_code = SI_TKILL; | 2871 | info.si_code = SI_TKILL; |
2873 | info.si_pid = task_tgid_vnr(current); | 2872 | info.si_pid = task_tgid_vnr(current); |
2874 | info.si_uid = current_uid(); | 2873 | info.si_uid = from_kuid_munged(current_user_ns(), current_uid()); |
2875 | 2874 | ||
2876 | return do_send_specific(tgid, pid, sig, &info); | 2875 | return do_send_specific(tgid, pid, sig, &info); |
2877 | } | 2876 | } |
@@ -3236,6 +3235,21 @@ SYSCALL_DEFINE0(pause) | |||
3236 | 3235 | ||
3237 | #endif | 3236 | #endif |
3238 | 3237 | ||
3238 | #ifdef HAVE_SET_RESTORE_SIGMASK | ||
3239 | int sigsuspend(sigset_t *set) | ||
3240 | { | ||
3241 | sigdelsetmask(set, sigmask(SIGKILL)|sigmask(SIGSTOP)); | ||
3242 | |||
3243 | current->saved_sigmask = current->blocked; | ||
3244 | set_current_blocked(set); | ||
3245 | |||
3246 | current->state = TASK_INTERRUPTIBLE; | ||
3247 | schedule(); | ||
3248 | set_restore_sigmask(); | ||
3249 | return -ERESTARTNOHAND; | ||
3250 | } | ||
3251 | #endif | ||
3252 | |||
3239 | #ifdef __ARCH_WANT_SYS_RT_SIGSUSPEND | 3253 | #ifdef __ARCH_WANT_SYS_RT_SIGSUSPEND |
3240 | /** | 3254 | /** |
3241 | * sys_rt_sigsuspend - replace the signal mask for a value with the | 3255 | * sys_rt_sigsuspend - replace the signal mask for a value with the |
@@ -3253,15 +3267,7 @@ SYSCALL_DEFINE2(rt_sigsuspend, sigset_t __user *, unewset, size_t, sigsetsize) | |||
3253 | 3267 | ||
3254 | if (copy_from_user(&newset, unewset, sizeof(newset))) | 3268 | if (copy_from_user(&newset, unewset, sizeof(newset))) |
3255 | return -EFAULT; | 3269 | return -EFAULT; |
3256 | sigdelsetmask(&newset, sigmask(SIGKILL)|sigmask(SIGSTOP)); | 3270 | return sigsuspend(&newset); |
3257 | |||
3258 | current->saved_sigmask = current->blocked; | ||
3259 | set_current_blocked(&newset); | ||
3260 | |||
3261 | current->state = TASK_INTERRUPTIBLE; | ||
3262 | schedule(); | ||
3263 | set_restore_sigmask(); | ||
3264 | return -ERESTARTNOHAND; | ||
3265 | } | 3271 | } |
3266 | #endif /* __ARCH_WANT_SYS_RT_SIGSUSPEND */ | 3272 | #endif /* __ARCH_WANT_SYS_RT_SIGSUSPEND */ |
3267 | 3273 | ||