:: commit 852381e60f5d10818029b62f605918edfc30985c

Mintsuki <mintsuki@protonmail.com> — 2026-02-02 01:14

parents: 8631da1c92

drivers/disk: Get rid of more unreliable volume detection methods and misc fixes

diff --git a/common/drivers/disk.s2.c b/common/drivers/disk.s2.c
index 90e2e8be..4d8a286d 100644
--- a/common/drivers/disk.s2.c
+++ b/common/drivers/disk.s2.c
@@ -500,15 +500,14 @@ static bool is_efi_handle_optical(EFI_HANDLE efi_handle) {
             break;
         }
 
-        uint16_t len = *(uint16_t *)dp->Length;
-        if (len < sizeof(EFI_DEVICE_PATH_PROTOCOL)) {
-            break;  // Malformed device path node
-        }
-
         if (dp->Type == MEDIA_DEVICE_PATH && dp->SubType == MEDIA_CDROM_DP) {
             return true;
         }
 
+        uint16_t len = *(uint16_t *)dp->Length;
+        if (len < sizeof(EFI_DEVICE_PATH_PROTOCOL)) {
+            break;  // Malformed device path node
+        }
         dp = (void *)dp + len;
     }
 
@@ -552,12 +551,16 @@ static bool device_paths_match_disk(EFI_DEVICE_PATH_PROTOCOL *dp1,
             return false;
         }
 
+        if (len1 < sizeof(EFI_DEVICE_PATH_PROTOCOL)) {
+            return false;
+        }
+
         if (memcmp(dp1, dp2, len1) != 0) {
             return false;
         }
 
-        dp1 = NextDevicePathNode(dp1);
-        dp2 = NextDevicePathNode(dp2);
+        dp1 = (void *)dp1 + len1;
+        dp2 = (void *)dp2 + len2;
     }
 
     return true;
@@ -576,84 +579,47 @@ static struct volume *volume_by_device_path(EFI_HANDLE query_handle) {
         }
 
         if (device_paths_match_disk(query_dp, vol_dp)) {
+            // Convert first_sect from 512-byte sectors to device LBAs
+            int sector_size = volume_index[i]->sector_size;
+            if ((volume_index[i]->first_sect * 512) % sector_size) {
+                continue;  // Misaligned, skip this volume
+            }
+            uint64_t first_sect_lba = (volume_index[i]->first_sect * 512) / sector_size;
+
             EFI_DEVICE_PATH_PROTOCOL *qp = query_dp;
             while (!IsDevicePathEnd(qp)) {
                 if (qp->Type == MEDIA_DEVICE_PATH && qp->SubType == MEDIA_HARDDRIVE_DP) {
+                    uint16_t len = DevicePathNodeLength(qp);
+                    if (len < sizeof(HARDDRIVE_DEVICE_PATH)) {
+                        break;
+                    }
                     HARDDRIVE_DEVICE_PATH *query_hd = (HARDDRIVE_DEVICE_PATH *)qp;
-                    if (volume_index[i]->first_sect == query_hd->PartitionStart) {
+                    if (first_sect_lba == query_hd->PartitionStart) {
                         return volume_index[i];
                     }
                     break;
                 }
-                qp = NextDevicePathNode(qp);
-            }
-
-            if (IsDevicePathEnd(qp) && volume_index[i]->partition == 0) {
-                return volume_index[i];
-            }
-        }
-    }
-
-    return NULL;
-}
-
-static struct volume *volume_by_partition_signature(EFI_HANDLE query_handle) {
-    EFI_DEVICE_PATH_PROTOCOL *dp = get_device_path(query_handle);
-    if (dp == NULL) {
-        return NULL;
-    }
-
-    while (!IsDevicePathEnd(dp)) {
-        uint16_t len = DevicePathNodeLength(dp);
-        if (len < sizeof(EFI_DEVICE_PATH_PROTOCOL)) {
-            break;
-        }
-
-        if (dp->Type == MEDIA_DEVICE_PATH && dp->SubType == MEDIA_HARDDRIVE_DP) {
-            if (len < sizeof(HARDDRIVE_DEVICE_PATH)) {
-                break;
-            }
-
-            HARDDRIVE_DEVICE_PATH *hd = (HARDDRIVE_DEVICE_PATH *)dp;
-
-            // GPT: match by partition GUID
-            if (hd->SignatureType == SIGNATURE_TYPE_GUID) {
-                for (size_t i = 0; i < volume_index_i; i++) {
-                    if (volume_index[i]->guid_valid &&
-                        memcmp(&volume_index[i]->guid, hd->Signature, sizeof(EFI_GUID)) == 0) {
-                        return volume_index[i];
+                if (qp->Type == MEDIA_DEVICE_PATH && qp->SubType == MEDIA_CDROM_DP) {
+                    uint16_t len = DevicePathNodeLength(qp);
+                    if (len < sizeof(CDROM_DEVICE_PATH)) {
+                        break;
                     }
-                }
-            }
-
-            // MBR: match by partition start LBA
-            if (hd->SignatureType == SIGNATURE_TYPE_MBR) {
-                for (size_t i = 0; i < volume_index_i; i++) {
-                    if (volume_index[i]->first_sect == hd->PartitionStart) {
+                    CDROM_DEVICE_PATH *query_cd = (CDROM_DEVICE_PATH *)qp;
+                    if (first_sect_lba == query_cd->PartitionStart) {
                         return volume_index[i];
                     }
+                    break;
                 }
+                uint16_t len = DevicePathNodeLength(qp);
+                if (len < sizeof(EFI_DEVICE_PATH_PROTOCOL)) {
+                    break;
+                }
+                qp = (void *)qp + len;
             }
 
-            break;
-        }
-
-        dp = NextDevicePathNode(dp);
-    }
-
-    return NULL;
-}
-
-static struct volume *volume_by_media_match(EFI_BLOCK_IO *query_bio) {
-    for (size_t i = 0; i < volume_index_i; i++) {
-        EFI_BLOCK_IO *vol_bio = volume_index[i]->block_io;
-
-        if (vol_bio->Media->BlockSize == query_bio->Media->BlockSize &&
-            vol_bio->Media->LastBlock == query_bio->Media->LastBlock &&
-            vol_bio->Media->ReadOnly == query_bio->Media->ReadOnly &&
-            vol_bio->Media->RemovableMedia == query_bio->Media->RemovableMedia &&
-            vol_bio->Media->LogicalPartition == query_bio->Media->LogicalPartition) {
-            return volume_index[i];
+            if (IsDevicePathEnd(qp) && volume_index[i]->partition == 0) {
+                return volume_index[i];
+            }
         }
     }
 
@@ -661,8 +627,6 @@ static struct volume *volume_by_media_match(EFI_BLOCK_IO *query_bio) {
 }
 
 struct volume *disk_volume_from_efi_handle(EFI_HANDLE efi_handle) {
-    struct volume *ret;
-
     EFI_STATUS status;
 
     EFI_GUID block_io_guid = BLOCK_IO_PROTOCOL;
@@ -687,29 +651,14 @@ struct volume *disk_volume_from_efi_handle(EFI_HANDLE efi_handle) {
             uint8_t b2b[BLAKE2B_OUT_BYTES];
             blake2b(b2b, unique_sector_pool, UNIQUE_SECTOR_POOL_SIZE);
 
-            ret = volume_by_unique_sector(b2b);
+            struct volume *ret = volume_by_unique_sector(b2b);
             if (ret != NULL) {
                 return ret;
             }
         }
     }
 
-    ret = volume_by_device_path(efi_handle);
-    if (ret != NULL) {
-        return ret;
-    }
-
-    ret = volume_by_partition_signature(efi_handle);
-    if (ret != NULL) {
-        return ret;
-    }
-
-    ret = volume_by_media_match(block_io);
-    if (ret != NULL) {
-        return ret;
-    }
-
-    return NULL;
+    return volume_by_device_path(efi_handle);
 }
 
 static void find_unique_sectors(void) {
@@ -746,6 +695,7 @@ static void find_unique_sectors(void) {
             continue;
         }
 
+        // Invalidate collision's unique sector
         collision->unique_sector_valid = false;
     }
 }
tab: 248 wrap: offon