[parisc-linux] [PATCH] Compat signal fixes for 64-bit parisc.
Carlos O'Donell
carlos at systemhalted.org
Mon Feb 12 19:14:28 MST 2007
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.
<carlos at systemhalted.org>
[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 <carlos at systemhalted.org>
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;
}
More information about the parisc-linux
mailing list