[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;
 }
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.