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_PCIA, /* Lithium PCI Bridge A */
|
||||||
FIX_LI_PCIB, /* Lithium PCI Bridge B */
|
FIX_LI_PCIB, /* Lithium PCI Bridge B */
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_X86_F00F_BUG
|
FIX_RO_IDT, /* Virtual mapping for read-only IDT */
|
||||||
FIX_F00F_IDT, /* Virtual mapping for IDT */
|
|
||||||
#endif
|
|
||||||
#ifdef CONFIG_X86_CYCLONE_TIMER
|
#ifdef CONFIG_X86_CYCLONE_TIMER
|
||||||
FIX_CYCLONE_TIMER, /*cyclone timer register*/
|
FIX_CYCLONE_TIMER, /*cyclone timer register*/
|
||||||
#endif
|
#endif
|
||||||
|
@ -176,20 +176,6 @@ int __cpuinit ppro_with_ram_bug(void)
|
|||||||
return 0;
|
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)
|
static void __cpuinit intel_smp_check(struct cpuinfo_x86 *c)
|
||||||
{
|
{
|
||||||
/* calling is from identify_secondary_cpu() ? */
|
/* 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
|
* All current models of Pentium and Pentium with MMX technology CPUs
|
||||||
* have the F0 0F bug, which lets nonprivileged users lock up the
|
* have the F0 0F bug, which lets nonprivileged users lock up the
|
||||||
* system.
|
* system. Announce that the fault handler will be checking for it.
|
||||||
* Note that the workaround only should be initialized once...
|
|
||||||
*/
|
*/
|
||||||
clear_cpu_bug(c, X86_BUG_F00F);
|
clear_cpu_bug(c, X86_BUG_F00F);
|
||||||
if (!paravirt_enabled() && c->x86 == 5) {
|
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);
|
set_cpu_bug(c, X86_BUG_F00F);
|
||||||
if (!f00f_workaround_enabled) {
|
if (!f00f_workaround_enabled) {
|
||||||
trap_init_f00f_bug();
|
|
||||||
printk(KERN_NOTICE "Intel Pentium with F0 0F bug - workaround enabled.\n");
|
printk(KERN_NOTICE "Intel Pentium with F0 0F bug - workaround enabled.\n");
|
||||||
f00f_workaround_enabled = 1;
|
f00f_workaround_enabled = 1;
|
||||||
}
|
}
|
||||||
|
@ -56,6 +56,7 @@
|
|||||||
#include <asm/i387.h>
|
#include <asm/i387.h>
|
||||||
#include <asm/fpu-internal.h>
|
#include <asm/fpu-internal.h>
|
||||||
#include <asm/mce.h>
|
#include <asm/mce.h>
|
||||||
|
#include <asm/fixmap.h>
|
||||||
#include <asm/mach_traps.h>
|
#include <asm/mach_traps.h>
|
||||||
|
|
||||||
#ifdef CONFIG_X86_64
|
#ifdef CONFIG_X86_64
|
||||||
@ -768,6 +769,14 @@ void __init trap_init(void)
|
|||||||
set_bit(SYSCALL_VECTOR, used_vectors);
|
set_bit(SYSCALL_VECTOR, used_vectors);
|
||||||
#endif
|
#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:
|
* 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
|
HOST_EXTRACFLAGS += -I$(srctree)/tools/include
|
||||||
hostprogs-y += relocs
|
hostprogs-y += relocs
|
||||||
|
relocs-objs := relocs_32.o relocs_64.o relocs_common.o
|
||||||
relocs: $(obj)/relocs
|
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) {
|
switch (idx) {
|
||||||
case FIX_BTMAP_END ... FIX_BTMAP_BEGIN:
|
case FIX_BTMAP_END ... FIX_BTMAP_BEGIN:
|
||||||
#ifdef CONFIG_X86_F00F_BUG
|
case FIX_RO_IDT:
|
||||||
case FIX_F00F_IDT:
|
|
||||||
#endif
|
|
||||||
#ifdef CONFIG_X86_32
|
#ifdef CONFIG_X86_32
|
||||||
case FIX_WP_TEST:
|
case FIX_WP_TEST:
|
||||||
case FIX_VDSO:
|
case FIX_VDSO:
|
||||||
|
Loading…
Reference in New Issue
Block a user