stivale2: Introduce fully virtual kernel mappings (KASLR/PIE fixes)

This commit is contained in:
mintsuki 2021-10-29 19:51:22 +02:00
parent dbbef9f6d3
commit dcd422806c
4 changed files with 33 additions and 14 deletions

View File

@ -457,6 +457,8 @@ int elf64_load(uint8_t *elf, uint64_t *entry_point, uint64_t *top, uint64_t *_sl
uint64_t max_align = elf64_max_align(elf);
uint64_t image_size = 0;
if (fully_virtual) {
simulation = false;
@ -470,9 +472,6 @@ int elf64_load(uint8_t *elf, uint64_t *entry_point, uint64_t *top, uint64_t *_sl
if (phdr.p_type != PT_LOAD)
continue;
if (phdr.p_type != PT_LOAD)
continue;
if (phdr.p_vaddr < min_vaddr) {
min_vaddr = phdr.p_vaddr;
}
@ -482,7 +481,7 @@ int elf64_load(uint8_t *elf, uint64_t *entry_point, uint64_t *top, uint64_t *_sl
}
}
uint64_t image_size = max_vaddr - min_vaddr;
image_size = max_vaddr - min_vaddr;
*physical_base = (uintptr_t)ext_mem_alloc_type_aligned(image_size, alloc_type, max_align);
*virtual_base = min_vaddr;
@ -494,9 +493,19 @@ int elf64_load(uint8_t *elf, uint64_t *entry_point, uint64_t *top, uint64_t *_sl
}
again:
if (kaslr)
if (kaslr) {
slide = rand32() & ~(max_align - 1);
if (fully_virtual) {
if ((*virtual_base - FIXED_HIGHER_HALF_OFFSET_64) + slide + image_size >= 0x80000000) {
if (++try_count == max_simulated_tries) {
panic("elf: Image wants to load too high");
}
goto again;
}
}
}
final:
if (top)
*top = 0;
@ -528,16 +537,12 @@ final:
}
if (!fully_virtual) {
if (higher_half == true && load_addr + phdr.p_memsz > 0x80000000) {
panic("elf: Higher half executable trying to load too high");
}
load_addr += slide;
}
uint64_t this_top = load_addr + phdr.p_memsz;
// Make sure we don't overshoot due to KASLR
// Make sure we don't overshoot
if (higher_half == true && this_top > 0x80000000) {
goto again;
}
@ -596,6 +601,10 @@ final:
goto final;
}
if (fully_virtual) {
*virtual_base += slide;
}
*entry_point = entry + slide;
if (_slide)
*_slide = slide;

View File

@ -169,6 +169,9 @@ void stivale2_load(char *config, char *cmdline, bool pxe, void *efi_system_table
want_fully_virtual, &physical_base, &virtual_base))
panic("stivale2: ELF64 load failure");
printv("stivale2: Physical base: %X\n", physical_base);
printv("stivale2: Virtual base: %X\n", virtual_base);
ret = elf64_load_section(kernel, &stivale2_hdr, ".stivale2hdr",
sizeof(struct stivale2_header), slide);
}

View File

@ -9,7 +9,10 @@ INTERNALLDFLAGS := \
-Tlinker.ld \
-nostdlib \
-zmax-page-size=0x1000 \
-static
-static \
-pie \
--no-dynamic-linker \
-ztext
INTERNALCFLAGS := \
-I../stivale \
@ -17,15 +20,14 @@ INTERNALCFLAGS := \
-std=gnu11 \
-ffreestanding \
-fno-stack-protector \
-fno-pic -fno-pie \
-fpie \
-mabi=sysv \
-mno-80387 \
-mno-mmx \
-mno-3dnow \
-mno-sse \
-mno-sse2 \
-mno-red-zone \
-mcmodel=kernel
-mno-red-zone
all: test.elf

View File

@ -6,6 +6,7 @@ PHDRS
text PT_LOAD FLAGS((1 << 0) | (1 << 2)) ; /* Execute + Read */
rodata PT_LOAD FLAGS((1 << 2)) ; /* Read only */
data PT_LOAD FLAGS((1 << 1) | (1 << 2)) ; /* Write + Read */
dynamic PT_DYNAMIC FLAGS((1 << 1) | (1 << 2)) ; /* Dynamic segment needed for PIE */
}
SECTIONS
@ -36,6 +37,10 @@ SECTIONS
*(.data*)
} :data
.dynamic : {
*(.dynamic)
} :data :dynamic
.bss : {
*(COMMON)
*(.bss*)