diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-02-23 18:50:11 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-02-23 18:50:11 -0800 |
commit | 9e2d59ad580d590134285f361a0e80f0e98c0207 (patch) | |
tree | f3232be75781484193413f32ec82c21f6d8eb76e /arch/parisc | |
parent | 5ce1a70e2f00f0bce0cab57f798ca354b9496169 (diff) | |
parent | 235b80226b986dabcbba844968f7807866bd0bfe (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/signal
Pull signal handling cleanups from Al Viro:
"This is the first pile; another one will come a bit later and will
contain SYSCALL_DEFINE-related patches.
- a bunch of signal-related syscalls (both native and compat)
unified.
- a bunch of compat syscalls switched to COMPAT_SYSCALL_DEFINE
(fixing several potential problems with missing argument
validation, while we are at it)
- a lot of now-pointless wrappers killed
- a couple of architectures (cris and hexagon) forgot to save
altstack settings into sigframe, even though they used the
(uninitialized) values in sigreturn; fixed.
- microblaze fixes for delivery of multiple signals arriving at once
- saner set of helpers for signal delivery introduced, several
architectures switched to using those."
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/signal: (143 commits)
x86: convert to ksignal
sparc: convert to ksignal
arm: switch to struct ksignal * passing
alpha: pass k_sigaction and siginfo_t using ksignal pointer
burying unused conditionals
make do_sigaltstack() static
arm64: switch to generic old sigaction() (compat-only)
arm64: switch to generic compat rt_sigaction()
arm64: switch compat to generic old sigsuspend
arm64: switch to generic compat rt_sigqueueinfo()
arm64: switch to generic compat rt_sigpending()
arm64: switch to generic compat rt_sigprocmask()
arm64: switch to generic sigaltstack
sparc: switch to generic old sigsuspend
sparc: COMPAT_SYSCALL_DEFINE does all sign-extension as well as SYSCALL_DEFINE
sparc: kill sign-extending wrappers for native syscalls
kill sparc32_open()
sparc: switch to use of generic old sigaction
sparc: switch sys_compat_rt_sigaction() to COMPAT_SYSCALL_DEFINE
mips: switch to generic sys_fork() and sys_clone()
...
Diffstat (limited to 'arch/parisc')
-rw-r--r-- | arch/parisc/include/asm/signal.h | 6 | ||||
-rw-r--r-- | arch/parisc/include/asm/unistd.h | 3 | ||||
-rw-r--r-- | arch/parisc/kernel/entry.S | 38 | ||||
-rw-r--r-- | arch/parisc/kernel/signal.c | 19 | ||||
-rw-r--r-- | arch/parisc/kernel/signal32.c | 149 | ||||
-rw-r--r-- | arch/parisc/kernel/signal32.h | 23 | ||||
-rw-r--r-- | arch/parisc/kernel/sys32.h | 12 | ||||
-rw-r--r-- | arch/parisc/kernel/syscall_table.S | 8 |
8 files changed, 10 insertions, 248 deletions
diff --git a/arch/parisc/include/asm/signal.h b/arch/parisc/include/asm/signal.h index b1a7c4c4a53..81a54577397 100644 --- a/arch/parisc/include/asm/signal.h +++ b/arch/parisc/include/asm/signal.h @@ -20,15 +20,13 @@ typedef struct { unsigned long sig[_NSIG_WORDS]; } sigset_t; +#ifndef __KERNEL__ struct sigaction { __sighandler_t sa_handler; unsigned long sa_flags; sigset_t sa_mask; /* mask last for extensibility */ }; - -struct k_sigaction { - struct sigaction sa; -}; +#endif #include <asm/sigcontext.h> diff --git a/arch/parisc/include/asm/unistd.h b/arch/parisc/include/asm/unistd.h index 74f801ebbe7..ae9a46cbfd9 100644 --- a/arch/parisc/include/asm/unistd.h +++ b/arch/parisc/include/asm/unistd.h @@ -161,9 +161,6 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) \ #define __ARCH_WANT_SYS_OLDUMOUNT #define __ARCH_WANT_SYS_SIGPENDING #define __ARCH_WANT_SYS_SIGPROCMASK -#define __ARCH_WANT_SYS_RT_SIGACTION -#define __ARCH_WANT_SYS_RT_SIGSUSPEND -#define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND #define __ARCH_WANT_SYS_FORK #define __ARCH_WANT_SYS_VFORK #define __ARCH_WANT_SYS_CLONE diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S index 7c9648919c9..f33201bf897 100644 --- a/arch/parisc/kernel/entry.S +++ b/arch/parisc/kernel/entry.S @@ -1748,44 +1748,6 @@ ENTRY(sys_rt_sigreturn_wrapper) LDREG PT_GR28(%r1),%r28 /* reload original r28 for syscall_exit */ ENDPROC(sys_rt_sigreturn_wrapper) -ENTRY(sys_sigaltstack_wrapper) - /* Get the user stack pointer */ - LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1 - ldo TASK_REGS(%r1),%r24 /* get pt regs */ - LDREG TASK_PT_GR30(%r24),%r24 - STREG %r2, -RP_OFFSET(%r30) -#ifdef CONFIG_64BIT - ldo FRAME_SIZE(%r30), %r30 - BL do_sigaltstack,%r2 - ldo -16(%r30),%r29 /* Reference param save area */ -#else - BL do_sigaltstack,%r2 - ldo FRAME_SIZE(%r30), %r30 -#endif - - ldo -FRAME_SIZE(%r30), %r30 - LDREG -RP_OFFSET(%r30), %r2 - bv %r0(%r2) - nop -ENDPROC(sys_sigaltstack_wrapper) - -#ifdef CONFIG_64BIT -ENTRY(sys32_sigaltstack_wrapper) - /* Get the user stack pointer */ - LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r24 - LDREG TASK_PT_GR30(%r24),%r24 - STREG %r2, -RP_OFFSET(%r30) - ldo FRAME_SIZE(%r30), %r30 - BL do_sigaltstack32,%r2 - ldo -16(%r30),%r29 /* Reference param save area */ - - ldo -FRAME_SIZE(%r30), %r30 - LDREG -RP_OFFSET(%r30), %r2 - bv %r0(%r2) - nop -ENDPROC(sys32_sigaltstack_wrapper) -#endif - ENTRY(syscall_exit) /* NOTE: HP-UX syscalls also come through here * after hpux_syscall_exit fixes up return diff --git a/arch/parisc/kernel/signal.c b/arch/parisc/kernel/signal.c index 52c85b2f502..98e9e712656 100644 --- a/arch/parisc/kernel/signal.c +++ b/arch/parisc/kernel/signal.c @@ -143,7 +143,7 @@ sys_rt_sigreturn(struct pt_regs *regs, int in_syscall) goto give_sigsegv; DBG(1,"sys_rt_sigreturn: usp %#08lx stack 0x%p\n", usp, &compat_frame->uc.uc_stack); - if (do_sigaltstack32(&compat_frame->uc.uc_stack, NULL, usp) == -EFAULT) + if (compat_restore_altstack(&compat_frame->uc.uc_stack)) goto give_sigsegv; } else #endif @@ -154,7 +154,7 @@ sys_rt_sigreturn(struct pt_regs *regs, int in_syscall) goto give_sigsegv; DBG(1,"sys_rt_sigreturn: usp %#08lx stack 0x%p\n", usp, &frame->uc.uc_stack); - if (do_sigaltstack(&frame->uc.uc_stack, NULL, usp) == -EFAULT) + if (restore_altstack(&frame->uc.uc_stack)) goto give_sigsegv; } @@ -262,15 +262,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, if (is_compat_task()) { DBG(1,"setup_rt_frame: frame->info = 0x%p\n", &compat_frame->info); err |= copy_siginfo_to_user32(&compat_frame->info, info); - DBG(1,"SETUP_RT_FRAME: 1\n"); - compat_val = (compat_int_t)current->sas_ss_sp; - err |= __put_user(compat_val, &compat_frame->uc.uc_stack.ss_sp); - DBG(1,"SETUP_RT_FRAME: 2\n"); - compat_val = (compat_int_t)current->sas_ss_size; - err |= __put_user(compat_val, &compat_frame->uc.uc_stack.ss_size); - DBG(1,"SETUP_RT_FRAME: 3\n"); - compat_val = sas_ss_flags(regs->gr[30]); - err |= __put_user(compat_val, &compat_frame->uc.uc_stack.ss_flags); + err |= __compat_save_altstack( &compat_frame->uc.uc_stack, regs->gr[30]); DBG(1,"setup_rt_frame: frame->uc = 0x%p\n", &compat_frame->uc); DBG(1,"setup_rt_frame: frame->uc.uc_mcontext = 0x%p\n", &compat_frame->uc.uc_mcontext); err |= setup_sigcontext32(&compat_frame->uc.uc_mcontext, @@ -282,10 +274,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, { DBG(1,"setup_rt_frame: frame->info = 0x%p\n", &frame->info); err |= copy_siginfo_to_user(&frame->info, info); - err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp); - err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size); - err |= __put_user(sas_ss_flags(regs->gr[30]), - &frame->uc.uc_stack.ss_flags); + err |= __save_altstack(&frame->uc.uc_stack, regs->gr[30]); DBG(1,"setup_rt_frame: frame->uc = 0x%p\n", &frame->uc); DBG(1,"setup_rt_frame: frame->uc.uc_mcontext = 0x%p\n", &frame->uc.uc_mcontext); err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, in_syscall); diff --git a/arch/parisc/kernel/signal32.c b/arch/parisc/kernel/signal32.c index 2ddcabb616c..33eca1b0492 100644 --- a/arch/parisc/kernel/signal32.c +++ b/arch/parisc/kernel/signal32.c @@ -60,136 +60,6 @@ sigset_64to32(compat_sigset_t *s32, sigset_t *s64) s32->sig[1] = (s64->sig[0] >> 32) & 0xffffffffUL; } -static int -put_sigset32(compat_sigset_t __user *up, sigset_t *set, size_t sz) -{ - compat_sigset_t s; - - if (sz != sizeof(compat_sigset_t)) - return -EINVAL; - sigset_64to32(&s, set); - - return copy_to_user(up, &s, sizeof s); -} - -static int -get_sigset32(compat_sigset_t __user *up, sigset_t *set, size_t sz) -{ - compat_sigset_t s; - int r; - - if (sz != sizeof(compat_sigset_t)) - return -EINVAL; - - if ((r = copy_from_user(&s, up, sz)) == 0) { - sigset_32to64(set, &s); - } - - return r; -} - -int sys32_rt_sigprocmask(int how, compat_sigset_t __user *set, compat_sigset_t __user *oset, - unsigned int sigsetsize) -{ - sigset_t old_set, new_set; - int ret; - - if (set) { - ret = get_sigset32(set, &new_set, sigsetsize); - if (ret) - return ret; - } - - KERNEL_SYSCALL(ret, sys_rt_sigprocmask, how, set ? (sigset_t __user *)&new_set : NULL, - oset ? (sigset_t __user *)&old_set : NULL, sigsetsize); - - if (!ret && oset && put_sigset32(oset, &old_set, sigsetsize)) - return -EFAULT; - - return ret; -} - - -int sys32_rt_sigpending(compat_sigset_t __user *uset, unsigned int sigsetsize) -{ - int ret; - sigset_t set; - - KERNEL_SYSCALL(ret, sys_rt_sigpending, (sigset_t __user *)&set, sigsetsize); - - if (!ret && put_sigset32(uset, &set, sigsetsize)) - return -EFAULT; - - return ret; -} - -long -sys32_rt_sigaction(int sig, const struct sigaction32 __user *act, struct sigaction32 __user *oact, - size_t sigsetsize) -{ - struct k_sigaction32 new_sa32, old_sa32; - struct k_sigaction new_sa, old_sa; - int ret = -EINVAL; - - /* XXX: Don't preclude handling different sized sigset_t's. */ - if (sigsetsize != sizeof(compat_sigset_t)) - return -EINVAL; - - if (act) { - if (copy_from_user(&new_sa32.sa, act, sizeof new_sa32.sa)) - return -EFAULT; - new_sa.sa.sa_handler = (__sighandler_t)(unsigned long)new_sa32.sa.sa_handler; - new_sa.sa.sa_flags = new_sa32.sa.sa_flags; - sigset_32to64(&new_sa.sa.sa_mask, &new_sa32.sa.sa_mask); - } - - ret = do_sigaction(sig, act ? &new_sa : NULL, oact ? &old_sa : NULL); - - if (!ret && oact) { - sigset_64to32(&old_sa32.sa.sa_mask, &old_sa.sa.sa_mask); - old_sa32.sa.sa_flags = old_sa.sa.sa_flags; - old_sa32.sa.sa_handler = (__sighandler_t32)(unsigned long)old_sa.sa.sa_handler; - if (copy_to_user(oact, &old_sa32.sa, sizeof old_sa32.sa)) - return -EFAULT; - } - return ret; -} - -int -do_sigaltstack32 (const compat_stack_t __user *uss32, compat_stack_t __user *uoss32, unsigned long sp) -{ - compat_stack_t ss32, oss32; - stack_t ss, oss; - stack_t *ssp = NULL, *ossp = NULL; - int ret; - - if (uss32) { - if (copy_from_user(&ss32, uss32, sizeof ss32)) - return -EFAULT; - - ss.ss_sp = (void __user *)(unsigned long)ss32.ss_sp; - ss.ss_flags = ss32.ss_flags; - ss.ss_size = ss32.ss_size; - - ssp = &ss; - } - - if (uoss32) - ossp = &oss; - - KERNEL_SYSCALL(ret, do_sigaltstack, (const stack_t __user *)ssp, (stack_t __user *)ossp, sp); - - if (!ret && uoss32) { - oss32.ss_sp = (unsigned int)(unsigned long)oss.ss_sp; - oss32.ss_flags = oss.ss_flags; - oss32.ss_size = oss.ss_size; - if (copy_to_user(uoss32, &oss32, sizeof *uoss32)) - return -EFAULT; - } - - return ret; -} - long restore_sigcontext32(struct compat_sigcontext __user *sc, struct compat_regfile __user * rf, struct pt_regs *regs) @@ -506,22 +376,3 @@ copy_siginfo_to_user32 (compat_siginfo_t __user *to, siginfo_t *from) } return err; } - -asmlinkage long compat_sys_rt_sigqueueinfo(int pid, int sig, - struct compat_siginfo __user *uinfo) -{ - siginfo_t info; - - if (copy_siginfo_from_user32(&info, uinfo)) - return -EFAULT; - - /* Not even root can pretend to send signals from the kernel. - Nor can they impersonate a kill(), which adds source info. */ - if (info.si_code >= 0) - return -EPERM; - info.si_signo = sig; - - /* POSIX.1b doesn't mention process groups. */ - return kill_proc_info(sig, &info, pid); -} - diff --git a/arch/parisc/kernel/signal32.h b/arch/parisc/kernel/signal32.h index 08a88b5349a..72ab41a51f3 100644 --- a/arch/parisc/kernel/signal32.h +++ b/arch/parisc/kernel/signal32.h @@ -21,23 +21,6 @@ #include <linux/compat.h> -typedef compat_uptr_t compat_sighandler_t; - -typedef struct compat_sigaltstack { - compat_uptr_t ss_sp; - compat_int_t ss_flags; - compat_size_t ss_size; -} compat_stack_t; - -/* Most things should be clean enough to redefine this at will, if care - is taken to make libc match. */ - -struct compat_sigaction { - compat_sighandler_t sa_handler; - compat_uint_t sa_flags; - compat_sigset_t sa_mask; /* mask last for extensibility */ -}; - /* 32-bit ucontext as seen from an 64-bit kernel */ struct compat_ucontext { compat_uint_t uc_flags; @@ -51,10 +34,6 @@ struct compat_ucontext { /* ELF32 signal handling */ -struct k_sigaction32 { - struct compat_sigaction sa; -}; - int copy_siginfo_to_user32 (compat_siginfo_t __user *to, siginfo_t *from); int copy_siginfo_from_user32 (siginfo_t *to, compat_siginfo_t __user *from); @@ -102,8 +81,6 @@ struct compat_rt_sigframe { void sigset_32to64(sigset_t *s64, compat_sigset_t *s32); void sigset_64to32(compat_sigset_t *s32, sigset_t *s64); -int do_sigaltstack32 (const compat_stack_t __user *uss32, - compat_stack_t __user *uoss32, unsigned long sp); long restore_sigcontext32(struct compat_sigcontext __user *sc, struct compat_regfile __user *rf, struct pt_regs *regs); diff --git a/arch/parisc/kernel/sys32.h b/arch/parisc/kernel/sys32.h index 06c2090cfab..60dd470f39f 100644 --- a/arch/parisc/kernel/sys32.h +++ b/arch/parisc/kernel/sys32.h @@ -33,16 +33,4 @@ set_fs (old_fs); \ } -#ifdef CONFIG_COMPAT - -typedef __u32 __sighandler_t32; - -struct sigaction32 { - __sighandler_t32 sa_handler; - unsigned int sa_flags; - compat_sigset_t sa_mask; /* mask last for extensibility */ -}; - -#endif - #endif diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S index 129fd472c47..fc9cab1cc2d 100644 --- a/arch/parisc/kernel/syscall_table.S +++ b/arch/parisc/kernel/syscall_table.S @@ -252,7 +252,7 @@ ENTRY_SAME(mremap) ENTRY_SAME(setresuid) ENTRY_SAME(getresuid) /* 165 */ - ENTRY_DIFF(sigaltstack_wrapper) + ENTRY_COMP(sigaltstack) ENTRY_SAME(ni_syscall) /* query_module */ ENTRY_SAME(poll) /* structs contain pointers and an in_addr... */ @@ -262,9 +262,9 @@ ENTRY_SAME(prctl) /* signals need a careful review */ ENTRY_SAME(rt_sigreturn_wrapper) - ENTRY_DIFF(rt_sigaction) - ENTRY_DIFF(rt_sigprocmask) /* 175 */ - ENTRY_DIFF(rt_sigpending) + ENTRY_COMP(rt_sigaction) + ENTRY_COMP(rt_sigprocmask) /* 175 */ + ENTRY_COMP(rt_sigpending) ENTRY_COMP(rt_sigtimedwait) /* even though the struct siginfo_t is different, it appears like * all the paths use values which should be same wide and narrow. |