⬢ DragonFlyBSD Kernel Audit
DF-2498 / run_nonfatal.log
← back to finding ↓ download raw
== DF-2496 test12: production Intel parse installs degenerate geometry verbatim ==
ata_raid_intel_read_meta() rc=1 raidp[0]=0xfffff801183add00
installed geometry (all copied verbatim from crafted metadata, never checked for zero):
  rdp->type         = 0x4 (AR_T_RAID0)
  rdp->status       = 0x1 (AR_S_READY)
  rdp->interleave   = 0   <-- map->stripe_sectors = 0 (ata-raid.c:2229)
  rdp->total_sectors= 0  <-- map->total_sectors = 0 (ata-raid.c:2231)
  rdp->width        = 2
these feed, unguarded:
  ata-raid.c:359  chunk = blkno % rdp->interleave      (strategy RAID0/01)
  ata-raid.c:1028 progress = 100*lba / rdp->total_sectors (ata_raid_status)
  ata-raid.c:181  total_sectors/(heads*sectors)         (ata_raid_attach)
tests 20/21/22 fire those three sites (fatal, one per boot).
last_rc=1

== DF-2497 test11: production HPTv2 SPAN parse + production ata_raid_strategy() walk past the array end ==
parse rc=1 raidp[0]=0xfffff80116975500
parse installed (verbatim from crafted metadata):
  type=AR_T_SPAN total_disks=2 width=2 total_sectors=2000
  disks[0].sectors=0 disks[1].sectors=1000 (total usable=1000)
  sizeof(struct ar_softc)=2424 disks[] at +112 disks[30].sectors stride at +1576
stopper planted at rdp+1576 (disks[30].sectors stride) = ffffffff8260b440 (disks[30].dev same)
firing production ata_raid_strategy(): blkno=5000 (past the 1000-sector array), count=1 ...
strategy returned 0; dispatches=1
PROOF: production strategy dispatched to disk index drv=this=30 (dev=0xffffffff8260b440 read OOB at disks[30]) -- total_disks=2, MAX_DISKS=16: the walk read 29 entries past the configured disks and 15 past disks[] bounds before the stopper (ata-raid.c:352-353 has no bound)
last_rc=1

== DF-2498 test10: production Intel parse, map->total_disks=60 -> raid->disks[16..59] OOB writes ==
parse rc=1 raidp[0]=0xfffff80118973700 (retained: serial matched fake parent)
sizeof(struct ar_softc)=2424 disks[] at +112 entry size=48 => disks[49] starts at +2464 (first past the allocation)
guard[ 0]=0xfffff801172d7d00
guard[ 8]=0xfffff801172c5100
guard[16]=0xfffff801172cd300
guard[24]=0xfffff801172d2300
guard[32]=0 (freed hole)
guard[40]=0xfffff80118978700
guard[48]=0xfffff8011897d700
guard[56]=0xfffff80118962900
victim lands IN/NEAR the freed hole (guards[31]=0xfffff801172d5f00 guards[33]=0xfffff80118974b00)
parse-installed array: total_disks=60 width=60 type=0x4 interleave=64
in-object smash readback (fields past disks[15] written by the disks[disk<60] loop):
  disks[16] @rdp+880  : dev=ffffffff8260b440 serial=d0d1d2 sectors=c0ffee flags=b
  disks[24] @rdp+1264 : dev=ffffffff8260b440 serial=d0d1d2 sectors=c0ffee flags=b
  disks[32] @rdp+1648 : dev=ffffffff8260b440 serial=d0d1d2 sectors=c0ffee flags=b
  disks[40] @rdp+2032 : dev=ffffffff8260b440 serial=d0d1d2 sectors=c0ffee flags=b
  disks[48] @rdp+2416 : dev=ffffffff8260b440 serial=d0d1d2 sectors=c0ffee flags=b
  (expected per disks[disk] write: dev=NULL, serial=D0..DF, sectors=0xC0FFEE, flags=0xa ONLINE|ASSIGNED)
raw u64s at victim+2424..+2488 (past the object):
  +2424: d7d6d5d4d3d2d1d0 dfdedddcdbdad9d8
  +2440: 0000000000c0ffee 0000000000000000
  +2456: 000000000000000b ffffffff8260b440
  +2472: d7d6d5d4d3d2d1d0 dfdedddcdbdad9d8
guard[33] 0xfffff80118974100 SMASHED (324/2424 bytes): first words ffffffff8260b440 d7d6d5d4d3d2d1d0 dfdedddcdbdad9d8 c0ffee
guard chunks hit by the overflow: 1/64
in-object proof: disks[16].serial[0..1]=d0d1 == crafted D0 D1 -- OOB WRITE CONFIRMED
past-object proof: 11/11 entries disks[49..59] carry the crafted sectors marker 0xC0FFEE at rdp+2488..+2992 (object ends at +2424)
PROOF: raid->disks[disk] loop wrote 44 entries past disks[MAX_DISKS-1] in-object (confirmed) and 11/11 past the allocation (raw readback) via raid->total_disks=60 taken verbatim from map->total_disks (ata-raid.c:2230); the serial-match loop then wrote .dev/flags OOB for those same entries (ata-raid.c:2266-2283)
last_rc=1

== DF-2497 test13: walk stop at the disks[60].sectors stride (PAST the ar_softc allocation) ==
victim rdp=0xfffff8008decf100 size=2424; disks[60].sectors stride at rdp+3016 (600 past the allocation end)
guards 0xfffff8008dec3300..0xfffff8008decfb00 (32 x 2424, uniformly filled with fake-ad-dev pointer)
stride address rdp+3016 = 0xfffff8008decfcc8 INSIDE guard range
strategy returned 0; dispatches=1
PROOF: walk reached disk index 51 before dispatch (>= 49 means past the 2424-byte allocation): disks[51].sectors is 168 bytes past the object
last_rc=1