DF-3694 / analysis.txt
DF-3694 source trace (sys/dev/disk/nata/ata-raid.c):
jmicron write path:
2688 ata_raid_jmicron_write_meta(struct ar_softc *rdp)
2732 for (disk = 0; disk < rdp->total_disks && disk < JM_MAX_DISKS; disk++) {
2733 if (rdp->disks[disk].serial[0])
2734 bcopy(rdp->disks[disk].serial,&meta->disks[disk],sizeof(u_int32_t));
2735 else
2736 meta->disks[disk] = (u_int32_t)(uintptr_t)rdp->disks[disk].dev; <-- kernel pointer
...
2753 if (ata_raid_rw(rdp->disks[disk].dev, JMICRON_LBA(...), meta,
2755 sizeof(struct jmicron_raid_conf), ATA_R_WRITE|ATA_R_DIRECT))
via write path:
3937 ata_raid_via_write_meta(struct ar_softc *rdp)
3985 for (disk = 0; disk < rdp->total_disks; disk++)
3986 meta->disks[disk] = (u_int32_t)(uintptr_t)rdp->disks[disk].dev; <-- kernel pointer, unconditional
...
4005 if (ata_raid_rw(rdp->disks[disk].dev, VIA_LBA(...), meta,
4007 sizeof(struct via_raid_conf), ATA_R_WRITE|ATA_R_DIRECT))
`serial[0] == 0` for all disks of an ioctl-created array:
1048 rdp = kmalloc(... M_ZERO) in ata_raid_create; no serial assignment anywhere
between :1048 and ata_raid_attach (:1274) -> serial[] stays zeroed.
Round trip: the leaked value is also *checksummed into* the metadata
(jmicron checksum :2746-2748 covers meta->disks[]; via checksum :3999-4000
covers the first 50 bytes which include disks[0..7]) and later re-parsed
(via :3915 `meta->disks[disk] == meta->disk_id`), so it is durably present
in the on-disk image of the array.
Vendor gating on this guest (Intel PIIX3 only):
1433 case ATA_JMICRON_ID: ... ata_raid_jmicron_read_meta(...)
1460 case ATA_VIA_ID: ... ata_raid_via_read_meta(...)
-> format unreachable -> runtime test not possible here.