Date: Sun, 23 Jul 2023 15:30:05 +0000 From: bugzilla-noreply@freebsd.org To: bugs@FreeBSD.org Subject: [Bug 192839] Duplicate entries in an mtree file cause nmtree to coredump Message-ID: <bug-192839-227-miEB5YDZtQ@https.bugs.freebsd.org/bugzilla/> In-Reply-To: <bug-192839-227@https.bugs.freebsd.org/bugzilla/> References: <bug-192839-227@https.bugs.freebsd.org/bugzilla/>
next in thread | previous in thread | raw e-mail | index | archive | help
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=3D192839 --- Comment #7 from Felix Dietrich <felix.dietrich+freebsd-bugtracker@sperr= haken.name> --- The problem that brought me here is a segmentation fault resulting from fee= ding the following example to nmtree: /set type=3Ddir . dup .. dup child_entry type=3Dfile Line numbers in the following paragraph are according to FreeBSD 12.4-RELEASE-p2 (git hash 149768b65d619833331bcf0c2fb121b20643f2f1). The segmentation fault is caused by using the memory pointed to by centry (=E2=80=9Clast =3D cenry=E2=80=9D in the =E2=80=9Cspec=E2=80=9D function [s= pec.c:252]) after it has been freed in replacenode (=E2=80=9Cfree(new)=E2=80=9D [spec.c:536]). (A comment in the = addchild function [spec.c:775] indicates that at least addchild is aware that replacenode will free the centry.) The memory gets reused for the next centry (=E2=80=9Ccen= try =3D calloc(=E2=80=A6=E2=80=9D [spec.c:207]) and assigned the global defaults (= =E2=80=9C*centry =3D ginfo=E2=80=9D [spec.c:209]). The parent member of the ginfo record is NULL [spec.c:122], and, as a consequence of the faulty memory reuse, addchild gets passed NULL (=E2=80=9Caddchild(last->parent, centry)=E2=80=9D [spec.c:260]) for its pat= hparent parameter.=20 This results in a segmentation fault early in addchild because of a NULL dereference (=E2=80=9Ccur =3D pathparent->child=E2=80=9D [spec.c:734]). Al= so note that last->type gets overridden and set to F_FILE [spec.c:215], and, therefore, = not the branch =E2=80=9Clast->type =3D=3D F_DIR && !(last->flags & F_DONE)=E2= =80=9D [spec.c:245] is taken, as one would expect by correct operation, but the final else branch = =E2=80=9Cnew relative child in parent dir=E2=80=9D [spec.c:253]. I have not reasoned much about solutions. It might be possible for a quick= and dirty fix to dispense with the =E2=80=9Cfree(new)=E2=80=9D call in replacen= ode [spec.c:536] at the cost of leaking memory and making the code even harder to reason about.= =20 Another solutions could make replacenode actually replace the node (removing =E2=80=9Ccur=E2=80=9D from the data structure and emplacing =E2=80=9Cnew=E2= =80=9D in its stead) instead of overwriting the members of the existing =E2=80=9Ccur=E2=80=9D node =E2=80= =93 but I have not tried to understand and follow the assumptions addchild makes of replacenode=CA=BCs operations. --=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-192839-227-miEB5YDZtQ>