diff options
Diffstat (limited to 'kernel/signal.c')
-rw-r--r-- | kernel/signal.c | 140 |
1 files changed, 80 insertions, 60 deletions
diff --git a/kernel/signal.c b/kernel/signal.c index 17afcaf582d0..677102789cf2 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. |
@@ -2376,24 +2368,34 @@ relock: | |||
2376 | } | 2368 | } |
2377 | 2369 | ||
2378 | /** | 2370 | /** |
2379 | * block_sigmask - add @ka's signal mask to current->blocked | 2371 | * signal_delivered - |
2380 | * @ka: action for @signr | 2372 | * @sig: number of signal being delivered |
2381 | * @signr: signal that has been successfully delivered | 2373 | * @info: siginfo_t of signal being delivered |
2374 | * @ka: sigaction setting that chose the handler | ||
2375 | * @regs: user register state | ||
2376 | * @stepping: nonzero if debugger single-step or block-step in use | ||
2382 | * | 2377 | * |
2383 | * This function should be called when a signal has succesfully been | 2378 | * This function should be called when a signal has succesfully been |
2384 | * delivered. It adds the mask of signals for @ka to current->blocked | 2379 | * delivered. It updates the blocked signals accordingly (@ka->sa.sa_mask |
2385 | * so that they are blocked during the execution of the signal | 2380 | * is always blocked, and the signal itself is blocked unless %SA_NODEFER |
2386 | * handler. In addition, @signr will be blocked unless %SA_NODEFER is | 2381 | * is set in @ka->sa.sa_flags. Tracing is notified. |
2387 | * set in @ka->sa.sa_flags. | ||
2388 | */ | 2382 | */ |
2389 | void block_sigmask(struct k_sigaction *ka, int signr) | 2383 | void signal_delivered(int sig, siginfo_t *info, struct k_sigaction *ka, |
2384 | struct pt_regs *regs, int stepping) | ||
2390 | { | 2385 | { |
2391 | sigset_t blocked; | 2386 | sigset_t blocked; |
2392 | 2387 | ||
2388 | /* A signal was successfully delivered, and the | ||
2389 | saved sigmask was stored on the signal frame, | ||
2390 | and will be restored by sigreturn. So we can | ||
2391 | simply clear the restore sigmask flag. */ | ||
2392 | clear_restore_sigmask(); | ||
2393 | |||
2393 | sigorsets(&blocked, ¤t->blocked, &ka->sa.sa_mask); | 2394 | sigorsets(&blocked, ¤t->blocked, &ka->sa.sa_mask); |
2394 | if (!(ka->sa.sa_flags & SA_NODEFER)) | 2395 | if (!(ka->sa.sa_flags & SA_NODEFER)) |
2395 | sigaddset(&blocked, signr); | 2396 | sigaddset(&blocked, sig); |
2396 | set_current_blocked(&blocked); | 2397 | set_current_blocked(&blocked); |
2398 | tracehook_signal_handler(sig, info, ka, regs, stepping); | ||
2397 | } | 2399 | } |
2398 | 2400 | ||
2399 | /* | 2401 | /* |
@@ -2526,7 +2528,16 @@ static void __set_task_blocked(struct task_struct *tsk, const sigset_t *newset) | |||
2526 | * It is wrong to change ->blocked directly, this helper should be used | 2528 | * It is wrong to change ->blocked directly, this helper should be used |
2527 | * to ensure the process can't miss a shared signal we are going to block. | 2529 | * to ensure the process can't miss a shared signal we are going to block. |
2528 | */ | 2530 | */ |
2529 | void set_current_blocked(const sigset_t *newset) | 2531 | void set_current_blocked(sigset_t *newset) |
2532 | { | ||
2533 | struct task_struct *tsk = current; | ||
2534 | sigdelsetmask(newset, sigmask(SIGKILL) | sigmask(SIGSTOP)); | ||
2535 | spin_lock_irq(&tsk->sighand->siglock); | ||
2536 | __set_task_blocked(tsk, newset); | ||
2537 | spin_unlock_irq(&tsk->sighand->siglock); | ||
2538 | } | ||
2539 | |||
2540 | void __set_current_blocked(const sigset_t *newset) | ||
2530 | { | 2541 | { |
2531 | struct task_struct *tsk = current; | 2542 | struct task_struct *tsk = current; |
2532 | 2543 | ||
@@ -2566,7 +2577,7 @@ int sigprocmask(int how, sigset_t *set, sigset_t *oldset) | |||
2566 | return -EINVAL; | 2577 | return -EINVAL; |
2567 | } | 2578 | } |
2568 | 2579 | ||
2569 | set_current_blocked(&newset); | 2580 | __set_current_blocked(&newset); |
2570 | return 0; | 2581 | return 0; |
2571 | } | 2582 | } |
2572 | 2583 | ||
@@ -2706,6 +2717,13 @@ int copy_siginfo_to_user(siginfo_t __user *to, siginfo_t *from) | |||
2706 | err |= __put_user(from->si_uid, &to->si_uid); | 2717 | err |= __put_user(from->si_uid, &to->si_uid); |
2707 | err |= __put_user(from->si_ptr, &to->si_ptr); | 2718 | err |= __put_user(from->si_ptr, &to->si_ptr); |
2708 | break; | 2719 | break; |
2720 | #ifdef __ARCH_SIGSYS | ||
2721 | case __SI_SYS: | ||
2722 | err |= __put_user(from->si_call_addr, &to->si_call_addr); | ||
2723 | err |= __put_user(from->si_syscall, &to->si_syscall); | ||
2724 | err |= __put_user(from->si_arch, &to->si_arch); | ||
2725 | break; | ||
2726 | #endif | ||
2709 | default: /* this is just in case for now ... */ | 2727 | default: /* this is just in case for now ... */ |
2710 | err |= __put_user(from->si_pid, &to->si_pid); | 2728 | err |= __put_user(from->si_pid, &to->si_pid); |
2711 | err |= __put_user(from->si_uid, &to->si_uid); | 2729 | err |= __put_user(from->si_uid, &to->si_uid); |
@@ -2828,7 +2846,7 @@ SYSCALL_DEFINE2(kill, pid_t, pid, int, sig) | |||
2828 | info.si_errno = 0; | 2846 | info.si_errno = 0; |
2829 | info.si_code = SI_USER; | 2847 | info.si_code = SI_USER; |
2830 | info.si_pid = task_tgid_vnr(current); | 2848 | info.si_pid = task_tgid_vnr(current); |
2831 | info.si_uid = current_uid(); | 2849 | info.si_uid = from_kuid_munged(current_user_ns(), current_uid()); |
2832 | 2850 | ||
2833 | return kill_something_info(sig, &info, pid); | 2851 | return kill_something_info(sig, &info, pid); |
2834 | } | 2852 | } |
@@ -2871,7 +2889,7 @@ static int do_tkill(pid_t tgid, pid_t pid, int sig) | |||
2871 | info.si_errno = 0; | 2889 | info.si_errno = 0; |
2872 | info.si_code = SI_TKILL; | 2890 | info.si_code = SI_TKILL; |
2873 | info.si_pid = task_tgid_vnr(current); | 2891 | info.si_pid = task_tgid_vnr(current); |
2874 | info.si_uid = current_uid(); | 2892 | info.si_uid = from_kuid_munged(current_user_ns(), current_uid()); |
2875 | 2893 | ||
2876 | return do_send_specific(tgid, pid, sig, &info); | 2894 | return do_send_specific(tgid, pid, sig, &info); |
2877 | } | 2895 | } |
@@ -3133,7 +3151,7 @@ SYSCALL_DEFINE3(sigprocmask, int, how, old_sigset_t __user *, nset, | |||
3133 | return -EINVAL; | 3151 | return -EINVAL; |
3134 | } | 3152 | } |
3135 | 3153 | ||
3136 | set_current_blocked(&new_blocked); | 3154 | __set_current_blocked(&new_blocked); |
3137 | } | 3155 | } |
3138 | 3156 | ||
3139 | if (oset) { | 3157 | if (oset) { |
@@ -3197,7 +3215,6 @@ SYSCALL_DEFINE1(ssetmask, int, newmask) | |||
3197 | int old = current->blocked.sig[0]; | 3215 | int old = current->blocked.sig[0]; |
3198 | sigset_t newset; | 3216 | sigset_t newset; |
3199 | 3217 | ||
3200 | siginitset(&newset, newmask & ~(sigmask(SIGKILL) | sigmask(SIGSTOP))); | ||
3201 | set_current_blocked(&newset); | 3218 | set_current_blocked(&newset); |
3202 | 3219 | ||
3203 | return old; | 3220 | return old; |
@@ -3236,6 +3253,17 @@ SYSCALL_DEFINE0(pause) | |||
3236 | 3253 | ||
3237 | #endif | 3254 | #endif |
3238 | 3255 | ||
3256 | int sigsuspend(sigset_t *set) | ||
3257 | { | ||
3258 | current->saved_sigmask = current->blocked; | ||
3259 | set_current_blocked(set); | ||
3260 | |||
3261 | current->state = TASK_INTERRUPTIBLE; | ||
3262 | schedule(); | ||
3263 | set_restore_sigmask(); | ||
3264 | return -ERESTARTNOHAND; | ||
3265 | } | ||
3266 | |||
3239 | #ifdef __ARCH_WANT_SYS_RT_SIGSUSPEND | 3267 | #ifdef __ARCH_WANT_SYS_RT_SIGSUSPEND |
3240 | /** | 3268 | /** |
3241 | * sys_rt_sigsuspend - replace the signal mask for a value with the | 3269 | * sys_rt_sigsuspend - replace the signal mask for a value with the |
@@ -3253,15 +3281,7 @@ SYSCALL_DEFINE2(rt_sigsuspend, sigset_t __user *, unewset, size_t, sigsetsize) | |||
3253 | 3281 | ||
3254 | if (copy_from_user(&newset, unewset, sizeof(newset))) | 3282 | if (copy_from_user(&newset, unewset, sizeof(newset))) |
3255 | return -EFAULT; | 3283 | return -EFAULT; |
3256 | sigdelsetmask(&newset, sigmask(SIGKILL)|sigmask(SIGSTOP)); | 3284 | 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 | } | 3285 | } |
3266 | #endif /* __ARCH_WANT_SYS_RT_SIGSUSPEND */ | 3286 | #endif /* __ARCH_WANT_SYS_RT_SIGSUSPEND */ |
3267 | 3287 | ||