diff --git a/libtirpc-clntunix_create.patch b/libtirpc-clntunix_create.patch new file mode 100644 index 0000000..ed0a606 --- /dev/null +++ b/libtirpc-clntunix_create.patch @@ -0,0 +1,70 @@ +commit 79bf7950d8c8bc9d323887ba0e5fa7555aa6644a +Author: Olaf Kirch +Date: Tue Feb 8 10:21:16 2011 +0100 + + Fix a crash in clntunix_create + + Programs using clntunix_create would abort because glibc detected an + attempt to free a bad pointer. It turns out that clntunix_create + has two bugs: + + - it sets up a struct netbuf to hold the sockaddr_un passed + into the function, but instead of copying the data, it + just assigns the sockaddr pointer - and eventually tries to + free that pointer. + + - when setting up the netbuf, it uses sizeof(raddr) instead + of sizeof(*raddr). + + Instead of doing the trivial fixes, I changed the function to use + the __rpc_set_netbuf utility function. While I was at it, I removed + an unused local variable. + + Signed-off-by: Olaf Kirch + +--- + src/rpc_soc.c | 20 ++++++-------------- + 1 file changed, 6 insertions(+), 14 deletions(-) + +Index: libtirpc-0.2.4-rc2/src/rpc_soc.c +=================================================================== +--- libtirpc-0.2.4-rc2.orig/src/rpc_soc.c ++++ libtirpc-0.2.4-rc2/src/rpc_soc.c +@@ -564,16 +564,12 @@ clntunix_create(raddr, prog, vers, sockp + u_int sendsz; + u_int recvsz; + { +- struct netbuf *svcaddr; +- CLIENT *cl; ++ struct netbuf svcaddr; ++ CLIENT *cl = NULL; + int len; + +- cl = NULL; +- svcaddr = NULL; +- if (((svcaddr = malloc(sizeof(struct netbuf))) == NULL ) || +- ((svcaddr->buf = malloc(sizeof(struct sockaddr_un))) == NULL)) { +- if (svcaddr != NULL) +- free(svcaddr); ++ memset(&svcaddr, 0, sizeof(svcaddr)); ++ if (__rpc_set_netbuf(&svcaddr, raddr, sizeof(*raddr)) == NULL) { + rpc_createerr.cf_stat = RPC_SYSTEMERROR; + rpc_createerr.cf_error.re_errno = errno; + return(cl); +@@ -590,14 +586,10 @@ clntunix_create(raddr, prog, vers, sockp + goto done; + } + } +- svcaddr->buf = raddr; +- svcaddr->len = sizeof(raddr); +- svcaddr->maxlen = sizeof (struct sockaddr_un); +- cl = clnt_vc_create(*sockp, svcaddr, prog, ++ cl = clnt_vc_create(*sockp, &svcaddr, prog, + vers, sendsz, recvsz); + done: +- free(svcaddr->buf); +- free(svcaddr); ++ free(svcaddr.buf); + return(cl); + } + diff --git a/libtirpc-misc-segfaults.patch b/libtirpc-misc-segfaults.patch new file mode 100644 index 0000000..63f8339 --- /dev/null +++ b/libtirpc-misc-segfaults.patch @@ -0,0 +1,68 @@ +This patch fixes various unexpected segfaults caused by invoking rpcb_* functions with +NULL arguments. + + +diff -u -ur libtirpc-0.2.4-rc2/src/rpcb_clnt.c libtirpc-0.2.4-rc2/src/rpcb_clnt.c +--- libtirpc-0.2.4-rc2/src/rpcb_clnt.c 2014-01-09 09:09:59.000000000 +0100 ++++ libtirpc-0.2.4-rc2/src/rpcb_clnt.c 2014-01-09 11:13:01.000000000 +0100 +@@ -287,6 +287,18 @@ + struct address_cache *ad_cache; + char *tmpaddr; + ++ if (nconf == NULL) { ++ rpc_createerr.cf_stat = RPC_UNKNOWNPROTO; ++ return NULL; ++ } ++ ++ if (nconf->nc_protofmly != NULL && ++ strcmp(nconf->nc_protofmly, NC_LOOPBACK) != 0 && ++ host == NULL) { ++ rpc_createerr.cf_stat = RPC_UNKNOWNHOST; ++ return NULL; ++ } ++ + /* VARIABLES PROTECTED BY rpcbaddr_cache_lock: ad_cache */ + + /* Get the address of the rpcbind. Check cache first */ +@@ -296,6 +308,7 @@ + addr_to_delete.len = 0; + rwlock_rdlock(&rpcbaddr_cache_lock); + ad_cache = NULL; ++ + if (host != NULL) + ad_cache = check_cache(host, nconf->nc_netid); + if (ad_cache != NULL) { +@@ -303,7 +316,7 @@ + client = clnt_tli_create(RPC_ANYFD, nconf, addr, + (rpcprog_t)RPCBPROG, (rpcvers_t)RPCBVERS4, 0, 0); + if (client != NULL) { +- if (targaddr) ++ if (targaddr && ad_cache->ac_uaddr) + *targaddr = strdup(ad_cache->ac_uaddr); + rwlock_unlock(&rpcbaddr_cache_lock); + return (client); +@@ -353,9 +366,11 @@ + } else { + struct sockaddr_un sun; + +- *targaddr = malloc(sizeof(sun.sun_path)); +- strncpy(*targaddr, _PATH_RPCBINDSOCK, +- sizeof(sun.sun_path)); ++ if (targaddr) { ++ *targaddr = malloc(sizeof(sun.sun_path)); ++ strncpy(*targaddr, _PATH_RPCBINDSOCK, ++ sizeof(sun.sun_path)); ++ } + return (client); + } + } else { +@@ -402,7 +417,8 @@ + + if (client) { + tmpaddr = targaddr ? taddr2uaddr(nconf, &taddr) : NULL; +- add_cache(host, nconf->nc_netid, &taddr, tmpaddr); ++ if (host) ++ add_cache(host, nconf->nc_netid, &taddr, tmpaddr); + if (targaddr) + *targaddr = tmpaddr; + break; diff --git a/libtirpc-new-path-rpcbindsock.patch b/libtirpc-new-path-rpcbindsock.patch new file mode 100644 index 0000000..eed3919 --- /dev/null +++ b/libtirpc-new-path-rpcbindsock.patch @@ -0,0 +1,35 @@ +Starting with openSUSE 13.1, rpcbind creates its socket in /var rather that /var/run. +Update libtirpc to go looking for it in the right place. + +Signed-off-by: Olaf Kirch +--- + tirpc/rpc/rpcb_prot.h | 2 +- + tirpc/rpc/rpcb_prot.x | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +Index: libtirpc-0.2.4-rc2/tirpc/rpc/rpcb_prot.h +=================================================================== +--- libtirpc-0.2.4-rc2/tirpc/rpc/rpcb_prot.h ++++ libtirpc-0.2.4-rc2/tirpc/rpc/rpcb_prot.h +@@ -476,7 +476,7 @@ extern bool_t xdr_netbuf(XDR *, struct n + #define RPCBVERS_3 RPCBVERS + #define RPCBVERS_4 RPCBVERS4 + +-#define _PATH_RPCBINDSOCK "/var/run/rpcbind.sock" ++#define _PATH_RPCBINDSOCK "/run/rpcbind.sock" + + #else /* ndef _KERNEL */ + #ifdef __cplusplus +Index: libtirpc-0.2.4-rc2/tirpc/rpc/rpcb_prot.x +=================================================================== +--- libtirpc-0.2.4-rc2/tirpc/rpc/rpcb_prot.x ++++ libtirpc-0.2.4-rc2/tirpc/rpc/rpcb_prot.x +@@ -410,7 +410,7 @@ program RPCBPROG { + %#define RPCBVERS_3 RPCBVERS + %#define RPCBVERS_4 RPCBVERS4 + % +-%#define _PATH_RPCBINDSOCK "/var/run/rpcbind.sock" ++%#define _PATH_RPCBINDSOCK "/run/rpcbind.sock" + % + %#else /* ndef _KERNEL */ + %#ifdef __cplusplus diff --git a/libtirpc-taddr2uaddr-local.patch b/libtirpc-taddr2uaddr-local.patch new file mode 100644 index 0000000..2cb29d9 --- /dev/null +++ b/libtirpc-taddr2uaddr-local.patch @@ -0,0 +1,42 @@ +taddr2uaddr would return trailing garbage for AF_LOCAL addresses + +taddr2uaddr assumed that the sun_path field of an AF_LOCAL address +was always NULL terminated, but that is not necessarily the case, +especially if the buffer was allocated using the correct SUN_LEN(). + +Signed-off-by: Olaf Kirch +--- + src/rpc_generic.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +Index: libtirpc-0.2.4-rc2/src/rpc_generic.c +=================================================================== +--- libtirpc-0.2.4-rc2.orig/src/rpc_generic.c ++++ libtirpc-0.2.4-rc2/src/rpc_generic.c +@@ -608,6 +608,7 @@ __rpc_taddr2uaddr_af(int af, const struc + struct sockaddr_in6 *sin6; + char namebuf6[INET6_ADDRSTRLEN]; + #endif ++ int path_len; + u_int16_t port; + + if (nbuf->len <= 0) +@@ -638,13 +639,12 @@ __rpc_taddr2uaddr_af(int af, const struc + #endif + case AF_LOCAL: + sun = nbuf->buf; +- /* if (asprintf(&ret, "%.*s", (int)(sun->sun_len - +- offsetof(struct sockaddr_un, sun_path)), +- sun->sun_path) < 0)*/ +- if (asprintf(&ret, "%.*s", (int)(sizeof(*sun) - +- offsetof(struct sockaddr_un, sun_path)), +- sun->sun_path) < 0) + ++ path_len = nbuf->len - offsetof(struct sockaddr_un, sun_path); ++ if (path_len < 0) ++ return NULL; ++ ++ if (asprintf(&ret, "%.*s", path_len, sun->sun_path) < 0) + return (NULL); + break; + default: diff --git a/libtirpc.changes b/libtirpc.changes index 3562538..900634c 100644 --- a/libtirpc.changes +++ b/libtirpc.changes @@ -1,3 +1,16 @@ +------------------------------------------------------------------- +Fri Jan 10 11:54:35 UTC 2014 - okir@suse.com + +- taddr2uaddr would return trailing garbage for AF_LOCAL addresses (libtirpc-taddr2uaddr-local.patch) + +------------------------------------------------------------------- +Thu Jan 9 11:15:17 UTC 2014 - okir@suse.com + +- Fix a segfault in clntunix_create (libtirpc-clntunix_create.patch) +- Fix misc segfaults in rpcb_* function (libtirpc-misc-segfaults.patch) +- Fix _PATH_RPCBSOCK to match rpcbind behavior under systemd + (libtirpc-new-path-rpcbindsock.patch) + ------------------------------------------------------------------- Mon Dec 2 04:51:00 UTC 2013 - nfbrown@suse.com diff --git a/libtirpc.spec b/libtirpc.spec index 0f4e35d..efde5fb 100644 --- a/libtirpc.spec +++ b/libtirpc.spec @@ -1,7 +1,7 @@ # # spec file for package libtirpc # -# Copyright (c) 2013 SUSE LINUX Products GmbH, Nuernberg, Germany. +# Copyright (c) 2014 SUSE LINUX Products GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -42,6 +42,10 @@ Patch22: libtirpc-rpc_broadcast_misformed_replies.patch Patch31: libtirpc-getpmaphandle.patch Patch32: libtirpc-pmap-setunset.patch Patch34: libtirpc-bindresvport_blacklist.patch +Patch35: libtirpc-clntunix_create.patch +Patch36: libtirpc-misc-segfaults.patch +Patch37: libtirpc-new-path-rpcbindsock.patch +Patch38: libtirpc-taddr2uaddr-local.patch BuildRoot: %{_tmppath}/%{name}-%{version}-build %define debug_package_requires libtirpc1 = %{version}-%{release} @@ -82,6 +86,10 @@ TCP over IPv4 %patch31 -p1 %patch32 -p1 %patch34 -p1 +%patch35 -p1 +%patch36 -p1 +%patch37 -p1 +%patch38 -p1 %build autoreconf -fiv