X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fs390%2Fkernel%2Fsignal.c;h=d5b6481532ad3a1fe2538388f18a01fc93c2158a;hb=9bf4aaab3e101692164d49b7ca357651eb691cb6;hp=2379b673450bab161eca7f74eefec43f2f3bd36a;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c index 2379b6734..d5b648153 100644 --- a/arch/s390/kernel/signal.c +++ b/arch/s390/kernel/signal.c @@ -39,6 +39,7 @@ typedef struct __u8 callee_used_stack[__SIGNAL_FRAMESIZE]; struct sigcontext sc; _sigregs sregs; + int signo; __u8 retcode[S390_SYSCALL_SIZE]; } sigframe; @@ -77,8 +78,9 @@ sys_sigsuspend(struct pt_regs * regs, int history0, int history1, } } -asmlinkage int -sys_rt_sigsuspend(struct pt_regs * regs,sigset_t *unewset, size_t sigsetsize) +asmlinkage long +sys_rt_sigsuspend(struct pt_regs *regs, sigset_t __user *unewset, + size_t sigsetsize) { sigset_t saveset, newset; @@ -105,9 +107,9 @@ sys_rt_sigsuspend(struct pt_regs * regs,sigset_t *unewset, size_t sigsetsize) } } -asmlinkage int -sys_sigaction(int sig, const struct old_sigaction *act, - struct old_sigaction *oact) +asmlinkage long +sys_sigaction(int sig, const struct old_sigaction __user *act, + struct old_sigaction __user *oact) { struct k_sigaction new_ka, old_ka; int ret; @@ -137,8 +139,9 @@ sys_sigaction(int sig, const struct old_sigaction *act, return ret; } -asmlinkage int -sys_sigaltstack(const stack_t *uss, stack_t *uoss, struct pt_regs *regs) +asmlinkage long +sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, + struct pt_regs *regs) { return do_sigaltstack(uss, uoss, regs->gprs[15]); } @@ -146,7 +149,7 @@ sys_sigaltstack(const stack_t *uss, stack_t *uoss, struct pt_regs *regs) /* Returns non-zero on fault. */ -static int save_sigregs(struct pt_regs *regs, _sigregs *sregs) +static int save_sigregs(struct pt_regs *regs, _sigregs __user *sregs) { unsigned long old_mask = regs->psw.mask; int err; @@ -175,7 +178,7 @@ static int save_sigregs(struct pt_regs *regs, _sigregs *sregs) } /* Returns positive number on error */ -static int restore_sigregs(struct pt_regs *regs, _sigregs *sregs) +static int restore_sigregs(struct pt_regs *regs, _sigregs __user *sregs) { unsigned long old_mask = regs->psw.mask; int err; @@ -208,7 +211,7 @@ static int restore_sigregs(struct pt_regs *regs, _sigregs *sregs) asmlinkage long sys_sigreturn(struct pt_regs *regs) { - sigframe *frame = (sigframe *)regs->gprs[15]; + sigframe __user *frame = (sigframe __user *)regs->gprs[15]; sigset_t set; if (verify_area(VERIFY_READ, frame, sizeof(*frame))) @@ -234,7 +237,7 @@ badframe: asmlinkage long sys_rt_sigreturn(struct pt_regs *regs) { - rt_sigframe *frame = (rt_sigframe *)regs->gprs[15]; + rt_sigframe __user *frame = (rt_sigframe __user *)regs->gprs[15]; sigset_t set; if (verify_area(VERIFY_READ, frame, sizeof(*frame))) @@ -269,7 +272,7 @@ badframe: /* * Determine which stack to use.. */ -static inline void * +static inline void __user * get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size) { unsigned long sp; @@ -290,7 +293,7 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size) sp = (unsigned long) ka->sa.sa_restorer; } - return (void *)((sp - frame_size) & -8ul); + return (void __user *)((sp - frame_size) & -8ul); } static inline int map_signal(int sig) @@ -306,7 +309,9 @@ static inline int map_signal(int sig) static void setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, struct pt_regs * regs) { - sigframe *frame = get_sigframe(ka, regs, sizeof(sigframe)); + sigframe __user *frame; + + frame = get_sigframe(ka, regs, sizeof(sigframe)); if (!access_ok(VERIFY_WRITE, frame, sizeof(sigframe))) goto give_sigsegv; @@ -326,13 +331,13 @@ static void setup_frame(int sig, struct k_sigaction *ka, } else { regs->gprs[14] = (unsigned long) frame->retcode | PSW_ADDR_AMODE; - if (__put_user(S390_SYSCALL_OPCODE | __NR_sigreturn, - (u16 *)(frame->retcode))) + if (__put_user(S390_SYSCALL_OPCODE | __NR_sigreturn, + (u16 __user *)(frame->retcode))) goto give_sigsegv; } /* Set up backchain. */ - if (__put_user(regs->gprs[15], (addr_t *) frame)) + if (__put_user(regs->gprs[15], (addr_t __user *) frame)) goto give_sigsegv; /* Set up registers for signal handler */ @@ -346,6 +351,10 @@ static void setup_frame(int sig, struct k_sigaction *ka, To avoid breaking binary compatibility, they are passed as args. */ regs->gprs[4] = current->thread.trap_no; regs->gprs[5] = current->thread.prot_addr; + + /* Place signal number on stack to allow backtrace from handler. */ + if (__put_user(regs->gprs[2], (int __user *) &frame->signo)) + goto give_sigsegv; return; give_sigsegv: @@ -358,7 +367,9 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *set, struct pt_regs * regs) { int err = 0; - rt_sigframe *frame = get_sigframe(ka, regs, sizeof(rt_sigframe)); + rt_sigframe __user *frame; + + frame = get_sigframe(ka, regs, sizeof(rt_sigframe)); if (!access_ok(VERIFY_WRITE, frame, sizeof(rt_sigframe))) goto give_sigsegv; @@ -385,12 +396,12 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, } else { regs->gprs[14] = (unsigned long) frame->retcode | PSW_ADDR_AMODE; - err |= __put_user(S390_SYSCALL_OPCODE | __NR_rt_sigreturn, - (u16 *)(frame->retcode)); + err |= __put_user(S390_SYSCALL_OPCODE | __NR_rt_sigreturn, + (u16 __user *)(frame->retcode)); } /* Set up backchain. */ - if (__put_user(regs->gprs[15], (addr_t *) frame)) + if (__put_user(regs->gprs[15], (addr_t __user *) frame)) goto give_sigsegv; /* Set up registers for signal handler */