fix: gpt_read checks every entry, and says when there are more than max (#180)

gpt_read() stopped at max used entries (16 for the identity code, 4 in the
mint): a disk whose StarshipOS partitions came after the first max read as
having none, and the entries after max were never range-checked.

Now every entry is checked and every used one counted; a good table with more
used entries than max is GPT_MANY (the first max in parts), and the identity
code says "GPT: a USB drive has more than 16 partitions -- not used". Other
callers treat anything but GPT_OK as before.

Tested first, seen to fail: qemu_session.py gpt_many -- a data stick with its
two partitions as entries 17 and 18 after 16 others, and the same with an entry
19 past the usable range: both "not this system's stick" before (silently cut,
entry 19 never checked; logs/20261112-162236). After: "more than 16
partitions" and "a damaged partition table" (logs/20261112-162921).
Regressions: gpt_bad_entries, gpt_foreign PASS. gpt_zuse FAILS, on a stale
expectation unrelated to this change -- an identity-only GPT drive with no
system stick has been held silently as a possible real Zuse since #92 Task 4;
its log is kept here. The gpt_many images are made before the boot: a first
version made them after, failed in sgdisk and left its QEMU running, stopped
by hand (logs/20261112-162003).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017RzZgrf7V7Zk2iczBXDRbm
This commit is contained in:
Claude
2026-11-12 16:41:00 +00:00
parent ab63789e5b
commit 9700a7b404
16 changed files with 83 additions and 7 deletions
+6 -2
View File
@@ -26,10 +26,14 @@ typedef struct {
#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; gpt_write_one: nothing was written */
#define GPT_PART 4 /* gpt_write_one only: a write failed after others were made -- the disk is changed (#168) */
#define GPT_MANY 5 /* gpt_read: a valid GPT with more used entries than max -- every entry checked, none cut (#180) */
/* 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,
* `*count` partitions with a non-zero type (at most `max`) are in `parts`.
* checking both CRC-32s, the revision, the sizes and the geometry, and every
* entry's range. On GPT_OK, `*count` partitions with a non-zero type (at most
* `max`) are in `parts`. GPT_MANY when the table is good but has more used
* entries than `max`: the first `max` are in `parts`, `*count` is `max`, and the
* caller says so rather than taking the disk as having only those (#180).
* Reads only. */
int gpt_read(blkio_dev_t *disk, gpt_part_t *parts, unsigned max, unsigned *count);