aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-12-20 21:05:28 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-12-20 21:05:28 -0500
commit54d46ea993744c5408e39ce0cb4851e13cbea716 (patch)
tree8e38fa92cc2ae72e0353c44e1e68be9bf5a7a058 /kernel
parentf59dc2bb5a50b26ea751f9eac1c81e4cc7de5257 (diff)
parent50ececcfa7d1acee085b2c518cad495062db6379 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/signal
Pull signal handling cleanups from Al Viro: "sigaltstack infrastructure + conversion for x86, alpha and um, COMPAT_SYSCALL_DEFINE infrastructure. Note that there are several conflicts between "unify SS_ONSTACK/SS_DISABLE definitions" and UAPI patches in mainline; resolution is trivial - just remove definitions of SS_ONSTACK and SS_DISABLED from arch/*/uapi/asm/signal.h; they are all identical and include/uapi/linux/signal.h contains the unified variant." Fixed up conflicts as per Al. * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/signal: alpha: switch to generic sigaltstack new helpers: __save_altstack/__compat_save_altstack, switch x86 and um to those generic compat_sys_sigaltstack() introduce generic sys_sigaltstack(), switch x86 and um to it new helper: compat_user_stack_pointer() new helper: restore_altstack() unify SS_ONSTACK/SS_DISABLE definitions new helper: current_user_stack_pointer() missing user_stack_pointer() instances Bury the conditionals from kernel_thread/kernel_execve series COMPAT_SYSCALL_DEFINE: infrastructure
Diffstat (limited to 'kernel')
-rw-r--r--kernel/fork.c2
-rw-r--r--kernel/kmod.c6
-rw-r--r--kernel/signal.c74
3 files changed, 77 insertions, 5 deletions
diff --git a/kernel/fork.c b/kernel/fork.c
index 85f6d536608d..a31b823b3c2d 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -1613,7 +1613,6 @@ long do_fork(unsigned long clone_flags,
1613 return nr; 1613 return nr;
1614} 1614}
1615 1615
1616#ifdef CONFIG_GENERIC_KERNEL_THREAD
1617/* 1616/*
1618 * Create a kernel thread. 1617 * Create a kernel thread.
1619 */ 1618 */
@@ -1622,7 +1621,6 @@ pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
1622 return do_fork(flags|CLONE_VM|CLONE_UNTRACED, (unsigned long)fn, 1621 return do_fork(flags|CLONE_VM|CLONE_UNTRACED, (unsigned long)fn,
1623 (unsigned long)arg, NULL, NULL); 1622 (unsigned long)arg, NULL, NULL);
1624} 1623}
1625#endif
1626 1624
1627#ifdef __ARCH_WANT_SYS_FORK 1625#ifdef __ARCH_WANT_SYS_FORK
1628SYSCALL_DEFINE0(fork) 1626SYSCALL_DEFINE0(fork)
diff --git a/kernel/kmod.c b/kernel/kmod.c
index 1c317e386831..0023a87e8de6 100644
--- a/kernel/kmod.c
+++ b/kernel/kmod.c
@@ -219,9 +219,9 @@ static int ____call_usermodehelper(void *data)
219 219
220 commit_creds(new); 220 commit_creds(new);
221 221
222 retval = kernel_execve(sub_info->path, 222 retval = do_execve(sub_info->path,
223 (const char *const *)sub_info->argv, 223 (const char __user *const __user *)sub_info->argv,
224 (const char *const *)sub_info->envp); 224 (const char __user *const __user *)sub_info->envp);
225 if (!retval) 225 if (!retval)
226 return 0; 226 return 0;
227 227
diff --git a/kernel/signal.c b/kernel/signal.c
index 580a91e63471..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
@@ -3094,6 +3095,79 @@ do_sigaltstack (const stack_t __user *uss, stack_t __user *uoss, unsigned long s
3094out: 3095out:
3095 return error; 3096 return error;
3096} 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
3097 3171
3098#ifdef __ARCH_WANT_SYS_SIGPENDING 3172#ifdef __ARCH_WANT_SYS_SIGPENDING
3099 3173