Skip to content

Commit

Permalink
x86: Make sure IDT is page aligned
Browse files Browse the repository at this point in the history
Since the IDT is referenced from a fixmap, make sure it is page aligned.
Merge with 32-bit one, since it was already aligned to deal with F00F
bug. Since bss is cleared before IDT setup, it can live there. This also
moves the other *_idt_table variables into common locations.

This avoids the risk of the IDT ever being moved in the bss and having
the mapping be offset, resulting in calling incorrect handlers. In the
current upstream kernel this is not a manifested bug, but heavily patched
kernels (such as those using the PaX patch series) did encounter this bug.

The tables other than idt_table technically do not need to be page
aligned, at least not at the current time, but using a common
declaration avoids mistakes.  On 64 bits the table is exactly one page
long, anyway.

Signed-off-by: Kees Cook <keescook@chromium.org>
Link: http://lkml.kernel.org/r/20130716183441.GA14232@www.outflux.net
Reported-by: PaX Team <pageexec@gmail.com>
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
  • Loading branch information
Kees Cook authored and H. Peter Anvin committed Jul 16, 2013
1 parent 5ff560f commit 4df05f3
Show file tree
Hide file tree
Showing 3 changed files with 8 additions and 25 deletions.
15 changes: 0 additions & 15 deletions arch/x86/kernel/head_64.S
Original file line number Diff line number Diff line change
Expand Up @@ -512,21 +512,6 @@ ENTRY(phys_base)

#include "../../x86/xen/xen-head.S"

.section .bss, "aw", @nobits
.align L1_CACHE_BYTES
ENTRY(idt_table)
.skip IDT_ENTRIES * 16

.align L1_CACHE_BYTES
ENTRY(debug_idt_table)
.skip IDT_ENTRIES * 16

#ifdef CONFIG_TRACING
.align L1_CACHE_BYTES
ENTRY(trace_idt_table)
.skip IDT_ENTRIES * 16
#endif

__PAGE_ALIGNED_BSS
NEXT_PAGE(empty_zero_page)
.skip PAGE_SIZE
6 changes: 2 additions & 4 deletions arch/x86/kernel/tracepoint.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,8 @@ atomic_t trace_idt_ctr = ATOMIC_INIT(0);
struct desc_ptr trace_idt_descr = { NR_VECTORS * 16 - 1,
(unsigned long) trace_idt_table };

#ifndef CONFIG_X86_64
gate_desc trace_idt_table[NR_VECTORS] __page_aligned_data
= { { { { 0, 0 } } }, };
#endif
/* No need to be aligned, but done to keep all IDTs defined the same way. */
gate_desc trace_idt_table[NR_VECTORS] __page_aligned_bss;

static int trace_irq_vector_refcount;
static DEFINE_MUTEX(irq_vector_mutex);
Expand Down
12 changes: 6 additions & 6 deletions arch/x86/kernel/traps.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,19 +63,19 @@
#include <asm/x86_init.h>
#include <asm/pgalloc.h>
#include <asm/proto.h>

/* No need to be aligned, but done to keep all IDTs defined the same way. */
gate_desc debug_idt_table[NR_VECTORS] __page_aligned_bss;
#else
#include <asm/processor-flags.h>
#include <asm/setup.h>

asmlinkage int system_call(void);

/*
* The IDT has to be page-aligned to simplify the Pentium
* F0 0F bug workaround.
*/
gate_desc idt_table[NR_VECTORS] __page_aligned_data = { { { { 0, 0 } } }, };
#endif

/* Must be page-aligned because the real IDT is used in a fixmap. */
gate_desc idt_table[NR_VECTORS] __page_aligned_bss;

DECLARE_BITMAP(used_vectors, NR_VECTORS);
EXPORT_SYMBOL_GPL(used_vectors);

Expand Down

0 comments on commit 4df05f3

Please sign in to comment.