mirror of
https://github.com/limine-bootloader/limine
synced 2025-01-07 13:22:18 +03:00
elf: Make sure KASLR doesn't result in load addresses higher than 0x80000000 for higher half kernels
This commit is contained in:
parent
af28eee1bc
commit
9540ea620b
@ -8,8 +8,6 @@
|
|||||||
#include <mm/pmm.h>
|
#include <mm/pmm.h>
|
||||||
#include <fs/file.h>
|
#include <fs/file.h>
|
||||||
|
|
||||||
#define KASLR_SLIDE_BITMASK ((uintptr_t)0x8ffff000)
|
|
||||||
|
|
||||||
#define PT_LOAD 0x00000001
|
#define PT_LOAD 0x00000001
|
||||||
#define PT_INTERP 0x00000003
|
#define PT_INTERP 0x00000003
|
||||||
#define PT_PHDR 0x00000006
|
#define PT_PHDR 0x00000006
|
||||||
@ -394,10 +392,7 @@ int elf64_load(uint8_t *elf, uint64_t *entry_point, uint64_t *top, uint64_t *_sl
|
|||||||
uint64_t entry = hdr.entry;
|
uint64_t entry = hdr.entry;
|
||||||
bool entry_adjusted = false;
|
bool entry_adjusted = false;
|
||||||
|
|
||||||
uint64_t max_align = 1;
|
uint64_t max_align = elf64_max_align(elf);
|
||||||
if (ranges != NULL) {
|
|
||||||
max_align = elf64_max_align(elf);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!elf64_is_relocatable(elf, &hdr)) {
|
if (!elf64_is_relocatable(elf, &hdr)) {
|
||||||
simulation = false;
|
simulation = false;
|
||||||
@ -406,12 +401,14 @@ int elf64_load(uint8_t *elf, uint64_t *entry_point, uint64_t *top, uint64_t *_sl
|
|||||||
|
|
||||||
again:
|
again:
|
||||||
if (kaslr)
|
if (kaslr)
|
||||||
slide = (rand64() & KASLR_SLIDE_BITMASK) & ~(max_align - 1);
|
slide = rand32() & ~(max_align - 1);
|
||||||
|
|
||||||
final:
|
final:
|
||||||
if (top)
|
if (top)
|
||||||
*top = 0;
|
*top = 0;
|
||||||
|
|
||||||
|
bool higher_half = false;
|
||||||
|
|
||||||
for (uint16_t i = 0; i < hdr.ph_num; i++) {
|
for (uint16_t i = 0; i < hdr.ph_num; i++) {
|
||||||
struct elf64_phdr phdr;
|
struct elf64_phdr phdr;
|
||||||
memcpy(&phdr, elf + (hdr.phoff + i * sizeof(struct elf64_phdr)),
|
memcpy(&phdr, elf + (hdr.phoff + i * sizeof(struct elf64_phdr)),
|
||||||
@ -427,14 +424,25 @@ final:
|
|||||||
} else {
|
} else {
|
||||||
load_addr = phdr.p_vaddr;
|
load_addr = phdr.p_vaddr;
|
||||||
|
|
||||||
if (load_addr & ((uint64_t)1 << 63))
|
if (load_addr & ((uint64_t)1 << 63)) {
|
||||||
|
higher_half = true;
|
||||||
load_addr -= FIXED_HIGHER_HALF_OFFSET_64;
|
load_addr -= FIXED_HIGHER_HALF_OFFSET_64;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (higher_half == true && load_addr + phdr.p_memsz > 0x80000000) {
|
||||||
|
panic("elf: Higher half executable trying to load too high");
|
||||||
}
|
}
|
||||||
|
|
||||||
load_addr += slide;
|
load_addr += slide;
|
||||||
|
|
||||||
uint64_t this_top = load_addr + phdr.p_memsz;
|
uint64_t this_top = load_addr + phdr.p_memsz;
|
||||||
|
|
||||||
|
// Make sure we don't overshoot due to KASLR
|
||||||
|
if (higher_half == true && this_top > 0x80000000) {
|
||||||
|
goto again;
|
||||||
|
}
|
||||||
|
|
||||||
if (top) {
|
if (top) {
|
||||||
if (this_top > *top) {
|
if (this_top > *top) {
|
||||||
*top = this_top;
|
*top = this_top;
|
||||||
|
Loading…
Reference in New Issue
Block a user