[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