Messages in this thread Patch in this message | | | From | Christophe Leroy <> | Subject | [RFC PATCH v1 17/19] signal: Add unsafe_put_compat_sigset() | Date | Wed, 12 Aug 2020 12:06:09 +0000 (UTC) |
| |
Implement 'unsafe' version of put_compat_sigset()
For the bigendian, use unsafe_put_user() directly to avoid intermediate copy through the stack.
For the littleendian, use a straight unsafe_copy_to_user().
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu> Cc: Dmitry V. Levin <ldv@altlinux.org> Cc: Al Viro <viro@zeniv.linux.org.uk> --- include/linux/compat.h | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+)
diff --git a/include/linux/compat.h b/include/linux/compat.h index c4255d8a4a8a..bbe5f9658ed1 100644 --- a/include/linux/compat.h +++ b/include/linux/compat.h @@ -442,6 +442,38 @@ put_compat_sigset(compat_sigset_t __user *compat, const sigset_t *set, #endif } +#ifdef CONFIG_CPU_BIG_ENDIAN +#define unsafe_put_compat_sigset(compat, set, label) do { \ + compat_sigset_t __user *__c = compat; \ + const sigset_t *__s = set; \ + \ + switch (_NSIG_WORDS) { \ + case 4: \ + unsafe_put_user(__s->sig[3] >> 32, __c->sig[7], label); \ + unsafe_put_user(__s->sig[3], __c->sig[6], label); \ + fallthrough; \ + case 3: \ + unsafe_put_user(__s->sig[2] >> 32, __c->sig[5], label); \ + unsafe_put_user(__s->sig[2], __c->sig[4], label); \ + fallthrough; \ + case 2: \ + unsafe_put_user(__s->sig[1] >> 32, __c->sig[3], label); \ + unsafe_put_user(__s->sig[1], __c->sig[2], label); \ + fallthrough; \ + case 1: \ + unsafe_put_user(__s->sig[0] >> 32, __c->sig[1], label); \ + unsafe_put_user(__s->sig[0], __c->sig[0], label); \ + } \ +} while (0) +#else +#define unsafe_put_compat_sigset(compat, set, label) do { \ + compat_sigset_t __user *__c = compat; \ + const sigset_t *__s = set; \ + \ + unsafe_copy_to_user(__c, __s, sizeof(*__c), label); \ +} while (0) +#endif + extern int compat_ptrace_request(struct task_struct *child, compat_long_t request, compat_ulong_t addr, compat_ulong_t data); -- 2.25.0
| |