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