Return to BSD News archive
Path: sserve!newshost.anu.edu.au!harbinger.cc.monash.edu.au!msuinfo!agate!ICSI.Berkeley.EDU!stolcke From: stolcke@ICSI.Berkeley.EDU (Andreas Stolcke) Newsgroups: comp.os.386bsd.bugs,info.bsdi.users Subject: mountd bug + fix Date: 15 Apr 1994 17:21:29 GMT Organization: International Computer Science Institute, Berkeley, CA, U.S.A. Lines: 78 Distribution: world Message-ID: <2omiep$ott@agate.berkeley.edu> NNTP-Posting-Host: tiramisu.icsi.berkeley.edu The bug described below was found on BSD/386, but inspection of the sources reveal that the faulty code is straight from Net2, and present, e.g., in NetBSD and probably others. To: problem@BSDI.COM Subject: mountd dumps core (with fix) Description: /sbin/mountd dumps core after an appropriate sequence of mount and unmount rpcs. The problem is a faulty management of the linked list headed by *mlhead in del_mlist(). A pointer ends up pointing to freed memory (see diff below). Release: 1.1 Repeat-By: Make sure the mount list is empty. Mount two filesystems from host foo, so the mountlist contains foo:/a and foo:/b. Unmount both, by way of RPCMNT_UMNTALL. (I accomplished this by using a more recent version of amd that actually does RPCMNT_UMNTALL when a type:=host filesystem is unmounted. umount -a may also do the trick). The mountlist will now mistakenly still contain foo:/a, in freed memory. Try mounting something again, and get a core dump. Fix: There are two problems in the mountd.c code: 1) the mlpp = &mlp->ml_next line is executed even when mlp was just freed (this the real source of above problem). 2) freed memory is used for iterating pointers (which is probably fine by the current malloc, but not guaranteed to work). The patch fixes both. *** mountd.c.dist Wed Apr 13 14:45:26 1994 --- mountd.c Wed Apr 13 20:30:15 1994 *************** *** 871,884 **** mlpp = &mlhead; mlp = mlhead; while (mlp) { if (!strcmp(mlp->ml_host, hostp) && (!dirp || !strcmp(mlp->ml_dirp, dirp))) { fnd = 1; *mlpp = mlp->ml_next; ! free((caddr_t)mlp); } - mlpp = &mlp->ml_next; mlp = mlp->ml_next; } if (fnd) { if ((mlfile = fopen(_PATH_RMOUNTLIST, "w")) == NULL) { --- 871,888 ---- mlpp = &mlhead; mlp = mlhead; while (mlp) { + caddr_t *freep = NULL; + if (!strcmp(mlp->ml_host, hostp) && (!dirp || !strcmp(mlp->ml_dirp, dirp))) { fnd = 1; *mlpp = mlp->ml_next; ! freep = (caddr_t)mlp; ! } else { ! mlpp = &mlp->ml_next; } mlp = mlp->ml_next; + if (freep) free(freep); } if (fnd) { if ((mlfile = fopen(_PATH_RMOUNTLIST, "w")) == NULL) { -- Andreas Stolcke stolcke@icsi.berkeley.edu International Computer Science Institute stolcke@ucbicsi.bitnet 1947 Center St., Suite 600, Berkeley, CA 94704 (510) 642-4274 ext. 126