Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 29 Sep 2015 18:06:28 +0000 (UTC)
From:      Xin LI <delphij@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org
Subject:   svn commit: r288384 - in stable: 10/usr.sbin/rpcbind 9/usr.sbin/rpcbind
Message-ID:  <201509291806.t8TI6SZR006055@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
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;
 }



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