Date: Mon, 08 May 2023 08:55:23 +0000 From: bugzilla-noreply@freebsd.org To: bugs@FreeBSD.org Subject: [Bug 271310] potential NULL dereference in fsck_ffs's changeino() Message-ID: <bug-271310-227@https.bugs.freebsd.org/bugzilla/>
next in thread | raw e-mail | index | archive | help
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=3D271310 Bug ID: 271310 Summary: potential NULL dereference in fsck_ffs's changeino() Product: Base System Version: CURRENT Hardware: Any OS: Any Status: New Severity: Affects Some People Priority: --- Component: bin Assignee: bugs@FreeBSD.org Reporter: rtm@lcs.mit.edu Created attachment 242049 --> https://bugs.freebsd.org/bugzilla/attachment.cgi?id=3D242049&action= =3Dedit a broken FS image that causes a NULL dereference in fsck's changeino() Running fsck_ffs -y on the attached image causes this line in sbin/fsck_ffs/dir.c changeino() to dereference NULL: getinoinfo(dir)->i_depth =3D depth; I think the reason is that the link count of the i-node in question (i-number 3, a directory) has its high bit set, so that it looks negative in di_nlink (which is int16_t) in this code in checkinode() in pass1.c: if (mode =3D=3D IFDIR) { if (DIP(dp, di_size) =3D=3D 0) { inoinfo(inumber)->ino_state =3D DCLEAR; } else if (DIP(dp, di_nlink) <=3D 0) { inoinfo(inumber)->ino_state =3D DZLINK; } else { inoinfo(inumber)->ino_state =3D DSTATE; cacheino(dp, inumber); countdirs++; } As a result, ino_state is set to DZLINK, and cacheino() is not called, which is why getinoinfo() eventually returns NULL. Later, in pass4(), I think the expectation is that ino_linkcnt will be zero, and clri() will be called. But in fact ino_linkcnt is not zero (it's negative), so adjust() is called, which effectively expects cacheino() to have been called. case DZLINK: if (inoinfo(inumber)->ino_linkcnt =3D=3D 0)= { clri(&idesc, "UNREF", 1); break; } /* fall through */ case FSTATE: case DFOUND: n =3D inoinfo(inumber)->ino_linkcnt; if (n) { adjust(&idesc, (short)n); A backtrace from fsck_ffs -y fsck13a.img : Program received signal SIGSEGV, Segmentation fault. Address not mapped to object. 0x000000000020b165 in changeino (dir=3D3, name=3D0x201ecf "..", newnum=3D4,= depth=3D2) at dir.c:712 712 getinoinfo(dir)->i_depth =3D depth; (gdb) where #0 0x000000000020b165 in changeino (dir=3D3, name=3D0x201ecf "..", newnum= =3D4,=20 depth=3D2) at dir.c:712 #1 0x000000000020a553 in linkup (orphan=3D3, parentdir=3D0, name=3D0x0) at= dir.c:664 #2 0x0000000000209acd in adjust (idesc=3D0x7fffffffe7d0, lcnt=3D-32765) at dir.c:470 #3 0x000000000022025e in pass4 () at pass4.c:94 #4 0x0000000000219ae9 in checkfilesys (filesys=3D0x7fffffffed79 "junk") at main.c:484 #5 0x0000000000218f42 in main (argc=3D1, argv=3D0x7fffffffea28) at main.c:= 210 --=20 You are receiving this mail because: You are the assignee for the bug.=
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?bug-271310-227>