Exercise 3: Corrupting the LENGTH Field Itself — Possible Solution ==================================================================== THE TEST ------------------------------ wal = WAL(wal_path) page = Page(); page.add_record(b'GOOD-RECORD') wal.append(9, bytes(page.data)) with open(wal_path, 'r+b') as f: f.seek(3) # a byte inside the 4-byte LENGTH field itself f.write(bytes([0xFF])) # corrupt it -- makes the declared length huge records = read_all_records(wal_path) RESULT ------------------------------ after corrupting a byte inside the LENGTH field: records found -> 0 read_all_records() returns an empty list -- the record is completely, correctly rejected. WHICH CHECK ACTUALLY CATCHES THIS ------------------------------ The bounds check does -- the checksum is never even reached. The record's length field is the first thing read_all_records() looks at: length, crc = struct.unpack_from('>II', data, offset) payload_start = offset + 8 payload_end = payload_start + length if bounds_check and payload_end > len(data): break # <-- this is the line that fires Flipping a byte inside a 4-byte big-endian integer near its most significant end turns a small, correct length (a few hundred bytes, matching one page-sized record) into an enormous, essentially random 32-bit number -- almost certainly far larger than the entire WAL file could possibly hold. payload_end, computed from that corrupted length, ends up pointing somewhere far past the real end of the file. The bounds check payload_end > len(data) catches this immediately and stops reading right there, before the payload is even sliced out, let alone checksummed. WHY THIS IS DIFFERENT FROM FINDING 2b ------------------------------ Finding 2b corrupted a byte INSIDE the payload while leaving the length field itself completely correct -- the file's own shape still looked entirely plausible (the declared length still matched a real, in-bounds region of the file), so only comparing the payload against its own stored checksum could catch it. Here, the corruption is in the LENGTH field itself, which throws the file's own apparent shape into obvious disarray -- the bounds check alone is enough, because the corrupted value is implausible on its face, long before anything about the payload's actual content is examined. Together, the two exercises show the two checks aren't redundant: the bounds check catches corruption that makes a record's own declared SHAPE impossible; the checksum catches corruption that leaves the shape alone but changes the CONTENT. A reader with only one of the two would still have a real, exploitable blind spot. WHY THIS WORKS AS AN ANSWER ------------------------------ Precisely identifying WHICH of the two checks fires -- and explaining why the other one isn't even needed for this particular kind of corruption -- demonstrates the two checks are covering two genuinely different failure shapes (implausible length vs. plausible length with wrong content), not just two redundant ways of double-checking the same thing.