aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/signal.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/signal.c')
-rw-r--r--kernel/signal.c111
1 files changed, 88 insertions, 23 deletions
diff --git a/kernel/signal.c b/kernel/signal.c
index 0af8868525d6..7aaa51d8e5b8 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -31,6 +31,7 @@
31#include <linux/nsproxy.h> 31#include <linux/nsproxy.h>
32#include <linux/user_namespace.h> 32#include <linux/user_namespace.h>
33#include <linux/uprobes.h> 33#include <linux/uprobes.h>
34#include <linux/compat.h>
34#define CREATE_TRACE_POINTS 35#define CREATE_TRACE_POINTS
35#include <trace/events/signal.h> 36#include <trace/events/signal.h>
36 37
@@ -1159,8 +1160,9 @@ static int send_signal(int sig, struct siginfo *info, struct task_struct *t,
1159 return __send_signal(sig, info, t, group, from_ancestor_ns); 1160 return __send_signal(sig, info, t, group, from_ancestor_ns);
1160} 1161}
1161 1162
1162static void print_fatal_signal(struct pt_regs *regs, int signr) 1163static void print_fatal_signal(int signr)
1163{ 1164{
1165 struct pt_regs *regs = signal_pt_regs();
1164 printk("%s/%d: potentially unexpected fatal signal %d.\n", 1166 printk("%s/%d: potentially unexpected fatal signal %d.\n",
1165 current->comm, task_pid_nr(current), signr); 1167 current->comm, task_pid_nr(current), signr);
1166 1168
@@ -1752,7 +1754,7 @@ static void do_notify_parent_cldstop(struct task_struct *tsk,
1752 * see comment in do_notify_parent() about the following 4 lines 1754 * see comment in do_notify_parent() about the following 4 lines
1753 */ 1755 */
1754 rcu_read_lock(); 1756 rcu_read_lock();
1755 info.si_pid = task_pid_nr_ns(tsk, parent->nsproxy->pid_ns); 1757 info.si_pid = task_pid_nr_ns(tsk, task_active_pid_ns(parent));
1756 info.si_uid = from_kuid_munged(task_cred_xxx(parent, user_ns), task_uid(tsk)); 1758 info.si_uid = from_kuid_munged(task_cred_xxx(parent, user_ns), task_uid(tsk));
1757 rcu_read_unlock(); 1759 rcu_read_unlock();
1758 1760
@@ -1908,7 +1910,7 @@ static void ptrace_stop(int exit_code, int why, int clear_code, siginfo_t *info)
1908 preempt_disable(); 1910 preempt_disable();
1909 read_unlock(&tasklist_lock); 1911 read_unlock(&tasklist_lock);
1910 preempt_enable_no_resched(); 1912 preempt_enable_no_resched();
1911 schedule(); 1913 freezable_schedule();
1912 } else { 1914 } else {
1913 /* 1915 /*
1914 * By the time we got the lock, our tracer went away. 1916 * By the time we got the lock, our tracer went away.
@@ -1930,13 +1932,6 @@ static void ptrace_stop(int exit_code, int why, int clear_code, siginfo_t *info)
1930 } 1932 }
1931 1933
1932 /* 1934 /*
1933 * While in TASK_TRACED, we were considered "frozen enough".
1934 * Now that we woke up, it's crucial if we're supposed to be
1935 * frozen that we freeze now before running anything substantial.
1936 */
1937 try_to_freeze();
1938
1939 /*
1940 * We are back. Now reacquire the siglock before touching 1935 * We are back. Now reacquire the siglock before touching
1941 * last_siginfo, so that we are sure to have synchronized with 1936 * last_siginfo, so that we are sure to have synchronized with
1942 * any signal-sending on another CPU that wants to examine it. 1937 * any signal-sending on another CPU that wants to examine it.
@@ -2092,7 +2087,7 @@ static bool do_signal_stop(int signr)
2092 } 2087 }
2093 2088
2094 /* Now we don't run again until woken by SIGCONT or SIGKILL */ 2089 /* Now we don't run again until woken by SIGCONT or SIGKILL */
2095 schedule(); 2090 freezable_schedule();
2096 return true; 2091 return true;
2097 } else { 2092 } else {
2098 /* 2093 /*
@@ -2138,10 +2133,9 @@ static void do_jobctl_trap(void)
2138 } 2133 }
2139} 2134}
2140 2135
2141static int ptrace_signal(int signr, siginfo_t *info, 2136static int ptrace_signal(int signr, siginfo_t *info)
2142 struct pt_regs *regs, void *cookie)
2143{ 2137{
2144 ptrace_signal_deliver(regs, cookie); 2138 ptrace_signal_deliver();
2145 /* 2139 /*
2146 * We do not check sig_kernel_stop(signr) but set this marker 2140 * We do not check sig_kernel_stop(signr) but set this marker
2147 * unconditionally because we do not know whether debugger will 2141 * unconditionally because we do not know whether debugger will
@@ -2200,15 +2194,14 @@ int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka,
2200 if (unlikely(uprobe_deny_signal())) 2194 if (unlikely(uprobe_deny_signal()))
2201 return 0; 2195 return 0;
2202 2196
2203relock:
2204 /* 2197 /*
2205 * We'll jump back here after any time we were stopped in TASK_STOPPED. 2198 * Do this once, we can't return to user-mode if freezing() == T.
2206 * While in TASK_STOPPED, we were considered "frozen enough". 2199 * do_signal_stop() and ptrace_stop() do freezable_schedule() and
2207 * Now that we woke up, it's crucial if we're supposed to be 2200 * thus do not need another check after return.
2208 * frozen that we freeze now before running anything substantial.
2209 */ 2201 */
2210 try_to_freeze(); 2202 try_to_freeze();
2211 2203
2204relock:
2212 spin_lock_irq(&sighand->siglock); 2205 spin_lock_irq(&sighand->siglock);
2213 /* 2206 /*
2214 * Every stopped thread goes here after wakeup. Check to see if 2207 * Every stopped thread goes here after wakeup. Check to see if
@@ -2265,8 +2258,7 @@ relock:
2265 break; /* will return 0 */ 2258 break; /* will return 0 */
2266 2259
2267 if (unlikely(current->ptrace) && signr != SIGKILL) { 2260 if (unlikely(current->ptrace) && signr != SIGKILL) {
2268 signr = ptrace_signal(signr, info, 2261 signr = ptrace_signal(signr, info);
2269 regs, cookie);
2270 if (!signr) 2262 if (!signr)
2271 continue; 2263 continue;
2272 } 2264 }
@@ -2351,7 +2343,7 @@ relock:
2351 2343
2352 if (sig_kernel_coredump(signr)) { 2344 if (sig_kernel_coredump(signr)) {
2353 if (print_fatal_signals) 2345 if (print_fatal_signals)
2354 print_fatal_signal(regs, info->si_signo); 2346 print_fatal_signal(info->si_signo);
2355 /* 2347 /*
2356 * If it was able to dump core, this kills all 2348 * If it was able to dump core, this kills all
2357 * other threads in the group and synchronizes with 2349 * other threads in the group and synchronizes with
@@ -2360,7 +2352,7 @@ relock:
2360 * first and our do_group_exit call below will use 2352 * first and our do_group_exit call below will use
2361 * that value and ignore the one we pass it. 2353 * that value and ignore the one we pass it.
2362 */ 2354 */
2363 do_coredump(info, regs); 2355 do_coredump(info);
2364 } 2356 }
2365 2357
2366 /* 2358 /*
@@ -3103,6 +3095,79 @@ do_sigaltstack (const stack_t __user *uss, stack_t __user *uoss, unsigned long s
3103out: 3095out:
3104 return error; 3096 return error;
3105} 3097}
3098#ifdef CONFIG_GENERIC_SIGALTSTACK
3099SYSCALL_DEFINE2(sigaltstack,const stack_t __user *,uss, stack_t __user *,uoss)
3100{
3101 return do_sigaltstack(uss, uoss, current_user_stack_pointer());
3102}
3103#endif
3104
3105int restore_altstack(const stack_t __user *uss)
3106{
3107 int err = do_sigaltstack(uss, NULL, current_user_stack_pointer());
3108 /* squash all but EFAULT for now */
3109 return err == -EFAULT ? err : 0;
3110}
3111
3112int __save_altstack(stack_t __user *uss, unsigned long sp)
3113{
3114 struct task_struct *t = current;
3115 return __put_user((void __user *)t->sas_ss_sp, &uss->ss_sp) |
3116 __put_user(sas_ss_flags(sp), &uss->ss_flags) |
3117 __put_user(t->sas_ss_size, &uss->ss_size);
3118}
3119
3120#ifdef CONFIG_COMPAT
3121#ifdef CONFIG_GENERIC_SIGALTSTACK
3122asmlinkage long compat_sys_sigaltstack(const compat_stack_t __user *uss_ptr,
3123 compat_stack_t __user *uoss_ptr)
3124{
3125 stack_t uss, uoss;
3126 int ret;
3127 mm_segment_t seg;
3128
3129 if (uss_ptr) {
3130 compat_stack_t uss32;
3131
3132 memset(&uss, 0, sizeof(stack_t));
3133 if (copy_from_user(&uss32, uss_ptr, sizeof(compat_stack_t)))
3134 return -EFAULT;
3135 uss.ss_sp = compat_ptr(uss32.ss_sp);
3136 uss.ss_flags = uss32.ss_flags;
3137 uss.ss_size = uss32.ss_size;
3138 }
3139 seg = get_fs();
3140 set_fs(KERNEL_DS);
3141 ret = do_sigaltstack((stack_t __force __user *) (uss_ptr ? &uss : NULL),
3142 (stack_t __force __user *) &uoss,
3143 compat_user_stack_pointer());
3144 set_fs(seg);
3145 if (ret >= 0 && uoss_ptr) {
3146 if (!access_ok(VERIFY_WRITE, uoss_ptr, sizeof(compat_stack_t)) ||
3147 __put_user(ptr_to_compat(uoss.ss_sp), &uoss_ptr->ss_sp) ||
3148 __put_user(uoss.ss_flags, &uoss_ptr->ss_flags) ||
3149 __put_user(uoss.ss_size, &uoss_ptr->ss_size))
3150 ret = -EFAULT;
3151 }
3152 return ret;
3153}
3154
3155int compat_restore_altstack(const compat_stack_t __user *uss)
3156{
3157 int err = compat_sys_sigaltstack(uss, NULL);
3158 /* squash all but -EFAULT for now */
3159 return err == -EFAULT ? err : 0;
3160}
3161
3162int __compat_save_altstack(compat_stack_t __user *uss, unsigned long sp)
3163{
3164 struct task_struct *t = current;
3165 return __put_user(ptr_to_compat((void __user *)t->sas_ss_sp), &uss->ss_sp) |
3166 __put_user(sas_ss_flags(sp), &uss->ss_flags) |
3167 __put_user(t->sas_ss_size, &uss->ss_size);
3168}
3169#endif
3170#endif
3106 3171
3107#ifdef __ARCH_WANT_SYS_SIGPENDING 3172#ifdef __ARCH_WANT_SYS_SIGPENDING
3108 3173