Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 23 Apr 2001 18:27:10 -0400 (EDT)
From:      ak03@gte.com
To:        FreeBSD-gnats-submit@freebsd.org
Subject:   bin/26806: FIX: rpcbind dumps core sometimes 
Message-ID:  <200104232227.f3NMRAd01041@h132-197-97-45.gte.com>

next in thread | raw e-mail | index | archive | help

>Number:         26806
>Category:       bin
>Synopsis:       rpcbind can dump core under certain circumstances
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Apr 23 15:30:01 PDT 2001
>Closed-Date:
>Last-Modified:
>Originator:     Alexander N. Kabaev
>Release:        FreeBSD 5.0-CURRENT i386
>Organization:
Verizon Laboratories Inc.
>Environment:
System: FreeBSD kanpc.gte.com 5.0-CURRENT FreeBSD 5.0-CURRENT #2: Mon Apr 23 14:50:40 EDT 2001 root@kanpc.gte.com:/usr/src/sys/compile/KANPC i386

>Description:
	rpcbind occasionally dump core on my -CURRENT box. After I was unable
	to get the meaningful core dump, it turns out that the program
	is crashing due to the unitialized parameter in addrmerge 
	procedure in rpcbind/util.c

	It looks like addrmerge tries to locate the network device most
	suitable for sending request reply to the client and then converts
	the unterface network address into a string. When the client
	address is on the local subnet, everything is OK and one of
	the branches of the switch statement on util.c:111 will execute
 	and initialize tbuf structure with proper values. If client is
	not on the local address, procedure tries to select "best"
	interface to handle the requiest but does NOT initialize
	tbuf structure and passes random garbage to the taddr2uaddr later
	when it reaches found: label.
	taddr2uaddr crashes with sig 11 in inet_ntop shortly after that.
	
>How-To-Repeat:
	Not sure. Simply run -CURRENT box in a large network with
	multiple subnets?
>Fix:
	Attached patch delays initialization of the tbuf structure
	until right before taddr2uaddr is called. rpcbind did not crash
	for a three days already while before it was reliably dumping 
	core no later than 30 min after system reboot.

Index: util.c
===================================================================
RCS file: /usr/ncvs/src/usr.sbin/rpcbind/util.c,v
retrieving revision 1.1
diff -u -r1.1 util.c
--- util.c	2001/03/19 12:50:11	1.1
+++ util.c	2001/04/23 21:48:25
@@ -174,29 +174,14 @@
 			 * ifsin: address of interface being examined.
 			 * clntsin: address that client want us to contact
 			 *           it on
-			 * servsin: local address of RPC service.
 			 * sinmask: netmask of this interface
-			 * newsin: initially a copy of clntsin, eventually
-			 *         the merged address
 			 */
-			servsin = (struct sockaddr_in *)serv_sa;
 			clntsin = (struct sockaddr_in *)clnt_sa;
 			sinmask = (struct sockaddr_in *)ifap->ifa_netmask;
-			newsin = (struct sockaddr_in *)&ss;
 			ifsin = (struct sockaddr_in *)ifap->ifa_addr;
 			if (!bitmaskcmp(&ifsin->sin_addr, &clntsin->sin_addr,
-			    &sinmask->sin_addr, sizeof (struct in_addr))) {
-				/*
-				 * Found it.
-				 */
-				memcpy(newsin, ifap->ifa_addr,
-				    clnt_sa->sa_len);
-				newsin->sin_port = servsin->sin_port;
-				tbuf.len = clnt_sa->sa_len;
-				tbuf.maxlen = sizeof (struct sockaddr_storage);
-				tbuf.buf = newsin;
+			    &sinmask->sin_addr, sizeof (struct in_addr)))
 				goto found;
-			}
 			break;
 #ifdef INET6
 		case AF_INET6:
@@ -205,10 +190,7 @@
 			 * ifsin6: address of interface being examined.
 			 * clntsin6: address that client want us to contact
 			 *           it on
-			 * servsin6: local address of RPC service.
 			 * sin6mask: netmask of this interface
-			 * newsin6: initially a copy of clntsin, eventually
-			 *          the merged address
 			 *
 			 * For v6 link local addresses, if the client contacted
 			 * us via a link-local address, and wants us to reply
@@ -218,27 +200,19 @@
 			ifsin6 = (struct sockaddr_in6 *)ifap->ifa_addr;
 			in6_fillscopeid(ifsin6);
 			clntsin6 = (struct sockaddr_in6 *)clnt_sa;
-			servsin6 = (struct sockaddr_in6 *)serv_sa;
 			sin6mask = (struct sockaddr_in6 *)ifap->ifa_netmask;
-			newsin6 = (struct sockaddr_in6 *)&ss;
 			if (IN6_IS_ADDR_LINKLOCAL(&ifsin6->sin6_addr) &&
 			    IN6_IS_ADDR_LINKLOCAL(&realsin6->sin6_addr) &&
 			    IN6_IS_ADDR_LINKLOCAL(&clntsin6->sin6_addr)) {
 				if (ifsin6->sin6_scope_id !=
 				    realsin6->sin6_scope_id)
 					continue;
-match:
-				memcpy(newsin6, ifsin6, clnt_sa->sa_len);
-				newsin6->sin6_port = servsin6->sin6_port;
-				tbuf.maxlen = sizeof (struct sockaddr_storage);
-				tbuf.len = clnt_sa->sa_len;
-				tbuf.buf = newsin6;
 				goto found;
 			}
 			if (!bitmaskcmp(&ifsin6->sin6_addr,
 			    &clntsin6->sin6_addr, &sin6mask->sin6_addr,
 			    sizeof (struct in6_addr)))
-				goto match;
+				goto found;
 			break;
 #endif
 		default:
@@ -268,8 +242,31 @@
 	}
 	ifap = bestif;
 found:
-	if (ifap != NULL)
+	if (ifap != NULL) {
+		memcpy(newsin, ifap->ifa_addr, clnt_sa->sa_len);
+		tbuf.len = clnt_sa->sa_len;
+		tbuf.maxlen = sizeof (struct sockaddr_storage);
+		tbuf.buf = &ss;
+
+		switch (clnt->sa_family) {
+		case AF_INET:
+			servsin = (struct sockaddr_in *)serv_sa;
+			newsin = (struct sockaddr_in *)&ss;
+			newsin->sin_port = servsin->sin_port;
+			break;
+#ifdef INET6
+		case AF_INET6:
+			servsin6 = (struct sockaddr_in6 *)serv_sa;
+			newsin6 = (struct sockaddr_in6 *)&ss;
+			newsin6->sin6_port = servsin6->sin6_port;
+			break;
+#endif
+		default:
+			goto freeit;
+		}
+
 		ret = taddr2uaddr(nconf, &tbuf);
+	}
 freeit:
 	freenetconfigent(nconf);
 	free(serv_sa);
>Release-Note:
>Audit-Trail:
>Unformatted:

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200104232227.f3NMRAd01041>