commit:     de6d02b6cf69bec8e91b7e7e3b4a083f8b13b822
Author:     Mike Frysinger <vapier <AT> gentoo <DOT> org>
AuthorDate: Tue Nov  3 14:53:27 2015 +0000
Commit:     Mike Frysinger <vapier <AT> gentoo <DOT> org>
CommitDate: Tue Nov  3 15:08:06 2015 +0000
URL:        https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=de6d02b6

net-nds/rpcbind: add upstream fix for CVE-2015-7236 #560990

 .../rpcbind/files/rpcbind-0.2.3-mem-corrupt.patch  | 86 ++++++++++++++++++++++
 net-nds/rpcbind/rpcbind-0.2.3-r1.ebuild            | 57 ++++++++++++++
 2 files changed, 143 insertions(+)

diff --git a/net-nds/rpcbind/files/rpcbind-0.2.3-mem-corrupt.patch 
b/net-nds/rpcbind/files/rpcbind-0.2.3-mem-corrupt.patch
new file mode 100644
index 0000000..9c03bda
--- /dev/null
+++ b/net-nds/rpcbind/files/rpcbind-0.2.3-mem-corrupt.patch
@@ -0,0 +1,86 @@
+https://bugs.gentoo.org/560990
+
+fix from upstream
+
+From d5dace219953c45d26ae42db238052b68540649a Mon Sep 17 00:00:00 2001
+From: Olaf Kirch <o...@suse.de>
+Date: Fri, 30 Oct 2015 10:18:20 -0400
+Subject: [PATCH rpcbind] Fix memory corruption in PMAP_CALLIT code
+
+ - A PMAP_CALLIT call comes in on IPv4 UDP
+ - rpcbind duplicates the caller's address to a netbuf and stores it in
+   FINFO[0].caller_addr. caller_addr->buf now points to a memory region A
+   with a size of 16 bytes
+ - rpcbind forwards the call to the local service, receives a reply
+ - when processing the reply, it does this in xprt_set_caller:
+    xprt->xp_rtaddr = *FINFO[0].caller_addr
+   It sends out the reply, and then frees the netbuf caller_addr and
+   caller_addr.buf.
+   However, it does not clear xp_rtaddr, so xp_rtaddr.buf now refers
+   to memory region A, which is free.
+ - When the next call comes in on the UDP/IPv4 socket, svc_dg_recv will
+   be called, which will set xp_rtaddr to the client's address.
+   It will reuse the buffer inside xp_rtaddr, ie it will write a
+   sockaddr_in to region A
+
+Some time down the road, an incoming TCP connection is accepted,
+allocating a fresh SVCXPRT. The memory region A is inside the
+new SVCXPRT
+
+ - While processing the TCP call, another UDP call comes in, again
+   overwriting region A with the client's address
+ - TCP client closes connection. In svc_destroy, we now trip over
+   the garbage left in region A
+
+We ran into the case where a commercial scanner was triggering
+occasional rpcbind segfaults. The core file that was captured showed
+a corrupted xprt->xp_netid pointer that was really a sockaddr_in.
+
+Signed-off-by: Olaf Kirch <o...@suse.de>
+Signed-off-by: Steve Dickson <ste...@redhat.com>
+---
+ src/rpcb_svc_com.c | 23 ++++++++++++++++++++++-
+ 1 file changed, 22 insertions(+), 1 deletion(-)
+
+diff --git a/src/rpcb_svc_com.c b/src/rpcb_svc_com.c
+index ff9ce6b..4ae93f1 100644
+--- a/src/rpcb_svc_com.c
++++ b/src/rpcb_svc_com.c
+@@ -1183,12 +1183,33 @@ check_rmtcalls(struct pollfd *pfds, int nfds)
+       return (ncallbacks_found);
+ }
+ 
++/*
++ * This is really a helper function defined in libtirpc, 
++ * but unfortunately, it hasn't been exported yet.
++ */
++static struct netbuf *
++__rpc_set_netbuf(struct netbuf *nb, const void *ptr, size_t len)
++{
++      if (nb->len != len) {
++              if (nb->len)
++                      mem_free(nb->buf, nb->len);
++              nb->buf = mem_alloc(len);
++              if (nb->buf == NULL)
++                      return NULL;
++
++              nb->maxlen = nb->len = len;
++      }
++      memcpy(nb->buf, ptr, len);
++      return nb;
++}
++
+ static void
+ xprt_set_caller(SVCXPRT *xprt, struct finfo *fi)
+ {
++      const struct netbuf *caller = fi->caller_addr;
+       u_int32_t *xidp;
+ 
+-      *(svc_getrpccaller(xprt)) = *(fi->caller_addr);
++      __rpc_set_netbuf(svc_getrpccaller(xprt), caller->buf, caller->len);
+       xidp = __rpcb_get_dg_xidp(xprt);
+       *xidp = fi->caller_xid;
+ }
+-- 
+2.5.2
+

diff --git a/net-nds/rpcbind/rpcbind-0.2.3-r1.ebuild 
b/net-nds/rpcbind/rpcbind-0.2.3-r1.ebuild
new file mode 100644
index 0000000..937aaae
--- /dev/null
+++ b/net-nds/rpcbind/rpcbind-0.2.3-r1.ebuild
@@ -0,0 +1,57 @@
+# Copyright 1999-2015 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Id$
+
+EAPI="5"
+
+inherit eutils systemd
+
+if [[ ${PV} == "9999" ]] ; then
+       EGIT_REPO_URI="git://linux-nfs.org/~steved/rpcbind.git"
+       inherit autotools git-r3
+else
+       SRC_URI="mirror://sourceforge/${PN}/${P}.tar.bz2"
+       KEYWORDS="~alpha ~amd64 ~arm ~arm64 ~hppa ~ia64 ~mips ~ppc ~ppc64 ~s390 
~sh ~sparc ~x86"
+fi
+
+DESCRIPTION="portmap replacement which supports RPC over various protocols"
+HOMEPAGE="http://sourceforge.net/projects/rpcbind/";
+
+LICENSE="BSD"
+SLOT="0"
+IUSE="debug selinux systemd tcpd warmstarts"
+
+CDEPEND=">=net-libs/libtirpc-0.2.3:=
+       systemd? ( sys-apps/systemd:= )
+       tcpd? ( sys-apps/tcp-wrappers )"
+DEPEND="${CDEPEND}
+       virtual/pkgconfig"
+RDEPEND="${CDEPEND}
+       selinux? ( sec-policy/selinux-rpcbind )"
+
+src_prepare() {
+       [[ ${PV} == "9999" ]] && eautoreconf
+       epatch "${FILESDIR}"/${P}-libtirpc.patch
+       epatch "${FILESDIR}"/${P}-mem-corrupt.patch #560990
+       epatch_user
+}
+
+src_configure() {
+       econf \
+               --bindir="${EPREFIX}"/sbin \
+               --with-statedir="${EPREFIX}"/run/${PN} \
+               --with-rpcuser=root \
+               --with-systemdsystemunitdir=$(usex systemd 
"$(systemd_get_unitdir)" "no") \
+               $(use_enable tcpd libwrap) \
+               $(use_enable debug) \
+               $(use_enable warmstarts)
+}
+
+src_install() {
+       default
+
+       newinitd "${FILESDIR}"/${PN}.initd ${PN}
+       newconfd "${FILESDIR}"/${PN}.confd ${PN}
+
+       systemd_dounit "${FILESDIR}"/${PN}.service
+}

Reply via email to