Subject: Re: new rpc code: what am I doing wrong ?
To: Frank van der Linden <frank@wins.uva.nl>
From: None <itojun@iijlab.net>
List: current-users
Date: 06/13/2000 09:28:56
>> Looks like a recursive call to free() but it's also possible that the stack
>> is corrupted. I'll recompile with '-g' and investigate.
>I noticed the same too, but have not been able to reproduce it (and was
>away for a day and a half this weekend). Let me know if you find
>something out. If freeaddrinfo() is at fault, it is probably a bug
>I introduced when making reading the exports file more AF-independent.

	free_grp() tries to free things too much.   freeaddrinfo() takes
	care of recursive struct.  the patch also corrects possible memory leak.

itojun


Index: mountd.c
===================================================================
RCS file: /cvsroot/basesrc/usr.sbin/mountd/mountd.c,v
retrieving revision 1.67
diff -u -r1.67 mountd.c
--- mountd.c	2000/06/10 08:01:07	1.67
+++ mountd.c	2000/06/13 00:28:39
@@ -2124,14 +2124,14 @@
 		if (getaddrinfo(cp, NULL, &hints, &ai) == 0)
 			sa = ai->ai_addr;
 		else
-			return 1;
+			goto fail;
 	} else
-		return 1;
+		goto fail;
 
 	ecode = getnameinfo(sa, sa->sa_len, netname, sizeof netname,
 	    NULL, 0, NI_NUMERICHOST);
 	if (ecode != 0)
-		return 1;
+		goto fail;
 
 	if (maskflg)
 		net->nt_len = countones(sa);
@@ -2139,7 +2139,7 @@
 		if (opt_flags & OP_MASKLEN) {
 			preflen = strtol(prefp, NULL, 10);
 			if (preflen == LONG_MIN && errno == ERANGE)
-				return 1;
+				goto fail;
 			net->nt_len = (int)preflen;
 			*p = '/';
 		}
@@ -2173,6 +2173,11 @@
 	if (ai)
 		freeaddrinfo(ai);
 	return 0;
+
+fail:
+	if (ai)
+		freeaddrinfo(ai);
+	return 1;
 }
 
 /*
@@ -2427,18 +2432,10 @@
 free_grp(grp)
 	struct grouplist *grp;
 {
-	struct addrinfo *ai;
 
 	if (grp->gr_type == GT_HOST) {
-		if (grp->gr_ptr.gt_addrinfo != NULL) {
-			ai = grp->gr_ptr.gt_addrinfo;
-			do {
-				if (ai->ai_flags & AI_CANONNAME)
-					free(ai->ai_canonname);
-				ai = ai->ai_next;
-			} while (ai != NULL);
+		if (grp->gr_ptr.gt_addrinfo != NULL)
 			freeaddrinfo(grp->gr_ptr.gt_addrinfo);
-		}
 	} else if (grp->gr_type == GT_NET) {
 		if (grp->gr_ptr.gt_net.nt_name)
 			free(grp->gr_ptr.gt_net.nt_name);