DF-2480 / verdict.json
{ "finding_id": "DF-2480", "status": "reproduced", "reproduced": 1, "impact": "corruption", "confidence": "certain", "verdict": "The verbatim mmcsd_rw/mmcsd_delete (extracted whole) assign bio->bio_offset/sz into daddr_t (= __int32_t, sys/types.h:80) block/end. Control (1000 sectors): cmd.arg correct. At exactly 1 TiB the arg still bit-matches (0x80000000). At 2 TiB the u64 block 0x100000000 arrives at the card as cmd.arg=0x00000000, and at 4 TiB+12345 sectors as 0x00003039 - the READ/WRITE/ERASE command is issued against the WRONG SECTOR (silent data corruption on >1TiB SDXC/eMMC media, or spurious EIO depending on card). mmcsd_delete shares the math (cited :534). Fix (64-bit locals + reject blocks beyond the 32-bit MMC argument with EIO) A/B: no MMC command is issued for the hostile offsets (opcode/arg unchanged, transfer skipped).", "exploit_chain": "no attacker needed - media-size correctness bug; corruption affects data at wrong sectors on large cards.", "evidence": "run.log: 2TiB -> cmd.arg=0x00000000 (expected 0x100000000) TRUNCATED/WRONG; 4TiB -> 0x00003039; control 0x3e8 CORRECT.", "kernel_refs": [ "sys/dev/disk/mmcsd/mmcsd.c:327", "sys/dev/disk/mmcsd/mmcsd.c:328", "sys/dev/disk/mmcsd/mmcsd.c:345", "sys/dev/disk/mmcsd/mmcsd.c:415", "sys/sys/types.h:80" ], "poc_changes": "MMCBUS_WAIT_FOR_REQUEST interposed to capture cmd.arg; device reports success.", "attempts": 1, "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT DragonFly 6.5-DEVELOPMENT #0: Thu Jul 2 06:02:54 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC x86_64", "runtime_sec": 600, "guest_dirty": 0, "build_cmd": "sh /root/rigs/dfv_mmcsd/gen.sh && make -m /usr/src/share/mk (in dfv_mmcsd)", "run_cmd": "kldload dfv_mmcsd.ko; for i in 0 1 2 3 4; do sysctl kern.dfv_mmcsd_run=$i >/dev/null; sysctl -n kern.dfv_mmcsd_status; done", "code_hash": "e9326f24fb77555d8173b358b7b35b0e7be0969b443005a93e25a8420844f88d", "notes": "daddr_t is __int32_t (sys/types.h:80). At 2TiB the u32 arg still matches (0x80000000), at 2TiB+ it wraps to 0 and at 4TiB+ arbitrary low bits - wrong-sector commands against large SDXC/eMMC. Fixed code rejects beyond-32-bit blocks with EIO (rig: no MMC command issued).", "recommended_fix": "64-bit block math and reject blocks beyond the 32-bit MMC argument", "fix_status": "fixed" } |