From owner-svn-src-all@freebsd.org Tue Sep 29 18:05:55 2015 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 12E80A0B1F4; Tue, 29 Sep 2015 18:05:55 +0000 (UTC) (envelope-from delphij@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id DC20A1DA3; Tue, 29 Sep 2015 18:05:54 +0000 (UTC) (envelope-from delphij@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.70]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id t8TI5srB005962; Tue, 29 Sep 2015 18:05:54 GMT (envelope-from delphij@FreeBSD.org) Received: (from delphij@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id t8TI5sBE005961; Tue, 29 Sep 2015 18:05:54 GMT (envelope-from delphij@FreeBSD.org) Message-Id: <201509291805.t8TI5sBE005961@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: delphij set sender to delphij@FreeBSD.org using -f From: Xin LI Date: Tue, 29 Sep 2015 18:05:54 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r288383 - head/usr.sbin/rpcbind X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 29 Sep 2015 18:05:55 -0000 Author: delphij Date: Tue Sep 29 18:05:54 2015 New Revision: 288383 URL: https://svnweb.freebsd.org/changeset/base/288383 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: head/usr.sbin/rpcbind/rpcb_svc_com.c Modified: head/usr.sbin/rpcbind/rpcb_svc_com.c ============================================================================== --- head/usr.sbin/rpcbind/rpcb_svc_com.c Tue Sep 29 17:54:28 2015 (r288382) +++ head/usr.sbin/rpcbind/rpcb_svc_com.c Tue Sep 29 18:05:54 2015 (r288383) @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include @@ -1047,19 +1048,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); } @@ -1067,6 +1080,7 @@ static void netbuffree(struct netbuf *ap) { free(ap->buf); + ap->buf = NULL; free(ap); } @@ -1184,7 +1198,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; }