svn commit: r288385 - in releng: 10.1 10.1/sys/conf 10.1/usr.sbin/rpcbind 10.2 10.2/sys/conf 10.2/usr.sbin/rpcbind 9.3 9.3/sys/conf 9.3/usr.sbin/rpcbind

Xin LI delphij at FreeBSD.org
Tue Sep 29 18:07:21 UTC 2015


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

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
  Approved by:	so

Modified:
  releng/10.1/UPDATING
  releng/10.1/sys/conf/newvers.sh
  releng/10.1/usr.sbin/rpcbind/rpcb_svc_com.c
  releng/10.2/UPDATING
  releng/10.2/sys/conf/newvers.sh
  releng/10.2/usr.sbin/rpcbind/rpcb_svc_com.c
  releng/9.3/UPDATING
  releng/9.3/sys/conf/newvers.sh
  releng/9.3/usr.sbin/rpcbind/rpcb_svc_com.c

Modified: releng/10.1/UPDATING
==============================================================================
--- releng/10.1/UPDATING	Tue Sep 29 18:06:27 2015	(r288384)
+++ releng/10.1/UPDATING	Tue Sep 29 18:07:18 2015	(r288385)
@@ -16,6 +16,10 @@ from older versions of FreeBSD, try WITH
 stable/10, and then rebuild without this option. The bootstrap process from
 older version of current is a bit fragile.
 
+20150929:	p21	FreeBSD-SA-15:24.rpcbind
+
+	Fix rpcbind(8) remote denial of service. [SA-15:24]
+
 20150916:	p20	FreeBSD-EN-15:18.pkg
 
 	Implement pubkey support for pkg(7) bootstrap. [EN-15:18]

Modified: releng/10.1/sys/conf/newvers.sh
==============================================================================
--- releng/10.1/sys/conf/newvers.sh	Tue Sep 29 18:06:27 2015	(r288384)
+++ releng/10.1/sys/conf/newvers.sh	Tue Sep 29 18:07:18 2015	(r288385)
@@ -32,7 +32,7 @@
 
 TYPE="FreeBSD"
 REVISION="10.1"
-BRANCH="RELEASE-p20"
+BRANCH="RELEASE-p21"
 if [ "X${BRANCH_OVERRIDE}" != "X" ]; then
 	BRANCH=${BRANCH_OVERRIDE}
 fi

Modified: releng/10.1/usr.sbin/rpcbind/rpcb_svc_com.c
==============================================================================
--- releng/10.1/usr.sbin/rpcbind/rpcb_svc_com.c	Tue Sep 29 18:06:27 2015	(r288384)
+++ releng/10.1/usr.sbin/rpcbind/rpcb_svc_com.c	Tue Sep 29 18:07:18 2015	(r288385)
@@ -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;
 }

Modified: releng/10.2/UPDATING
==============================================================================
--- releng/10.2/UPDATING	Tue Sep 29 18:06:27 2015	(r288384)
+++ releng/10.2/UPDATING	Tue Sep 29 18:07:18 2015	(r288385)
@@ -16,6 +16,10 @@ from older versions of FreeBSD, try WITH
 stable/10, and then rebuild without this option. The bootstrap process from
 older version of current is a bit fragile.
 
+20150929:	p4	FreeBSD-SA-15:24.rpcbind
+
+	Fix rpcbind(8) remote denial of service. [SA-15:24]
+
 20150916:	p3	FreeBSD-EN-15:16.pw
 			FreeBSD-EN-15:17.libc
 			FreeBSD-EN-15:18.pkg

Modified: releng/10.2/sys/conf/newvers.sh
==============================================================================
--- releng/10.2/sys/conf/newvers.sh	Tue Sep 29 18:06:27 2015	(r288384)
+++ releng/10.2/sys/conf/newvers.sh	Tue Sep 29 18:07:18 2015	(r288385)
@@ -32,7 +32,7 @@
 
 TYPE="FreeBSD"
 REVISION="10.2"
-BRANCH="RELEASE-p3"
+BRANCH="RELEASE-p4"
 if [ "X${BRANCH_OVERRIDE}" != "X" ]; then
 	BRANCH=${BRANCH_OVERRIDE}
 fi

Modified: releng/10.2/usr.sbin/rpcbind/rpcb_svc_com.c
==============================================================================
--- releng/10.2/usr.sbin/rpcbind/rpcb_svc_com.c	Tue Sep 29 18:06:27 2015	(r288384)
+++ releng/10.2/usr.sbin/rpcbind/rpcb_svc_com.c	Tue Sep 29 18:07:18 2015	(r288385)
@@ -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;
 }

Modified: releng/9.3/UPDATING
==============================================================================
--- releng/9.3/UPDATING	Tue Sep 29 18:06:27 2015	(r288384)
+++ releng/9.3/UPDATING	Tue Sep 29 18:07:18 2015	(r288385)
@@ -11,6 +11,10 @@ handbook:
 Items affecting the ports and packages system can be found in
 /usr/ports/UPDATING.  Please read that file before running portupgrade.
 
+20150929:	p27	FreeBSD-SA-15:24.rpcbind
+
+	Fix rpcbind(8) remote denial of service. [SA-15:24]
+
 20150916:	p26	FreeBSD-EN-15:18.pkg
 
 	Implement pubkey support for pkg(7) bootstrap. [EN-15:18]

Modified: releng/9.3/sys/conf/newvers.sh
==============================================================================
--- releng/9.3/sys/conf/newvers.sh	Tue Sep 29 18:06:27 2015	(r288384)
+++ releng/9.3/sys/conf/newvers.sh	Tue Sep 29 18:07:18 2015	(r288385)
@@ -32,7 +32,7 @@
 
 TYPE="FreeBSD"
 REVISION="9.3"
-BRANCH="RELEASE-p26"
+BRANCH="RELEASE-p27"
 if [ "X${BRANCH_OVERRIDE}" != "X" ]; then
 	BRANCH=${BRANCH_OVERRIDE}
 fi

Modified: releng/9.3/usr.sbin/rpcbind/rpcb_svc_com.c
==============================================================================
--- releng/9.3/usr.sbin/rpcbind/rpcb_svc_com.c	Tue Sep 29 18:06:27 2015	(r288384)
+++ releng/9.3/usr.sbin/rpcbind/rpcb_svc_com.c	Tue Sep 29 18:07:18 2015	(r288385)
@@ -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