[Midnightbsd-cvs] src [7337] trunk/usr.sbin/rpcbind/rpcb_svc_com.c: In rpcbind(8), netbuf structures are copied directly, which would result in

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Wed Sep 30 09:10:40 EDT 2015


Revision: 7337
          http://svnweb.midnightbsd.org/src/?rev=7337
Author:   laffer1
Date:     2015-09-30 09:10:39 -0400 (Wed, 30 Sep 2015)
Log Message:
-----------
In rpcbind(8), netbuf structures are copied directly, which would result in
two netbuf structures that reference to one shared address buffer.  When one
of the two netbuf structures is freed, access to the other netbuf structure
would result in an undefined result that may crash the rpcbind(8) daemon.

Modified Paths:
--------------
    trunk/usr.sbin/rpcbind/rpcb_svc_com.c

Modified: trunk/usr.sbin/rpcbind/rpcb_svc_com.c
===================================================================
--- trunk/usr.sbin/rpcbind/rpcb_svc_com.c	2015-09-30 13:07:57 UTC (rev 7336)
+++ trunk/usr.sbin/rpcbind/rpcb_svc_com.c	2015-09-30 13:10:39 UTC (rev 7337)
@@ -48,6 +48,7 @@
 #include <rpc/rpc.h>
 #include <rpc/rpcb_prot.h>
 #include <rpc/svc_dg.h>
+#include <assert.h>
 #include <netconfig.h>
 #include <errno.h>
 #include <syslog.h>
@@ -1048,19 +1049,31 @@
 	return ((n1->len != n2->len) || memcmp(n1->buf, n2->buf, n1->len));
 }
 
+static bool_t
+netbuf_copybuf(struct netbuf *dst, const struct netbuf *src)
+{
+
+	assert(dst->buf == NULL);
+
+	if ((dst->buf = malloc(src->len)) == NULL)
+		return (FALSE);
+
+	dst->maxlen = dst->len = src->len;
+	memcpy(dst->buf, src->buf, src->len);
+	return (TRUE);
+}
+
 static struct netbuf *
 netbufdup(struct netbuf *ap)
 {
 	struct netbuf  *np;
 
-	if ((np = malloc(sizeof(struct netbuf))) == NULL)
+	if ((np = calloc(1, sizeof(struct netbuf))) == NULL)
 		return (NULL);
-	if ((np->buf = malloc(ap->len)) == NULL) {
+	if (netbuf_copybuf(np, ap) == FALSE) {
 		free(np);
 		return (NULL);
 	}
-	np->maxlen = np->len = ap->len;
-	memcpy(np->buf, ap->buf, ap->len);
 	return (np);
 }
 
@@ -1068,6 +1081,7 @@
 netbuffree(struct netbuf *ap)
 {
 	free(ap->buf);
+	ap->buf = NULL;
 	free(ap);
 }
 
@@ -1185,7 +1199,7 @@
 {
 	u_int32_t *xidp;
 
-	*(svc_getrpccaller(xprt)) = *(fi->caller_addr);
+	netbuf_copybuf(svc_getrpccaller(xprt), fi->caller_addr);
 	xidp = __rpcb_get_dg_xidp(xprt);
 	*xidp = fi->caller_xid;
 }



More information about the Midnightbsd-cvs mailing list