[PATCH] Compat signal fixes for 64-bit parisc.
"Carlos O'Donell" <[email protected]>
| Newsgroups | gmane.linux.ports.hppa |
|---|---|
| Message-ID | <[email protected]> |
Willy, Kyle, I see we are back to using our antiquated version of copy_siginfo_to_user32. Let's stomp some bugs shall we? Please review. This fixes the tst-timer segfault with glibc head, and does a little cleanup. I have an acute feeling of deja-vu. Thankfully I feel taller than ever, and the whole fix only took a little sleuthing. For nostalgia read.. Date Wed, 10 Dec 2003 19:17:56 -0500 From Carlos O'Donell <> Subject [RFC] Compat siginfo_t for 64-bit kernels running 32-bit userspace. http://lkml.org/lkml/2003/12/10/225 ...and note the date. Patch at: http://www.parisc-linux.org/~carlos/patch-2007-02-12-signal32.diff Patch inline for review purposes only. Let me remind you that I'm a tool when it comes to using git, so I may need some hand holding again to remember the right incantation. <[email protected]> [PATCH] Compat signal fixes for 64-bit parisc. In copy_siginfo_to_user32: Employ the proper truncation and casting to copy the si_addr field without compiler warnings. The sigevent_t structure has a 64-bit si_ptr field that when copied to a 32-bit si_ptr will copy the wrong word. For the compat copy use the si_int field instead. In compat_sys_rt_sigtimedwait: The function should call the real sys_rt_sigqueueinfo not kill_proc_info. Signed-off-by: Carlos O'Donell <[email protected]> diff --git a/arch/parisc/kernel/signal32.c b/arch/parisc/kernel/signal32.c index 2cbb4af..32393dd 100644 --- a/arch/parisc/kernel/signal32.c +++ b/arch/parisc/kernel/signal32.c @@ -476,8 +476,8 @@ copy_siginfo_to_user32 (compat_siginfo_t 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); + addr = (unsigned int)((u64)from->si_addr & 0xffffffffUL); + err |= __put_user(addr, &to->si_addr); break; case __SI_POLL >> 16: err |= __put_user(from->si_band, &to->si_band); @@ -486,15 +486,15 @@ copy_siginfo_to_user32 (compat_siginfo_t 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); + addr = (unsigned int)from->si_int; + err |= __put_user(addr, &to->si_int); 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); + addr = (unsigned int)from->si_int; + err |= __put_user(addr, &to->si_int); break; } } @@ -505,17 +505,15 @@ asmlinkage long compat_sys_rt_sigqueuein struct compat_siginfo __user *uinfo) { siginfo_t info; + int ret; + mm_segment_t old_fs = get_fs(); 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); + set_fs (KERNEL_DS); + ret = sys_rt_sigqueueinfo(pid, sig, &info); + set_fs (old_fs); + return ret; }