summaryrefslogtreecommitdiff
path: root/kernel/compat.c
diff options
context:
space:
mode:
authorDmitry V. Levin <ldv@altlinux.org>2017-08-22 02:16:11 +0300
committerAl Viro <viro@zeniv.linux.org.uk>2017-09-19 17:55:54 -0400
commitf454322efbf6faee695f517c6b52c4dc03cacd3e (patch)
treeb1ecef65d6590d5f1421e1a4621a7e8ad3f24e6d /kernel/compat.c
parent2bd6bf03f4c1c59381d62c61d03f6cc3fe71f66e (diff)
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: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: Dmitry V. Levin <ldv@altlinux.org> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'kernel/compat.c')
-rw-r--r--kernel/compat.c20
1 files changed, 14 insertions, 6 deletions
diff --git a/kernel/compat.c b/kernel/compat.c
index 772e038d04d9..18dd902c9052 100644
--- a/kernel/compat.c
+++ b/kernel/compat.c
@@ -497,15 +497,23 @@ sigset_from_compat(sigset_t *set, const compat_sigset_t *compat)
}
EXPORT_SYMBOL_GPL(sigset_from_compat);
-void
-sigset_to_compat(compat_sigset_t *compat, const sigset_t *set)
+int
+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) {
- case 4: compat->sig[7] = (set->sig[3] >> 32); compat->sig[6] = set->sig[3];
- case 3: compat->sig[5] = (set->sig[2] >> 32); compat->sig[4] = set->sig[2];
- case 2: compat->sig[3] = (set->sig[1] >> 32); compat->sig[2] = set->sig[1];
- case 1: compat->sig[1] = (set->sig[0] >> 32); compat->sig[0] = set->sig[0];
+ case 4: v.sig[7] = (set->sig[3] >> 32); v.sig[6] = set->sig[3];
+ case 3: v.sig[5] = (set->sig[2] >> 32); v.sig[4] = set->sig[2];
+ case 2: v.sig[3] = (set->sig[1] >> 32); v.sig[2] = set->sig[1];
+ 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