[PATCH 30/30] x86, kaiser, xen: Dynamically disable KAISER when running under Xen PV
From: Dave HansenIf you paravirtualize the MMU, you can not use KAISER. This boils down to the fact that KAISER needs to do CR3 writes in places that it is not feasible to do real hypercalls. If Xen PV is detected to be in use, do not do the KAISER CR3 switches. I don't think this too bug of a deal for Xen. I was under the impression that the Xen guest kernel and Xen guest userspace didn't share an address space *anyway* so Xen PV is not normally even exposed to the kinds of things that KAISER protects against. This allows KAISER=y kernels to deployed in environments that also require PARAVIRT=y. Signed-off-by: Dave Hansen Acked-by: Juergen Gross Cc: Moritz Lipp Cc: Daniel Gruss Cc: Michael Schwarz Cc: Richard Fellner Cc: Andy Lutomirski Cc: Linus Torvalds Cc: Kees Cook Cc: Hugh Dickins Cc: x...@kernel.org --- b/arch/x86/mm/kaiser.c | 24 ++-- b/security/Kconfig |2 +- 2 files changed, 23 insertions(+), 3 deletions(-) diff -puN arch/x86/mm/kaiser.c~kaiser-disable-for-xen-pv arch/x86/mm/kaiser.c --- a/arch/x86/mm/kaiser.c~kaiser-disable-for-xen-pv2017-11-10 11:22:21.668244918 -0800 +++ b/arch/x86/mm/kaiser.c 2017-11-10 11:22:21.673244918 -0800 @@ -42,8 +42,20 @@ #include #include +/* + * We need a two-stage enable/disable. One (kaiser_enabled) to stop + * the ongoing work that keeps KAISER from being disabled (like PGD + * poisoning) and another (kaiser_asm_do_switch) that we set when it + * is completely safe to run without doing KAISER switches. + */ +int kaiser_enabled; + +/* + * Sized and aligned so that we can easily map it out to userspace + * for use before we have done the assembly CR3 switching. + */ __aligned(PAGE_SIZE) -unsigned long kaiser_asm_do_switch[PAGE_SIZE/sizeof(unsigned long)] = { 1 }; +unsigned long kaiser_asm_do_switch[PAGE_SIZE/sizeof(unsigned long)]; /* * At runtime, the only things we map are some things for CPU @@ -415,6 +427,15 @@ void __init kaiser_init(void) kaiser_add_user_map_ptrs_early(__irqentry_text_start, __irqentry_text_end, __PAGE_KERNEL_RX | _PAGE_GLOBAL); + + if (cpu_feature_enabled(X86_FEATURE_XENPV)) { + pr_info("x86/kaiser: Xen PV detected, disabling " + "KAISER protection\n"); + } else { + pr_info("x86/kaiser: Unmapping kernel while in userspace\n"); + kaiser_asm_do_switch[0] = 1; + kaiser_enabled = 1; + } } int kaiser_add_mapping(unsigned long addr, unsigned long size, @@ -465,7 +486,6 @@ void kaiser_remove_mapping(unsigned long __native_flush_tlb_global(); } -int kaiser_enabled = 1; static ssize_t kaiser_enabled_read_file(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { diff -puN security/Kconfig~kaiser-disable-for-xen-pv security/Kconfig --- a/security/Kconfig~kaiser-disable-for-xen-pv2017-11-10 11:22:21.670244918 -0800 +++ b/security/Kconfig 2017-11-10 11:22:21.673244918 -0800 @@ -56,7 +56,7 @@ config SECURITY_NETWORK config KAISER bool "Remove the kernel mapping in user mode" - depends on X86_64 && SMP && !PARAVIRT + depends on X86_64 && SMP help This feature reduces the number of hardware side channels by ensuring that the majority of kernel addresses are not mapped _
[PATCH 30/30] x86, kaiser, xen: Dynamically disable KAISER when running under Xen PV
From: Dave Hansen If you paravirtualize the MMU, you can not use KAISER. This boils down to the fact that KAISER needs to do CR3 writes in places that it is not feasible to do real hypercalls. If Xen PV is detected to be in use, do not do the KAISER CR3 switches. I don't think this too bug of a deal for Xen. I was under the impression that the Xen guest kernel and Xen guest userspace didn't share an address space *anyway* so Xen PV is not normally even exposed to the kinds of things that KAISER protects against. This allows KAISER=y kernels to deployed in environments that also require PARAVIRT=y. Signed-off-by: Dave Hansen Acked-by: Juergen Gross Cc: Moritz Lipp Cc: Daniel Gruss Cc: Michael Schwarz Cc: Richard Fellner Cc: Andy Lutomirski Cc: Linus Torvalds Cc: Kees Cook Cc: Hugh Dickins Cc: x...@kernel.org --- b/arch/x86/mm/kaiser.c | 24 ++-- b/security/Kconfig |2 +- 2 files changed, 23 insertions(+), 3 deletions(-) diff -puN arch/x86/mm/kaiser.c~kaiser-disable-for-xen-pv arch/x86/mm/kaiser.c --- a/arch/x86/mm/kaiser.c~kaiser-disable-for-xen-pv2017-11-10 11:22:21.668244918 -0800 +++ b/arch/x86/mm/kaiser.c 2017-11-10 11:22:21.673244918 -0800 @@ -42,8 +42,20 @@ #include #include +/* + * We need a two-stage enable/disable. One (kaiser_enabled) to stop + * the ongoing work that keeps KAISER from being disabled (like PGD + * poisoning) and another (kaiser_asm_do_switch) that we set when it + * is completely safe to run without doing KAISER switches. + */ +int kaiser_enabled; + +/* + * Sized and aligned so that we can easily map it out to userspace + * for use before we have done the assembly CR3 switching. + */ __aligned(PAGE_SIZE) -unsigned long kaiser_asm_do_switch[PAGE_SIZE/sizeof(unsigned long)] = { 1 }; +unsigned long kaiser_asm_do_switch[PAGE_SIZE/sizeof(unsigned long)]; /* * At runtime, the only things we map are some things for CPU @@ -415,6 +427,15 @@ void __init kaiser_init(void) kaiser_add_user_map_ptrs_early(__irqentry_text_start, __irqentry_text_end, __PAGE_KERNEL_RX | _PAGE_GLOBAL); + + if (cpu_feature_enabled(X86_FEATURE_XENPV)) { + pr_info("x86/kaiser: Xen PV detected, disabling " + "KAISER protection\n"); + } else { + pr_info("x86/kaiser: Unmapping kernel while in userspace\n"); + kaiser_asm_do_switch[0] = 1; + kaiser_enabled = 1; + } } int kaiser_add_mapping(unsigned long addr, unsigned long size, @@ -465,7 +486,6 @@ void kaiser_remove_mapping(unsigned long __native_flush_tlb_global(); } -int kaiser_enabled = 1; static ssize_t kaiser_enabled_read_file(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { diff -puN security/Kconfig~kaiser-disable-for-xen-pv security/Kconfig --- a/security/Kconfig~kaiser-disable-for-xen-pv2017-11-10 11:22:21.670244918 -0800 +++ b/security/Kconfig 2017-11-10 11:22:21.673244918 -0800 @@ -56,7 +56,7 @@ config SECURITY_NETWORK config KAISER bool "Remove the kernel mapping in user mode" - depends on X86_64 && SMP && !PARAVIRT + depends on X86_64 && SMP help This feature reduces the number of hardware side channels by ensuring that the majority of kernel addresses are not mapped _
Re: [PATCH 30/30] x86, kaiser, xen: Dynamically disable KAISER when running under Xen PV
On 08/11/17 20:47, Dave Hansen wrote: > From: Dave Hansen> > If you paravirtualize the MMU, you can not use KAISER. This boils down > to the fact that KAISER needs to do CR3 writes in places that it is not > feasible to do real hypercalls. > > If we detect that Xen PV is in use, do not do the KAISER CR3 switches. > > I don't think this too bug of a deal for Xen. I was under the > impression that the Xen guest kernel and Xen guest userspace didn't > share an address space *anyway* so Xen PV is not normally even exposed > to the kinds of things that KAISER protects against. > > This allows KAISER=y kernels to deployed in environments that also > require PARAVIRT=y. > > Signed-off-by: Dave Hansen Acked-by: Juergen Gross Juergen
Re: [PATCH 30/30] x86, kaiser, xen: Dynamically disable KAISER when running under Xen PV
On 08/11/17 20:47, Dave Hansen wrote: > From: Dave Hansen > > If you paravirtualize the MMU, you can not use KAISER. This boils down > to the fact that KAISER needs to do CR3 writes in places that it is not > feasible to do real hypercalls. > > If we detect that Xen PV is in use, do not do the KAISER CR3 switches. > > I don't think this too bug of a deal for Xen. I was under the > impression that the Xen guest kernel and Xen guest userspace didn't > share an address space *anyway* so Xen PV is not normally even exposed > to the kinds of things that KAISER protects against. > > This allows KAISER=y kernels to deployed in environments that also > require PARAVIRT=y. > > Signed-off-by: Dave Hansen Acked-by: Juergen Gross Juergen
[PATCH 30/30] x86, kaiser, xen: Dynamically disable KAISER when running under Xen PV
From: Dave HansenIf you paravirtualize the MMU, you can not use KAISER. This boils down to the fact that KAISER needs to do CR3 writes in places that it is not feasible to do real hypercalls. If we detect that Xen PV is in use, do not do the KAISER CR3 switches. I don't think this too bug of a deal for Xen. I was under the impression that the Xen guest kernel and Xen guest userspace didn't share an address space *anyway* so Xen PV is not normally even exposed to the kinds of things that KAISER protects against. This allows KAISER=y kernels to deployed in environments that also require PARAVIRT=y. Signed-off-by: Dave Hansen Cc: Moritz Lipp Cc: Daniel Gruss Cc: Michael Schwarz Cc: Richard Fellner Cc: Andy Lutomirski Cc: Linus Torvalds Cc: Kees Cook Cc: Hugh Dickins Cc: x...@kernel.org Cc: Juergen Gross --- b/arch/x86/mm/kaiser.c | 24 ++-- b/security/Kconfig |2 +- 2 files changed, 23 insertions(+), 3 deletions(-) diff -puN arch/x86/mm/kaiser.c~kaiser-disable-for-xen-pv arch/x86/mm/kaiser.c --- a/arch/x86/mm/kaiser.c~kaiser-disable-for-xen-pv2017-11-08 10:46:16.913681276 -0800 +++ b/arch/x86/mm/kaiser.c 2017-11-08 10:46:16.918681276 -0800 @@ -31,8 +31,20 @@ #include #include +/* + * We need a two-stage enable/disable. One (kaiser_enabled) to stop + * the ongoing work that keeps KAISER from being disabled (like PGD + * poisoning) and another (kaiser_asm_do_switch) that we set when it + * is completely safe to run without doing KAISER switches. + */ +int kaiser_enabled; + +/* + * Sized and aligned so that we can easily map it out to userspace + * for use before we have done the assembly CR3 switching. + */ __aligned(PAGE_SIZE) -unsigned long kaiser_asm_do_switch[PAGE_SIZE/sizeof(unsigned long)] = { 1 }; +unsigned long kaiser_asm_do_switch[PAGE_SIZE/sizeof(unsigned long)]; /* * At runtime, the only things we map are some things for CPU @@ -404,6 +416,15 @@ void __init kaiser_init(void) kaiser_add_user_map_ptrs_early(__irqentry_text_start, __irqentry_text_end, __PAGE_KERNEL_RX | _PAGE_GLOBAL); + + if (cpu_feature_enabled(X86_FEATURE_XENPV)) { + pr_info("x86/kaiser: Xen PV detected, disabling " + "KAISER protection\n"); + } else { + pr_info("x86/kaiser: Unmapping kernel while in userspace\n"); + kaiser_asm_do_switch[0] = 1; + kaiser_enabled = 1; + } } int kaiser_add_mapping(unsigned long addr, unsigned long size, @@ -454,7 +475,6 @@ void kaiser_remove_mapping(unsigned long __native_flush_tlb_global(); } -int kaiser_enabled = 1; static ssize_t kaiser_enabled_read_file(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { diff -puN security/Kconfig~kaiser-disable-for-xen-pv security/Kconfig --- a/security/Kconfig~kaiser-disable-for-xen-pv2017-11-08 10:46:16.914681276 -0800 +++ b/security/Kconfig 2017-11-08 10:46:16.918681276 -0800 @@ -56,7 +56,7 @@ config SECURITY_NETWORK config KAISER bool "Remove the kernel mapping in user mode" - depends on X86_64 && SMP && !PARAVIRT + depends on X86_64 && SMP help This feature reduces the number of hardware side channels by ensuring that the majority of kernel addresses are not mapped _
[PATCH 30/30] x86, kaiser, xen: Dynamically disable KAISER when running under Xen PV
From: Dave Hansen If you paravirtualize the MMU, you can not use KAISER. This boils down to the fact that KAISER needs to do CR3 writes in places that it is not feasible to do real hypercalls. If we detect that Xen PV is in use, do not do the KAISER CR3 switches. I don't think this too bug of a deal for Xen. I was under the impression that the Xen guest kernel and Xen guest userspace didn't share an address space *anyway* so Xen PV is not normally even exposed to the kinds of things that KAISER protects against. This allows KAISER=y kernels to deployed in environments that also require PARAVIRT=y. Signed-off-by: Dave Hansen Cc: Moritz Lipp Cc: Daniel Gruss Cc: Michael Schwarz Cc: Richard Fellner Cc: Andy Lutomirski Cc: Linus Torvalds Cc: Kees Cook Cc: Hugh Dickins Cc: x...@kernel.org Cc: Juergen Gross --- b/arch/x86/mm/kaiser.c | 24 ++-- b/security/Kconfig |2 +- 2 files changed, 23 insertions(+), 3 deletions(-) diff -puN arch/x86/mm/kaiser.c~kaiser-disable-for-xen-pv arch/x86/mm/kaiser.c --- a/arch/x86/mm/kaiser.c~kaiser-disable-for-xen-pv2017-11-08 10:46:16.913681276 -0800 +++ b/arch/x86/mm/kaiser.c 2017-11-08 10:46:16.918681276 -0800 @@ -31,8 +31,20 @@ #include #include +/* + * We need a two-stage enable/disable. One (kaiser_enabled) to stop + * the ongoing work that keeps KAISER from being disabled (like PGD + * poisoning) and another (kaiser_asm_do_switch) that we set when it + * is completely safe to run without doing KAISER switches. + */ +int kaiser_enabled; + +/* + * Sized and aligned so that we can easily map it out to userspace + * for use before we have done the assembly CR3 switching. + */ __aligned(PAGE_SIZE) -unsigned long kaiser_asm_do_switch[PAGE_SIZE/sizeof(unsigned long)] = { 1 }; +unsigned long kaiser_asm_do_switch[PAGE_SIZE/sizeof(unsigned long)]; /* * At runtime, the only things we map are some things for CPU @@ -404,6 +416,15 @@ void __init kaiser_init(void) kaiser_add_user_map_ptrs_early(__irqentry_text_start, __irqentry_text_end, __PAGE_KERNEL_RX | _PAGE_GLOBAL); + + if (cpu_feature_enabled(X86_FEATURE_XENPV)) { + pr_info("x86/kaiser: Xen PV detected, disabling " + "KAISER protection\n"); + } else { + pr_info("x86/kaiser: Unmapping kernel while in userspace\n"); + kaiser_asm_do_switch[0] = 1; + kaiser_enabled = 1; + } } int kaiser_add_mapping(unsigned long addr, unsigned long size, @@ -454,7 +475,6 @@ void kaiser_remove_mapping(unsigned long __native_flush_tlb_global(); } -int kaiser_enabled = 1; static ssize_t kaiser_enabled_read_file(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { diff -puN security/Kconfig~kaiser-disable-for-xen-pv security/Kconfig --- a/security/Kconfig~kaiser-disable-for-xen-pv2017-11-08 10:46:16.914681276 -0800 +++ b/security/Kconfig 2017-11-08 10:46:16.918681276 -0800 @@ -56,7 +56,7 @@ config SECURITY_NETWORK config KAISER bool "Remove the kernel mapping in user mode" - depends on X86_64 && SMP && !PARAVIRT + depends on X86_64 && SMP help This feature reduces the number of hardware side channels by ensuring that the majority of kernel addresses are not mapped _