svn commit: r288384 - in stable: 10/usr.sbin/rpcbind 9/usr.sbin/rpcbind

Xin LI delphij at FreeBSD.org
Tue Sep 29 18:06:28 UTC 2015


Author: delphij
Date: Tue Sep 29 18:06:27 2015
New Revision: 288384
URL: https://svnweb.freebsd.org/changeset/base/288384

Log:
  The Sun RPC framework uses a netbuf structure to represent the
  transport specific form of a universal transport address.  The
  structure is expected to be opaque to consumers.  In the current
  implementation, the structure contains a pointer to a buffer
  that holds the actual address.
  
  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.
  
  Fix this by making a copy of the buffer that is going to be freed
  instead of doing a shallow copy.
  
  Security:	FreeBSD-SA-15:24.rpcbind
  Security:	CVE-2015-7236

Modified:
  stable/9/usr.sbin/rpcbind/rpcb_svc_com.c

Changes in other areas also in this revision:
Modified:
  stable/10/usr.sbin/rpcbind/rpcb_svc_com.c

Modified: stable/9/usr.sbin/rpcbind/rpcb_svc_com.c
==============================================================================
--- stable/9/usr.sbin/rpcbind/rpcb_svc_com.c	Tue Sep 29 18:05:54 2015	(r288383)
+++ stable/9/usr.sbin/rpcbind/rpcb_svc_com.c	Tue Sep 29 18:06:27 2015	(r288384)
@@ -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 @@ netbufcmp(struct netbuf *n1, struct netb
 	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 @@ static void
 netbuffree(struct netbuf *ap)
 {
 	free(ap->buf);
+	ap->buf = NULL;
 	free(ap);
 }
 
@@ -1185,7 +1199,7 @@ xprt_set_caller(SVCXPRT *xprt, struct fi
 {
 	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 svn-src-all mailing list