From 64280fb9d8fc5cd6803f1f1e22c6b858c70a53ee Mon Sep 17 00:00:00 2001 From: Steve Dickson Date: Sat, 20 Feb 2016 07:12:04 -0500 Subject: [PATCH] Updated to the latest RC release rpcbind-0_2_4-rc1 Signed-off-by: Steve Dickson --- rpcbind-0.2.3-pmap_callit.diff | 77 ------------ rpcbind-0.2.3-rpcbind-socket.patch | 46 ------- rpcbind-0.2.3-xp_auth.patch | 21 ---- rpcbind-0.2.4-rc1.patch | 193 +++++++++++++++++++++++++++++ rpcbind.spec | 11 +- 5 files changed, 198 insertions(+), 150 deletions(-) delete mode 100644 rpcbind-0.2.3-pmap_callit.diff delete mode 100644 rpcbind-0.2.3-rpcbind-socket.patch delete mode 100644 rpcbind-0.2.3-xp_auth.patch create mode 100644 rpcbind-0.2.4-rc1.patch diff --git a/rpcbind-0.2.3-pmap_callit.diff b/rpcbind-0.2.3-pmap_callit.diff deleted file mode 100644 index 4104a94..0000000 --- a/rpcbind-0.2.3-pmap_callit.diff +++ /dev/null @@ -1,77 +0,0 @@ -commit d5dace219953c45d26ae42db238052b68540649a -Author: Olaf Kirch -Date: Fri Oct 30 10:18:20 2015 -0400 - - 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 - Signed-off-by: Steve Dickson - -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; - } diff --git a/rpcbind-0.2.3-rpcbind-socket.patch b/rpcbind-0.2.3-rpcbind-socket.patch deleted file mode 100644 index cf24980..0000000 --- a/rpcbind-0.2.3-rpcbind-socket.patch +++ /dev/null @@ -1,46 +0,0 @@ -commit 3a664b1b5a310df39bd0f325b0edb1deb31c2249 -Author: Laurent Bigonville -Date: Wed Nov 18 14:34:26 2015 -0500 - - Delete the unix socket only if we have created it - - From: Laurent Bigonville - - If systemd has created the unix socket on our behalf, we shouldn't try - to delete it. - - https://bugzilla.redhat.com/show_bug.cgi?id=1279076 - - Signed-off-by: Laurent Bigonville - -diff --git a/src/rpcbind.c b/src/rpcbind.c -index 045daa1..c4265cd 100644 ---- a/src/rpcbind.c -+++ b/src/rpcbind.c -@@ -87,6 +87,7 @@ static inline void __nss_configure_lookup(const char *db, const char *s) {} - int debugging = 0; /* Tell me what's going on */ - int doabort = 0; /* When debugging, do an abort on errors */ - int dofork = 1; /* fork? */ -+int createdsocket = 0; /* Did I create the socket or systemd did it for me? */ - - rpcblist_ptr list_rbl; /* A list of version 3/4 rpcbind services */ - -@@ -445,6 +446,7 @@ init_transport(struct netconfig *nconf) - memset(&sun, 0, sizeof sun); - sun.sun_family = AF_LOCAL; - unlink(_PATH_RPCBINDSOCK); -+ createdsocket = 1; /* We are now in the process of creating the unix socket */ - strcpy(sun.sun_path, _PATH_RPCBINDSOCK); - addrlen = SUN_LEN(&sun); - sa = (struct sockaddr *)&sun; -@@ -846,7 +848,8 @@ static void - terminate(int dummy /*__unused*/) - { - close(rpcbindlockfd); -- unlink(_PATH_RPCBINDSOCK); -+ if(createdsocket) -+ unlink(_PATH_RPCBINDSOCK); - unlink(RPCBINDDLOCK); - #ifdef WARMSTART - write_warmstart(); /* Dump yourself */ diff --git a/rpcbind-0.2.3-xp_auth.patch b/rpcbind-0.2.3-xp_auth.patch deleted file mode 100644 index fc0797b..0000000 --- a/rpcbind-0.2.3-xp_auth.patch +++ /dev/null @@ -1,21 +0,0 @@ -diff -up rpcbind-0.2.3/src/rpcb_svc_com.c.orig rpcbind-0.2.3/src/rpcb_svc_com.c ---- rpcbind-0.2.3/src/rpcb_svc_com.c.orig 2015-11-02 16:23:08.584000000 -0500 -+++ rpcbind-0.2.3/src/rpcb_svc_com.c 2015-11-02 16:58:20.386000000 -0500 -@@ -1295,10 +1295,17 @@ handle_reply(int fd, SVCXPRT *xprt) - a.rmt_localvers = fi->versnum; - - xprt_set_caller(xprt, fi); -+#if defined(SVC_XP_AUTH) -+ SVC_XP_AUTH(xprt) = svc_auth_none; -+#else - xprt->xp_auth = &svc_auth_none; -+#endif - svc_sendreply(xprt, (xdrproc_t) xdr_rmtcall_result, (char *) &a); -+#if !defined(SVC_XP_AUTH) - SVCAUTH_DESTROY(xprt->xp_auth); - xprt->xp_auth = NULL; -+#endif -+ - done: - if (buffer) - free(buffer); diff --git a/rpcbind-0.2.4-rc1.patch b/rpcbind-0.2.4-rc1.patch new file mode 100644 index 0000000..be4b115 --- /dev/null +++ b/rpcbind-0.2.4-rc1.patch @@ -0,0 +1,193 @@ +diff --git a/src/rpcb_svc_com.c b/src/rpcb_svc_com.c +index ff9ce6b..148fe42 100644 +--- a/src/rpcb_svc_com.c ++++ b/src/rpcb_svc_com.c +@@ -536,10 +536,6 @@ create_rmtcall_fd(struct netconfig *nconf) + rmttail->next = rmt; + rmttail = rmt; + } +- /* XXX not threadsafe */ +- if (fd > svc_maxfd) +- svc_maxfd = fd; +- FD_SET(fd, &svc_fdset); + return (fd); + } + +@@ -1056,9 +1052,6 @@ free_slot_by_index(int index) + fi = &FINFO[index]; + if (fi->flag & FINFO_ACTIVE) { + netbuffree(fi->caller_addr); +- /* XXX may be too big, but can't access xprt array here */ +- if (fi->forward_fd >= svc_maxfd) +- svc_maxfd--; + free(fi->uaddr); + fi->flag &= ~FINFO_ACTIVE; + rpcb_rmtcalls--; +@@ -1097,35 +1090,28 @@ netbuffree(struct netbuf *ap) + } + + +-#define MASKVAL (POLLIN | POLLPRI | POLLRDNORM | POLLRDBAND) +-extern bool_t __svc_clean_idle(fd_set *, int, bool_t); +- + void + my_svc_run() + { +- size_t nfds; +- struct pollfd pollfds[FD_SETSIZE]; + int poll_ret, check_ret; + int n; +-#ifdef SVC_RUN_DEBUG +- int i; +-#endif +- register struct pollfd *p; +- fd_set cleanfds; + + for (;;) { +- p = pollfds; +- for (n = 0; n <= svc_maxfd; n++) { +- if (FD_ISSET(n, &svc_fdset)) { +- p->fd = n; +- p->events = MASKVAL; +- p++; +- } +- } +- nfds = p - pollfds; +- poll_ret = 0; ++ struct pollfd my_pollfd[svc_max_pollfd]; ++ int i; ++ ++ if (svc_max_pollfd == 0 && svc_pollfd == NULL) ++ return; + +- switch (poll_ret = poll(pollfds, nfds, 30 * 1000)) { ++ ++ for (i = 0; i < svc_max_pollfd; ++i) ++ { ++ my_pollfd[i].fd = svc_pollfd[i].fd; ++ my_pollfd[i].events = svc_pollfd[i].events; ++ my_pollfd[i].revents = 0; ++ } ++ ++ switch (poll_ret = poll(my_pollfd, svc_max_pollfd, 30 * 1000)) { + case -1: + /* + * We ignore all errors, continuing with the assumption +@@ -1133,8 +1119,6 @@ my_svc_run() + * other outside event) and not caused by poll(). + */ + case 0: +- cleanfds = svc_fdset; +- __svc_clean_idle(&cleanfds, 30, FALSE); + continue; + default: + /* +@@ -1144,10 +1128,10 @@ my_svc_run() + * don't call svc_getreq_poll. Otherwise, there + * must be another so we must call svc_getreq_poll. + */ +- if ((check_ret = check_rmtcalls(pollfds, nfds)) == ++ if ((check_ret = check_rmtcalls(my_pollfd, svc_max_pollfd)) == + poll_ret) + continue; +- svc_getreq_poll(pollfds, poll_ret-check_ret); ++ svc_getreq_poll(my_pollfd, poll_ret-check_ret); + } + } + } +@@ -1183,12 +1167,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; + } +@@ -1274,10 +1279,17 @@ handle_reply(int fd, SVCXPRT *xprt) + a.rmt_localvers = fi->versnum; + + xprt_set_caller(xprt, fi); ++#if defined(SVC_XP_AUTH) ++ SVC_XP_AUTH(xprt) = svc_auth_none; ++#else + xprt->xp_auth = &svc_auth_none; ++#endif + svc_sendreply(xprt, (xdrproc_t) xdr_rmtcall_result, (char *) &a); ++#if !defined(SVC_XP_AUTH) + SVCAUTH_DESTROY(xprt->xp_auth); + xprt->xp_auth = NULL; ++#endif ++ + done: + if (buffer) + free(buffer); +diff --git a/src/rpcbind.c b/src/rpcbind.c +index 045daa1..c4265cd 100644 +--- a/src/rpcbind.c ++++ b/src/rpcbind.c +@@ -87,6 +87,7 @@ static inline void __nss_configure_lookup(const char *db, const char *s) {} + int debugging = 0; /* Tell me what's going on */ + int doabort = 0; /* When debugging, do an abort on errors */ + int dofork = 1; /* fork? */ ++int createdsocket = 0; /* Did I create the socket or systemd did it for me? */ + + rpcblist_ptr list_rbl; /* A list of version 3/4 rpcbind services */ + +@@ -445,6 +446,7 @@ init_transport(struct netconfig *nconf) + memset(&sun, 0, sizeof sun); + sun.sun_family = AF_LOCAL; + unlink(_PATH_RPCBINDSOCK); ++ createdsocket = 1; /* We are now in the process of creating the unix socket */ + strcpy(sun.sun_path, _PATH_RPCBINDSOCK); + addrlen = SUN_LEN(&sun); + sa = (struct sockaddr *)&sun; +@@ -846,7 +848,8 @@ static void + terminate(int dummy /*__unused*/) + { + close(rpcbindlockfd); +- unlink(_PATH_RPCBINDSOCK); ++ if(createdsocket) ++ unlink(_PATH_RPCBINDSOCK); + unlink(RPCBINDDLOCK); + #ifdef WARMSTART + write_warmstart(); /* Dump yourself */ +diff --git a/src/security.c b/src/security.c +index 0c9453f..c54ce26 100644 +--- a/src/security.c ++++ b/src/security.c +@@ -17,6 +17,8 @@ + #include + #include + ++#include "xlog.h" ++ + /* + * XXX for special case checks in check_callit. + */ diff --git a/rpcbind.spec b/rpcbind.spec index b1ede30..85d9cef 100644 --- a/rpcbind.spec +++ b/rpcbind.spec @@ -1,6 +1,6 @@ Name: rpcbind Version: 0.2.3 -Release: 8%{?dist} +Release: 9.rc1%{?dist} Summary: Universal Addresses to RPC Program Number Mapper Group: System Environment/Daemons License: BSD @@ -21,9 +21,7 @@ Requires(post): chkconfig systemd Requires(preun): systemd Requires(postun): systemd coreutils -Patch001: rpcbind-0.2.3-pmap_callit.diff -Patch002: rpcbind-0.2.3-xp_auth.patch -Patch003: rpcbind-0.2.3-rpcbind-socket.patch +Patch001: rpcbind-0.2.4-rc1.patch Provides: portmap = %{version}-%{release} Obsoletes: portmap <= 4.0-65.3 @@ -37,8 +35,6 @@ RPC calls on a server on that machine. %setup -q %patch001 -p1 -%patch002 -p1 -%patch003 -p1 %build %ifarch s390 s390x @@ -130,6 +126,9 @@ fi %{_unitdir}/rpcbind.socket %changelog +* Sat Feb 20 2016 Steve Dickson - 0.2.3-9.rc1 +- Updated to the latest RC release rpcbind-0_2_4-rc1 + * Thu Feb 04 2016 Fedora Release Engineering - 0.2.3-8 - Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild