diff options
| author | Stephen Rothwell <sfr@canb.auug.org.au> | 2002-05-28 05:51:30 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@home.transmeta.com> | 2002-05-28 05:51:30 -0700 |
| commit | 849badb7cb50461d97936fb9fd23817d64e2ac4a (patch) | |
| tree | 374fc96475921e82fc796e26ad28ea1144b5a975 | |
| parent | 052508d3acd8004cf62a4e3b83ee268475feabd9 (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.c | 36 | ||||
| -rw-r--r-- | arch/i386/kernel/signal.c | 35 | ||||
| -rw-r--r-- | arch/m68k/kernel/signal.c | 35 | ||||
| -rw-r--r-- | arch/mips/kernel/signal.c | 35 | ||||
| -rw-r--r-- | arch/ppc/kernel/signal.c | 35 | ||||
| -rw-r--r-- | arch/ppc64/kernel/signal.c | 35 | ||||
| -rw-r--r-- | arch/s390/kernel/signal.c | 35 | ||||
| -rw-r--r-- | arch/s390x/kernel/signal.c | 35 | ||||
| -rw-r--r-- | arch/sh/kernel/signal.c | 35 | ||||
| -rw-r--r-- | arch/x86_64/kernel/signal.c | 35 | ||||
| -rw-r--r-- | include/asm-alpha/siginfo.h | 1 | ||||
| -rw-r--r-- | include/asm-cris/siginfo.h | 1 | ||||
| -rw-r--r-- | include/asm-ia64/siginfo.h | 1 | ||||
| -rw-r--r-- | include/asm-mips64/siginfo.h | 1 | ||||
| -rw-r--r-- | include/asm-parisc/siginfo.h | 1 | ||||
| -rw-r--r-- | include/asm-sparc/siginfo.h | 1 | ||||
| -rw-r--r-- | include/asm-sparc64/siginfo.h | 1 | ||||
| -rw-r--r-- | kernel/signal.c | 40 |
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) |
