From f671c45df23005692daa200aba768c642fb14ef2 Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Sun, 15 Jan 2006 14:10:29 -0500 Subject: [PARISC] Arch-specific compat signals Add enough arch-specific compat signals code to enable parisc64 to compile and boot out of the mainline tree. There are likely still many dragons here, but this is a start to squashing the last big difference between the mainline tree and the parisc-linux tree. The remaining bugs can be squashed as they come up. Signed-off-by: Kyle McMartin --- arch/parisc/kernel/signal32.c | 102 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 101 insertions(+), 1 deletion(-) (limited to 'arch/parisc/kernel/signal32.c') diff --git a/arch/parisc/kernel/signal32.c b/arch/parisc/kernel/signal32.c index 0792e20efef3..a6b4231cafa1 100644 --- a/arch/parisc/kernel/signal32.c +++ b/arch/parisc/kernel/signal32.c @@ -31,7 +31,6 @@ #include #include -#include #include #include "signal32.h" @@ -398,3 +397,104 @@ setup_sigcontext32(struct compat_sigcontext __user *sc, struct compat_regfile __ return err; } + +int +copy_siginfo_from_user32 (siginfo_t *to, compat_siginfo_t __user *from) +{ + unsigned long tmp; + int err; + + if (!access_ok(VERIFY_READ, from, sizeof(compat_siginfo_t))) + return -EFAULT; + + err = __get_user(to->si_signo, &from->si_signo); + err |= __get_user(to->si_errno, &from->si_errno); + err |= __get_user(to->si_code, &from->si_code); + + if (to->si_code < 0) + err |= __copy_from_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE); + else { + switch (to->si_code >> 16) { + case __SI_CHLD >> 16: + err |= __get_user(to->si_utime, &from->si_utime); + err |= __get_user(to->si_stime, &from->si_stime); + err |= __get_user(to->si_status, &from->si_status); + default: + err |= __get_user(to->si_pid, &from->si_pid); + err |= __get_user(to->si_uid, &from->si_uid); + break; + case __SI_FAULT >> 16: + err |= __get_user(tmp, &from->si_addr); + to->si_addr = (void __user *) tmp; + break; + case __SI_POLL >> 16: + err |= __get_user(to->si_band, &from->si_band); + err |= __get_user(to->si_fd, &from->si_fd); + break; + case __SI_RT >> 16: /* This is not generated by the kernel as of now. */ + case __SI_MESGQ >> 16: + err |= __get_user(to->si_pid, &from->si_pid); + err |= __get_user(to->si_uid, &from->si_uid); + err |= __get_user(to->si_int, &from->si_int); + break; + } + } + return err; +} + +int +copy_siginfo_to_user32 (compat_siginfo_t __user *to, siginfo_t *from) +{ + unsigned int addr; + int err; + + if (!access_ok(VERIFY_WRITE, to, sizeof(compat_siginfo_t))) + return -EFAULT; + + /* 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. + This routine must convert siginfo from 64bit to 32bit as well + at the same time. */ + err = __put_user(from->si_signo, &to->si_signo); + err |= __put_user(from->si_errno, &to->si_errno); + err |= __put_user((short)from->si_code, &to->si_code); + if (from->si_code < 0) + err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE); + else { + 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); + err |= __put_user(from->si_status, &to->si_status); + default: + err |= __put_user(from->si_pid, &to->si_pid); + err |= __put_user(from->si_uid, &to->si_uid); + break; + case __SI_FAULT >> 16: + /* avoid type-checking warnings by copying _pad[0] in lieu of si_addr... */ + err |= __put_user(from->_sifields._pad[0], &to->si_addr); + break; + case __SI_POLL >> 16: + err |= __put_user(from->si_band, &to->si_band); + err |= __put_user(from->si_fd, &to->si_fd); + break; + case __SI_TIMER >> 16: + err |= __put_user(from->si_tid, &to->si_tid); + err |= __put_user(from->si_overrun, &to->si_overrun); + addr = (unsigned long) from->si_ptr; + err |= __put_user(addr, &to->si_ptr); + break; + case __SI_RT >> 16: /* Not generated by the kernel as of now. */ + case __SI_MESGQ >> 16: + err |= __put_user(from->si_uid, &to->si_uid); + err |= __put_user(from->si_pid, &to->si_pid); + addr = (unsigned long) from->si_ptr; + err |= __put_user(addr, &to->si_ptr); + break; + } + } + return err; +} -- cgit v1.2.3