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

From: bob prohaska <fbsd_at_www.zefox.net>
Date: Wed, 15 Feb 2023 00:29:46 UTC
On Tue, Feb 14, 2023 at 03:27:46PM -0800, John-Mark Gurney wrote:
> bob prohaska wrote this message on Tue, Feb 14, 2023 at 13:06 -0800:
> > On Tue, Feb 14, 2023 at 10:38:27AM -0800, John-Mark Gurney wrote:
> > > bob prohaska wrote this message on Tue, Feb 14, 2023 at 08:14 -0800:
> > > > 
> > > > Is this a demonstration that the fsck segfault can be reproduced 
> > > > independtly of my particular corrupt filesystem? AFL is new to me. 
> > > 
> > > Yes, it is.  It turns out that the FS to produce this failure is a LOT
> > > smaller than I expected when compresed, I have included it later in the
> > > email.  The constant above was taken directly from the failing FS.
> > > 
> > > AFL is a very useful tool, and found this crash and apparently 50+
> > > other crashes in only 5-10 minutes of running... I'll be investigating
> > > a few of the other crashes as well, as fsck does ocassionally deal w/
> > > untrusted fs's.
> > > 
> > 
> > Would trying to run fsck on the corrupt filesystem from an 8GB Pi4
> > (also running -current) make any difference? I.e., might more physical
> > RAM cover up the bug and allow fsck to complete successfully? 
> 
> No, it will not.  It's trying to access memory address 0x4 which does
> not exist, no matter how much memory.
> 
> In this case, an inode's mtime is wildly incorrect.  Here is a simple
> patch that will let it get farther, BUT, it doesn't necessarily mean
> that the kernel can properly handle the mtime:
> diff --git a/sbin/fsck_ffs/inode.c b/sbin/fsck_ffs/inode.c
> index 82338f4f8c08..d0892a822dc5 100644
> --- a/sbin/fsck_ffs/inode.c
> +++ b/sbin/fsck_ffs/inode.c
> @@ -1311,7 +1311,10 @@ prtinode(struct inode *ip)
>         printf("SIZE=%ju ", (uintmax_t)DIP(dp, di_size));
>         t = DIP(dp, di_mtime);
>         p = ctime(&t);
> -       printf("MTIME=%12.12s %4.4s ", &p[4], &p[20]);
> +       if (p == NULL)
> +               printf("MTIME=invalid ");
> +       else
> +               printf("MTIME=%12.12s %4.4s ", &p[4], &p[20]);
>  }
>  
>  void
> 
> 
> If you can get the inode number (should be in the gdb backtrace in one
> of the frames), you can use fsdb to switch to the inode (inode <num>),
> and then set the mtime to something reasonable (mtime 0), and then fsck
> should complete as well...
>

That looks fairly tricky. I'm tempted to just wait till the fix propagates
into -current, unless that'll take an extraordinary amount of time. 

> > Is there a plain-English description of how AFL works? I gather it
> > manipulates input read by a program to discover improperly handled
> > cases, but even that is far from certain. There's no hope of me doing 
> > anything useful with AFL. I'm merely curious.  
> 
> You are correct.  It insturments a program to see when it modifies
> the input, which branches it takes, and uses that to make better choices
> on how to mutate the input.
> 
> In another email I sent the instructions on how I ran it, but I used:
> https://afl-1.readthedocs.io/en/latest/quick_start.html
> 
> to figure/remind myself how to run it.  Only difference is that instead
> of running ./configure, I used make instead in the correct directory of
> the FreeBSD src tree.

The Wikepedia page is nearly readable for a non-programmer.
It seems to suggest that one starts with a valid input file
and valid input command for a specially-compiled version of
the test program, then randomly modifies the command or input,
catalogs the result and repeats successively until something 
gets past the program's error handling filters.  

Thanks for writing!

bob prohaska