Merge branch 'x86-kaslr-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull perparatory x86 kasrl changes from Ingo Molnar: "This contains changes from the ongoing KASLR work, by Kees Cook. The main changes are the use of a read-only IDT on x86 (which decouples the userspace visible virtual IDT address from the physical address), and a rework of ELF relocation support, in preparation of random, boot-time kernel image relocation." * 'x86-kaslr-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86, relocs: Refactor the relocs tool to merge 32- and 64-bit ELF x86, relocs: Build separate 32/64-bit tools x86, relocs: Add 64-bit ELF support to relocs tool x86, relocs: Consolidate processing logic x86, relocs: Generalize ELF structure names x86: Use a read-only IDT alias on all CPUs
This commit is contained in:
commit
01c7cd0ef5
@ -104,9 +104,7 @@ enum fixed_addresses {
|
||||
FIX_LI_PCIA, /* Lithium PCI Bridge A */
|
||||
FIX_LI_PCIB, /* Lithium PCI Bridge B */
|
||||
#endif
|
||||
#ifdef CONFIG_X86_F00F_BUG
|
||||
FIX_F00F_IDT, /* Virtual mapping for IDT */
|
||||
#endif
|
||||
FIX_RO_IDT, /* Virtual mapping for read-only IDT */
|
||||
#ifdef CONFIG_X86_CYCLONE_TIMER
|
||||
FIX_CYCLONE_TIMER, /*cyclone timer register*/
|
||||
#endif
|
||||
|
@ -176,20 +176,6 @@ int __cpuinit ppro_with_ram_bug(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_X86_F00F_BUG
|
||||
static void __cpuinit trap_init_f00f_bug(void)
|
||||
{
|
||||
__set_fixmap(FIX_F00F_IDT, __pa_symbol(idt_table), PAGE_KERNEL_RO);
|
||||
|
||||
/*
|
||||
* Update the IDT descriptor and reload the IDT so that
|
||||
* it uses the read-only mapped virtual address.
|
||||
*/
|
||||
idt_descr.address = fix_to_virt(FIX_F00F_IDT);
|
||||
load_idt(&idt_descr);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void __cpuinit intel_smp_check(struct cpuinfo_x86 *c)
|
||||
{
|
||||
/* calling is from identify_secondary_cpu() ? */
|
||||
@ -218,8 +204,7 @@ static void __cpuinit intel_workarounds(struct cpuinfo_x86 *c)
|
||||
/*
|
||||
* All current models of Pentium and Pentium with MMX technology CPUs
|
||||
* have the F0 0F bug, which lets nonprivileged users lock up the
|
||||
* system.
|
||||
* Note that the workaround only should be initialized once...
|
||||
* system. Announce that the fault handler will be checking for it.
|
||||
*/
|
||||
clear_cpu_bug(c, X86_BUG_F00F);
|
||||
if (!paravirt_enabled() && c->x86 == 5) {
|
||||
@ -227,7 +212,6 @@ static void __cpuinit intel_workarounds(struct cpuinfo_x86 *c)
|
||||
|
||||
set_cpu_bug(c, X86_BUG_F00F);
|
||||
if (!f00f_workaround_enabled) {
|
||||
trap_init_f00f_bug();
|
||||
printk(KERN_NOTICE "Intel Pentium with F0 0F bug - workaround enabled.\n");
|
||||
f00f_workaround_enabled = 1;
|
||||
}
|
||||
|
@ -56,6 +56,7 @@
|
||||
#include <asm/i387.h>
|
||||
#include <asm/fpu-internal.h>
|
||||
#include <asm/mce.h>
|
||||
#include <asm/fixmap.h>
|
||||
#include <asm/mach_traps.h>
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
@ -768,6 +769,14 @@ void __init trap_init(void)
|
||||
set_bit(SYSCALL_VECTOR, used_vectors);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Set the IDT descriptor to a fixed read-only location, so that the
|
||||
* "sidt" instruction will not leak the location of the kernel, and
|
||||
* to defend the IDT against arbitrary memory write vulnerabilities.
|
||||
* It will be reloaded in cpu_init() */
|
||||
__set_fixmap(FIX_RO_IDT, __pa_symbol(idt_table), PAGE_KERNEL_RO);
|
||||
idt_descr.address = fix_to_virt(FIX_RO_IDT);
|
||||
|
||||
/*
|
||||
* Should be a barrier for any external CPU state:
|
||||
*/
|
||||
|
@ -39,4 +39,5 @@ $(obj)/insn_sanity.o: $(srctree)/arch/x86/lib/insn.c $(srctree)/arch/x86/lib/ina
|
||||
|
||||
HOST_EXTRACFLAGS += -I$(srctree)/tools/include
|
||||
hostprogs-y += relocs
|
||||
relocs-objs := relocs_32.o relocs_64.o relocs_common.o
|
||||
relocs: $(obj)/relocs
|
||||
|
File diff suppressed because it is too large
Load Diff
36
arch/x86/tools/relocs.h
Normal file
36
arch/x86/tools/relocs.h
Normal file
@ -0,0 +1,36 @@
|
||||
#ifndef RELOCS_H
|
||||
#define RELOCS_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <inttypes.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <elf.h>
|
||||
#include <byteswap.h>
|
||||
#define USE_BSD
|
||||
#include <endian.h>
|
||||
#include <regex.h>
|
||||
#include <tools/le_byteshift.h>
|
||||
|
||||
void die(char *fmt, ...);
|
||||
|
||||
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
||||
|
||||
enum symtype {
|
||||
S_ABS,
|
||||
S_REL,
|
||||
S_SEG,
|
||||
S_LIN,
|
||||
S_NSYMTYPES
|
||||
};
|
||||
|
||||
void process_32(FILE *fp, int use_real_mode, int as_text,
|
||||
int show_absolute_syms, int show_absolute_relocs);
|
||||
void process_64(FILE *fp, int use_real_mode, int as_text,
|
||||
int show_absolute_syms, int show_absolute_relocs);
|
||||
|
||||
#endif /* RELOCS_H */
|
17
arch/x86/tools/relocs_32.c
Normal file
17
arch/x86/tools/relocs_32.c
Normal file
@ -0,0 +1,17 @@
|
||||
#include "relocs.h"
|
||||
|
||||
#define ELF_BITS 32
|
||||
|
||||
#define ELF_MACHINE EM_386
|
||||
#define ELF_MACHINE_NAME "i386"
|
||||
#define SHT_REL_TYPE SHT_REL
|
||||
#define Elf_Rel ElfW(Rel)
|
||||
|
||||
#define ELF_CLASS ELFCLASS32
|
||||
#define ELF_R_SYM(val) ELF32_R_SYM(val)
|
||||
#define ELF_R_TYPE(val) ELF32_R_TYPE(val)
|
||||
#define ELF_ST_TYPE(o) ELF32_ST_TYPE(o)
|
||||
#define ELF_ST_BIND(o) ELF32_ST_BIND(o)
|
||||
#define ELF_ST_VISIBILITY(o) ELF32_ST_VISIBILITY(o)
|
||||
|
||||
#include "relocs.c"
|
17
arch/x86/tools/relocs_64.c
Normal file
17
arch/x86/tools/relocs_64.c
Normal file
@ -0,0 +1,17 @@
|
||||
#include "relocs.h"
|
||||
|
||||
#define ELF_BITS 64
|
||||
|
||||
#define ELF_MACHINE EM_X86_64
|
||||
#define ELF_MACHINE_NAME "x86_64"
|
||||
#define SHT_REL_TYPE SHT_RELA
|
||||
#define Elf_Rel Elf64_Rela
|
||||
|
||||
#define ELF_CLASS ELFCLASS64
|
||||
#define ELF_R_SYM(val) ELF64_R_SYM(val)
|
||||
#define ELF_R_TYPE(val) ELF64_R_TYPE(val)
|
||||
#define ELF_ST_TYPE(o) ELF64_ST_TYPE(o)
|
||||
#define ELF_ST_BIND(o) ELF64_ST_BIND(o)
|
||||
#define ELF_ST_VISIBILITY(o) ELF64_ST_VISIBILITY(o)
|
||||
|
||||
#include "relocs.c"
|
76
arch/x86/tools/relocs_common.c
Normal file
76
arch/x86/tools/relocs_common.c
Normal file
@ -0,0 +1,76 @@
|
||||
#include "relocs.h"
|
||||
|
||||
void die(char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
vfprintf(stderr, fmt, ap);
|
||||
va_end(ap);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static void usage(void)
|
||||
{
|
||||
die("relocs [--abs-syms|--abs-relocs|--text|--realmode] vmlinux\n");
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int show_absolute_syms, show_absolute_relocs;
|
||||
int as_text, use_real_mode;
|
||||
const char *fname;
|
||||
FILE *fp;
|
||||
int i;
|
||||
unsigned char e_ident[EI_NIDENT];
|
||||
|
||||
show_absolute_syms = 0;
|
||||
show_absolute_relocs = 0;
|
||||
as_text = 0;
|
||||
use_real_mode = 0;
|
||||
fname = NULL;
|
||||
for (i = 1; i < argc; i++) {
|
||||
char *arg = argv[i];
|
||||
if (*arg == '-') {
|
||||
if (strcmp(arg, "--abs-syms") == 0) {
|
||||
show_absolute_syms = 1;
|
||||
continue;
|
||||
}
|
||||
if (strcmp(arg, "--abs-relocs") == 0) {
|
||||
show_absolute_relocs = 1;
|
||||
continue;
|
||||
}
|
||||
if (strcmp(arg, "--text") == 0) {
|
||||
as_text = 1;
|
||||
continue;
|
||||
}
|
||||
if (strcmp(arg, "--realmode") == 0) {
|
||||
use_real_mode = 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (!fname) {
|
||||
fname = arg;
|
||||
continue;
|
||||
}
|
||||
usage();
|
||||
}
|
||||
if (!fname) {
|
||||
usage();
|
||||
}
|
||||
fp = fopen(fname, "r");
|
||||
if (!fp) {
|
||||
die("Cannot open %s: %s\n", fname, strerror(errno));
|
||||
}
|
||||
if (fread(&e_ident, 1, EI_NIDENT, fp) != EI_NIDENT) {
|
||||
die("Cannot read %s: %s", fname, strerror(errno));
|
||||
}
|
||||
rewind(fp);
|
||||
if (e_ident[EI_CLASS] == ELFCLASS64)
|
||||
process_64(fp, use_real_mode, as_text,
|
||||
show_absolute_syms, show_absolute_relocs);
|
||||
else
|
||||
process_32(fp, use_real_mode, as_text,
|
||||
show_absolute_syms, show_absolute_relocs);
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
@ -2043,9 +2043,7 @@ static void xen_set_fixmap(unsigned idx, phys_addr_t phys, pgprot_t prot)
|
||||
|
||||
switch (idx) {
|
||||
case FIX_BTMAP_END ... FIX_BTMAP_BEGIN:
|
||||
#ifdef CONFIG_X86_F00F_BUG
|
||||
case FIX_F00F_IDT:
|
||||
#endif
|
||||
case FIX_RO_IDT:
|
||||
#ifdef CONFIG_X86_32
|
||||
case FIX_WP_TEST:
|
||||
case FIX_VDSO:
|
||||
|
Loading…
Reference in New Issue
Block a user