:: commit 7fc7ececbce2c1856188c8ab3a06f627ee843ddb

mintsuki <mintsuki@protonmail.com> — 2024-10-12 01:47

parents: dc12098981

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__)
tab: 248 wrap: offon