Re: [tip:x86/smap] Introduce [compat_]save_altstack_ex() to unbreakx86 SMAP

From: Stephen Rothwell
Date: Tue Sep 03 2013 - 21:11:28 EST


On Sun, 1 Sep 2013 14:45:56 -0700 tip-bot for Al Viro <tipbot@xxxxxxxxx> wrote:
>
> Commit-ID: bd1c149aa9915b9abb6d83d0f01dfd2ace0680b5
> Gitweb: http://git.kernel.org/tip/bd1c149aa9915b9abb6d83d0f01dfd2ace0680b5
> Author: Al Viro <viro@xxxxxxxxxxxxxxxxxx>
> AuthorDate: Sun, 1 Sep 2013 20:35:01 +0100
> Committer: H. Peter Anvin <hpa@xxxxxxxxxxxxxxx>
> CommitDate: Sun, 1 Sep 2013 14:16:33 -0700
>
> Introduce [compat_]save_altstack_ex() to unbreak x86 SMAP
>
> For performance reasons, when SMAP is in use, SMAP is left open for an
> entire put_user_try { ... } put_user_catch(); block, however, calling
> __put_user() in the middle of that block will close SMAP as the
> STAC..CLAC constructs intentionally do not nest.
>
> Furthermore, using __put_user() rather than put_user_ex() here is bad
> for performance.
>
> Thus, introduce new [compat_]save_altstack_ex() helpers that replace
> __[compat_]save_altstack() for x86, being currently the only
> architecture which supports put_user_try { ... } put_user_catch().
>
> Reported-by: H. Peter Anvin <hpa@xxxxxxxxxxxxxxx>
> Signed-off-by: Al Viro <viro@xxxxxxxxxxxxxxxxxx>
> Signed-off-by: H. Peter Anvin <hpa@xxxxxxxxxxxxxxx>
> Cc: <stable@xxxxxxxxxxxxxxx> # v3.8+
> Link: http://lkml.kernel.org/n/tip-es5p6y64if71k8p5u08agv9n@xxxxxxxxxxxxxx
> diff --git a/include/linux/compat.h b/include/linux/compat.h
> index 7f0c1dd..ec1aee4 100644
> --- a/include/linux/compat.h
> +++ b/include/linux/compat.h
> @@ -669,6 +669,13 @@ asmlinkage long compat_sys_sigaltstack(const compat_stack_t __user *uss_ptr,
>
> int compat_restore_altstack(const compat_stack_t __user *uss);
> int __compat_save_altstack(compat_stack_t __user *, unsigned long);
> +#define compat_save_altstack_ex(uss, sp) do { \
> + compat_stack_t __user *__uss = uss; \
> + struct task_struct *t = current; \
> + put_user_ex(ptr_to_compat((void __user *)t->sas_ss_sp), &__uss->ss_sp); \
> + put_user_ex(sas_ss_flags(sp), &__uss->ss_flags); \
> + put_user_ex(t->sas_ss_size, &__uss->ss_size); \
> +} while (0);

I am just wondering if there is some reason that these macros are not
implemented as (static inline) C functions?

> +#define save_altstack_ex(uss, sp) do { \
> + stack_t __user *__uss = uss; \
> + struct task_struct *t = current; \
> + put_user_ex((void __user *)t->sas_ss_sp, &__uss->ss_sp); \
> + put_user_ex(sas_ss_flags(sp), &__uss->ss_flags); \
> + put_user_ex(t->sas_ss_size, &__uss->ss_size); \
> +} while (0);
> +
--
Cheers,
Stephen Rothwell sfr@xxxxxxxxxxxxxxxx

Attachment: pgp00000.pgp
Description: PGP signature