summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephen Rothwell <sfr@canb.auug.org.au>2002-05-28 05:51:30 -0700
committerLinus Torvalds <torvalds@home.transmeta.com>2002-05-28 05:51:30 -0700
commit849badb7cb50461d97936fb9fd23817d64e2ac4a (patch)
tree374fc96475921e82fc796e26ad28ea1144b5a975
parent052508d3acd8004cf62a4e3b83ee268475feabd9 (diff)
[PATCH] consolidate arch specific copy_siginfo_to_user
This patch moves a version of copy_siginfo_to_user that is common to ten of our architectures into the gerneic code and allows the other architectures to override it. I suspect more of the remaining architectures will be able to use it as well once it is fixed (patch to follow).
-rw-r--r--arch/arm/kernel/signal.c36
-rw-r--r--arch/i386/kernel/signal.c35
-rw-r--r--arch/m68k/kernel/signal.c35
-rw-r--r--arch/mips/kernel/signal.c35
-rw-r--r--arch/ppc/kernel/signal.c35
-rw-r--r--arch/ppc64/kernel/signal.c35
-rw-r--r--arch/s390/kernel/signal.c35
-rw-r--r--arch/s390x/kernel/signal.c35
-rw-r--r--arch/sh/kernel/signal.c35
-rw-r--r--arch/x86_64/kernel/signal.c35
-rw-r--r--include/asm-alpha/siginfo.h1
-rw-r--r--include/asm-cris/siginfo.h1
-rw-r--r--include/asm-ia64/siginfo.h1
-rw-r--r--include/asm-mips64/siginfo.h1
-rw-r--r--include/asm-parisc/siginfo.h1
-rw-r--r--include/asm-sparc/siginfo.h1
-rw-r--r--include/asm-sparc64/siginfo.h1
-rw-r--r--kernel/signal.c40
18 files changed, 47 insertions, 351 deletions
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index fa5df23bf4c0..19f19865c7cc 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -51,42 +51,6 @@ static const unsigned long retcodes[4] = {
asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs, int syscall);
-int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from)
-{
- int err = -EFAULT;;
-
- if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t)))
- goto out;
-
- if (from->si_code < 0)
- return __copy_to_user(to, from, sizeof(siginfo_t));
-
- /* If you change siginfo_t structure, please be sure
- this code is fixed accordingly.
- It should never copy any pad contained in the structure
- to avoid security leaks, but must copy the generic
- 3 ints plus the relevant union member. */
- err = __put_user(from->si_signo, &to->si_signo);
- err |= __put_user(from->si_errno, &to->si_errno);
- err |= __put_user((short)from->si_code, &to->si_code);
- /* First 32bits of unions are always present. */
- err |= __put_user(from->si_pid, &to->si_pid);
- switch (from->si_code >> 16) {
- case __SI_FAULT >> 16:
- break;
- case __SI_CHLD >> 16:
- err |= __put_user(from->si_utime, &to->si_utime);
- err |= __put_user(from->si_stime, &to->si_stime);
- err |= __put_user(from->si_status, &to->si_status);
- default:
- err |= __put_user(from->si_uid, &to->si_uid);
- break;
- /* case __SI_RT: This is not generated by the kernel as of now. */
- }
-out:
- return err;
-}
-
/*
* atomically swap in the new signal mask, and wait for a signal.
*/
diff --git a/arch/i386/kernel/signal.c b/arch/i386/kernel/signal.c
index 981bf811e1b5..6bc90370e563 100644
--- a/arch/i386/kernel/signal.c
+++ b/arch/i386/kernel/signal.c
@@ -30,41 +30,6 @@
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
-int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from)
-{
- if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t)))
- return -EFAULT;
- if (from->si_code < 0)
- return __copy_to_user(to, from, sizeof(siginfo_t));
- else {
- int err;
-
- /* If you change siginfo_t structure, please be sure
- this code is fixed accordingly.
- It should never copy any pad contained in the structure
- to avoid security leaks, but must copy the generic
- 3 ints plus the relevant union member. */
- err = __put_user(from->si_signo, &to->si_signo);
- err |= __put_user(from->si_errno, &to->si_errno);
- err |= __put_user((short)from->si_code, &to->si_code);
- /* First 32bits of unions are always present. */
- err |= __put_user(from->si_pid, &to->si_pid);
- switch (from->si_code >> 16) {
- case __SI_FAULT >> 16:
- break;
- case __SI_CHLD >> 16:
- err |= __put_user(from->si_utime, &to->si_utime);
- err |= __put_user(from->si_stime, &to->si_stime);
- err |= __put_user(from->si_status, &to->si_status);
- default:
- err |= __put_user(from->si_uid, &to->si_uid);
- break;
- /* case __SI_RT: This is not generated by the kernel as of now. */
- }
- return err;
- }
-}
-
/*
* Atomically swap in the new signal mask, and wait for a signal.
*/
diff --git a/arch/m68k/kernel/signal.c b/arch/m68k/kernel/signal.c
index a5d4061dde28..bedc542cc234 100644
--- a/arch/m68k/kernel/signal.c
+++ b/arch/m68k/kernel/signal.c
@@ -190,41 +190,6 @@ struct rt_sigframe
};
-int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from)
-{
- if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t)))
- return -EFAULT;
- if (from->si_code < 0)
- return __copy_to_user(to, from, sizeof(siginfo_t));
- else {
- int err;
-
- /* If you change siginfo_t structure, please be sure
- this code is fixed accordingly.
- It should never copy any pad contained in the structure
- to avoid security leaks, but must copy the generic
- 3 ints plus the relevant union member. */
- err = __put_user(from->si_signo, &to->si_signo);
- err |= __put_user(from->si_errno, &to->si_errno);
- err |= __put_user((short)from->si_code, &to->si_code);
- /* First 32bits of unions are always present. */
- err |= __put_user(from->si_pid, &to->si_pid);
- switch (from->si_code >> 16) {
- case __SI_FAULT >> 16:
- break;
- case __SI_CHLD >> 16:
- err |= __put_user(from->si_utime, &to->si_utime);
- err |= __put_user(from->si_stime, &to->si_stime);
- err |= __put_user(from->si_status, &to->si_status);
- default:
- err |= __put_user(from->si_uid, &to->si_uid);
- break;
- /* case __SI_RT: This is not generated by the kernel as of now. */
- }
- return err;
- }
-}
-
static unsigned char fpu_version = 0; /* version number of fpu, set by setup_frame */
static inline int restore_fpu_state(struct sigcontext *sc)
diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c
index b5ad2cc6015a..fa143d4785fc 100644
--- a/arch/mips/kernel/signal.c
+++ b/arch/mips/kernel/signal.c
@@ -37,41 +37,6 @@ extern asmlinkage int (*restore_fp_context)(struct sigcontext *sc);
extern asmlinkage void syscall_trace(void);
-int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from)
-{
- if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t)))
- return -EFAULT;
- if (from->si_code < 0)
- return __copy_to_user(to, from, sizeof(siginfo_t));
- else {
- int err;
-
- /* If you change siginfo_t structure, please be sure
- this code is fixed accordingly.
- It should never copy any pad contained in the structure
- to avoid security leaks, but must copy the generic
- 3 ints plus the relevant union member. */
- err = __put_user(from->si_signo, &to->si_signo);
- err |= __put_user(from->si_errno, &to->si_errno);
- err |= __put_user((short)from->si_code, &to->si_code);
- /* First 32bits of unions are always present. */
- err |= __put_user(from->si_pid, &to->si_pid);
- switch (from->si_code >> 16) {
- case __SI_FAULT >> 16:
- break;
- case __SI_CHLD >> 16:
- err |= __put_user(from->si_utime, &to->si_utime);
- err |= __put_user(from->si_stime, &to->si_stime);
- err |= __put_user(from->si_status, &to->si_status);
- default:
- err |= __put_user(from->si_uid, &to->si_uid);
- break;
- /* case __SI_RT: This is not generated by the kernel as of now. */
- }
- return err;
- }
-}
-
/*
* Atomically swap in the new signal mask, and wait for a signal.
*/
diff --git a/arch/ppc/kernel/signal.c b/arch/ppc/kernel/signal.c
index 1e3c0b19ce77..3702f8ef4c7b 100644
--- a/arch/ppc/kernel/signal.c
+++ b/arch/ppc/kernel/signal.c
@@ -62,41 +62,6 @@ extern void sigreturn_exit(struct pt_regs *);
int do_signal(sigset_t *oldset, struct pt_regs *regs);
-int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from)
-{
- if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t)))
- return -EFAULT;
- if (from->si_code < 0)
- return __copy_to_user(to, from, sizeof(siginfo_t));
- else {
- int err;
-
- /* If you change siginfo_t structure, please be sure
- this code is fixed accordingly.
- It should never copy any pad contained in the structure
- to avoid security leaks, but must copy the generic
- 3 ints plus the relevant union member. */
- err = __put_user(from->si_signo, &to->si_signo);
- err |= __put_user(from->si_errno, &to->si_errno);
- err |= __put_user((short)from->si_code, &to->si_code);
- /* First 32bits of unions are always present. */
- err |= __put_user(from->si_pid, &to->si_pid);
- switch (from->si_code >> 16) {
- case __SI_FAULT >> 16:
- break;
- case __SI_CHLD >> 16:
- err |= __put_user(from->si_utime, &to->si_utime);
- err |= __put_user(from->si_stime, &to->si_stime);
- err |= __put_user(from->si_status, &to->si_status);
- default:
- err |= __put_user(from->si_uid, &to->si_uid);
- break;
- /* case __SI_RT: This is not generated by the kernel as of now. */
- }
- return err;
- }
-}
-
/*
* Atomically swap in the new signal mask, and wait for a signal.
*/
diff --git a/arch/ppc64/kernel/signal.c b/arch/ppc64/kernel/signal.c
index d70a7f622a7e..5318026e5874 100644
--- a/arch/ppc64/kernel/signal.c
+++ b/arch/ppc64/kernel/signal.c
@@ -65,41 +65,6 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs);
extern long sys_wait4(pid_t pid, unsigned int *stat_addr,
int options, /*unsigned long*/ struct rusage *ru);
-int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from)
-{
- if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t)))
- return -EFAULT;
- if (from->si_code < 0)
- return __copy_to_user(to, from, sizeof(siginfo_t));
- else {
- int err;
-
- /* If you change siginfo_t structure, please be sure
- this code is fixed accordingly.
- It should never copy any pad contained in the structure
- to avoid security leaks, but must copy the generic
- 3 ints plus the relevant union member. */
- err = __put_user(from->si_signo, &to->si_signo);
- err |= __put_user(from->si_errno, &to->si_errno);
- err |= __put_user((short)from->si_code, &to->si_code);
- /* First 32bits of unions are always present. */
- err |= __put_user(from->si_pid, &to->si_pid);
- switch (from->si_code >> 16) {
- case __SI_FAULT >> 16:
- break;
- case __SI_CHLD >> 16:
- err |= __put_user(from->si_utime, &to->si_utime);
- err |= __put_user(from->si_stime, &to->si_stime);
- err |= __put_user(from->si_status, &to->si_status);
- default:
- err |= __put_user(from->si_uid, &to->si_uid);
- break;
- /* case __SI_RT: This is not generated by the kernel as of now. */
- }
- return err;
- }
-}
-
/*
* Atomically swap in the new signal mask, and wait for a signal.
*/
diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c
index d7d2e47c770e..bf453c691c38 100644
--- a/arch/s390/kernel/signal.c
+++ b/arch/s390/kernel/signal.c
@@ -49,41 +49,6 @@ typedef struct
asmlinkage int FASTCALL(do_signal(struct pt_regs *regs, sigset_t *oldset));
-int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from)
-{
- if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t)))
- return -EFAULT;
- if (from->si_code < 0)
- return __copy_to_user(to, from, sizeof(siginfo_t));
- else {
- int err;
-
- /* If you change siginfo_t structure, please be sure
- this code is fixed accordingly.
- It should never copy any pad contained in the structure
- to avoid security leaks, but must copy the generic
- 3 ints plus the relevant union member. */
- err = __put_user(from->si_signo, &to->si_signo);
- err |= __put_user(from->si_errno, &to->si_errno);
- err |= __put_user((short)from->si_code, &to->si_code);
- /* First 32bits of unions are always present. */
- err |= __put_user(from->si_pid, &to->si_pid);
- switch (from->si_code >> 16) {
- case __SI_FAULT >> 16:
- break;
- case __SI_CHLD >> 16:
- err |= __put_user(from->si_utime, &to->si_utime);
- err |= __put_user(from->si_stime, &to->si_stime);
- err |= __put_user(from->si_status, &to->si_status);
- default:
- err |= __put_user(from->si_uid, &to->si_uid);
- break;
- /* case __SI_RT: This is not generated by the kernel as of now. */
- }
- return err;
- }
-}
-
/*
* Atomically swap in the new signal mask, and wait for a signal.
*/
diff --git a/arch/s390x/kernel/signal.c b/arch/s390x/kernel/signal.c
index 022b4f00f20c..b3279a47b739 100644
--- a/arch/s390x/kernel/signal.c
+++ b/arch/s390x/kernel/signal.c
@@ -49,41 +49,6 @@ typedef struct
asmlinkage int FASTCALL(do_signal(struct pt_regs *regs, sigset_t *oldset));
-int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from)
-{
- if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t)))
- return -EFAULT;
- if (from->si_code < 0)
- return __copy_to_user(to, from, sizeof(siginfo_t));
- else {
- int err;
-
- /* If you change siginfo_t structure, please be sure
- this code is fixed accordingly.
- It should never copy any pad contained in the structure
- to avoid security leaks, but must copy the generic
- 3 ints plus the relevant union member. */
- err = __put_user(from->si_signo, &to->si_signo);
- err |= __put_user(from->si_errno, &to->si_errno);
- err |= __put_user((short)from->si_code, &to->si_code);
- /* First 32bits of unions are always present. */
- err |= __put_user(from->si_pid, &to->si_pid);
- switch (from->si_code >> 16) {
- case __SI_FAULT >> 16:
- break;
- case __SI_CHLD >> 16:
- err |= __put_user(from->si_utime, &to->si_utime);
- err |= __put_user(from->si_stime, &to->si_stime);
- err |= __put_user(from->si_status, &to->si_status);
- default:
- err |= __put_user(from->si_uid, &to->si_uid);
- break;
- /* case __SI_RT: This is not generated by the kernel as of now. */
- }
- return err;
- }
-}
-
/*
* Atomically swap in the new signal mask, and wait for a signal.
*/
diff --git a/arch/sh/kernel/signal.c b/arch/sh/kernel/signal.c
index 93c6b3d7f359..b25359b1aba3 100644
--- a/arch/sh/kernel/signal.c
+++ b/arch/sh/kernel/signal.c
@@ -34,41 +34,6 @@
asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset);
-int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from)
-{
- if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t)))
- return -EFAULT;
- if (from->si_code < 0)
- return __copy_to_user(to, from, sizeof(siginfo_t));
- else {
- int err;
-
- /* If you change siginfo_t structure, please be sure
- this code is fixed accordingly.
- It should never copy any pad contained in the structure
- to avoid security leaks, but must copy the generic
- 3 ints plus the relevant union member. */
- err = __put_user(from->si_signo, &to->si_signo);
- err |= __put_user(from->si_errno, &to->si_errno);
- err |= __put_user((short)from->si_code, &to->si_code);
- /* First 32bits of unions are always present. */
- err |= __put_user(from->si_pid, &to->si_pid);
- switch (from->si_code >> 16) {
- case __SI_FAULT >> 16:
- break;
- case __SI_CHLD >> 16:
- err |= __put_user(from->si_utime, &to->si_utime);
- err |= __put_user(from->si_stime, &to->si_stime);
- err |= __put_user(from->si_status, &to->si_status);
- default:
- err |= __put_user(from->si_uid, &to->si_uid);
- break;
- /* case __SI_RT: This is not generated by the kernel as of now. */
- }
- return err;
- }
-}
-
/*
* Atomically swap in the new signal mask, and wait for a signal.
*/
diff --git a/arch/x86_64/kernel/signal.c b/arch/x86_64/kernel/signal.c
index 5f4006335cfc..5066784dad1c 100644
--- a/arch/x86_64/kernel/signal.c
+++ b/arch/x86_64/kernel/signal.c
@@ -39,41 +39,6 @@ void ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
void ia32_setup_frame(int sig, struct k_sigaction *ka,
sigset_t *set, struct pt_regs * regs);
-int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from)
-{
- if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t)))
- return -EFAULT;
- if (from->si_code < 0)
- return __copy_to_user(to, from, sizeof(siginfo_t));
- else {
- int err;
-
- /* If you change siginfo_t structure, please be sure
- this code is fixed accordingly.
- It should never copy any pad contained in the structure
- to avoid security leaks, but must copy the generic
- 3 ints plus the relevant union member. */
- err = __put_user(from->si_signo, &to->si_signo);
- err |= __put_user(from->si_errno, &to->si_errno);
- err |= __put_user((short)from->si_code, &to->si_code);
- /* First 32bits of unions are always present. */
- err |= __put_user(from->si_pid, &to->si_pid);
- switch (from->si_code >> 16) {
- case __SI_FAULT >> 16:
- break;
- case __SI_CHLD >> 16:
- err |= __put_user(from->si_utime, &to->si_utime);
- err |= __put_user(from->si_stime, &to->si_stime);
- err |= __put_user(from->si_status, &to->si_status);
- default:
- err |= __put_user(from->si_uid, &to->si_uid);
- break;
- /* case __SI_RT: This is not generated by the kernel as of now. */
- }
- return err;
- }
-}
-
asmlinkage long
sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize, struct pt_regs regs)
{
diff --git a/include/asm-alpha/siginfo.h b/include/asm-alpha/siginfo.h
index b6ff2471d9df..5e5e59d81429 100644
--- a/include/asm-alpha/siginfo.h
+++ b/include/asm-alpha/siginfo.h
@@ -227,6 +227,7 @@ extern inline void copy_siginfo(siginfo_t *to, siginfo_t *from)
memcpy(to, from, 4*sizeof(int) + sizeof(from->_sifields._sigchld));
}
+#define HAVE_ARCH_COPY_SIGINFO_TO_USER
extern int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from);
#endif /* __KERNEL__ */
diff --git a/include/asm-cris/siginfo.h b/include/asm-cris/siginfo.h
index d843ace9c962..6938a2b738c8 100644
--- a/include/asm-cris/siginfo.h
+++ b/include/asm-cris/siginfo.h
@@ -226,6 +226,7 @@ extern inline void copy_siginfo(siginfo_t *to, siginfo_t *from)
memcpy(to, from, 3*sizeof(int) + sizeof(from->_sifields._sigchld));
}
+#define HAVE_ARCH_COPY_SIGINFO_TO_USER
extern int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from);
#endif /* __KERNEL__ */
diff --git a/include/asm-ia64/siginfo.h b/include/asm-ia64/siginfo.h
index bfe08f5097ee..0fba20e4d47c 100644
--- a/include/asm-ia64/siginfo.h
+++ b/include/asm-ia64/siginfo.h
@@ -271,6 +271,7 @@ copy_siginfo (siginfo_t *to, siginfo_t *from)
memcpy(to, from, 3*sizeof(int) + sizeof(from->_sifields._sigchld));
}
+#define HAVE_ARCH_COPY_SIGINFO_TO_USER
extern int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from);
extern int copy_siginfo_from_user(siginfo_t *to, siginfo_t *from);
diff --git a/include/asm-mips64/siginfo.h b/include/asm-mips64/siginfo.h
index 0a10716d6ab9..2c5233efb6d9 100644
--- a/include/asm-mips64/siginfo.h
+++ b/include/asm-mips64/siginfo.h
@@ -248,6 +248,7 @@ extern inline void copy_siginfo(siginfo_t *to, siginfo_t *from)
memcpy(to, from, 3*sizeof(int) + sizeof(from->_sifields._sigchld));
}
+#define HAVE_ARCH_COPY_SIGINFO_TO_USER
extern int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from);
#endif /* __KERNEL__ */
diff --git a/include/asm-parisc/siginfo.h b/include/asm-parisc/siginfo.h
index 349b614eca38..6c41fb2f8e56 100644
--- a/include/asm-parisc/siginfo.h
+++ b/include/asm-parisc/siginfo.h
@@ -228,6 +228,7 @@ extern inline void copy_siginfo(siginfo_t *to, siginfo_t *from)
memcpy(to, from, 3*sizeof(int) + sizeof(from->_sifields._sigchld));
}
+#define HAVE_ARCH_COPY_SIGINFO_TO_USER
extern int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from);
#endif /* __KERNEL__ */
diff --git a/include/asm-sparc/siginfo.h b/include/asm-sparc/siginfo.h
index 7ea5b45db59e..302e2bcb8139 100644
--- a/include/asm-sparc/siginfo.h
+++ b/include/asm-sparc/siginfo.h
@@ -236,6 +236,7 @@ extern inline void copy_siginfo(siginfo_t *to, siginfo_t *from)
memcpy(to, from, 3*sizeof(int) + sizeof(from->_sifields._sigchld));
}
+#define HAVE_ARCH_COPY_SIGINFO_TO_USER
extern int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from);
#endif /* __KERNEL__ */
diff --git a/include/asm-sparc64/siginfo.h b/include/asm-sparc64/siginfo.h
index daaf3beff68d..12187839d1cf 100644
--- a/include/asm-sparc64/siginfo.h
+++ b/include/asm-sparc64/siginfo.h
@@ -311,6 +311,7 @@ extern inline void copy_siginfo(siginfo_t *to, siginfo_t *from)
memcpy(to, from, 4*sizeof(int) + sizeof(from->_sifields._sigchld));
}
+#define HAVE_ARCH_COPY_SIGINFO_TO_USER
extern int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from);
extern int copy_siginfo_to_user32(siginfo_t32 *to, siginfo_t *from);
diff --git a/kernel/signal.c b/kernel/signal.c
index d45a2da06ad0..f195db26ed91 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -16,6 +16,7 @@
#include <linux/fs.h>
#include <asm/uaccess.h>
+#include <asm/siginfo.h>
/*
* SLAB caches for signal bits.
@@ -932,6 +933,45 @@ sys_rt_sigpending(sigset_t *set, size_t sigsetsize)
return do_sigpending(set, sigsetsize);
}
+#ifndef HAVE_ARCH_COPY_SIGINFO_TO_USER
+
+int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from)
+{
+ if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t)))
+ return -EFAULT;
+ if (from->si_code < 0)
+ return __copy_to_user(to, from, sizeof(siginfo_t));
+ else {
+ int err;
+
+ /* If you change siginfo_t structure, please be sure
+ this code is fixed accordingly.
+ It should never copy any pad contained in the structure
+ to avoid security leaks, but must copy the generic
+ 3 ints plus the relevant union member. */
+ err = __put_user(from->si_signo, &to->si_signo);
+ err |= __put_user(from->si_errno, &to->si_errno);
+ err |= __put_user((short)from->si_code, &to->si_code);
+ /* First 32bits of unions are always present. */
+ err |= __put_user(from->si_pid, &to->si_pid);
+ switch (from->si_code >> 16) {
+ case __SI_FAULT >> 16:
+ break;
+ case __SI_CHLD >> 16:
+ err |= __put_user(from->si_utime, &to->si_utime);
+ err |= __put_user(from->si_stime, &to->si_stime);
+ err |= __put_user(from->si_status, &to->si_status);
+ default:
+ err |= __put_user(from->si_uid, &to->si_uid);
+ break;
+ /* case __SI_RT: This is not generated by the kernel as of now. */
+ }
+ return err;
+ }
+}
+
+#endif
+
asmlinkage long
sys_rt_sigtimedwait(const sigset_t *uthese, siginfo_t *uinfo,
const struct timespec *uts, size_t sigsetsize)