The branch main has been updated by mckusick:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=6a71277c3037df2c3a70464c2e2bf20dec2c128a

commit 6a71277c3037df2c3a70464c2e2bf20dec2c128a
Author:     Kirk McKusick <[email protected]>
AuthorDate: 2023-05-29 21:58:20 +0000
Commit:     Kirk McKusick <[email protected]>
CommitDate: 2023-05-29 21:58:20 +0000

    Fix a bug in fsck_ffs(8) triggered by corrupted filesystems.
    
    When loading the root directory ensure that it is a directory
    and has a size greater than the minimum directory size. If an
    invalid root directory is found, fall back to full fsck.
    
    Reported-by:  Robert Morris
    PR:           271414
    MFC-after:    1 week
    Sponsored-by: The FreeBSD Foundation
---
 sbin/fsck_ffs/suj.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/sbin/fsck_ffs/suj.c b/sbin/fsck_ffs/suj.c
index c86d6b711635..1e935b864b7c 100644
--- a/sbin/fsck_ffs/suj.c
+++ b/sbin/fsck_ffs/suj.c
@@ -2377,7 +2377,7 @@ suj_check(const char *filesys)
 {
        struct inodesc idesc;
        struct csum *cgsum;
-       union dinode *jip;
+       union dinode *dp, *jip;
        struct inode ip;
        uint64_t blocks;
        int i, retval;
@@ -2419,7 +2419,17 @@ suj_check(const char *filesys)
        idesc.id_func = findino;
        idesc.id_name = SUJ_FILE;
        ginode(UFS_ROOTINO, &ip);
-       if ((ckinode(ip.i_dp, &idesc) & FOUND) == FOUND) {
+       dp = ip.i_dp;
+       if ((DIP(dp, di_mode) & IFMT) != IFDIR) {
+               irelse(&ip);
+               err_suj("root inode is not a directory\n");
+       }
+       if (DIP(dp, di_size) < 0 || DIP(dp, di_size) > MAXDIRSIZE) {
+               irelse(&ip);
+               err_suj("negative or oversized root directory %jd\n",
+                   (uintmax_t)DIP(dp, di_size));
+       }
+       if ((ckinode(dp, &idesc) & FOUND) == FOUND) {
                sujino = idesc.id_parent;
                irelse(&ip);
        } else {

Reply via email to