:: commit 0f0dddf75e73f45f9f7c51699e4da6db2597daa9

mintsuki <mintsuki@protonmail.com> — 2021-03-29 10:14

parents: 25bba4ecea

part: Harden MBR detection code

diff --git a/limine-install/limine-install.c b/limine-install/limine-install.c
index 15832164..022dc7f9 100644
--- a/limine-install/limine-install.c
+++ b/limine-install/limine-install.c
@@ -329,6 +329,55 @@ int main(int argc, char *argv[]) {
         }
     }
 
+    int mbr = 0;
+    if (gpt == 0) {
+        // Do all sanity checks on MBR
+        mbr = 1;
+
+        uint16_t hint = 0;
+        device_read(&hint, 218, sizeof(uint16_t));
+        if (hint != 0)
+            mbr = 0;
+
+        device_read(&hint, 444, sizeof(uint16_t));
+        if (hint != 0 && hint != 0x5a5a)
+            mbr = 0;
+
+        device_read(&hint, 510, sizeof(uint16_t));
+        if (hint != 0xaa55)
+            mbr = 0;
+
+        device_read(&hint, 446, sizeof(uint8_t));
+        if ((uint8_t)hint != 0x00 && (uint8_t)hint != 0x80)
+            mbr = 0;
+        device_read(&hint, 462, sizeof(uint8_t));
+        if ((uint8_t)hint != 0x00 && (uint8_t)hint != 0x80)
+            mbr = 0;
+        device_read(&hint, 478, sizeof(uint8_t));
+        if ((uint8_t)hint != 0x00 && (uint8_t)hint != 0x80)
+            mbr = 0;
+        device_read(&hint, 494, sizeof(uint8_t));
+        if ((uint8_t)hint != 0x00 && (uint8_t)hint != 0x80)
+            mbr = 0;
+
+        char hintc[64];
+        device_read(hintc, 4, 8);
+        if (memcmp(hintc, "_ECH_FS_", 8) == 0)
+            mbr = 0;
+        device_read(hintc, 54, 3);
+        if (memcmp(hintc, "FAT", 3) == 0)
+            mbr = 0;
+        device_read(&hint, 1080, sizeof(uint16_t));
+        if (hint == 0xef53)
+            mbr = 0;
+    }
+
+    if (gpt == 0 && mbr == 0) {
+        fprintf(stderr, "ERROR: Could not determine if the device has a valid partition table.\n");
+        fprintf(stderr, "       Please ensure the device has a valid MBR or GPT.\n");
+        goto cleanup;
+    }
+
     size_t   stage2_size   = bootloader_file_size - 512;
 
     size_t   stage2_sects  = DIV_ROUNDUP(stage2_size, 512);
diff --git a/stage23/lib/part.s2.c b/stage23/lib/part.s2.c
index 43f68fdf..860d5073 100644
--- a/stage23/lib/part.s2.c
+++ b/stage23/lib/part.s2.c
@@ -234,8 +234,40 @@ static int mbr_get_logical_part(struct volume *ret, struct volume *extended_part
 static int mbr_get_part(struct volume *ret, struct volume *volume, int partition) {
     // Check if actually valid mbr
     uint16_t hint = 0;
+    volume_read(volume, &hint, 218, sizeof(uint16_t));
+    if (hint != 0)
+        return INVALID_TABLE;
+
     volume_read(volume, &hint, 444, sizeof(uint16_t));
-    if (hint && hint != 0x5a5a)
+    if (hint != 0 && hint != 0x5a5a)
+        return INVALID_TABLE;
+
+    volume_read(volume, &hint, 510, sizeof(uint16_t));
+    if (hint != 0xaa55)
+        return INVALID_TABLE;
+
+    volume_read(volume, &hint, 446, sizeof(uint8_t));
+    if ((uint8_t)hint != 0x00 && (uint8_t)hint != 0x80)
+        return INVALID_TABLE;
+    volume_read(volume, &hint, 462, sizeof(uint8_t));
+    if ((uint8_t)hint != 0x00 && (uint8_t)hint != 0x80)
+        return INVALID_TABLE;
+    volume_read(volume, &hint, 478, sizeof(uint8_t));
+    if ((uint8_t)hint != 0x00 && (uint8_t)hint != 0x80)
+        return INVALID_TABLE;
+    volume_read(volume, &hint, 494, sizeof(uint8_t));
+    if ((uint8_t)hint != 0x00 && (uint8_t)hint != 0x80)
+        return INVALID_TABLE;
+
+    char hintc[64];
+    volume_read(volume, hintc, 4, 8);
+    if (memcmp(hintc, "_ECH_FS_", 8) == 0)
+        return INVALID_TABLE;
+    volume_read(volume, hintc, 54, 3);
+    if (memcmp(hintc, "FAT", 3) == 0)
+        return INVALID_TABLE;
+    volume_read(volume, &hint, 1080, sizeof(uint16_t));
+    if (hint == 0xef53)
         return INVALID_TABLE;
 
     struct mbr_entry entry;
tab: 248 wrap: offon