summaryrefslogtreecommitdiffstats
path: root/drivers/pnp/pnpbios
diff options
context:
space:
mode:
authorThomas Garnier <thgarnie@google.com>2017-03-14 13:05:07 -0400
committerIngo Molnar <mingo@kernel.org>2017-03-16 04:06:35 -0400
commit69218e47994da614e7af600bf06887750ab6657a (patch)
treec1399085e63a1b42cda253a73a0d33b1e84cb864 /drivers/pnp/pnpbios
parentf06bdd4001c257792c54dce9427399f2896470af (diff)
x86: Remap GDT tables in the fixmap section
Each processor holds a GDT in its per-cpu structure. The sgdt instruction gives the base address of the current GDT. This address can be used to bypass KASLR memory randomization. With another bug, an attacker could target other per-cpu structures or deduce the base of the main memory section (PAGE_OFFSET). This patch relocates the GDT table for each processor inside the fixmap section. The space is reserved based on number of supported processors. For consistency, the remapping is done by default on 32 and 64-bit. Each processor switches to its remapped GDT at the end of initialization. For hibernation, the main processor returns with the original GDT and switches back to the remapping at completion. This patch was tested on both architectures. Hibernation and KVM were both tested specially for their usage of the GDT. Thanks to Boris Ostrovsky <boris.ostrovsky@oracle.com> for testing and recommending changes for Xen support. Signed-off-by: Thomas Garnier <thgarnie@google.com> Cc: Alexander Potapenko <glider@google.com> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Andrey Ryabinin <aryabinin@virtuozzo.com> Cc: Andy Lutomirski <luto@kernel.org> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org> Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com> Cc: Borislav Petkov <bp@suse.de> Cc: Chris Wilson <chris@chris-wilson.co.uk> Cc: Christian Borntraeger <borntraeger@de.ibm.com> Cc: Dmitry Vyukov <dvyukov@google.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Jiri Kosina <jikos@kernel.org> Cc: Joerg Roedel <joro@8bytes.org> Cc: Jonathan Corbet <corbet@lwn.net> Cc: Josh Poimboeuf <jpoimboe@redhat.com> Cc: Juergen Gross <jgross@suse.com> Cc: Kees Cook <keescook@chromium.org> Cc: Len Brown <len.brown@intel.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Lorenzo Stoakes <lstoakes@gmail.com> Cc: Luis R . Rodriguez <mcgrof@kernel.org> Cc: Matt Fleming <matt@codeblueprint.co.uk> Cc: Michal Hocko <mhocko@suse.com> Cc: Paolo Bonzini <pbonzini@redhat.com> Cc: Paul Gortmaker <paul.gortmaker@windriver.com> Cc: Pavel Machek <pavel@ucw.cz> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Radim Krčmář <rkrcmar@redhat.com> Cc: Rafael J . Wysocki <rjw@rjwysocki.net> Cc: Rusty Russell <rusty@rustcorp.com.au> Cc: Stanislaw Gruszka <sgruszka@redhat.com> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Tim Chen <tim.c.chen@linux.intel.com> Cc: Vitaly Kuznetsov <vkuznets@redhat.com> Cc: kasan-dev@googlegroups.com Cc: kernel-hardening@lists.openwall.com Cc: kvm@vger.kernel.org Cc: lguest@lists.ozlabs.org Cc: linux-doc@vger.kernel.org Cc: linux-efi@vger.kernel.org Cc: linux-mm@kvack.org Cc: linux-pm@vger.kernel.org Cc: xen-devel@lists.xenproject.org Cc: zijun_hu <zijun_hu@htc.com> Link: http://lkml.kernel.org/r/20170314170508.100882-2-thgarnie@google.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'drivers/pnp/pnpbios')
-rw-r--r--drivers/pnp/pnpbios/bioscalls.c10
1 files changed, 5 insertions, 5 deletions
diff --git a/drivers/pnp/pnpbios/bioscalls.c b/drivers/pnp/pnpbios/bioscalls.c
index 438d4c72c7b3..ff563db025b3 100644
--- a/drivers/pnp/pnpbios/bioscalls.c
+++ b/drivers/pnp/pnpbios/bioscalls.c
@@ -54,7 +54,7 @@ __asm__(".text \n"
54 54
55#define Q2_SET_SEL(cpu, selname, address, size) \ 55#define Q2_SET_SEL(cpu, selname, address, size) \
56do { \ 56do { \
57 struct desc_struct *gdt = get_cpu_gdt_table((cpu)); \ 57 struct desc_struct *gdt = get_cpu_gdt_rw((cpu)); \
58 set_desc_base(&gdt[(selname) >> 3], (u32)(address)); \ 58 set_desc_base(&gdt[(selname) >> 3], (u32)(address)); \
59 set_desc_limit(&gdt[(selname) >> 3], (size) - 1); \ 59 set_desc_limit(&gdt[(selname) >> 3], (size) - 1); \
60} while(0) 60} while(0)
@@ -95,8 +95,8 @@ static inline u16 call_pnp_bios(u16 func, u16 arg1, u16 arg2, u16 arg3,
95 return PNP_FUNCTION_NOT_SUPPORTED; 95 return PNP_FUNCTION_NOT_SUPPORTED;
96 96
97 cpu = get_cpu(); 97 cpu = get_cpu();
98 save_desc_40 = get_cpu_gdt_table(cpu)[0x40 / 8]; 98 save_desc_40 = get_cpu_gdt_rw(cpu)[0x40 / 8];
99 get_cpu_gdt_table(cpu)[0x40 / 8] = bad_bios_desc; 99 get_cpu_gdt_rw(cpu)[0x40 / 8] = bad_bios_desc;
100 100
101 /* On some boxes IRQ's during PnP BIOS calls are deadly. */ 101 /* On some boxes IRQ's during PnP BIOS calls are deadly. */
102 spin_lock_irqsave(&pnp_bios_lock, flags); 102 spin_lock_irqsave(&pnp_bios_lock, flags);
@@ -134,7 +134,7 @@ static inline u16 call_pnp_bios(u16 func, u16 arg1, u16 arg2, u16 arg3,
134 :"memory"); 134 :"memory");
135 spin_unlock_irqrestore(&pnp_bios_lock, flags); 135 spin_unlock_irqrestore(&pnp_bios_lock, flags);
136 136
137 get_cpu_gdt_table(cpu)[0x40 / 8] = save_desc_40; 137 get_cpu_gdt_rw(cpu)[0x40 / 8] = save_desc_40;
138 put_cpu(); 138 put_cpu();
139 139
140 /* If we get here and this is set then the PnP BIOS faulted on us. */ 140 /* If we get here and this is set then the PnP BIOS faulted on us. */
@@ -477,7 +477,7 @@ void pnpbios_calls_init(union pnp_bios_install_struct *header)
477 pnp_bios_callpoint.segment = PNP_CS16; 477 pnp_bios_callpoint.segment = PNP_CS16;
478 478
479 for_each_possible_cpu(i) { 479 for_each_possible_cpu(i) {
480 struct desc_struct *gdt = get_cpu_gdt_table(i); 480 struct desc_struct *gdt = get_cpu_gdt_rw(i);
481 if (!gdt) 481 if (!gdt)
482 continue; 482 continue;
483 set_desc_base(&gdt[GDT_ENTRY_PNPBIOS_CS32], 483 set_desc_base(&gdt[GDT_ENTRY_PNPBIOS_CS32],