diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-12-20 21:05:28 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-12-20 21:05:28 -0500 |
commit | 54d46ea993744c5408e39ce0cb4851e13cbea716 (patch) | |
tree | 8e38fa92cc2ae72e0353c44e1e68be9bf5a7a058 /kernel | |
parent | f59dc2bb5a50b26ea751f9eac1c81e4cc7de5257 (diff) | |
parent | 50ececcfa7d1acee085b2c518cad495062db6379 (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.c | 2 | ||||
-rw-r--r-- | kernel/kmod.c | 6 | ||||
-rw-r--r-- | kernel/signal.c | 74 |
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 |
1628 | SYSCALL_DEFINE0(fork) | 1626 | SYSCALL_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 | |||
3094 | out: | 3095 | out: |
3095 | return error; | 3096 | return error; |
3096 | } | 3097 | } |
3098 | #ifdef CONFIG_GENERIC_SIGALTSTACK | ||
3099 | SYSCALL_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 | |||
3105 | int 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 | |||
3112 | int __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 | ||
3122 | asmlinkage 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 | |||
3155 | int 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 | |||
3162 | int __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 | ||