diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-06-16 23:00:36 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-06-16 23:00:36 +0000 |
commit | 14dd2ec093cfabda3ae7efeeaf0e23c66ebaccc0 (patch) | |
tree | 9a9ce5cff6ef92faa6e07a82785b9a6d6838f7e4 /arch/sparc64/kernel/signal.c | |
parent | 847290510f811c572cc2aa80c1f02a04721410b1 (diff) |
Merge with 2.4.0-test1.
Diffstat (limited to 'arch/sparc64/kernel/signal.c')
-rw-r--r-- | arch/sparc64/kernel/signal.c | 34 |
1 files changed, 33 insertions, 1 deletions
diff --git a/arch/sparc64/kernel/signal.c b/arch/sparc64/kernel/signal.c index efd6a64d1..f893e7f3a 100644 --- a/arch/sparc64/kernel/signal.c +++ b/arch/sparc64/kernel/signal.c @@ -42,6 +42,38 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs, /* #define DEBUG_SIGNALS_TRACE 1 */ /* #define DEBUG_SIGNALS_MAPS 1 */ +int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from) +{ + if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t))) + return -EFAULT; + if (from->si_code < 0) + return __copy_to_user(to, from, sizeof(siginfo_t)); + else { + int err; + + /* If you change siginfo_t structure, please be sure + this code is fixed accordingly. + It should never copy any pad contained in the structure + to avoid security leaks, but must copy the generic + 3 ints plus the relevant union member. */ + err = __put_user(*(long *)&from->si_signo, (long *)&to->si_signo); + err |= __put_user((short)from->si_code, &to->si_code); + switch (from->si_code >> 16) { + case __SI_CHLD >> 16: + err |= __put_user(from->si_utime, &to->si_utime); + err |= __put_user(from->si_stime, &to->si_stime); + case __SI_FAULT >> 16: + case __SI_POLL >> 16: + err |= __put_user(from->si_trapno, &to->si_trapno); + default: + err |= __put_user(from->si_addr, &to->si_addr); + break; + /* case __SI_RT: This is not generated by the kernel as of now. */ + } + return err; + } +} + /* {set, get}context() needed for 64-bit SparcLinux userland. */ asmlinkage void sparc64_set_context(struct pt_regs *regs) { @@ -512,7 +544,7 @@ setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, sizeof(struct reg_window)); if (info) - err |= copy_to_user(&sf->info, info, sizeof(siginfo_t)); + err |= copy_siginfo_to_user(&sf->info, info); else { err |= __put_user(signo, &sf->info.si_signo); err |= __put_user(SI_NOINFO, &sf->info.si_code); |