[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20190731125306.GU31381@hirez.programming.kicks-ass.net>
Date: Wed, 31 Jul 2019 14:53:06 +0200
From: Peter Zijlstra <peterz@...radead.org>
To: Thomas Garnier <thgarnie@...omium.org>
Cc: kernel-hardening@...ts.openwall.com, kristen@...ux.intel.com,
keescook@...omium.org, Juergen Gross <jgross@...e.com>,
Thomas Hellstrom <thellstrom@...are.com>,
"VMware, Inc." <pv-drivers@...are.com>,
Thomas Gleixner <tglx@...utronix.de>,
Ingo Molnar <mingo@...hat.com>, Borislav Petkov <bp@...en8.de>,
"H. Peter Anvin" <hpa@...or.com>, x86@...nel.org,
virtualization@...ts.linux-foundation.org,
linux-kernel@...r.kernel.org
Subject: Re: [PATCH v9 10/11] x86/paravirt: Adapt assembly for PIE support
On Tue, Jul 30, 2019 at 12:12:54PM -0700, Thomas Garnier wrote:
> if PIE is enabled, switch the paravirt assembly constraints to be
> compatible. The %c/i constrains generate smaller code so is kept by
> default.
>
> Position Independent Executable (PIE) support will allow to extend the
> KASLR randomization range below 0xffffffff80000000.
>
> Signed-off-by: Thomas Garnier <thgarnie@...omium.org>
> Acked-by: Juergen Gross <jgross@...e.com>
> ---
> arch/x86/include/asm/paravirt_types.h | 25 +++++++++++++++++++++----
> 1 file changed, 21 insertions(+), 4 deletions(-)
>
> diff --git a/arch/x86/include/asm/paravirt_types.h b/arch/x86/include/asm/paravirt_types.h
> index 70b654f3ffe5..fd7dc37d0010 100644
> --- a/arch/x86/include/asm/paravirt_types.h
> +++ b/arch/x86/include/asm/paravirt_types.h
> @@ -338,9 +338,25 @@ extern struct paravirt_patch_template pv_ops;
> #define PARAVIRT_PATCH(x) \
> (offsetof(struct paravirt_patch_template, x) / sizeof(void *))
>
> +#ifdef CONFIG_X86_PIE
> +#define paravirt_opptr_call "a"
> +#define paravirt_opptr_type "p"
> +
> +/*
> + * Alternative patching requires a maximum of 7 bytes but the relative call is
> + * only 6 bytes. If PIE is enabled, add an additional nop to the call
> + * instruction to ensure patching is possible.
> + */
> +#define PARAVIRT_CALL_POST "nop;"
I'm confused; where does the 7 come from? The relative call is 6 bytes,
a normal call is 5 bytes (which is what we normally replace them with),
and the longest 'native' sequence we seem to have is also 6 bytes
(.cpu_usergs_sysret64).
> +#else
> +#define paravirt_opptr_call "c"
> +#define paravirt_opptr_type "i"
> +#define PARAVIRT_CALL_POST ""
> +#endif
> +
> #define paravirt_type(op) \
> [paravirt_typenum] "i" (PARAVIRT_PATCH(op)), \
> - [paravirt_opptr] "i" (&(pv_ops.op))
> + [paravirt_opptr] paravirt_opptr_type (&(pv_ops.op))
> #define paravirt_clobber(clobber) \
> [paravirt_clobber] "i" (clobber)
>
> @@ -379,9 +395,10 @@ int paravirt_disable_iospace(void);
> * offset into the paravirt_patch_template structure, and can therefore be
> * freely converted back into a structure offset.
> */
> -#define PARAVIRT_CALL \
> - ANNOTATE_RETPOLINE_SAFE \
> - "call *%c[paravirt_opptr];"
> +#define PARAVIRT_CALL \
> + ANNOTATE_RETPOLINE_SAFE \
> + "call *%" paravirt_opptr_call "[paravirt_opptr];" \
> + PARAVIRT_CALL_POST
Powered by blists - more mailing lists