public inbox for linux-arch@vger.kernel.org
 help / color / mirror / Atom feed
* Generic compat_sys_rt_sigqueueinfo
@ 2006-10-28 22:37 Kyle McMartin
  2006-10-28 22:47 ` Matthew Wilcox
                   ` (2 more replies)
  0 siblings, 3 replies; 11+ messages in thread
From: Kyle McMartin @ 2006-10-28 22:37 UTC (permalink / raw)
  To: akpm; +Cc: linux-arch

Every 32-on-64 arch (except parisc) was implementing effectively the
same sys32_rt_sigqueueinfo. Add a generic implementation taken from
x86_64 and add it to kernel/compat.c, which required the addition of
copy_siginfo_from_user32 on mips and powerpc. sparc64 had a sufficient
implementation for this purpose, so crib it for both those platforms.

This yields a nice clean up and is one step towards cleaning up some
of the compat signals mess parisc has been carrying out of tree for a few
years.

Signed-off-by: Kyle McMartin <kyle@parisc-linux.org>
--
[N.B. the modification to powerpc is probably wrong, since it seems
 to require a wrapper for handling the signed ints like sparc64 and s390
 have. -- Kyle]

 arch/ia64/ia32/ia32_entry.S        |    2 +-
 arch/ia64/ia32/ia32_signal.c       |   15 ---------------
 arch/mips/kernel/scall64-n32.S     |    2 +-
 arch/mips/kernel/scall64-o32.S     |    2 +-
 arch/mips/kernel/signal32.c        |   31 ++++++++++++++++---------------
 arch/parisc/kernel/syscall_table.S |    2 +-
 arch/powerpc/kernel/signal_32.c    |   33 +++++++++++++--------------------
 arch/s390/kernel/compat_linux.c    |   15 ---------------
 arch/s390/kernel/compat_wrapper.S  |    2 +-
 arch/sparc64/kernel/sys_sparc32.c  |   16 ----------------
 arch/x86_64/ia32/ia32entry.S       |    2 +-
 arch/x86_64/ia32/sys_ia32.c        |   15 ---------------
 kernel/compat.c                    |   17 +++++++++++++++++
 13 files changed, 52 insertions(+), 102 deletions(-)

diff --git a/arch/ia64/ia32/ia32_entry.S b/arch/ia64/ia32/ia32_entry.S
index a32cd59..8d41c2c 100644
--- a/arch/ia64/ia32/ia32_entry.S
+++ b/arch/ia64/ia32/ia32_entry.S
@@ -388,7 +388,7 @@ ia32_syscall_table:
 	data8 sys32_rt_sigprocmask /* 175 */
 	data8 sys_rt_sigpending
 	data8 compat_sys_rt_sigtimedwait
-	data8 sys32_rt_sigqueueinfo
+	data8 compat_sys_rt_sigqueueinfo
 	data8 sys32_rt_sigsuspend
 	data8 sys32_pread	  /* 180 */
 	data8 sys32_pwrite
diff --git a/arch/ia64/ia32/ia32_signal.c b/arch/ia64/ia32/ia32_signal.c
index b3355a9..00341ff 100644
--- a/arch/ia64/ia32/ia32_signal.c
+++ b/arch/ia64/ia32/ia32_signal.c
@@ -588,21 +588,6 @@ sys32_rt_sigprocmask (int how, compat_si
 }
 
 asmlinkage long
-sys32_rt_sigqueueinfo (int pid, int sig, compat_siginfo_t __user *uinfo)
-{
-	mm_segment_t old_fs = get_fs();
-	siginfo_t info;
-	int ret;
-
-	if (copy_siginfo_from_user32(&info, uinfo))
-		return -EFAULT;
-	set_fs(KERNEL_DS);
-	ret = sys_rt_sigqueueinfo(pid, sig, (siginfo_t __user *) &info);
-	set_fs(old_fs);
-	return ret;
-}
-
-asmlinkage long
 sys32_sigaction (int sig, struct old_sigaction32 __user *act, struct old_sigaction32 __user *oact)
 {
 	struct k_sigaction new_ka, old_ka;
diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S
index 67b92a1..013efe9 100644
--- a/arch/mips/kernel/scall64-n32.S
+++ b/arch/mips/kernel/scall64-n32.S
@@ -247,7 +247,7 @@ EXPORT(sysn32_call_table)
 	PTR	sys_capset
 	PTR	sys32_rt_sigpending		/* 6125 */
 	PTR	compat_sys_rt_sigtimedwait
-	PTR	sys32_rt_sigqueueinfo
+	PTR	compat_sys_rt_sigqueueinfo
 	PTR	sysn32_rt_sigsuspend
 	PTR	sys32_sigaltstack
 	PTR	compat_sys_utime		/* 6130 */
diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S
index 2875c4a..e9bc5a6 100644
--- a/arch/mips/kernel/scall64-o32.S
+++ b/arch/mips/kernel/scall64-o32.S
@@ -403,7 +403,7 @@ sys_call_table:
 	PTR	sys32_rt_sigprocmask 		/* 4195 */
 	PTR	sys32_rt_sigpending
 	PTR	compat_sys_rt_sigtimedwait
-	PTR	sys32_rt_sigqueueinfo
+	PTR	compat_sys_rt_sigqueueinfo
 	PTR	sys32_rt_sigsuspend
 	PTR	sys32_pread			/* 4200 */
 	PTR	sys32_pwrite
diff --git a/arch/mips/kernel/signal32.c b/arch/mips/kernel/signal32.c
index c86a5dd..b680e7d 100644
--- a/arch/mips/kernel/signal32.c
+++ b/arch/mips/kernel/signal32.c
@@ -463,6 +463,22 @@ int copy_siginfo_to_user32(compat_siginf
 	return err;
 }
 
+/* CAUTION: This is just a very minimalist implementation for the
+ *	    sake of compat_sys_rt_sigqueueinfo(), cribbed from sparc64.
+ */
+int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
+{
+	if (!access_ok(VERIFY_WRITE, from, sizeof(compat_siginfo_t)))
+		return -EFAULT;
+
+	if (copy_from_user(to, from, 3*sizeof(int)) ||
+	    copy_from_user(to->_sifields._pad, from->_sifields._pad,
+			   SI_PAD_SIZE))
+		return -EFAULT;
+
+	return 0;
+}
+
 save_static_function(sys32_sigreturn);
 __attribute_used__ noinline static void
 _sys32_sigreturn(nabi_no_regargs struct pt_regs regs)
@@ -950,21 +966,6 @@ asmlinkage int sys32_rt_sigpending(compa
 	return ret;
 }
 
-asmlinkage int sys32_rt_sigqueueinfo(int pid, int sig, compat_siginfo_t __user *uinfo)
-{
-	siginfo_t info;
-	int ret;
-	mm_segment_t old_fs = get_fs();
-
-	if (copy_from_user (&info, uinfo, 3*sizeof(int)) ||
-	    copy_from_user (info._sifields._pad, uinfo->_sifields._pad, SI_PAD_SIZE))
-		return -EFAULT;
-	set_fs (KERNEL_DS);
-	ret = sys_rt_sigqueueinfo(pid, sig, (siginfo_t __user *)&info);
-	set_fs (old_fs);
-	return ret;
-}
-
 asmlinkage long
 sys32_waitid(int which, compat_pid_t pid,
 	     compat_siginfo_t __user *uinfo, int options,
diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S
index 701d66a..c91605b 100644
--- a/arch/parisc/kernel/syscall_table.S
+++ b/arch/parisc/kernel/syscall_table.S
@@ -282,7 +282,7 @@ #endif
 	 * to worry about faulting trying to copy in a larger 64-bit
 	 * struct from a 32-bit user-space app.
 	 */
-	ENTRY_SAME(rt_sigqueueinfo)
+	ENTRY_COMP(rt_sigqueueinfo)
 	ENTRY_SAME(rt_sigsuspend_wrapper) /* not really SAME -- see the code */
 	ENTRY_SAME(chown)		/* 180 */
 	/* setsockopt() used by iptables: SO_SET_REPLACE/SO_SET_ADD_COUNTERS */
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index 320353f..6bdc1a4 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -573,7 +573,6 @@ long compat_sys_rt_sigpending(compat_sig
 	return ret;
 }
 
-
 int copy_siginfo_to_user32(struct compat_siginfo __user *d, siginfo_t *s)
 {
 	int err;
@@ -629,30 +628,24 @@ int copy_siginfo_to_user32(struct compat
 	return err;
 }
 
-#define copy_siginfo_to_user	copy_siginfo_to_user32
-
-/*
- * Note: it is necessary to treat pid and sig as unsigned ints, with the
- * corresponding cast to a signed int to insure that the proper conversion
- * (sign extension) between the register representation of a signed int
- * (msr in 32-bit mode) and the register representation of a signed int
- * (msr in 64-bit mode) is performed.
+/* CAUTION: This is just a very minimalist implementation for the
+ *	    sake of compat_sys_rt_sigqueueinfo(), cribbed from sparc64.
  */
-long compat_sys_rt_sigqueueinfo(u32 pid, u32 sig, compat_siginfo_t __user *uinfo)
+int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
 {
-	siginfo_t info;
-	int ret;
-	mm_segment_t old_fs = get_fs();
+	if (!access_ok(VERIFY_WRITE, from, sizeof(compat_siginfo_t)))
+		return -EFAULT;
 
-	if (copy_from_user (&info, uinfo, 3*sizeof(int)) ||
-	    copy_from_user (info._sifields._pad, uinfo->_sifields._pad, SI_PAD_SIZE32))
+	if (copy_from_user(to, from, 3*sizeof(int)) ||
+	    copy_from_user(to->_sifields._pad, from->_sifields._pad,
+			   SI_PAD_SIZE))
 		return -EFAULT;
-	set_fs (KERNEL_DS);
-	/* The __user pointer cast is valid becasuse of the set_fs() */
-	ret = sys_rt_sigqueueinfo((int)pid, (int)sig, (siginfo_t __user *) &info);
-	set_fs (old_fs);
-	return ret;
+
+	return 0;
 }
+
+#define copy_siginfo_to_user	copy_siginfo_to_user32
+
 /*
  *  Start Alternate signal stack support
  *
diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c
index 2001767..7566d07 100644
--- a/arch/s390/kernel/compat_linux.c
+++ b/arch/s390/kernel/compat_linux.c
@@ -514,21 +514,6 @@ asmlinkage long sys32_rt_sigpending(comp
 	return ret;
 }
 
-asmlinkage long
-sys32_rt_sigqueueinfo(int pid, int sig, compat_siginfo_t __user *uinfo)
-{
-	siginfo_t info;
-	int ret;
-	mm_segment_t old_fs = get_fs();
-	
-	if (copy_siginfo_from_user32(&info, uinfo))
-		return -EFAULT;
-	set_fs (KERNEL_DS);
-	ret = sys_rt_sigqueueinfo(pid, sig, (siginfo_t __user *) &info);
-	set_fs (old_fs);
-	return ret;
-}
-
 /*
  * sys32_execve() executes a new program after the asm stub has set
  * things up for us.  This should basically do what I want it to.
diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S
index cb0efae..251844c 100644
--- a/arch/s390/kernel/compat_wrapper.S
+++ b/arch/s390/kernel/compat_wrapper.S
@@ -857,7 +857,7 @@ sys32_rt_sigqueueinfo_wrapper:
 	lgfr	%r2,%r2			# int
 	lgfr	%r3,%r3			# int
 	llgtr	%r4,%r4			# siginfo_emu31_t *
-	jg	sys32_rt_sigqueueinfo	# branch to system call
+	jg	compat_sys_rt_sigqueueinfo	# branch to system call
 
 	.globl compat_sys_rt_sigsuspend_wrapper
 compat_sys_rt_sigsuspend_wrapper:
diff --git a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c
index e27cb71..16ff6ff 100644
--- a/arch/sparc64/kernel/sys_sparc32.c
+++ b/arch/sparc64/kernel/sys_sparc32.c
@@ -601,22 +601,6 @@ asmlinkage long sys32_rt_sigpending(comp
 	return ret;
 }
 
-asmlinkage long compat_sys_rt_sigqueueinfo(int pid, int sig,
-					   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;
-
-	set_fs (KERNEL_DS);
-	ret = sys_rt_sigqueueinfo(pid, sig, (siginfo_t __user *) &info);
-	set_fs (old_fs);
-	return ret;
-}
-
 asmlinkage long compat_sys_sigaction(int sig, struct old_sigaction32 __user *act,
 				     struct old_sigaction32 __user *oact)
 {
diff --git a/arch/x86_64/ia32/ia32entry.S b/arch/x86_64/ia32/ia32entry.S
index b4aa875..9fa991a 100644
--- a/arch/x86_64/ia32/ia32entry.S
+++ b/arch/x86_64/ia32/ia32entry.S
@@ -577,7 +577,7 @@ #endif
 	.quad sys32_rt_sigprocmask	/* 175 */
 	.quad sys32_rt_sigpending
 	.quad compat_sys_rt_sigtimedwait
-	.quad sys32_rt_sigqueueinfo
+	.quad compat_sys_rt_sigqueueinfo
 	.quad stub32_rt_sigsuspend
 	.quad sys32_pread		/* 180 */
 	.quad sys32_pwrite
diff --git a/arch/x86_64/ia32/sys_ia32.c b/arch/x86_64/ia32/sys_ia32.c
index c9bac3a..db10734 100644
--- a/arch/x86_64/ia32/sys_ia32.c
+++ b/arch/x86_64/ia32/sys_ia32.c
@@ -628,21 +628,6 @@ sys32_rt_sigpending(compat_sigset_t __us
 	return ret;
 }
 
-asmlinkage long
-sys32_rt_sigqueueinfo(int pid, int sig, compat_siginfo_t __user *uinfo)
-{
-	siginfo_t info;
-	int ret;
-	mm_segment_t old_fs = get_fs();
-	
-	if (copy_siginfo_from_user32(&info, uinfo))
-		return -EFAULT;
-	set_fs (KERNEL_DS);
-	ret = sys_rt_sigqueueinfo(pid, sig, (siginfo_t __user *)&info);
-	set_fs (old_fs);
-	return ret;
-}
-
 /* These are here just in case some old ia32 binary calls it. */
 asmlinkage long
 sys32_pause(void)
diff --git a/kernel/compat.c b/kernel/compat.c
index 75573e5..cc77247 100644
--- a/kernel/compat.c
+++ b/kernel/compat.c
@@ -837,6 +837,23 @@ compat_sys_rt_sigtimedwait (compat_sigse
 
 }
 
+asmlinkage long compat_sys_rt_sigqueueinfo(int pid, int sig,
+	struct compat_siginfo __user *uinfo)
+{
+	mm_segment_t old_fs = get_fs();
+	siginfo_t info;
+	int ret;
+
+	if (copy_siginfo_from_user32(&info, uinfo))
+		return -EFAULT;
+
+	set_fs(KERNEL_DS);
+	ret = sys_rt_sigqueueinfo(pid, sig, (siginfo_t __user *)&info);
+	set_fs(old_fs);
+
+	return ret;
+}
+
 #ifdef __ARCH_WANT_COMPAT_SYS_TIME
 
 /* compat_time_t is a 32 bit "long" and needs to get converted. */

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: Generic compat_sys_rt_sigqueueinfo
  2006-10-28 22:37 Generic compat_sys_rt_sigqueueinfo Kyle McMartin
@ 2006-10-28 22:47 ` Matthew Wilcox
  2006-10-28 22:53   ` Kyle McMartin
  2006-10-28 23:09 ` Arnd Bergmann
  2006-10-30 15:59 ` Kyle McMartin
  2 siblings, 1 reply; 11+ messages in thread
From: Matthew Wilcox @ 2006-10-28 22:47 UTC (permalink / raw)
  To: Kyle McMartin; +Cc: akpm, linux-arch

On Sat, Oct 28, 2006 at 06:37:30PM -0400, Kyle McMartin wrote:
> Every 32-on-64 arch (except parisc) was implementing effectively the
> same sys32_rt_sigqueueinfo. Add a generic implementation taken from
> x86_64 and add it to kernel/compat.c, which required the addition of
> copy_siginfo_from_user32 on mips and powerpc. sparc64 had a sufficient
> implementation for this purpose, so crib it for both those platforms.

Why can't we have a compat_copy_siginfo_from_user() (and
compat_copy_siginfo_to_user() for that matter) defined in
kernel/compat.c for all architectures?  The user32 convention really
grates for some reason ;-)


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Generic compat_sys_rt_sigqueueinfo
  2006-10-28 22:47 ` Matthew Wilcox
@ 2006-10-28 22:53   ` Kyle McMartin
  2006-10-28 23:09     ` Matthew Wilcox
  0 siblings, 1 reply; 11+ messages in thread
From: Kyle McMartin @ 2006-10-28 22:53 UTC (permalink / raw)
  To: Matthew Wilcox; +Cc: Kyle McMartin, akpm, linux-arch

On Sat, Oct 28, 2006 at 04:47:38PM -0600, Matthew Wilcox wrote:
> Why can't we have a compat_copy_siginfo_from_user() (and
> compat_copy_siginfo_to_user() for that matter) defined in
> kernel/compat.c for all architectures?  The user32 convention really
> grates for some reason ;-)
> 

Coming in a later patch... This is just fixing one of the places where
compat signals changed generic code in signal.c

Cheers,
	Kyle

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Generic compat_sys_rt_sigqueueinfo
  2006-10-28 22:37 Generic compat_sys_rt_sigqueueinfo Kyle McMartin
  2006-10-28 22:47 ` Matthew Wilcox
@ 2006-10-28 23:09 ` Arnd Bergmann
  2006-10-28 23:12   ` Arnd Bergmann
  2006-10-30 15:46   ` Kyle McMartin
  2006-10-30 15:59 ` Kyle McMartin
  2 siblings, 2 replies; 11+ messages in thread
From: Arnd Bergmann @ 2006-10-28 23:09 UTC (permalink / raw)
  To: Kyle McMartin; +Cc: akpm, linux-arch

On Sunday 29 October 2006 00:37, Kyle McMartin wrote:
> +asmlinkage long compat_sys_rt_sigqueueinfo(int pid, int sig,
> +       struct compat_siginfo __user *uinfo)
> +{
> +       mm_segment_t old_fs = get_fs();
> +       siginfo_t info;
> +       int ret;
> +
> +       if (copy_siginfo_from_user32(&info, uinfo))
> +               return -EFAULT;
> +
> +       set_fs(KERNEL_DS);
> +       ret = sys_rt_sigqueueinfo(pid, sig, (siginfo_t __user *)&info);
> +       set_fs(old_fs);
> +
> +       return ret;
> +}

Since sys_rt_sigqueueinfo() is so simple, I think it would be much
better to define the common version as 

asmlinkage long
sys_rt_sigqueueinfo(int pid, int sig, siginfo_t __user *uinfo)
{
	siginfo_t info;

	if (compat_copy_siginfo_from_user(&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);
}

	Arnd <><

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Generic compat_sys_rt_sigqueueinfo
  2006-10-28 22:53   ` Kyle McMartin
@ 2006-10-28 23:09     ` Matthew Wilcox
  0 siblings, 0 replies; 11+ messages in thread
From: Matthew Wilcox @ 2006-10-28 23:09 UTC (permalink / raw)
  To: Kyle McMartin; +Cc: akpm, linux-arch

On Sat, Oct 28, 2006 at 06:53:14PM -0400, Kyle McMartin wrote:
> On Sat, Oct 28, 2006 at 04:47:38PM -0600, Matthew Wilcox wrote:
> > Why can't we have a compat_copy_siginfo_from_user() (and
> > compat_copy_siginfo_to_user() for that matter) defined in
> > kernel/compat.c for all architectures?  The user32 convention really
> > grates for some reason ;-)
> > 
> 
> Coming in a later patch... This is just fixing one of the places where
> compat signals changed generic code in signal.c

OK.  It just doesn't make too much sense to me to add this copy_compat
code to a half-dozen architectures, only to take it out again in a later
patch.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Generic compat_sys_rt_sigqueueinfo
  2006-10-28 23:09 ` Arnd Bergmann
@ 2006-10-28 23:12   ` Arnd Bergmann
  2006-10-30 15:46   ` Kyle McMartin
  1 sibling, 0 replies; 11+ messages in thread
From: Arnd Bergmann @ 2006-10-28 23:12 UTC (permalink / raw)
  To: Kyle McMartin; +Cc: akpm, linux-arch

On Sunday 29 October 2006 01:09, Arnd Bergmann wrote:
> Since sys_rt_sigqueueinfo() is so simple, I think it would be much
> better to define the common version as 
> 
> asmlinkage long
> sys_rt_sigqueueinfo(int pid, int sig, siginfo_t __user *uinfo)

that should read compat_sys_rt_sigqueueinfo, of course.

	Arnd <><

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Generic compat_sys_rt_sigqueueinfo
  2006-10-28 23:09 ` Arnd Bergmann
  2006-10-28 23:12   ` Arnd Bergmann
@ 2006-10-30 15:46   ` Kyle McMartin
  1 sibling, 0 replies; 11+ messages in thread
From: Kyle McMartin @ 2006-10-30 15:46 UTC (permalink / raw)
  To: Arnd Bergmann; +Cc: Kyle McMartin, akpm, linux-arch

On Sun, Oct 29, 2006 at 01:09:08AM +0200, Arnd Bergmann wrote:
> Since sys_rt_sigqueueinfo() is so simple, I think it would be much
> better to define the common version as 
> 
> <snip>

Agreed, that seems to be the convention in compat.c for `simple'
syscalls.

> 	Arnd <><
> 

Cheers,
	Kyle M.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Generic compat_sys_rt_sigqueueinfo
  2006-10-28 22:37 Generic compat_sys_rt_sigqueueinfo Kyle McMartin
  2006-10-28 22:47 ` Matthew Wilcox
  2006-10-28 23:09 ` Arnd Bergmann
@ 2006-10-30 15:59 ` Kyle McMartin
  2006-10-31  7:02   ` Andrew Morton
  2 siblings, 1 reply; 11+ messages in thread
From: Kyle McMartin @ 2006-10-30 15:59 UTC (permalink / raw)
  To: Kyle McMartin; +Cc: akpm, linux-arch

Every 32-on-64 arch (except parisc) was implementing effectively the
same sys32_rt_sigqueueinfo. Add a generic implementation taken from
x86_64 and add it to kernel/compat.c, which required the addition of
copy_siginfo_from_user32 on mips and powerpc. sparc64 had a sufficient
implementation for this purpose, so crib it for both those platforms.

This yields a nice clean up and is one step towards cleaning up some
of the compat signals mess parisc has been carrying out of tree for a few
years.

Incorporated Arnd's suggestion of not bothering to call sys_rt_sigqueueinfo
and just doing the full syscall in compat_sys_rt_sigqueueinfo.

Signed-off-by: Kyle McMartin <kyle@parisc-linux.org>
--
[N.B. the modification to powerpc is probably wrong, since it seems
 to require a wrapper for handling the signed ints like sparc64 and s390
 have. -- Kyle]
--
 arch/ia64/ia32/ia32_entry.S        |    2 +-
 arch/ia64/ia32/ia32_signal.c       |   15 ---------------
 arch/mips/kernel/scall64-n32.S     |    2 +-
 arch/mips/kernel/scall64-o32.S     |    2 +-
 arch/mips/kernel/signal32.c        |   31 ++++++++++++++++---------------
 arch/parisc/kernel/syscall_table.S |    2 +-
 arch/powerpc/kernel/signal_32.c    |   33 +++++++++++++--------------------
 arch/s390/kernel/compat_linux.c    |   15 ---------------
 arch/s390/kernel/compat_wrapper.S  |    2 +-
 arch/sparc64/kernel/sys_sparc32.c  |   16 ----------------
 arch/x86_64/ia32/ia32entry.S       |    2 +-
 arch/x86_64/ia32/sys_ia32.c        |   15 ---------------
 kernel/compat.c                    |   18 ++++++++++++++++++
 13 files changed, 53 insertions(+), 102 deletions(-)

diff --git a/arch/ia64/ia32/ia32_entry.S b/arch/ia64/ia32/ia32_entry.S
index a32cd59..8d41c2c 100644
--- a/arch/ia64/ia32/ia32_entry.S
+++ b/arch/ia64/ia32/ia32_entry.S
@@ -388,7 +388,7 @@ ia32_syscall_table:
 	data8 sys32_rt_sigprocmask /* 175 */
 	data8 sys_rt_sigpending
 	data8 compat_sys_rt_sigtimedwait
-	data8 sys32_rt_sigqueueinfo
+	data8 compat_sys_rt_sigqueueinfo
 	data8 sys32_rt_sigsuspend
 	data8 sys32_pread	  /* 180 */
 	data8 sys32_pwrite
diff --git a/arch/ia64/ia32/ia32_signal.c b/arch/ia64/ia32/ia32_signal.c
index b3355a9..00341ff 100644
--- a/arch/ia64/ia32/ia32_signal.c
+++ b/arch/ia64/ia32/ia32_signal.c
@@ -588,21 +588,6 @@ sys32_rt_sigprocmask (int how, compat_si
 }
 
 asmlinkage long
-sys32_rt_sigqueueinfo (int pid, int sig, compat_siginfo_t __user *uinfo)
-{
-	mm_segment_t old_fs = get_fs();
-	siginfo_t info;
-	int ret;
-
-	if (copy_siginfo_from_user32(&info, uinfo))
-		return -EFAULT;
-	set_fs(KERNEL_DS);
-	ret = sys_rt_sigqueueinfo(pid, sig, (siginfo_t __user *) &info);
-	set_fs(old_fs);
-	return ret;
-}
-
-asmlinkage long
 sys32_sigaction (int sig, struct old_sigaction32 __user *act, struct old_sigaction32 __user *oact)
 {
 	struct k_sigaction new_ka, old_ka;
diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S
index 67b92a1..013efe9 100644
--- a/arch/mips/kernel/scall64-n32.S
+++ b/arch/mips/kernel/scall64-n32.S
@@ -247,7 +247,7 @@ EXPORT(sysn32_call_table)
 	PTR	sys_capset
 	PTR	sys32_rt_sigpending		/* 6125 */
 	PTR	compat_sys_rt_sigtimedwait
-	PTR	sys32_rt_sigqueueinfo
+	PTR	compat_sys_rt_sigqueueinfo
 	PTR	sysn32_rt_sigsuspend
 	PTR	sys32_sigaltstack
 	PTR	compat_sys_utime		/* 6130 */
diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S
index 2875c4a..e9bc5a6 100644
--- a/arch/mips/kernel/scall64-o32.S
+++ b/arch/mips/kernel/scall64-o32.S
@@ -403,7 +403,7 @@ sys_call_table:
 	PTR	sys32_rt_sigprocmask 		/* 4195 */
 	PTR	sys32_rt_sigpending
 	PTR	compat_sys_rt_sigtimedwait
-	PTR	sys32_rt_sigqueueinfo
+	PTR	compat_sys_rt_sigqueueinfo
 	PTR	sys32_rt_sigsuspend
 	PTR	sys32_pread			/* 4200 */
 	PTR	sys32_pwrite
diff --git a/arch/mips/kernel/signal32.c b/arch/mips/kernel/signal32.c
index c86a5dd..b680e7d 100644
--- a/arch/mips/kernel/signal32.c
+++ b/arch/mips/kernel/signal32.c
@@ -463,6 +463,22 @@ int copy_siginfo_to_user32(compat_siginf
 	return err;
 }
 
+/* CAUTION: This is just a very minimalist implementation for the
+ *	    sake of compat_sys_rt_sigqueueinfo(), cribbed from sparc64.
+ */
+int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
+{
+	if (!access_ok(VERIFY_WRITE, from, sizeof(compat_siginfo_t)))
+		return -EFAULT;
+
+	if (copy_from_user(to, from, 3*sizeof(int)) ||
+	    copy_from_user(to->_sifields._pad, from->_sifields._pad,
+			   SI_PAD_SIZE))
+		return -EFAULT;
+
+	return 0;
+}
+
 save_static_function(sys32_sigreturn);
 __attribute_used__ noinline static void
 _sys32_sigreturn(nabi_no_regargs struct pt_regs regs)
@@ -950,21 +966,6 @@ asmlinkage int sys32_rt_sigpending(compa
 	return ret;
 }
 
-asmlinkage int sys32_rt_sigqueueinfo(int pid, int sig, compat_siginfo_t __user *uinfo)
-{
-	siginfo_t info;
-	int ret;
-	mm_segment_t old_fs = get_fs();
-
-	if (copy_from_user (&info, uinfo, 3*sizeof(int)) ||
-	    copy_from_user (info._sifields._pad, uinfo->_sifields._pad, SI_PAD_SIZE))
-		return -EFAULT;
-	set_fs (KERNEL_DS);
-	ret = sys_rt_sigqueueinfo(pid, sig, (siginfo_t __user *)&info);
-	set_fs (old_fs);
-	return ret;
-}
-
 asmlinkage long
 sys32_waitid(int which, compat_pid_t pid,
 	     compat_siginfo_t __user *uinfo, int options,
diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S
index 701d66a..c91605b 100644
--- a/arch/parisc/kernel/syscall_table.S
+++ b/arch/parisc/kernel/syscall_table.S
@@ -282,7 +282,7 @@ #endif
 	 * to worry about faulting trying to copy in a larger 64-bit
 	 * struct from a 32-bit user-space app.
 	 */
-	ENTRY_SAME(rt_sigqueueinfo)
+	ENTRY_COMP(rt_sigqueueinfo)
 	ENTRY_SAME(rt_sigsuspend_wrapper) /* not really SAME -- see the code */
 	ENTRY_SAME(chown)		/* 180 */
 	/* setsockopt() used by iptables: SO_SET_REPLACE/SO_SET_ADD_COUNTERS */
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index 320353f..6bdc1a4 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -573,7 +573,6 @@ long compat_sys_rt_sigpending(compat_sig
 	return ret;
 }
 
-
 int copy_siginfo_to_user32(struct compat_siginfo __user *d, siginfo_t *s)
 {
 	int err;
@@ -629,30 +628,24 @@ int copy_siginfo_to_user32(struct compat
 	return err;
 }
 
-#define copy_siginfo_to_user	copy_siginfo_to_user32
-
-/*
- * Note: it is necessary to treat pid and sig as unsigned ints, with the
- * corresponding cast to a signed int to insure that the proper conversion
- * (sign extension) between the register representation of a signed int
- * (msr in 32-bit mode) and the register representation of a signed int
- * (msr in 64-bit mode) is performed.
+/* CAUTION: This is just a very minimalist implementation for the
+ *	    sake of compat_sys_rt_sigqueueinfo(), cribbed from sparc64.
  */
-long compat_sys_rt_sigqueueinfo(u32 pid, u32 sig, compat_siginfo_t __user *uinfo)
+int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
 {
-	siginfo_t info;
-	int ret;
-	mm_segment_t old_fs = get_fs();
+	if (!access_ok(VERIFY_WRITE, from, sizeof(compat_siginfo_t)))
+		return -EFAULT;
 
-	if (copy_from_user (&info, uinfo, 3*sizeof(int)) ||
-	    copy_from_user (info._sifields._pad, uinfo->_sifields._pad, SI_PAD_SIZE32))
+	if (copy_from_user(to, from, 3*sizeof(int)) ||
+	    copy_from_user(to->_sifields._pad, from->_sifields._pad,
+			   SI_PAD_SIZE))
 		return -EFAULT;
-	set_fs (KERNEL_DS);
-	/* The __user pointer cast is valid becasuse of the set_fs() */
-	ret = sys_rt_sigqueueinfo((int)pid, (int)sig, (siginfo_t __user *) &info);
-	set_fs (old_fs);
-	return ret;
+
+	return 0;
 }
+
+#define copy_siginfo_to_user	copy_siginfo_to_user32
+
 /*
  *  Start Alternate signal stack support
  *
diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c
index 5b33f82..295d2bb 100644
--- a/arch/s390/kernel/compat_linux.c
+++ b/arch/s390/kernel/compat_linux.c
@@ -514,21 +514,6 @@ asmlinkage long sys32_rt_sigpending(comp
 	return ret;
 }
 
-asmlinkage long
-sys32_rt_sigqueueinfo(int pid, int sig, compat_siginfo_t __user *uinfo)
-{
-	siginfo_t info;
-	int ret;
-	mm_segment_t old_fs = get_fs();
-	
-	if (copy_siginfo_from_user32(&info, uinfo))
-		return -EFAULT;
-	set_fs (KERNEL_DS);
-	ret = sys_rt_sigqueueinfo(pid, sig, (siginfo_t __user *) &info);
-	set_fs (old_fs);
-	return ret;
-}
-
 /*
  * sys32_execve() executes a new program after the asm stub has set
  * things up for us.  This should basically do what I want it to.
diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S
index 71e54ef..71c1127 100644
--- a/arch/s390/kernel/compat_wrapper.S
+++ b/arch/s390/kernel/compat_wrapper.S
@@ -857,7 +857,7 @@ sys32_rt_sigqueueinfo_wrapper:
 	lgfr	%r2,%r2			# int
 	lgfr	%r3,%r3			# int
 	llgtr	%r4,%r4			# siginfo_emu31_t *
-	jg	sys32_rt_sigqueueinfo	# branch to system call
+	jg	compat_sys_rt_sigqueueinfo	# branch to system call
 
 	.globl compat_sys_rt_sigsuspend_wrapper
 compat_sys_rt_sigsuspend_wrapper:
diff --git a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c
index e27cb71..16ff6ff 100644
--- a/arch/sparc64/kernel/sys_sparc32.c
+++ b/arch/sparc64/kernel/sys_sparc32.c
@@ -601,22 +601,6 @@ asmlinkage long sys32_rt_sigpending(comp
 	return ret;
 }
 
-asmlinkage long compat_sys_rt_sigqueueinfo(int pid, int sig,
-					   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;
-
-	set_fs (KERNEL_DS);
-	ret = sys_rt_sigqueueinfo(pid, sig, (siginfo_t __user *) &info);
-	set_fs (old_fs);
-	return ret;
-}
-
 asmlinkage long compat_sys_sigaction(int sig, struct old_sigaction32 __user *act,
 				     struct old_sigaction32 __user *oact)
 {
diff --git a/arch/x86_64/ia32/ia32entry.S b/arch/x86_64/ia32/ia32entry.S
index b4aa875..9fa991a 100644
--- a/arch/x86_64/ia32/ia32entry.S
+++ b/arch/x86_64/ia32/ia32entry.S
@@ -577,7 +577,7 @@ #endif
 	.quad sys32_rt_sigprocmask	/* 175 */
 	.quad sys32_rt_sigpending
 	.quad compat_sys_rt_sigtimedwait
-	.quad sys32_rt_sigqueueinfo
+	.quad compat_sys_rt_sigqueueinfo
 	.quad stub32_rt_sigsuspend
 	.quad sys32_pread		/* 180 */
 	.quad sys32_pwrite
diff --git a/arch/x86_64/ia32/sys_ia32.c b/arch/x86_64/ia32/sys_ia32.c
index c9bac3a..db10734 100644
--- a/arch/x86_64/ia32/sys_ia32.c
+++ b/arch/x86_64/ia32/sys_ia32.c
@@ -628,21 +628,6 @@ sys32_rt_sigpending(compat_sigset_t __us
 	return ret;
 }
 
-asmlinkage long
-sys32_rt_sigqueueinfo(int pid, int sig, compat_siginfo_t __user *uinfo)
-{
-	siginfo_t info;
-	int ret;
-	mm_segment_t old_fs = get_fs();
-	
-	if (copy_siginfo_from_user32(&info, uinfo))
-		return -EFAULT;
-	set_fs (KERNEL_DS);
-	ret = sys_rt_sigqueueinfo(pid, sig, (siginfo_t __user *)&info);
-	set_fs (old_fs);
-	return ret;
-}
-
 /* These are here just in case some old ia32 binary calls it. */
 asmlinkage long
 sys32_pause(void)
diff --git a/kernel/compat.c b/kernel/compat.c
index d4898aa..022821a 100644
--- a/kernel/compat.c
+++ b/kernel/compat.c
@@ -837,6 +837,24 @@ compat_sys_rt_sigtimedwait (compat_sigse
 
 }
 
+asmlinkage long compat_sys_rt_sigqueueinfo(int pid, int sig,
+	struct compat_siginfo __user *uinfo)
+{
+	siginfo_t info;
+
+	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);
+}
+
 #ifdef __ARCH_WANT_COMPAT_SYS_TIME
 
 /* compat_time_t is a 32 bit "long" and needs to get converted. */

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: Generic compat_sys_rt_sigqueueinfo
  2006-10-30 15:59 ` Kyle McMartin
@ 2006-10-31  7:02   ` Andrew Morton
  2006-11-01  7:23     ` Stephen Rothwell
  0 siblings, 1 reply; 11+ messages in thread
From: Andrew Morton @ 2006-10-31  7:02 UTC (permalink / raw)
  To: Kyle McMartin; +Cc: linux-arch

On Mon, 30 Oct 2006 10:59:10 -0500
Kyle McMartin <kyle@parisc-linux.org> wrote:

> Every 32-on-64 arch (except parisc) was implementing effectively the
> same sys32_rt_sigqueueinfo. Add a generic implementation taken from
> x86_64 and add it to kernel/compat.c, which required the addition of
> copy_siginfo_from_user32 on mips and powerpc. sparc64 had a sufficient
> implementation for this purpose, so crib it for both those platforms.
> 
> This yields a nice clean up and is one step towards cleaning up some
> of the compat signals mess parisc has been carrying out of tree for a few
> years.
> 
> Incorporated Arnd's suggestion of not bothering to call sys_rt_sigqueueinfo
> and just doing the full syscall in compat_sys_rt_sigqueueinfo.
> 
> Signed-off-by: Kyle McMartin <kyle@parisc-linux.org>
> --
> [N.B. the modification to powerpc is probably wrong, since it seems
>  to require a wrapper for handling the signed ints like sparc64 and s390
>  have. -- Kyle]

Well that's a bit sad.  Could the ppc guys please take a look?

Thanks.


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Generic compat_sys_rt_sigqueueinfo
  2006-10-31  7:02   ` Andrew Morton
@ 2006-11-01  7:23     ` Stephen Rothwell
  2006-11-01 14:24       ` Kyle McMartin
  0 siblings, 1 reply; 11+ messages in thread
From: Stephen Rothwell @ 2006-11-01  7:23 UTC (permalink / raw)
  To: Andrew Morton; +Cc: Kyle McMartin, linux-arch

[-- Attachment #1: Type: text/plain, Size: 764 bytes --]

On Mon, 30 Oct 2006 23:02:10 -0800 Andrew Morton <akpm@osdl.org> wrote:
>
> On Mon, 30 Oct 2006 10:59:10 -0500
> Kyle McMartin <kyle@parisc-linux.org> wrote:
>
> > [N.B. the modification to powerpc is probably wrong, since it seems
> >  to require a wrapper for handling the signed ints like sparc64 and s390
> >  have. -- Kyle]
>
> Well that's a bit sad.  Could the ppc guys please take a look?

It will be fine.  Neither of the passed ints have valid negative values.
The original comment was overly zealous.

However it would be nice to not have "32" in the names of gerneic compat
functions i.e. call it copy_compat_siginfo_from_user or
get_compat_siginfo.

--
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Generic compat_sys_rt_sigqueueinfo
  2006-11-01  7:23     ` Stephen Rothwell
@ 2006-11-01 14:24       ` Kyle McMartin
  0 siblings, 0 replies; 11+ messages in thread
From: Kyle McMartin @ 2006-11-01 14:24 UTC (permalink / raw)
  To: Stephen Rothwell; +Cc: Andrew Morton, Kyle McMartin, linux-arch

On Wed, Nov 01, 2006 at 06:23:52PM +1100, Stephen Rothwell wrote:
> It will be fine.  Neither of the passed ints have valid negative values.
> The original comment was overly zealous.
> 
> However it would be nice to not have "32" in the names of gerneic compat
> functions i.e. call it copy_compat_siginfo_from_user or
> get_compat_siginfo.
> 

This was for parity with copy_siginfo_to_user32. Once I replace both of
those on all arches but ia64 with a generic one (ia64 seems to be the only
arch with a different struct siginfo.) I will rename them to
compat_copy_siginfo_(to|from)_user, which seems to be the convention.

Cheers,
	Kyle M.

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2006-11-01 14:24 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-10-28 22:37 Generic compat_sys_rt_sigqueueinfo Kyle McMartin
2006-10-28 22:47 ` Matthew Wilcox
2006-10-28 22:53   ` Kyle McMartin
2006-10-28 23:09     ` Matthew Wilcox
2006-10-28 23:09 ` Arnd Bergmann
2006-10-28 23:12   ` Arnd Bergmann
2006-10-30 15:46   ` Kyle McMartin
2006-10-30 15:59 ` Kyle McMartin
2006-10-31  7:02   ` Andrew Morton
2006-11-01  7:23     ` Stephen Rothwell
2006-11-01 14:24       ` Kyle McMartin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox