*BSD News Article 29393


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