DragonFlyBSD Kernel Audit
DF-0859 / run.log
← back to finding ↓ download raw
=== DF-0859 deterministic OOB-WRITE proof ===
struct sizes: alblk=8 alleaf=12 alnode=8
containers : fnode fn_abd=0x60  alsec as_abd=0x1e0  alsec total=500  buffer-cache buf=512
legit max  : fnode-leaves=8 fnode-nodes=12 alsec-leaves=40 alsec-nodes=60

--- hpfs_alblk2alsec (sys/vfs/hpfs/hpfs_alsubr.c:314) ---
    bcopy(abp=fnode fn_ab, nabp=new alsec as_ab, sizeof(alblk_t)+sz*busycnt)
[BUG] alblk2alsec  busycnt=255 sz=12 (alleaf)  WRITTEN=3068B  OOB past 512B buf=2568B  poison=no
[BUG] alblk2alsec  busycnt=255 sz= 8 (alnode)  WRITTEN=2048B  OOB past 512B buf=1548B  poison=no

--- hpfs_splitalsec (sys/vfs/hpfs/hpfs_alsubr.c:225/229) ---
    n1=(busycnt+1)/2 n2=busycnt-n1 ; bcopy(abp+8+n1*sz, nabp+8, n2*sz)
[BUG] splitalsec   busycnt=255 sz=12 (alleaf)  WRITTEN=1524B  OOB past 512B buf=1032B  src OOB past as_abd=2580B  poison=no
[BUG] splitalsec   busycnt=255 sz= 8 (alnode)  WRITTEN=1016B  OOB past 512B buf=524B  src OOB past as_abd=1560B  poison=no

--- hpfs_concatalsec (sys/vfs/hpfs/hpfs_alsubr.c:271/278) ---
    if(ab0.freecnt>ab1.busycnt) bcopy(AB_ALNODE(ab1), AB_FREEANP(ab0), ab1.busycnt*sz)
[BUG] concatalsec  ab1.busycnt=254 ab0.freecnt=255 sz=12 (alleaf)  WRITTEN=3048B  OOB past 512B buf=2556B  src OOB past as_abd=2568B  poison=no
[BUG] concatalsec  ab1.busycnt=254 ab0.freecnt=255 sz= 8 (alnode)  WRITTEN=2032B  OOB past 512B buf=1540B  src OOB past as_abd=1552B  poison=no

--- FIXED: validate ab_busycnt against container max before bcopy ---
[FIX] alblk2alsec  leaf  forged busycnt=255 -> REJECTED (EINVAL)
[FIX] alblk2alsec  node  forged busycnt=255 -> REJECTED (EINVAL)
[FIX] split/concat leaf  forged busycnt=255 -> REJECTED (EINVAL)
[FIX] split/concat node  forged busycnt=255 -> REJECTED (EINVAL)

=== SUMMARY ===
DF_0859_BUG_OOB_WRITE_MAX_BYTES=2568
DF_0859_BUG_CONFIRMED=1
DF_0859_FIX_REJECTS_FORGED_BUSYCNT=1
RUN=0