提交 f454322e 编写于 作者: D Dmitry V. Levin 提交者: Al Viro

signal: replace sigset_to_compat() with put_compat_sigset()

There are 4 callers of sigset_to_compat() in the entire kernel.  One is
in sparc compat rt_sigaction(2), the rest are in kernel/signal.c itself.
All are followed by copy_to_user(), and all but the sparc one are under
"if it's big-endian..." ifdefs.

Let's transform sigset_to_compat() into put_compat_sigset() that also
calls copy_to_user().
Suggested-by: NAl Viro <viro@zeniv.linux.org.uk>
Signed-off-by: NDmitry V. Levin <ldv@altlinux.org>
Signed-off-by: NAl Viro <viro@zeniv.linux.org.uk>
上级 2bd6bf03
...@@ -159,7 +159,6 @@ COMPAT_SYSCALL_DEFINE5(rt_sigaction, int, sig, ...@@ -159,7 +159,6 @@ COMPAT_SYSCALL_DEFINE5(rt_sigaction, int, sig,
{ {
struct k_sigaction new_ka, old_ka; struct k_sigaction new_ka, old_ka;
int ret; int ret;
compat_sigset_t set32;
/* XXX: Don't preclude handling different sized sigset_t's. */ /* XXX: Don't preclude handling different sized sigset_t's. */
if (sigsetsize != sizeof(compat_sigset_t)) if (sigsetsize != sizeof(compat_sigset_t))
...@@ -167,6 +166,7 @@ COMPAT_SYSCALL_DEFINE5(rt_sigaction, int, sig, ...@@ -167,6 +166,7 @@ COMPAT_SYSCALL_DEFINE5(rt_sigaction, int, sig,
if (act) { if (act) {
u32 u_handler, u_restorer; u32 u_handler, u_restorer;
compat_sigset_t set32;
new_ka.ka_restorer = restorer; new_ka.ka_restorer = restorer;
ret = get_user(u_handler, &act->sa_handler); ret = get_user(u_handler, &act->sa_handler);
...@@ -183,9 +183,9 @@ COMPAT_SYSCALL_DEFINE5(rt_sigaction, int, sig, ...@@ -183,9 +183,9 @@ COMPAT_SYSCALL_DEFINE5(rt_sigaction, int, sig,
ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
if (!ret && oact) { if (!ret && oact) {
sigset_to_compat(&set32, &old_ka.sa.sa_mask);
ret = put_user(ptr_to_compat(old_ka.sa.sa_handler), &oact->sa_handler); ret = put_user(ptr_to_compat(old_ka.sa.sa_handler), &oact->sa_handler);
ret |= copy_to_user(&oact->sa_mask, &set32, sizeof(compat_sigset_t)); ret |= put_compat_sigset(&oact->sa_mask, &old_ka.sa.sa_mask,
sizeof(oact->sa_mask));
ret |= put_user(old_ka.sa.sa_flags, &oact->sa_flags); ret |= put_user(old_ka.sa.sa_flags, &oact->sa_flags);
ret |= put_user(ptr_to_compat(old_ka.sa.sa_restorer), &oact->sa_restorer); ret |= put_user(ptr_to_compat(old_ka.sa.sa_restorer), &oact->sa_restorer);
if (ret) if (ret)
......
...@@ -456,7 +456,8 @@ asmlinkage long compat_sys_settimeofday(struct compat_timeval __user *tv, ...@@ -456,7 +456,8 @@ asmlinkage long compat_sys_settimeofday(struct compat_timeval __user *tv,
asmlinkage long compat_sys_adjtimex(struct compat_timex __user *utp); asmlinkage long compat_sys_adjtimex(struct compat_timex __user *utp);
extern void sigset_from_compat(sigset_t *set, const compat_sigset_t *compat); extern void sigset_from_compat(sigset_t *set, const compat_sigset_t *compat);
extern void sigset_to_compat(compat_sigset_t *compat, const sigset_t *set); extern int put_compat_sigset(compat_sigset_t __user *compat,
const sigset_t *set, unsigned int size);
asmlinkage long compat_sys_migrate_pages(compat_pid_t pid, asmlinkage long compat_sys_migrate_pages(compat_pid_t pid,
compat_ulong_t maxnode, const compat_ulong_t __user *old_nodes, compat_ulong_t maxnode, const compat_ulong_t __user *old_nodes,
......
...@@ -497,15 +497,23 @@ sigset_from_compat(sigset_t *set, const compat_sigset_t *compat) ...@@ -497,15 +497,23 @@ sigset_from_compat(sigset_t *set, const compat_sigset_t *compat)
} }
EXPORT_SYMBOL_GPL(sigset_from_compat); EXPORT_SYMBOL_GPL(sigset_from_compat);
void int
sigset_to_compat(compat_sigset_t *compat, const sigset_t *set) put_compat_sigset(compat_sigset_t __user *compat, const sigset_t *set,
unsigned int size)
{ {
/* size <= sizeof(compat_sigset_t) <= sizeof(sigset_t) */
#ifdef __BIG_ENDIAN
compat_sigset_t v;
switch (_NSIG_WORDS) { switch (_NSIG_WORDS) {
case 4: compat->sig[7] = (set->sig[3] >> 32); compat->sig[6] = set->sig[3]; case 4: v.sig[7] = (set->sig[3] >> 32); v.sig[6] = set->sig[3];
case 3: compat->sig[5] = (set->sig[2] >> 32); compat->sig[4] = set->sig[2]; case 3: v.sig[5] = (set->sig[2] >> 32); v.sig[4] = set->sig[2];
case 2: compat->sig[3] = (set->sig[1] >> 32); compat->sig[2] = set->sig[1]; case 2: v.sig[3] = (set->sig[1] >> 32); v.sig[2] = set->sig[1];
case 1: compat->sig[1] = (set->sig[0] >> 32); compat->sig[0] = set->sig[0]; case 1: v.sig[1] = (set->sig[0] >> 32); v.sig[0] = set->sig[0];
} }
return copy_to_user(compat, &v, size) ? -EFAULT : 0;
#else
return copy_to_user(compat, set, size) ? -EFAULT : 0;
#endif
} }
#ifdef CONFIG_NUMA #ifdef CONFIG_NUMA
......
...@@ -2621,13 +2621,7 @@ COMPAT_SYSCALL_DEFINE4(rt_sigprocmask, int, how, compat_sigset_t __user *, nset, ...@@ -2621,13 +2621,7 @@ COMPAT_SYSCALL_DEFINE4(rt_sigprocmask, int, how, compat_sigset_t __user *, nset,
if (error) if (error)
return error; return error;
} }
if (oset) { return oset ? put_compat_sigset(oset, &old_set, sizeof(*oset)) : 0;
compat_sigset_t old32;
sigset_to_compat(&old32, &old_set);
if (copy_to_user(oset, &old32, sizeof(compat_sigset_t)))
return -EFAULT;
}
return 0;
#else #else
return sys_rt_sigprocmask(how, (sigset_t __user *)nset, return sys_rt_sigprocmask(how, (sigset_t __user *)nset,
(sigset_t __user *)oset, sigsetsize); (sigset_t __user *)oset, sigsetsize);
...@@ -2669,20 +2663,11 @@ SYSCALL_DEFINE2(rt_sigpending, sigset_t __user *, uset, size_t, sigsetsize) ...@@ -2669,20 +2663,11 @@ SYSCALL_DEFINE2(rt_sigpending, sigset_t __user *, uset, size_t, sigsetsize)
COMPAT_SYSCALL_DEFINE2(rt_sigpending, compat_sigset_t __user *, uset, COMPAT_SYSCALL_DEFINE2(rt_sigpending, compat_sigset_t __user *, uset,
compat_size_t, sigsetsize) compat_size_t, sigsetsize)
{ {
#ifdef __BIG_ENDIAN
sigset_t set; sigset_t set;
int err = do_sigpending(&set, sigsetsize); int err = do_sigpending(&set, sigsetsize);
if (!err) { if (!err)
compat_sigset_t set32; err = put_compat_sigset(uset, &set, sigsetsize);
sigset_to_compat(&set32, &set);
/* we can get here only if sigsetsize <= sizeof(set) */
if (copy_to_user(uset, &set32, sigsetsize))
err = -EFAULT;
}
return err; return err;
#else
return sys_rt_sigpending((sigset_t __user *)uset, sigsetsize);
#endif
} }
#endif #endif
...@@ -3451,7 +3436,6 @@ COMPAT_SYSCALL_DEFINE4(rt_sigaction, int, sig, ...@@ -3451,7 +3436,6 @@ COMPAT_SYSCALL_DEFINE4(rt_sigaction, int, sig,
compat_size_t, sigsetsize) compat_size_t, sigsetsize)
{ {
struct k_sigaction new_ka, old_ka; struct k_sigaction new_ka, old_ka;
compat_sigset_t mask;
#ifdef __ARCH_HAS_SA_RESTORER #ifdef __ARCH_HAS_SA_RESTORER
compat_uptr_t restorer; compat_uptr_t restorer;
#endif #endif
...@@ -3463,6 +3447,7 @@ COMPAT_SYSCALL_DEFINE4(rt_sigaction, int, sig, ...@@ -3463,6 +3447,7 @@ COMPAT_SYSCALL_DEFINE4(rt_sigaction, int, sig,
if (act) { if (act) {
compat_uptr_t handler; compat_uptr_t handler;
compat_sigset_t mask;
ret = get_user(handler, &act->sa_handler); ret = get_user(handler, &act->sa_handler);
new_ka.sa.sa_handler = compat_ptr(handler); new_ka.sa.sa_handler = compat_ptr(handler);
#ifdef __ARCH_HAS_SA_RESTORER #ifdef __ARCH_HAS_SA_RESTORER
...@@ -3478,10 +3463,10 @@ COMPAT_SYSCALL_DEFINE4(rt_sigaction, int, sig, ...@@ -3478,10 +3463,10 @@ COMPAT_SYSCALL_DEFINE4(rt_sigaction, int, sig,
ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
if (!ret && oact) { if (!ret && oact) {
sigset_to_compat(&mask, &old_ka.sa.sa_mask);
ret = put_user(ptr_to_compat(old_ka.sa.sa_handler), ret = put_user(ptr_to_compat(old_ka.sa.sa_handler),
&oact->sa_handler); &oact->sa_handler);
ret |= copy_to_user(&oact->sa_mask, &mask, sizeof(mask)); ret |= put_compat_sigset(&oact->sa_mask, &old_ka.sa.sa_mask,
sizeof(oact->sa_mask));
ret |= put_user(old_ka.sa.sa_flags, &oact->sa_flags); ret |= put_user(old_ka.sa.sa_flags, &oact->sa_flags);
#ifdef __ARCH_HAS_SA_RESTORER #ifdef __ARCH_HAS_SA_RESTORER
ret |= put_user(ptr_to_compat(old_ka.sa.sa_restorer), ret |= put_user(ptr_to_compat(old_ka.sa.sa_restorer),
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册