summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordelphij <delphij@FreeBSD.org>2015-09-29 18:07:18 +0000
committerdelphij <delphij@FreeBSD.org>2015-09-29 18:07:18 +0000
commit93d0d5de2d3005d15fe4ae2e9b84fabe58b43133 (patch)
tree2f75cbbba8e549cc0089f6ee3a4473cd9d3a9c97
parent4c99fecba230a99e9d8eb1b0bceff0241aa0a017 (diff)
downloadFreeBSD-src-93d0d5de2d3005d15fe4ae2e9b84fabe58b43133.zip
FreeBSD-src-93d0d5de2d3005d15fe4ae2e9b84fabe58b43133.tar.gz
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
-rw-r--r--UPDATING4
-rw-r--r--sys/conf/newvers.sh2
-rw-r--r--usr.sbin/rpcbind/rpcb_svc_com.c24
3 files changed, 24 insertions, 6 deletions
diff --git a/UPDATING b/UPDATING
index b8b197f..6e3dd4f 100644
--- a/UPDATING
+++ b/UPDATING
@@ -16,6 +16,10 @@ from older versions of FreeBSD, try WITHOUT_CLANG to bootstrap to the tip of
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]
diff --git a/sys/conf/newvers.sh b/sys/conf/newvers.sh
index d6f8167..b12b344 100644
--- a/sys/conf/newvers.sh
+++ b/sys/conf/newvers.sh
@@ -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
diff --git a/usr.sbin/rpcbind/rpcb_svc_com.c b/usr.sbin/rpcbind/rpcb_svc_com.c
index f90dc59..a725273 100644
--- a/usr.sbin/rpcbind/rpcb_svc_com.c
+++ b/usr.sbin/rpcbind/rpcb_svc_com.c
@@ -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 netbuf *n2)
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 finfo *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;
}
OpenPOWER on IntegriCloud