Re: fsck segfaults on rpi3 running 13-stable (and on 14-CURRENT analyzing the same file system that resulted from the 13-STABLE crash)

John-Mark Gurney <[email protected]>
Newsgroups gmane.os.freebsd.devel.arm
Message-ID <[email protected]>
John-Mark Gurney wrote this message on Mon, Feb 13, 2023 at 15:25 -0800:

After analyzing the remaining crashes that were detected, the following
was found..  This was done w/ a minimal FS,  It is possible that it'll
find more crashes w/ a slightly more complex FS, e.g. one w/ indirect
blocks, and other file types.

Note that FS's that exhibit these are available at:
https://www.funkthat.com/~jmg/FreeBSD/ffs.afl/

---- FIRST ----
std_checkblkavail doesn't check that blkno is within valid range, e.g.
if blkno is negative, it'll segfault:
0x0000000000121d6c in std_checkblkavail (blkno=blkno@entry=-288230376151711688, frags=frags@entry=1) at /usr/src/sbin/fsck_ffs/fsutil.c:1149
1149                    if (testbmap(blkno + j))


---- SECOND ----
pass5 doesn't check that cg_nextfreeoff is sane/within range, this
causes a large value to be passed to memset, in this case:
#1  0x000000000012fee4 in pass5 () at /usr/src/sbin/fsck_ffs/pass5.c:241
241                     memset(cg_inosused(newcg), 0, (size_t)(mapsize));
(gdb) print *newcg
$7 = {cg_firstfield = 0, cg_magic = 590421, cg_old_time = 0, cg_cgx = 0,
  cg_old_ncyl = 0, cg_old_niblk = 0, cg_ndblk = 256, cg_cs = {cs_ndir = 0,
  cs_nbfree = 0, cs_nifree = 128, cs_nffree = 0}, cg_rotor = 0,
  cg_frotor = 0, cg_irotor = 0, cg_frsum = {0, 0, 0, 0, 0, 0, 0, 0},
  cg_old_btotoff = 0, cg_old_boff = 0, cg_iusedoff = 168,
  cg_freeoff = 184, cg_nextfreeoff = 61341980,
  cg_clustersumoff = 54526164, cg_clusteroff = 54526232,
  cg_nclusterblks = 32, cg_niblk = 128, cg_initediblk = 128,
  cg_unrefs = 0, cg_sparecon32 = {0}, cg_ckhash = 3548071837,
  cg_time = 1676327229, cg_sparecon64 = {0, 0, 0}, cg_space = ""}

and mapsize is:
(gdb) print newcg->cg_nextfreeoff - newcg->cg_iusedoff
$6 = 61341812

which overflows buf, which is MAXBSIZE, or 8k.

---- THIRD ----
allocino doesn't make sure that cg_iusedoff is sane.  In this case,
cg_iusedoff is 4294965672, which means that in allocino, the setbit
function call will access invalid memory.

0x0000000000127168 in allocino (request=2, type=16877) at /usr/src/sbin/fsck_ffs/inode.c:1379
1379            setbit(cg_inosused(cgp), ino % sblock.fs_ipg);

(gdb) print *cgp
$14 = {cg_firstfield = 0, cg_magic = 590421, cg_old_time = 0, 
  cg_cgx = 0, cg_old_ncyl = 0, cg_old_niblk = 0, cg_ndblk = 256, 
  cg_cs = {cs_ndir = 2, cs_nbfree = 23, cs_nifree = 124, 
    cs_nffree = 21}, cg_rotor = 0, cg_frotor = 0, cg_irotor = 0, 
  cg_frsum = {0, 0, 0, 0, 0, 0, 0, 3}, cg_old_btotoff = 0, 
  cg_old_boff = 0, cg_iusedoff = 4294965672, cg_freeoff = 183, 
  cg_nextfreeoff = 284, cg_clustersumoff = 212, cg_clusteroff = 280, 
  cg_nclusterblks = 32, cg_niblk = 128, cg_initediblk = 128, 
  cg_unrefs = 0, cg_sparecon32 = {0}, cg_ckhash = 3548071837, 
  cg_time = 1676327229, cg_sparecon64 = {0, 0, 0}, cg_space = "\017"}

-- 
  John-Mark Gurney				Voice: +1 415 225 5579

     "All that I will do, has been done, All that I have, has not."
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.