* 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: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 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 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