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>
