fix(kernel): a GPT disk with a bad header, or an unreadable first block, is not used
The increment 2 final review's minors 1-4 (Captain Bob, 2026-10-27: "fix 1-4"): 1. A protective MBR with no "EFI PART" header is GPT_BAD, not GPT_NONE: the MBR says it is a GPT disk, and a GPT disk is never attached whole. 2. A disk whose block 0 cannot be read is GPT_EIO: "GPT: a USB drive could not be read -- not used", nothing attached (it was read raw, attached whole, and a raw Zuse drive behind it logged her in). 3. The entry array's LBA is checked against the disk's size directly. 4. gpt_bad_entries: the entry array changed, the header valid -- refused. Harness modes gpt_no_header, gpt_read_error (blkdebug EIO on sector 0), gpt_bad_entries. The plan carries the amendment. Red (amd64): gpt_no_header 070335, gpt_read_error 070717 FAIL; gpt_bad_entries 070048 PASS (existing check, now pinned). Green: every GPT mode on amd64 071113-072933; gpt_zuse, gpt_read_error, gpt_no_header on aarch64 073222-074047 and riscv64 074526-075535; the identity gate's and increment 1's sessions 080036-082345, emergency 083130 (082635 was run without EMERGENCY_CONSOLE_ENABLED=1 -- a harness invocation error). Accepted: suite EXIT 0; 093121, 093352, 093750, POST 538/538, dict_hash 0xfec8c47cfc6f437f; test-32, 0 failures. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
f612bb37a9
commit
2e71f7aa0d
@@ -19,8 +19,9 @@ typedef struct {
|
||||
} gpt_part_t;
|
||||
|
||||
#define GPT_OK 0 /* a valid GPT */
|
||||
#define GPT_NONE 1 /* not a GPT disk (or one whose sectors are not 512 bytes): read it raw */
|
||||
#define GPT_BAD 2 /* a GPT, but its header or entry array does not check out: not used */
|
||||
#define GPT_NONE 1 /* not a GPT disk -- no protective MBR -- (or one whose sectors are not 512 bytes): read it raw */
|
||||
#define GPT_BAD 2 /* a protective MBR, but its header or entry array does not check out: not used */
|
||||
#define GPT_EIO 3 /* its first block could not be read: not used */
|
||||
|
||||
/* Read `disk`'s protective MBR, primary GPT header and partition-entry array,
|
||||
* checking both CRC-32s, the revision, the sizes and the geometry. On GPT_OK,
|
||||
|
||||
+6
-4
@@ -71,15 +71,17 @@ int gpt_read(blkio_dev_t *disk, gpt_part_t *parts, unsigned max, unsigned *count
|
||||
return GPT_NONE;
|
||||
}
|
||||
}
|
||||
if (blkio_read(disk, 0u, g_gpt_hdr_block) != BLKIO_OK) return GPT_NONE;
|
||||
/* a disk whose first block cannot be read may be a GPT disk: not used */
|
||||
if (blkio_read(disk, 0u, g_gpt_hdr_block) != BLKIO_OK) return GPT_EIO;
|
||||
|
||||
/* the protective MBR: 0x55AA, and a partition of type 0xEE */
|
||||
if (mbr[510] != 0x55u || mbr[511] != 0xAAu) return GPT_NONE;
|
||||
for (i = 0; i < 4u; i++) if (mbr[446u + 16u * i + 4u] == 0xEEu) break;
|
||||
if (i == 4u) return GPT_NONE;
|
||||
if (memcmp(h, "EFI PART", 8) != 0) return GPT_NONE;
|
||||
|
||||
/* from here it is a GPT disk: anything wrong is GPT_BAD */
|
||||
/* from here it is a GPT disk -- the protective MBR says so: anything
|
||||
* wrong, the header's signature first, is GPT_BAD */
|
||||
if (memcmp(h, "EFI PART", 8) != 0) return GPT_BAD;
|
||||
if (le32(h + 8) != 0x00010000u) return GPT_BAD;
|
||||
hsize = le32(h + 12);
|
||||
if (hsize < 92u || hsize > GPT_SECTOR) return GPT_BAD;
|
||||
@@ -99,7 +101,7 @@ int gpt_read(blkio_dev_t *disk, gpt_part_t *parts, unsigned max, unsigned *count
|
||||
if (my_lba != 1u || esize < 128u || esize % 128u != 0u || nent == 0u) return GPT_BAD;
|
||||
if (first_usable > last_usable || last_usable >= disk_sectors) return GPT_BAD;
|
||||
ebytes = (size_t)nent * esize;
|
||||
if (ebytes > GPT_ENTRIES_MAX || ent_lba < 2u || (ent_lba % 2u) != 0u) return GPT_BAD;
|
||||
if (ebytes > GPT_ENTRIES_MAX || ent_lba < 2u || ent_lba >= disk_sectors || (ent_lba % 2u) != 0u) return GPT_BAD;
|
||||
if (ent_lba + (ebytes + GPT_SECTOR - 1u) / GPT_SECTOR > first_usable) return GPT_BAD;
|
||||
|
||||
/* the entry array, a 1 KiB block at a time */
|
||||
|
||||
@@ -120,14 +120,19 @@ static int sk_v4_drive_arrived(sk_v4_drive_t *d)
|
||||
|
||||
/* GPT first (docs/v4.0.0/STICK.md 4): a disk with a valid GPT is used
|
||||
* through its StarshipOS identity partition only; one with no such
|
||||
* partition, or a damaged table, is not used at all; a disk with no GPT
|
||||
* is read raw, as an identity drive always has been. */
|
||||
* partition, a damaged table or an unreadable first block is not used at
|
||||
* all; a disk with no GPT is read raw, as an identity drive always has
|
||||
* been. */
|
||||
d->used = (blkio_dev_t *)0;
|
||||
gpt_rc = gpt_read(&d->raw, g_gpt_parts, SK_V4_GPT_PARTS, &nparts);
|
||||
if (gpt_rc == GPT_BAD) {
|
||||
console_println("GPT: a USB drive has a damaged partition table -- not used");
|
||||
return 1;
|
||||
}
|
||||
if (gpt_rc == GPT_EIO) {
|
||||
console_println("GPT: a USB drive could not be read -- not used");
|
||||
return 1;
|
||||
}
|
||||
if (gpt_rc == GPT_OK) {
|
||||
idx = gpt_find(g_gpt_parts, nparts, gpt_type_starship_identity);
|
||||
if (idx < 0) return 1; /* no StarshipOS partition: not ours to use */
|
||||
|
||||
Reference in New Issue
Block a user