protos/limine: Add randomise_hhdm_base config option
diff --git a/CONFIG.md b/CONFIG.md
index 9162443a..43b158b3 100644
--- a/CONFIG.md
+++ b/CONFIG.md
@@ -125,6 +125,8 @@ Editor control options:
* `module_cmdline` - A command line to be passed to a module. This option can also be specified multiple times. It applies to the module described by the last module option specified.
* `resolution` - The resolution to be used. This setting takes the form of `<width>x<height>x<bpp>`. If the resolution is not available, Limine will pick another one automatically. Omitting `<bpp>` will default to 32.
* `kaslr` - For relocatable kernels, if set to `no`, disable kernel address space layout randomisation. KASLR is enabled by default.
+ * `randomise_hhdm_base` - If set to `yes`, randomise the base address of the higher half direct map. If set to `no`, do not. By default it is `yes` if KASLR is supported and enabled, else it is `no`.
+ * `randomize_hhdm_base` - Alias of `randomise_hhdm_base`.
* `max_paging_mode`, `min_paging_mode` - Limit the maximum and minimum paging modes to one of the following:
- x86-64 and aarch64: `4level`, `5level`.
- riscv64: `sv39`, `sv48`, `sv57`.
diff --git a/common/menu.c b/common/menu.c
index d67b7edb..eb8fd942 100644
--- a/common/menu.c
+++ b/common/menu.c
@@ -106,6 +106,8 @@ static const char *VALID_KEYS[] = {
"RESOLUTION",
"TEXTMODE",
"KASLR",
+ "RANDOMISE_HHDM_BASE",
+ "RANDOMIZE_HHDM_BASE",
"PAGING_MODE",
"MAX_PAGING_MODE",
"MIN_PAGING_MODE",
diff --git a/common/protos/limine.c b/common/protos/limine.c
index d668ba2a..314e27fd 100644
--- a/common/protos/limine.c
+++ b/common/protos/limine.c
@@ -300,9 +300,9 @@ static uint64_t physical_base, virtual_base, slide, direct_map_offset;
static size_t requests_count;
static void **requests;
-static void set_paging_mode(bool kaslr) {
+static void set_paging_mode(bool randomise_hhdm_base) {
direct_map_offset = paging_mode_higher_half(paging_mode);
- if (kaslr) {
+ if (randomise_hhdm_base) {
// A quarter of the higher half of wiggle room for KASLR, align to 1GiB steps.
uint64_t mask = ((uint64_t)1 << (paging_mode_va_bits(paging_mode) - 3)) - 1;
direct_map_offset += (rand64() & ~((uint64_t)0x40000000 - 1)) & mask;
@@ -763,6 +763,7 @@ hhdm_fail:
#endif
bool paging_mode_set = false;
+ bool randomise_hhdm_base;
FEAT_START
struct limine_paging_mode_request *pm_request = get_request(LIMINE_PAGING_MODE_REQUEST);
if (pm_request == NULL)
@@ -801,7 +802,17 @@ FEAT_START
paging_mode = kern_min_mode;
}
- set_paging_mode(kaslr);
+ char *randomise_hhdm_base_s = config_get_value(config, 0, "RANDOMISE_HHDM_BASE");
+ if (randomise_hhdm_base_s == NULL) {
+ randomise_hhdm_base_s = config_get_value(config, 0, "RANDOMIZE_HHDM_BASE");
+ }
+ if (randomise_hhdm_base_s == NULL) {
+ randomise_hhdm_base = kaslr;
+ } else {
+ randomise_hhdm_base = strcasecmp(randomise_hhdm_base_s, "no") != 0;
+ }
+
+ set_paging_mode(randomise_hhdm_base);
paging_mode_set = true;
struct limine_paging_mode_response *pm_response =
@@ -812,7 +823,7 @@ FEAT_START
FEAT_END
if (!paging_mode_set) {
- set_paging_mode(kaslr);
+ set_paging_mode(randomise_hhdm_base);
}
#if defined (__aarch64__)
