From d851f5e13b7846f6180641645e2daede67807c34 Mon Sep 17 00:00:00 2001 From: eabdullin Date: Wed, 14 May 2025 19:11:56 +0000 Subject: [PATCH] import UBI libtirpc-1.3.5-1.el10 --- .gitignore | 3 +- gating.yaml | 6 - libtirpc-1.1.4-blacklist.patch | 15 - libtirpc-1.1.4-covscan.patch | 151 -- libtirpc-1.1.4-dgcall-free.patch | 14 - libtirpc-1.1.4-disallow-auth_refresh.patch | 76 - libtirpc-1.1.4-dos-fix.patch | 154 --- libtirpc-1.1.4-double-free.patch | 32 - libtirpc-1.1.4-dup_ncp-bad-free.patch | 51 - libtirpc-1.1.4-fix-EOF-non-block.patch | 68 - libtirpc-1.1.4-ip_local_reserved_ports.patch | 185 --- libtirpc-1.1.4-multithr-cleanup.patch | 1230 ----------------- ...rpc-1.1.4-null-ptrs-not-reused-fixed.patch | 23 - libtirpc-1.1.4-null-ptrs-not-reused.patch | 48 - libtirpc-1.1.4-v2proto-mech.patch | 88 -- libtirpc.spec | 227 +-- sources | 2 +- 17 files changed, 132 insertions(+), 2241 deletions(-) delete mode 100644 gating.yaml delete mode 100644 libtirpc-1.1.4-blacklist.patch delete mode 100644 libtirpc-1.1.4-covscan.patch delete mode 100644 libtirpc-1.1.4-dgcall-free.patch delete mode 100644 libtirpc-1.1.4-disallow-auth_refresh.patch delete mode 100644 libtirpc-1.1.4-dos-fix.patch delete mode 100644 libtirpc-1.1.4-double-free.patch delete mode 100644 libtirpc-1.1.4-dup_ncp-bad-free.patch delete mode 100644 libtirpc-1.1.4-fix-EOF-non-block.patch delete mode 100644 libtirpc-1.1.4-ip_local_reserved_ports.patch delete mode 100644 libtirpc-1.1.4-multithr-cleanup.patch delete mode 100644 libtirpc-1.1.4-null-ptrs-not-reused-fixed.patch delete mode 100644 libtirpc-1.1.4-null-ptrs-not-reused.patch delete mode 100644 libtirpc-1.1.4-v2proto-mech.patch diff --git a/.gitignore b/.gitignore index f9c9048..300e69c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1 @@ -SOURCES/libtirpc-1.1.4.tar.bz2 -/libtirpc-1.1.4.tar.bz2 +libtirpc-1.3.5.tar.bz2 diff --git a/gating.yaml b/gating.yaml deleted file mode 100644 index 2942f6f..0000000 --- a/gating.yaml +++ /dev/null @@ -1,6 +0,0 @@ ---- !Policy -product_versions: - - rhel-8 -decision_context: osci_compose_gate -rules: - - !PassingTestCaseRule {test_case_name: osci.brew-build.revdeps.integration} diff --git a/libtirpc-1.1.4-blacklist.patch b/libtirpc-1.1.4-blacklist.patch deleted file mode 100644 index cc41a9e..0000000 --- a/libtirpc-1.1.4-blacklist.patch +++ /dev/null @@ -1,15 +0,0 @@ -diff -up libtirpc-1.1.4/doc/bindresvport.blacklist.save libtirpc-1.1.4/doc/bindresvport.blacklist ---- libtirpc-1.1.4/doc/bindresvport.blacklist.save 2021-04-17 13:04:20.092274589 -0400 -+++ libtirpc-1.1.4/doc/bindresvport.blacklist 2021-04-17 13:04:45.609945925 -0400 -@@ -8,6 +8,11 @@ - 631 # cups - 636 # ldaps - 664 # Secure ASF, used by IPMI on some cards -+749 # Kerberos V kadmin -+774 # rpasswd -+873 # rsyncd - 921 # lwresd -+992 # SSL-enabled telnet - 993 # imaps -+994 # irc - 995 # pops diff --git a/libtirpc-1.1.4-covscan.patch b/libtirpc-1.1.4-covscan.patch deleted file mode 100644 index 63484ab..0000000 --- a/libtirpc-1.1.4-covscan.patch +++ /dev/null @@ -1,151 +0,0 @@ -diff --git a/src/auth_gss.c b/src/auth_gss.c -index 5959893..7d08262 100644 ---- a/src/auth_gss.c -+++ b/src/auth_gss.c -@@ -207,6 +207,7 @@ authgss_create(CLIENT *clnt, gss_name_t name, struct rpc_gss_sec *sec) - rpc_createerr.cf_stat = RPC_SYSTEMERROR; - rpc_createerr.cf_error.re_errno = ENOMEM; - free(auth); -+ free(gd); - return (NULL); - } - } -@@ -592,7 +593,7 @@ _rpc_gss_refresh(AUTH *auth, rpc_gss_options_ret_t *options_ret) - if (rpc_gss_oid_to_mech(actual_mech_type, &mechanism)) { - strncpy(options_ret->actual_mechanism, - mechanism, -- sizeof(options_ret->actual_mechanism)); -+ (sizeof(options_ret->actual_mechanism)-1)); - } - - gd->established = TRUE; -diff --git a/src/clnt_bcast.c b/src/clnt_bcast.c -index 98cf061..2ad6c89 100644 ---- a/src/clnt_bcast.c -+++ b/src/clnt_bcast.c -@@ -330,6 +330,7 @@ rpc_broadcast_exp(prog, vers, proc, xargs, argsp, xresults, resultsp, - if (nettype == NULL) - nettype = "datagram_n"; - if ((handle = __rpc_setconf(nettype)) == NULL) { -+ AUTH_DESTROY(sys_auth); - return (RPC_UNKNOWNPROTO); - } - while ((nconf = __rpc_getconf(handle)) != NULL) { -diff --git a/src/getnetconfig.c b/src/getnetconfig.c -index 92e7c43..d67d97d 100644 ---- a/src/getnetconfig.c -+++ b/src/getnetconfig.c -@@ -709,6 +709,8 @@ struct netconfig *ncp; - p->nc_lookups = (char **)malloc((size_t)(p->nc_nlookups+1) * sizeof(char *)); - if (p->nc_lookups == NULL) { - free(p->nc_netid); -+ free(p); -+ free(tmp); - return(NULL); - } - for (i=0; i < p->nc_nlookups; i++) { -diff --git a/src/getnetpath.c b/src/getnetpath.c -index 7c19932..ea1a18c 100644 ---- a/src/getnetpath.c -+++ b/src/getnetpath.c -@@ -88,6 +88,7 @@ setnetpath() - } - if ((np_sessionp->nc_handlep = setnetconfig()) == NULL) { - syslog (LOG_ERR, "rpc: failed to open " NETCONFIG); -+ free(np_sessionp); - return (NULL); - } - np_sessionp->valid = NP_VALID; -diff --git a/src/rpc_generic.c b/src/rpc_generic.c -index 589cbd5..51f36ac 100644 ---- a/src/rpc_generic.c -+++ b/src/rpc_generic.c -@@ -319,6 +319,7 @@ __rpc_setconf(nettype) - handle->nflag = FALSE; - break; - default: -+ free(handle); - return (NULL); - } - -diff --git a/src/rpc_soc.c b/src/rpc_soc.c -index 5a6eeb7..a85cb17 100644 ---- a/src/rpc_soc.c -+++ b/src/rpc_soc.c -@@ -663,15 +663,17 @@ svcunix_create(sock, sendsize, recvsize, path) - strcmp(nconf->nc_protofmly, NC_LOOPBACK) == 0) - break; - } -- if (nconf == NULL) -+ if (nconf == NULL) { -+ endnetconfig(localhandle); - return(xprt); -+ } - - if ((sock = __rpc_nconf2fd(nconf)) < 0) - goto done; - - memset(&sun, 0, sizeof sun); - sun.sun_family = AF_LOCAL; -- strncpy(sun.sun_path, path, sizeof(sun.sun_path)); -+ strncpy(sun.sun_path, path, (sizeof(sun.sun_path)-1)); - addrlen = sizeof(struct sockaddr_un); - sa = (struct sockaddr *)&sun; - -@@ -692,6 +694,8 @@ svcunix_create(sock, sendsize, recvsize, path) - } - - xprt = (SVCXPRT *)svc_tli_create(sock, nconf, &taddr, sendsize, recvsize); -+ if (xprt == NULL) -+ close(sock); - - done: - endnetconfig(localhandle); -diff --git a/src/rpcb_clnt.c b/src/rpcb_clnt.c -index e45736a..0c34cb7 100644 ---- a/src/rpcb_clnt.c -+++ b/src/rpcb_clnt.c -@@ -547,6 +547,7 @@ try_nconf: - if (tmpnconf == NULL) { - rpc_createerr.cf_stat = RPC_UNKNOWNPROTO; - mutex_unlock(&loopnconf_lock); -+ endnetconfig(nc_handle); - return (NULL); - } - loopnconf = getnetconfigent(tmpnconf->nc_netid); -diff --git a/src/rtime.c b/src/rtime.c -index b642840..29fbf0a 100644 ---- a/src/rtime.c -+++ b/src/rtime.c -@@ -90,6 +90,7 @@ rtime(addrp, timep, timeout) - - /* TCP and UDP port are the same in this case */ - if ((serv = getservbyname("time", "tcp")) == NULL) { -+ do_close(s); - return(-1); - } - -diff --git a/src/svc_generic.c b/src/svc_generic.c -index 52a56c2..20abaa2 100644 ---- a/src/svc_generic.c -+++ b/src/svc_generic.c -@@ -113,6 +113,7 @@ svc_create(dispatch, prognum, versnum, nettype) - if (l == NULL) { - warnx("svc_create: no memory"); - mutex_unlock(&xprtlist_lock); -+ __rpc_endconf(handle); - return (0); - } - l->xprt = xprt; -diff --git a/src/svc_simple.c b/src/svc_simple.c -index cb58002..c32fe0a 100644 ---- a/src/svc_simple.c -+++ b/src/svc_simple.c -@@ -157,6 +157,7 @@ rpc_reg(prognum, versnum, procnum, progname, inproc, outproc, nettype) - ((netid = strdup(nconf->nc_netid)) == NULL)) { - warnx(rpc_reg_err, rpc_reg_msg, __no_mem_str); - SVC_DESTROY(svcxprt); -+ free(xdrbuf); - break; - } - madenow = TRUE; diff --git a/libtirpc-1.1.4-dgcall-free.patch b/libtirpc-1.1.4-dgcall-free.patch deleted file mode 100644 index 0f0f1a4..0000000 --- a/libtirpc-1.1.4-dgcall-free.patch +++ /dev/null @@ -1,14 +0,0 @@ -diff -up libtirpc-1.1.4/src/clnt_dg.c.orig libtirpc-1.1.4/src/clnt_dg.c ---- libtirpc-1.1.4/src/clnt_dg.c.orig 2022-05-31 08:14:09.408762537 -0400 -+++ libtirpc-1.1.4/src/clnt_dg.c 2022-05-31 08:17:28.950764885 -0400 -@@ -478,9 +478,9 @@ get_reply: - cmsg = CMSG_NXTHDR (&msg, cmsg)) - if (cmsg->cmsg_level == SOL_IP && cmsg->cmsg_type == IP_RECVERR) - { -- mem_free(cbuf, (outlen + 256)); - e = (struct sock_extended_err *) CMSG_DATA(cmsg); - cu->cu_error.re_errno = e->ee_errno; -+ mem_free(cbuf, (outlen + 256)); - release_fd_lock(cu->cu_fd, mask); - return (cu->cu_error.re_status = RPC_CANTRECV); - } diff --git a/libtirpc-1.1.4-disallow-auth_refresh.patch b/libtirpc-1.1.4-disallow-auth_refresh.patch deleted file mode 100644 index edf7466..0000000 --- a/libtirpc-1.1.4-disallow-auth_refresh.patch +++ /dev/null @@ -1,76 +0,0 @@ -diff -up libtirpc-1.1.4/src/auth_gss.c.orig libtirpc-1.1.4/src/auth_gss.c ---- libtirpc-1.1.4/src/auth_gss.c.orig 2021-04-17 13:11:03.229880600 -0400 -+++ libtirpc-1.1.4/src/auth_gss.c 2021-04-17 13:15:10.722391798 -0400 -@@ -982,3 +982,9 @@ rpc_gss_max_data_length(AUTH *auth, int - rpc_gss_clear_error(); - return result; - } -+ -+bool_t -+is_authgss_client(CLIENT *clnt) -+{ -+ return (clnt->cl_auth->ah_ops == &authgss_ops); -+} -diff -up libtirpc-1.1.4/src/clnt_dg.c.orig libtirpc-1.1.4/src/clnt_dg.c ---- libtirpc-1.1.4/src/clnt_dg.c.orig 2018-08-27 10:06:49.000000000 -0400 -+++ libtirpc-1.1.4/src/clnt_dg.c 2021-04-17 13:15:10.722391798 -0400 -@@ -60,6 +60,9 @@ - #include - #endif - -+#ifdef HAVE_RPCSEC_GSS -+#include -+#endif - - #define MAX_DEFAULT_FDS 20000 - -@@ -356,6 +359,11 @@ clnt_dg_call(cl, proc, xargs, argsp, xre - salen = cu->cu_rlen; - } - -+#ifdef HAVE_RPCSEC_GSS -+ if (is_authgss_client(cl)) -+ nrefreshes = 0; -+#endif -+ - /* Clean up in case the last call ended in a longjmp(3) call. */ - call_again: - xdrs = &(cu->cu_outxdrs); -diff -up libtirpc-1.1.4/src/clnt_vc.c.orig libtirpc-1.1.4/src/clnt_vc.c ---- libtirpc-1.1.4/src/clnt_vc.c.orig 2018-08-27 10:06:49.000000000 -0400 -+++ libtirpc-1.1.4/src/clnt_vc.c 2021-04-17 13:15:10.723391824 -0400 -@@ -68,6 +68,10 @@ - #include - #include "rpc_com.h" - -+#ifdef HAVE_RPCSEC_GSS -+#include -+#endif -+ - #define MCALL_MSG_SIZE 24 - - #define CMGROUP_MAX 16 -@@ -380,6 +384,11 @@ clnt_vc_call(cl, proc, xdr_args, args_pt - (xdr_results == NULL && timeout.tv_sec == 0 - && timeout.tv_usec == 0) ? FALSE : TRUE; - -+#ifdef HAVE_RPCSEC_GSS -+ if (is_authgss_client(cl)) -+ refreshes = 0; -+#endif -+ - call_again: - xdrs->x_op = XDR_ENCODE; - ct->ct_error.re_status = RPC_SUCCESS; -diff -up libtirpc-1.1.4/tirpc/rpc/auth_gss.h.orig libtirpc-1.1.4/tirpc/rpc/auth_gss.h ---- libtirpc-1.1.4/tirpc/rpc/auth_gss.h.orig 2018-08-27 10:06:49.000000000 -0400 -+++ libtirpc-1.1.4/tirpc/rpc/auth_gss.h 2021-04-17 13:15:10.723391824 -0400 -@@ -120,6 +120,8 @@ void gss_log_debug (const char *fmt, .. - void gss_log_status (char *m, OM_uint32 major, OM_uint32 minor); - void gss_log_hexdump (const u_char *buf, int len, int offset); - -+bool_t is_authgss_client (CLIENT *); -+ - #ifdef __cplusplus - } - #endif diff --git a/libtirpc-1.1.4-dos-fix.patch b/libtirpc-1.1.4-dos-fix.patch deleted file mode 100644 index 4b2c8eb..0000000 --- a/libtirpc-1.1.4-dos-fix.patch +++ /dev/null @@ -1,154 +0,0 @@ -diff --git a/src/rpc_com.h b/src/rpc_com.h -index 10bec79..76badef 100644 ---- a/src/rpc_com.h -+++ b/src/rpc_com.h -@@ -61,8 +61,7 @@ void __xprt_unregister_unlocked(SVCXPRT *); - void __xprt_set_raddr(SVCXPRT *, const struct sockaddr_storage *); - - --SVCXPRT **__svc_xports; --int __svc_maxrec; -+extern int __svc_maxrec; - - #ifdef __cplusplus - } -diff --git a/src/svc.c b/src/svc.c -index b59467b..3a8709f 100644 ---- a/src/svc.c -+++ b/src/svc.c -@@ -57,6 +57,9 @@ - - #define max(a, b) (a > b ? a : b) - -+SVCXPRT **__svc_xports; -+int __svc_maxrec; -+ - /* - * The services list - * Each entry represents a set of procedures (an rpc program). -@@ -191,6 +194,21 @@ __xprt_do_unregister (xprt, dolock) - rwlock_unlock (&svc_fd_lock); - } - -+int -+svc_open_fds() -+{ -+ int ix; -+ int nfds = 0; -+ -+ rwlock_rdlock (&svc_fd_lock); -+ for (ix = 0; ix < svc_max_pollfd; ++ix) { -+ if (svc_pollfd[ix].fd != -1) -+ nfds++; -+ } -+ rwlock_unlock (&svc_fd_lock); -+ return (nfds); -+} -+ - /* - * Add a service program to the callout list. - * The dispatch routine will be called when a rpc request for this -diff --git a/src/svc_vc.c b/src/svc_vc.c -index c23cd36..1729963 100644 ---- a/src/svc_vc.c -+++ b/src/svc_vc.c -@@ -64,6 +64,8 @@ - - - extern rwlock_t svc_fd_lock; -+extern SVCXPRT **__svc_xports; -+extern int svc_open_fds(); - - static SVCXPRT *makefd_xprt(int, u_int, u_int); - static bool_t rendezvous_request(SVCXPRT *, struct rpc_msg *); -@@ -82,6 +84,7 @@ static void svc_vc_ops(SVCXPRT *); - static bool_t svc_vc_control(SVCXPRT *xprt, const u_int rq, void *in); - static bool_t svc_vc_rendezvous_control (SVCXPRT *xprt, const u_int rq, - void *in); -+static int __svc_destroy_idle(int timeout); - - struct cf_rendezvous { /* kept in xprt->xp_p1 for rendezvouser */ - u_int sendsize; -@@ -312,13 +315,14 @@ done: - return (xprt); - } - -+ - /*ARGSUSED*/ - static bool_t - rendezvous_request(xprt, msg) - SVCXPRT *xprt; - struct rpc_msg *msg; - { -- int sock, flags; -+ int sock, flags, nfds, cnt; - struct cf_rendezvous *r; - struct cf_conn *cd; - struct sockaddr_storage addr; -@@ -378,6 +382,16 @@ again: - - gettimeofday(&cd->last_recv_time, NULL); - -+ nfds = svc_open_fds(); -+ if (nfds >= (_rpc_dtablesize() / 5) * 4) { -+ /* destroy idle connections */ -+ cnt = __svc_destroy_idle(15); -+ if (cnt == 0) { -+ /* destroy least active */ -+ __svc_destroy_idle(0); -+ } -+ } -+ - return (FALSE); /* there is never an rpc msg to be processed */ - } - -@@ -819,3 +833,49 @@ __svc_clean_idle(fd_set *fds, int timeout, bool_t cleanblock) - { - return FALSE; - } -+ -+static int -+__svc_destroy_idle(int timeout) -+{ -+ int i, ncleaned = 0; -+ SVCXPRT *xprt, *least_active; -+ struct timeval tv, tdiff, tmax; -+ struct cf_conn *cd; -+ -+ gettimeofday(&tv, NULL); -+ tmax.tv_sec = tmax.tv_usec = 0; -+ least_active = NULL; -+ rwlock_wrlock(&svc_fd_lock); -+ -+ for (i = 0; i <= svc_max_pollfd; i++) { -+ if (svc_pollfd[i].fd == -1) -+ continue; -+ xprt = __svc_xports[i]; -+ if (xprt == NULL || xprt->xp_ops == NULL || -+ xprt->xp_ops->xp_recv != svc_vc_recv) -+ continue; -+ cd = (struct cf_conn *)xprt->xp_p1; -+ if (!cd->nonblock) -+ continue; -+ if (timeout == 0) { -+ timersub(&tv, &cd->last_recv_time, &tdiff); -+ if (timercmp(&tdiff, &tmax, >)) { -+ tmax = tdiff; -+ least_active = xprt; -+ } -+ continue; -+ } -+ if (tv.tv_sec - cd->last_recv_time.tv_sec > timeout) { -+ __xprt_unregister_unlocked(xprt); -+ __svc_vc_dodestroy(xprt); -+ ncleaned++; -+ } -+ } -+ if (timeout == 0 && least_active != NULL) { -+ __xprt_unregister_unlocked(least_active); -+ __svc_vc_dodestroy(least_active); -+ ncleaned++; -+ } -+ rwlock_unlock(&svc_fd_lock); -+ return (ncleaned); -+} diff --git a/libtirpc-1.1.4-double-free.patch b/libtirpc-1.1.4-double-free.patch deleted file mode 100644 index a869b43..0000000 --- a/libtirpc-1.1.4-double-free.patch +++ /dev/null @@ -1,32 +0,0 @@ -commit 1d2e10afb2ffc35cb3623f57a15f712359f18e75 -Author: Herb Wartens -Date: Tue Aug 1 10:36:16 2023 -0400 - - rpcb_clnt.c: Eliminate double frees in delete_cache() - - Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=2224666 - Signed-off-by: Steve Dickson - -diff --git a/src/rpcb_clnt.c b/src/rpcb_clnt.c -index c0a9e12..68fe69a 100644 ---- a/src/rpcb_clnt.c -+++ b/src/rpcb_clnt.c -@@ -262,12 +262,15 @@ delete_cache(addr) - for (cptr = front; cptr != NULL; cptr = cptr->ac_next) { - if (!memcmp(cptr->ac_taddr->buf, addr->buf, addr->len)) { - /* Unlink from cache. We'll destroy it after releasing the mutex. */ -- if (cptr->ac_uaddr) -+ if (cptr->ac_uaddr) { - free(cptr->ac_uaddr); -- if (prevptr) -+ cptr->ac_uaddr = NULL; -+ } -+ if (prevptr) { - prevptr->ac_next = cptr->ac_next; -- else -+ } else { - front = cptr->ac_next; -+ } - cachesize--; - break; - } diff --git a/libtirpc-1.1.4-dup_ncp-bad-free.patch b/libtirpc-1.1.4-dup_ncp-bad-free.patch deleted file mode 100644 index 0c71fb4..0000000 --- a/libtirpc-1.1.4-dup_ncp-bad-free.patch +++ /dev/null @@ -1,51 +0,0 @@ -commit 959b2001458bca8f9228014371aad6ccbeb95a68 -Author: Zhi Li -Date: Wed Sep 26 14:05:29 2018 -0400 - - getnetconfig.c: fix a BAD_FREE (CWE-763) - - Signed-off-by: Steve Dickson - -diff --git a/src/getnetconfig.c b/src/getnetconfig.c -index d67d97d..cfd33c2 100644 ---- a/src/getnetconfig.c -+++ b/src/getnetconfig.c -@@ -681,6 +681,7 @@ struct netconfig *ncp; - { - struct netconfig *p; - char *tmp; -+ char *t; - u_int i; - - if ((tmp=malloc(MAXNETCONFIGLINE)) == NULL) -@@ -700,22 +701,21 @@ struct netconfig *ncp; - */ - *p = *ncp; - p->nc_netid = (char *)strcpy(tmp,ncp->nc_netid); -- tmp = strchr(tmp, 0) + 1; -- p->nc_protofmly = (char *)strcpy(tmp,ncp->nc_protofmly); -- tmp = strchr(tmp, 0) + 1; -- p->nc_proto = (char *)strcpy(tmp,ncp->nc_proto); -- tmp = strchr(tmp, 0) + 1; -- p->nc_device = (char *)strcpy(tmp,ncp->nc_device); -+ t = strchr(tmp, 0) + 1; -+ p->nc_protofmly = (char *)strcpy(t,ncp->nc_protofmly); -+ t = strchr(t, 0) + 1; -+ p->nc_proto = (char *)strcpy(t,ncp->nc_proto); -+ t = strchr(t, 0) + 1; -+ p->nc_device = (char *)strcpy(t,ncp->nc_device); - p->nc_lookups = (char **)malloc((size_t)(p->nc_nlookups+1) * sizeof(char *)); - if (p->nc_lookups == NULL) { -- free(p->nc_netid); - free(p); - free(tmp); - return(NULL); - } - for (i=0; i < p->nc_nlookups; i++) { -- tmp = strchr(tmp, 0) + 1; -- p->nc_lookups[i] = (char *)strcpy(tmp,ncp->nc_lookups[i]); -+ t = strchr(t, 0) + 1; -+ p->nc_lookups[i] = (char *)strcpy(t,ncp->nc_lookups[i]); - } - return(p); - } diff --git a/libtirpc-1.1.4-fix-EOF-non-block.patch b/libtirpc-1.1.4-fix-EOF-non-block.patch deleted file mode 100644 index ca91776..0000000 --- a/libtirpc-1.1.4-fix-EOF-non-block.patch +++ /dev/null @@ -1,68 +0,0 @@ -diff -up libtirpc-1.1.4/src/svc_vc.c.orig libtirpc-1.1.4/src/svc_vc.c ---- libtirpc-1.1.4/src/svc_vc.c.orig 2018-08-27 10:06:49.000000000 -0400 -+++ libtirpc-1.1.4/src/svc_vc.c 2019-07-24 11:51:32.191485387 -0400 -@@ -502,9 +502,14 @@ read_vc(xprtp, buf, len) - cfp = (struct cf_conn *)xprt->xp_p1; - - if (cfp->nonblock) { -+ /* Since len == 0 is returned on zero length -+ * read or EOF errno needs to be reset before -+ * the read -+ */ -+ errno = 0; - len = read(sock, buf, (size_t)len); - if (len < 0) { -- if (errno == EAGAIN) -+ if (errno == EAGAIN || errno == EWOULDBLOCK) - len = 0; - else - goto fatal_err; -diff -up libtirpc-1.1.4/src/xdr_rec.c.orig libtirpc-1.1.4/src/xdr_rec.c ---- libtirpc-1.1.4/src/xdr_rec.c.orig 2018-08-27 10:06:49.000000000 -0400 -+++ libtirpc-1.1.4/src/xdr_rec.c 2019-07-24 11:51:32.191485387 -0400 -@@ -61,6 +61,7 @@ - #include - #include - #include -+#include - #include "rpc_com.h" - static bool_t xdrrec_getlong(XDR *, long *); - static bool_t xdrrec_putlong(XDR *, const long *); -@@ -537,7 +538,13 @@ __xdrrec_getrec(xdrs, statp, expectdata) - n = rstrm->readit(rstrm->tcp_handle, rstrm->in_hdrp, - (int)sizeof (rstrm->in_header) - rstrm->in_hdrlen); - if (n == 0) { -- *statp = expectdata ? XPRT_DIED : XPRT_IDLE; -+ /* EAGAIN or EWOULDBLOCK means a zero length -+ * read not an EOF. -+ */ -+ if (errno == EAGAIN || errno == EWOULDBLOCK) -+ *statp = XPRT_IDLE; -+ else -+ *statp = expectdata ? XPRT_DIED : XPRT_IDLE; - return FALSE; - } - if (n < 0) { -@@ -564,6 +571,7 @@ __xdrrec_getrec(xdrs, statp, expectdata) - rstrm->in_header &= ~LAST_FRAG; - rstrm->last_frag = TRUE; - } -+ rstrm->in_haveheader = 1; - } - - n = rstrm->readit(rstrm->tcp_handle, -@@ -576,7 +584,13 @@ __xdrrec_getrec(xdrs, statp, expectdata) - } - - if (n == 0) { -- *statp = expectdata ? XPRT_DIED : XPRT_IDLE; -+ /* EAGAIN or EWOULDBLOCK means a zero length -+ * read not an EOF. -+ */ -+ if (errno == EAGAIN || errno == EWOULDBLOCK) -+ *statp = XPRT_IDLE; -+ else -+ *statp = expectdata ? XPRT_DIED : XPRT_IDLE; - return FALSE; - } - diff --git a/libtirpc-1.1.4-ip_local_reserved_ports.patch b/libtirpc-1.1.4-ip_local_reserved_ports.patch deleted file mode 100644 index 5b41f39..0000000 --- a/libtirpc-1.1.4-ip_local_reserved_ports.patch +++ /dev/null @@ -1,185 +0,0 @@ -From 20148930201b732c5dd1003933dd70543d3e929d Mon Sep 17 00:00:00 2001 -From: Otto Hollmann -Date: Sat, 7 Oct 2023 03:48:22 -0400 -Subject: [PATCH] binddynport.c honor ip_local_reserved_ports - -Read reserved ports from /proc/sys/net/ipv4/ip_local_reserved_ports, -store them into bit-wise array and before binding to random port check -if port is not reserved. - -Currently, there is no way how to reserve ports so then will not be -used by rpcbind. - -Random ports are opened by rpcbind because of rmtcalls. There is -compile-time flag for disabling them, but in some cases we can not -simply disable them. - -One solution would be run time option --enable-rmtcalls as already -discussed, but it was rejected. So if we want to keep rmtcalls enabled -and also be able to reserve some ports, there is no other way than -filtering available ports. The easiest and clearest way seems to be -just respect kernel list of ip_reserved_ports. - -Unfortunately there is one known disadvantage/side effect - it affects -probability of ports which are right after reserved ones. The bigger -reserved block is, the higher is probability of selecting following -unreserved port. But if there is no reserved port, impact of this patch -is minimal/none. - -Signed-off-by: Otto Hollmann -Signed-off-by: Steve Dickson ---- - src/binddynport.c | 108 ++++++++++++++++++++++++++++++++++++++++++---- - 1 file changed, 100 insertions(+), 8 deletions(-) - -diff --git a/src/binddynport.c b/src/binddynport.c -index 062629a..c2e9a20 100644 ---- a/src/binddynport.c -+++ b/src/binddynport.c -@@ -37,6 +37,7 @@ - #include - #include - #include -+#include - - #include - -@@ -56,6 +57,84 @@ enum { - NPORTS = ENDPORT - LOWPORT + 1, - }; - -+/* -+ * This function decodes information about given port from provided array and -+ * return if port is reserved or not. -+ * -+ * @reserved_ports an array of size at least "NPORTS / (8*sizeof(char)) + 1". -+ * @port port number within range LOWPORT and ENDPORT -+ * -+ * Returns 0 if port is not reserved, non-negative if port is reserved. -+ */ -+static int is_reserved(char *reserved_ports, int port) { -+ port -= LOWPORT; -+ if (port < 0 || port >= NPORTS) -+ return 0; -+ return reserved_ports[port/(8*sizeof(char))] & 1<<(port%(8*sizeof(char))); -+} -+ -+/* -+ * This function encodes information about given *reserved* port into provided -+ * array. Don't call this function for ports which are not reserved. -+ * -+ * @reserved_ports an array of size at least "NPORTS / (8*sizeof(char)) + 1". -+ * @port port number within range LOWPORT and ENDPORT -+ * -+ */ -+static void set_reserved(char *reserved_ports, int port) { -+ port -= LOWPORT; -+ if (port < 0 || port >= NPORTS) -+ return; -+ reserved_ports[port/(8*sizeof(char))] |= 1<<(port%(8*sizeof(char))); -+} -+ -+/* -+ * Parse local reserved ports obtained from -+ * /proc/sys/net/ipv4/ip_local_reserved_ports into bit array. -+ * -+ * @reserved_ports a zeroed array of size at least -+ * "NPORTS / (8*sizeof(char)) + 1". Will be used for bit-wise encoding of -+ * reserved ports. -+ * -+ * On each call, reserved ports are read from /proc and bit-wise stored into -+ * provided array -+ * -+ * Returns 0 on success, -1 on failure. -+ */ -+ -+static int parse_reserved_ports(char *reserved_ports) { -+ int from=0, to; -+ char delimiter = ','; -+ int res; -+ FILE * file_ptr = fopen("/proc/sys/net/ipv4/ip_local_reserved_ports","r"); -+ if (file_ptr == NULL) { -+ (void) syslog(LOG_ERR, -+ "Unable to open open /proc/sys/net/ipv4/ip_local_reserved_ports."); -+ return -1; -+ } -+ do { -+ if ((res = fscanf(file_ptr, "%d", &to)) != 1) { -+ if (res == EOF) break; -+ goto err; -+ } -+ if (delimiter != '-') { -+ from = to; -+ } -+ for (int i = from; i <= to; ++i) { -+ set_reserved(reserved_ports, i); -+ } -+ } while ((res = fscanf(file_ptr, "%c", &delimiter)) == 1); -+ if (res != EOF) -+ goto err; -+ fclose(file_ptr); -+ return 0; -+err: -+ (void) syslog(LOG_ERR, -+ "An error occurred while parsing ip_local_reserved_ports."); -+ fclose(file_ptr); -+ return -1; -+} -+ - /* - * Bind a socket to a dynamically-assigned IP port. - * -@@ -81,7 +160,8 @@ int __binddynport(int fd) - in_port_t port, *portp; - struct sockaddr *sap; - socklen_t salen; -- int i, res; -+ int i, res, array_size; -+ char *reserved_ports = NULL; - - if (__rpc_sockisbound(fd)) - return 0; -@@ -119,21 +199,33 @@ int __binddynport(int fd) - gettimeofday(&tv, NULL); - seed = tv.tv_usec * getpid(); - } -+ array_size = NPORTS / (8*sizeof(char)) + 1; -+ reserved_ports = malloc(array_size); -+ if (!reserved_ports) { -+ goto out; -+ } -+ memset(reserved_ports, 0, array_size); -+ if (parse_reserved_ports(reserved_ports) < 0) -+ goto out; -+ - port = (rand_r(&seed) % NPORTS) + LOWPORT; - for (i = 0; i < NPORTS; ++i) { -- *portp = htons(port++); -- res = bind(fd, sap, salen); -- if (res >= 0) { -- res = 0; -- break; -+ *portp = htons(port); -+ if (!is_reserved(reserved_ports, port++)) { -+ res = bind(fd, sap, salen); -+ if (res >= 0) { -+ res = 0; -+ break; -+ } -+ if (errno != EADDRINUSE) -+ break; - } -- if (errno != EADDRINUSE) -- break; - if (port > ENDPORT) - port = LOWPORT; - } - - out: -+ free(reserved_ports); - mutex_unlock(&port_lock); - return res; - } --- -2.40.1 - diff --git a/libtirpc-1.1.4-multithr-cleanup.patch b/libtirpc-1.1.4-multithr-cleanup.patch deleted file mode 100644 index d4fc2d6..0000000 --- a/libtirpc-1.1.4-multithr-cleanup.patch +++ /dev/null @@ -1,1230 +0,0 @@ -diff --git a/src/bindresvport.c b/src/bindresvport.c -index ef9b345..5c0ddcf 100644 ---- a/src/bindresvport.c -+++ b/src/bindresvport.c -@@ -164,10 +164,11 @@ bindresvport_sa(sd, sa) - int endport = ENDPORT; - int i; - -+ mutex_lock(&port_lock); -+ - if (!blacklist_read) - load_blacklist(); - -- mutex_lock(&port_lock); - nports = ENDPORT - startport + 1; - - if (sa == NULL) { -diff --git a/src/clnt_dg.c b/src/clnt_dg.c -index d8890b5..166af63 100644 ---- a/src/clnt_dg.c -+++ b/src/clnt_dg.c -@@ -53,6 +53,7 @@ - #include - #include - #include "rpc_com.h" -+#include "clnt_fd_locks.h" - - #ifdef IP_RECVERR - #include -@@ -81,24 +82,29 @@ static void clnt_dg_destroy(CLIENT *); - * This machinery implements per-fd locks for MT-safety. It is not - * sufficient to do per-CLIENT handle locks for MT-safety because a - * user may create more than one CLIENT handle with the same fd behind -- * it. Therfore, we allocate an array of flags (dg_fd_locks), protected -- * by the clnt_fd_lock mutex, and an array (dg_cv) of condition variables -- * similarly protected. Dg_fd_lock[fd] == 1 => a call is activte on some -- * CLIENT handle created for that fd. -+ * it. -+ * -+ * We keep track of a list of per-fd locks, protected by the clnt_fd_lock -+ * mutex. Each per-fd lock consists of a predicate indicating whether is -+ * active or not: fd_lock->active == TRUE => a call is active on some -+ * CLIENT handle created for that fd. Each fd predicate is guarded by a -+ * condition variable so that the global mutex can be unlocked while -+ * waiting for the predicate to change. -+ * - * The current implementation holds locks across the entire RPC and reply, - * including retransmissions. Yes, this is silly, and as soon as this - * code is proven to work, this should be the first thing fixed. One step - * at a time. - */ --static int *dg_fd_locks; -+static fd_locks_t *dg_fd_locks; - extern mutex_t clnt_fd_lock; --static cond_t *dg_cv; --#define release_fd_lock(fd, mask) { \ -+#define release_fd_lock(fd_lock, mask) { \ - mutex_lock(&clnt_fd_lock); \ -- dg_fd_locks[fd] = 0; \ -- mutex_unlock(&clnt_fd_lock); \ -+ fd_lock->active = FALSE; \ -+ fd_lock->pending--; \ - thr_sigsetmask(SIG_SETMASK, &(mask), NULL); \ -- cond_signal(&dg_cv[fd]); \ -+ cond_signal(&fd_lock->cv); \ -+ mutex_unlock(&clnt_fd_lock); \ - } - - static const char mem_err_clnt_dg[] = "clnt_dg_create: out of memory"; -@@ -110,6 +116,7 @@ static const char mem_err_clnt_dg[] = "clnt_dg_create: out of memory"; - */ - struct cu_data { - int cu_fd; /* connections fd */ -+ fd_lock_t *cu_fd_lock; - bool_t cu_closeit; /* opened by library */ - struct sockaddr_storage cu_raddr; /* remote address */ - int cu_rlen; -@@ -158,46 +165,22 @@ clnt_dg_create(fd, svcaddr, program, version, sendsz, recvsz) - sigset_t newmask; - struct __rpc_sockinfo si; - int one = 1; -+ fd_lock_t *fd_lock; - - sigfillset(&newmask); - thr_sigsetmask(SIG_SETMASK, &newmask, &mask); - mutex_lock(&clnt_fd_lock); -- if (dg_fd_locks == (int *) NULL) { -- size_t cv_allocsz, fd_allocsz; -- unsigned int dtbsize = __rpc_dtbsize(); -- -- if ( (size_t) dtbsize > SIZE_MAX/sizeof(cond_t)) { -+ if (dg_fd_locks == (fd_locks_t *) NULL) { -+ dg_fd_locks = fd_locks_init(); -+ if (dg_fd_locks == (fd_locks_t *) NULL) { - mutex_unlock(&clnt_fd_lock); -- thr_sigsetmask(SIG_SETMASK, &(mask), NULL); -- errno = EOVERFLOW; - goto err1; - } -- -- fd_allocsz = dtbsize * sizeof (int); -- dg_fd_locks = (int *) mem_alloc(fd_allocsz); -- if (dg_fd_locks == (int *) NULL) { -- mutex_unlock(&clnt_fd_lock); -- thr_sigsetmask(SIG_SETMASK, &(mask), NULL); -- errno = ENOMEM; -- goto err1; -- } else -- memset(dg_fd_locks, '\0', fd_allocsz); -- -- cv_allocsz = dtbsize * sizeof (cond_t); -- dg_cv = (cond_t *) mem_alloc(cv_allocsz); -- if (dg_cv == (cond_t *) NULL) { -- mem_free(dg_fd_locks, fd_allocsz); -- dg_fd_locks = (int *) NULL; -- mutex_unlock(&clnt_fd_lock); -- thr_sigsetmask(SIG_SETMASK, &(mask), NULL); -- errno = ENOMEM; -- goto err1; -- } else { -- int i; -- -- for (i = 0; i < dtbsize; i++) -- cond_init(&dg_cv[i], 0, (void *) 0); -- } -+ } -+ fd_lock = fd_lock_create(fd, dg_fd_locks); -+ if (fd_lock == (fd_lock_t *) NULL) { -+ mutex_unlock(&clnt_fd_lock); -+ goto err1; - } - - mutex_unlock(&clnt_fd_lock); -@@ -277,6 +260,7 @@ clnt_dg_create(fd, svcaddr, program, version, sendsz, recvsz) - */ - cu->cu_closeit = FALSE; - cu->cu_fd = fd; -+ cu->cu_fd_lock = fd_lock; - cl->cl_ops = clnt_dg_ops(); - cl->cl_private = (caddr_t)(void *)cu; - cl->cl_auth = authnone_create(); -@@ -322,17 +306,16 @@ clnt_dg_call(cl, proc, xargs, argsp, xresults, resultsp, utimeout) - sigset_t newmask; - socklen_t salen; - ssize_t recvlen = 0; -- int rpc_lock_value; - u_int32_t xid, inval, outval; - - outlen = 0; - sigfillset(&newmask); - thr_sigsetmask(SIG_SETMASK, &newmask, &mask); - mutex_lock(&clnt_fd_lock); -- while (dg_fd_locks[cu->cu_fd]) -- cond_wait(&dg_cv[cu->cu_fd], &clnt_fd_lock); -- rpc_lock_value = 1; -- dg_fd_locks[cu->cu_fd] = rpc_lock_value; -+ cu->cu_fd_lock->pending++; -+ while (cu->cu_fd_lock->active) -+ cond_wait(&cu->cu_fd_lock->cv, &clnt_fd_lock); -+ cu->cu_fd_lock->active = TRUE; - mutex_unlock(&clnt_fd_lock); - if (cu->cu_total.tv_usec == -1) { - timeout = utimeout; /* use supplied timeout */ -@@ -481,7 +464,7 @@ get_reply: - e = (struct sock_extended_err *) CMSG_DATA(cmsg); - cu->cu_error.re_errno = e->ee_errno; - mem_free(cbuf, (outlen + 256)); -- release_fd_lock(cu->cu_fd, mask); -+ release_fd_lock(cu->cu_fd_lock, mask); - return (cu->cu_error.re_status = RPC_CANTRECV); - } - mem_free(cbuf, (outlen + 256)); -@@ -561,7 +544,7 @@ get_reply: - - } - out: -- release_fd_lock(cu->cu_fd, mask); -+ release_fd_lock(cu->cu_fd_lock, mask); - return (cu->cu_error.re_status); - } - -@@ -590,13 +573,15 @@ clnt_dg_freeres(cl, xdr_res, res_ptr) - sigfillset(&newmask); - thr_sigsetmask(SIG_SETMASK, &newmask, &mask); - mutex_lock(&clnt_fd_lock); -- while (dg_fd_locks[cu->cu_fd]) -- cond_wait(&dg_cv[cu->cu_fd], &clnt_fd_lock); -+ cu->cu_fd_lock->pending++; -+ while (cu->cu_fd_lock->active) -+ cond_wait(&cu->cu_fd_lock->cv, &clnt_fd_lock); - xdrs->x_op = XDR_FREE; - dummy = (*xdr_res)(xdrs, res_ptr); -- mutex_unlock(&clnt_fd_lock); -+ cu->cu_fd_lock->pending--; - thr_sigsetmask(SIG_SETMASK, &mask, NULL); -- cond_signal(&dg_cv[cu->cu_fd]); -+ cond_signal(&cu->cu_fd_lock->cv); -+ mutex_unlock(&clnt_fd_lock); - return (dummy); - } - -@@ -617,36 +602,35 @@ clnt_dg_control(cl, request, info) - struct netbuf *addr; - sigset_t mask; - sigset_t newmask; -- int rpc_lock_value; - - sigfillset(&newmask); - thr_sigsetmask(SIG_SETMASK, &newmask, &mask); - mutex_lock(&clnt_fd_lock); -- while (dg_fd_locks[cu->cu_fd]) -- cond_wait(&dg_cv[cu->cu_fd], &clnt_fd_lock); -- rpc_lock_value = 1; -- dg_fd_locks[cu->cu_fd] = rpc_lock_value; -+ cu->cu_fd_lock->pending++; -+ while (cu->cu_fd_lock->active) -+ cond_wait(&cu->cu_fd_lock->cv, &clnt_fd_lock); -+ cu->cu_fd_lock->active = TRUE; - mutex_unlock(&clnt_fd_lock); - switch (request) { - case CLSET_FD_CLOSE: - cu->cu_closeit = TRUE; -- release_fd_lock(cu->cu_fd, mask); -+ release_fd_lock(cu->cu_fd_lock, mask); - return (TRUE); - case CLSET_FD_NCLOSE: - cu->cu_closeit = FALSE; -- release_fd_lock(cu->cu_fd, mask); -+ release_fd_lock(cu->cu_fd_lock, mask); - return (TRUE); - } - - /* for other requests which use info */ - if (info == NULL) { -- release_fd_lock(cu->cu_fd, mask); -+ release_fd_lock(cu->cu_fd_lock, mask); - return (FALSE); - } - switch (request) { - case CLSET_TIMEOUT: - if (time_not_ok((struct timeval *)info)) { -- release_fd_lock(cu->cu_fd, mask); -+ release_fd_lock(cu->cu_fd_lock, mask); - return (FALSE); - } - cu->cu_total = *(struct timeval *)info; -@@ -660,7 +644,7 @@ clnt_dg_control(cl, request, info) - break; - case CLSET_RETRY_TIMEOUT: - if (time_not_ok((struct timeval *)info)) { -- release_fd_lock(cu->cu_fd, mask); -+ release_fd_lock(cu->cu_fd_lock, mask); - return (FALSE); - } - cu->cu_wait = *(struct timeval *)info; -@@ -680,7 +664,7 @@ clnt_dg_control(cl, request, info) - case CLSET_SVC_ADDR: /* set to new address */ - addr = (struct netbuf *)info; - if (addr->len < sizeof cu->cu_raddr) { -- release_fd_lock(cu->cu_fd, mask); -+ release_fd_lock(cu->cu_fd_lock, mask); - return (FALSE); - } - (void) memcpy(&cu->cu_raddr, addr->buf, addr->len); -@@ -743,10 +727,10 @@ clnt_dg_control(cl, request, info) - cu->cu_connect = *(int *)info; - break; - default: -- release_fd_lock(cu->cu_fd, mask); -+ release_fd_lock(cu->cu_fd_lock, mask); - return (FALSE); - } -- release_fd_lock(cu->cu_fd, mask); -+ release_fd_lock(cu->cu_fd_lock, mask); - return (TRUE); - } - -@@ -756,14 +740,21 @@ clnt_dg_destroy(cl) - { - struct cu_data *cu = (struct cu_data *)cl->cl_private; - int cu_fd = cu->cu_fd; -+ fd_lock_t *cu_fd_lock = cu->cu_fd_lock; - sigset_t mask; - sigset_t newmask; - - sigfillset(&newmask); - thr_sigsetmask(SIG_SETMASK, &newmask, &mask); - mutex_lock(&clnt_fd_lock); -- while (dg_fd_locks[cu_fd]) -- cond_wait(&dg_cv[cu_fd], &clnt_fd_lock); -+ /* wait until all pending operations on client are completed. */ -+ while (cu_fd_lock->pending > 0) { -+ /* If a blocked operation can be awakened, then do it. */ -+ if (cu_fd_lock->active == FALSE) -+ cond_signal(&cu_fd_lock->cv); -+ /* keep waiting... */ -+ cond_wait(&cu_fd_lock->cv, &clnt_fd_lock); -+ } - if (cu->cu_closeit) - (void)close(cu_fd); - XDR_DESTROY(&(cu->cu_outxdrs)); -@@ -773,9 +764,10 @@ clnt_dg_destroy(cl) - if (cl->cl_tp && cl->cl_tp[0]) - mem_free(cl->cl_tp, strlen(cl->cl_tp) +1); - mem_free(cl, sizeof (CLIENT)); -+ cond_signal(&cu_fd_lock->cv); -+ fd_lock_destroy(cu_fd, cu_fd_lock, dg_fd_locks); - mutex_unlock(&clnt_fd_lock); - thr_sigsetmask(SIG_SETMASK, &mask, NULL); -- cond_signal(&dg_cv[cu_fd]); - } - - static struct clnt_ops * -diff --git a/src/clnt_fd_locks.h b/src/clnt_fd_locks.h -new file mode 100644 -index 0000000..6ba62cb ---- /dev/null -+++ b/src/clnt_fd_locks.h -@@ -0,0 +1,209 @@ -+/* -+ * debug.h -- debugging routines for libtirpc -+ * -+ * Copyright (c) 2020 SUSE LINUX GmbH, Nuernberg, Germany. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * - Redistributions of source code must retain the above copyright notice, -+ * this list of conditions and the following disclaimer. -+ * - Redistributions in binary form must reproduce the above copyright notice, -+ * this list of conditions and the following disclaimer in the documentation -+ * and/or other materials provided with the distribution. -+ * - Neither the name of Sun Microsystems, Inc. nor the names of its -+ * contributors may be used to endorse or promote products derived -+ * from this software without specific prior written permission. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -+ * POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#ifndef _CLNT_FD_LOCKS_H -+#define _CLNT_FD_LOCKS_H -+ -+#include -+#include -+#include -+#include -+ -+ -+/* -+ * This utility manages a list of per-fd locks for the clients. -+ * -+ * If MAX_FDLOCKS_PREALLOC is defined, a number of pre-fd locks will be -+ * pre-allocated. This number is the minimum of MAX_FDLOCKS_PREALLOC or -+ * the process soft limit of allowed fds. -+ */ -+#ifdef MAX_FDLOCKS_PREALLOC -+static unsigned int fd_locks_prealloc = 0; -+#endif -+ -+/* per-fd lock */ -+struct fd_lock_t { -+ bool_t active; -+ int pending; /* Number of pending operations on fd */ -+ cond_t cv; -+}; -+typedef struct fd_lock_t fd_lock_t; -+ -+ -+/* internal type to store per-fd locks in a list */ -+struct fd_lock_item_t { -+ /* fd_lock_t first so we can cast to fd_lock_item_t */ -+ fd_lock_t fd_lock; -+ int fd; -+ unsigned int refs; -+ TAILQ_ENTRY(fd_lock_item_t) link; -+}; -+typedef struct fd_lock_item_t fd_lock_item_t; -+#define to_fd_lock_item(fdlock_t_ptr) ((fd_lock_item_t*) fdlock_t_ptr) -+ -+ -+/* internal list of per-fd locks */ -+typedef TAILQ_HEAD(,fd_lock_item_t) fd_lock_list_t; -+ -+ -+#ifdef MAX_FDLOCKS_PREALLOC -+ -+/* With pre-allocation, keep track of both an array and a list */ -+struct fd_locks_t { -+ fd_lock_list_t fd_lock_list; -+ fd_lock_t *fd_lock_array; -+}; -+typedef struct fd_locks_t fd_locks_t; -+#define to_fd_lock_list(fd_locks_t_ptr) (&fd_locks_t_ptr->fd_lock_list) -+ -+#else -+ -+/* With no pre-allocation, just keep track of a list */ -+typedef fd_lock_list_t fd_locks_t; -+#define to_fd_lock_list(fd_locks_t_ptr) ((fd_lock_list_t *) fd_locks_t_ptr) -+ -+#endif -+ -+ -+/* allocate fd locks */ -+static inline -+fd_locks_t* fd_locks_init() { -+ fd_locks_t *fd_locks; -+ -+ fd_locks = (fd_locks_t *) mem_alloc(sizeof(fd_locks_t)); -+ if (fd_locks == (fd_locks_t *) NULL) { -+ errno = ENOMEM; -+ return (NULL); -+ } -+ TAILQ_INIT(to_fd_lock_list(fd_locks)); -+ -+#ifdef MAX_FDLOCKS_PREALLOC -+ size_t fd_lock_arraysz; -+ -+ if (fd_locks_prealloc == 0) { -+ unsigned int dtbsize = __rpc_dtbsize(); -+ if (0 < dtbsize && dtbsize < MAX_FDLOCKS_PREALLOC) -+ fd_locks_prealloc = dtbsize; -+ else -+ fd_locks_prealloc = MAX_FDLOCKS_PREALLOC; -+ } -+ -+ if ( (size_t) fd_locks_prealloc > SIZE_MAX/sizeof(fd_lock_t)) { -+ mem_free(fd_locks, sizeof (*fd_locks)); -+ errno = EOVERFLOW; -+ return (NULL); -+ } -+ -+ fd_lock_arraysz = fd_locks_prealloc * sizeof (fd_lock_t); -+ fd_locks->fd_lock_array = (fd_lock_t *) mem_alloc(fd_lock_arraysz); -+ if (fd_locks->fd_lock_array == (fd_lock_t *) NULL) { -+ mem_free(fd_locks, sizeof (*fd_locks)); -+ errno = ENOMEM; -+ return (NULL); -+ } -+ else { -+ int i; -+ -+ for (i = 0; i < fd_locks_prealloc; i++) { -+ fd_locks->fd_lock_array[i].active = FALSE; -+ cond_init(&fd_locks->fd_lock_array[i].cv, 0, (void *) 0); -+ } -+ } -+#endif -+ -+ return fd_locks; -+} -+ -+/* de-allocate fd locks */ -+static inline -+void fd_locks_destroy(fd_locks_t *fd_locks) { -+#ifdef MAX_FDLOCKS_PREALLOC -+ fd_lock_t *array = fd_locks->fd_lock_array; -+ mem_free(array, fd_locks_prealloc * sizeof (fd_lock_t)); -+#endif -+ fd_lock_item_t *item; -+ fd_lock_list_t *list = to_fd_lock_list(fd_locks); -+ -+ TAILQ_FOREACH(item, list, link) { -+ cond_destroy(&item->fd_lock.cv); -+ mem_free(item, sizeof (*item)); -+ } -+ mem_free(fd_locks, sizeof (*fd_locks)); -+} -+ -+/* allocate per-fd lock */ -+static inline -+fd_lock_t* fd_lock_create(int fd, fd_locks_t *fd_locks) { -+#ifdef MAX_FDLOCKS_PREALLOC -+ if (fd < fd_locks_prealloc) { -+ return &fd_locks->fd_lock_array[fd]; -+ } -+#endif -+ fd_lock_item_t *item; -+ fd_lock_list_t *list = to_fd_lock_list(fd_locks); -+ -+ for (item = TAILQ_FIRST(list); -+ item != (fd_lock_item_t *) NULL && item->fd != fd; -+ item = TAILQ_NEXT(item, link)); -+ -+ if (item == (fd_lock_item_t *) NULL) { -+ item = (fd_lock_item_t *) mem_alloc(sizeof(fd_lock_item_t)); -+ if (item == (fd_lock_item_t *) NULL) { -+ errno = ENOMEM; -+ return (NULL); -+ } -+ item->fd = fd; -+ item->refs = 1; -+ item->fd_lock.active = FALSE; -+ item->fd_lock.pending = 0; -+ cond_init(&item->fd_lock.cv, 0, (void *) 0); -+ TAILQ_INSERT_HEAD(list, item, link); -+ } else { -+ item->refs++; -+ } -+ return &item->fd_lock; -+} -+ -+/* de-allocate per-fd lock */ -+static inline -+void fd_lock_destroy(int fd, fd_lock_t *fd_lock, fd_locks_t *fd_locks) { -+#ifdef MAX_FDLOCKS_PREALLOC -+ if (fd < fd_locks_prealloc) -+ return; -+#endif -+ fd_lock_item_t* item = to_fd_lock_item(fd_lock); -+ item->refs--; -+ if (item->refs <= 0) { -+ TAILQ_REMOVE(to_fd_lock_list(fd_locks), item, link); -+ cond_destroy(&item->fd_lock.cv); -+ mem_free(item, sizeof (*item)); -+ } -+} -+ -+#endif /* _CLNT_FD_LOCKS_H */ -diff --git a/src/clnt_vc.c b/src/clnt_vc.c -index 3ba55de..7fe3016 100644 ---- a/src/clnt_vc.c -+++ b/src/clnt_vc.c -@@ -67,6 +67,7 @@ - - #include - #include "rpc_com.h" -+#include "clnt_fd_locks.h" - - #ifdef HAVE_RPCSEC_GSS - #include -@@ -114,6 +115,7 @@ static int write_vc(void *, void *, int); - - struct ct_data { - int ct_fd; /* connection's fd */ -+ fd_lock_t *ct_fd_lock; - bool_t ct_closeit; /* close it on destroy */ - struct timeval ct_wait; /* wait interval in milliseconds */ - bool_t ct_waitset; /* wait set by clnt_control? */ -@@ -128,27 +130,33 @@ struct ct_data { - }; - - /* -- * This machinery implements per-fd locks for MT-safety. It is not -- * sufficient to do per-CLIENT handle locks for MT-safety because a -- * user may create more than one CLIENT handle with the same fd behind -- * it. Therfore, we allocate an array of flags (vc_fd_locks), protected -- * by the clnt_fd_lock mutex, and an array (vc_cv) of condition variables -- * similarly protected. Vc_fd_lock[fd] == 1 => a call is active on some -- * CLIENT handle created for that fd. -- * The current implementation holds locks across the entire RPC and reply. -- * Yes, this is silly, and as soon as this code is proven to work, this -- * should be the first thing fixed. One step at a time. -+ * This machinery implements per-fd locks for MT-safety. It is not -+ * sufficient to do per-CLIENT handle locks for MT-safety because a -+ * user may create more than one CLIENT handle with the same fd behind -+ * it. -+ * -+ * We keep track of a list of per-fd locks, protected by the clnt_fd_lock -+ * mutex. Each per-fd lock consists of a predicate indicating whether is -+ * active or not: fd_lock->active == TRUE => a call is active on some -+ * CLIENT handle created for that fd. Each fd predicate is guarded by a -+ * condition variable so that the global mutex can be unlocked while -+ * waiting for the predicate to change. -+ * -+ * The current implementation holds locks across the entire RPC and reply, -+ * including retransmissions. Yes, this is silly, and as soon as this -+ * code is proven to work, this should be the first thing fixed. One step -+ * at a time. - */ --static int *vc_fd_locks; -+static fd_locks_t *vc_fd_locks; - extern pthread_mutex_t disrupt_lock; - extern mutex_t clnt_fd_lock; --static cond_t *vc_cv; --#define release_fd_lock(fd, mask) { \ -+#define release_fd_lock(fd_lock, mask) { \ - mutex_lock(&clnt_fd_lock); \ -- vc_fd_locks[fd] = 0; \ -- mutex_unlock(&clnt_fd_lock); \ -+ fd_lock->active = FALSE; \ -+ fd_lock->pending--; \ - thr_sigsetmask(SIG_SETMASK, &(mask), (sigset_t *) NULL); \ -- cond_signal(&vc_cv[fd]); \ -+ cond_signal(&fd_lock->cv); \ -+ mutex_unlock(&clnt_fd_lock); \ - } - - static const char clnt_vc_errstr[] = "%s : %s"; -@@ -185,6 +193,7 @@ clnt_vc_create(fd, raddr, prog, vers, sendsz, recvsz) - struct sockaddr_storage ss; - socklen_t slen; - struct __rpc_sockinfo si; -+ fd_lock_t *fd_lock; - - mutex_lock(&disrupt_lock); - if (disrupt == 0) -@@ -205,49 +214,26 @@ clnt_vc_create(fd, raddr, prog, vers, sendsz, recvsz) - sigfillset(&newmask); - thr_sigsetmask(SIG_SETMASK, &newmask, &mask); - mutex_lock(&clnt_fd_lock); -- if (vc_fd_locks == (int *) NULL) { -- size_t cv_allocsz, fd_allocsz; -- unsigned int dtbsize = __rpc_dtbsize(); -- struct rpc_createerr *ce = &get_rpc_createerr(); -- -- if ( (size_t) dtbsize > SIZE_MAX/sizeof(cond_t)) { -+ if (vc_fd_locks == (fd_locks_t *) NULL) { -+ vc_fd_locks = fd_locks_init(); -+ if (vc_fd_locks == (fd_locks_t *) NULL) { -+ struct rpc_createerr *ce; - mutex_unlock(&clnt_fd_lock); -- thr_sigsetmask(SIG_SETMASK, &(mask), NULL); -- ce->cf_stat = RPC_SYSTEMERROR; -- ce->cf_error.re_errno = EOVERFLOW; -- goto err; -- } -- -- fd_allocsz = dtbsize * sizeof (int); -- vc_fd_locks = (int *) mem_alloc(fd_allocsz); -- if (vc_fd_locks == (int *) NULL) { -- mutex_unlock(&clnt_fd_lock); -- thr_sigsetmask(SIG_SETMASK, &(mask), NULL); -- ce->cf_stat = RPC_SYSTEMERROR; -- ce->cf_error.re_errno = ENOMEM; -- goto err; -- } else -- memset(vc_fd_locks, '\0', fd_allocsz); -- -- assert(vc_cv == (cond_t *) NULL); -- cv_allocsz = dtbsize * sizeof (cond_t); -- vc_cv = (cond_t *) mem_alloc(cv_allocsz); -- if (vc_cv == (cond_t *) NULL) { -- mem_free(vc_fd_locks, fd_allocsz); -- vc_fd_locks = (int *) NULL; -- mutex_unlock(&clnt_fd_lock); -- thr_sigsetmask(SIG_SETMASK, &(mask), NULL); -+ ce = &get_rpc_createerr(); - ce->cf_stat = RPC_SYSTEMERROR; -- ce->cf_error.re_errno = ENOMEM; -+ ce->cf_error.re_errno = errno; - goto err; -- } else { -- int i; -- -- for (i = 0; i < dtbsize; i++) -- cond_init(&vc_cv[i], 0, (void *) 0); - } -- } else -- assert(vc_cv != (cond_t *) NULL); -+ } -+ fd_lock = fd_lock_create(fd, vc_fd_locks); -+ if (fd_lock == (fd_lock_t *) NULL) { -+ struct rpc_createerr *ce; -+ mutex_unlock(&clnt_fd_lock); -+ ce = &get_rpc_createerr(); -+ ce->cf_stat = RPC_SYSTEMERROR; -+ ce->cf_error.re_errno = errno; -+ goto err; -+ } - - /* - * Do not hold mutex during connect -@@ -283,6 +269,7 @@ clnt_vc_create(fd, raddr, prog, vers, sendsz, recvsz) - * Set up private data struct - */ - ct->ct_fd = fd; -+ ct->ct_fd_lock = fd_lock; - ct->ct_wait.tv_usec = 0; - ct->ct_waitset = FALSE; - ct->ct_addr.buf = malloc(raddr->maxlen); -@@ -362,17 +349,16 @@ clnt_vc_call(cl, proc, xdr_args, args_ptr, xdr_results, results_ptr, timeout) - bool_t shipnow; - int refreshes = 2; - sigset_t mask, newmask; -- int rpc_lock_value; - - assert(cl != NULL); - - sigfillset(&newmask); - thr_sigsetmask(SIG_SETMASK, &newmask, &mask); - mutex_lock(&clnt_fd_lock); -- while (vc_fd_locks[ct->ct_fd]) -- cond_wait(&vc_cv[ct->ct_fd], &clnt_fd_lock); -- rpc_lock_value = 1; -- vc_fd_locks[ct->ct_fd] = rpc_lock_value; -+ ct->ct_fd_lock->pending++; -+ while (ct->ct_fd_lock->active) -+ cond_wait(&ct->ct_fd_lock->cv, &clnt_fd_lock); -+ ct->ct_fd_lock->active = TRUE; - mutex_unlock(&clnt_fd_lock); - if (!ct->ct_waitset) { - /* If time is not within limits, we ignore it. */ -@@ -401,22 +387,22 @@ call_again: - if (ct->ct_error.re_status == RPC_SUCCESS) - ct->ct_error.re_status = RPC_CANTENCODEARGS; - (void)xdrrec_endofrecord(xdrs, TRUE); -- release_fd_lock(ct->ct_fd, mask); -+ release_fd_lock(ct->ct_fd_lock, mask); - return (ct->ct_error.re_status); - } - if (! xdrrec_endofrecord(xdrs, shipnow)) { -- release_fd_lock(ct->ct_fd, mask); -+ release_fd_lock(ct->ct_fd_lock, mask); - return (ct->ct_error.re_status = RPC_CANTSEND); - } - if (! shipnow) { -- release_fd_lock(ct->ct_fd, mask); -+ release_fd_lock(ct->ct_fd_lock, mask); - return (RPC_SUCCESS); - } - /* - * Hack to provide rpc-based message passing - */ - if (timeout.tv_sec == 0 && timeout.tv_usec == 0) { -- release_fd_lock(ct->ct_fd, mask); -+ release_fd_lock(ct->ct_fd_lock, mask); - return(ct->ct_error.re_status = RPC_TIMEDOUT); - } - -@@ -430,14 +416,14 @@ call_again: - reply_msg.acpted_rply.ar_results.where = NULL; - reply_msg.acpted_rply.ar_results.proc = (xdrproc_t)xdr_void; - if (! xdrrec_skiprecord(xdrs)) { -- release_fd_lock(ct->ct_fd, mask); -+ release_fd_lock(ct->ct_fd_lock, mask); - return (ct->ct_error.re_status); - } - /* now decode and validate the response header */ - if (! xdr_replymsg(xdrs, &reply_msg)) { - if (ct->ct_error.re_status == RPC_SUCCESS) - continue; -- release_fd_lock(ct->ct_fd, mask); -+ release_fd_lock(ct->ct_fd_lock, mask); - return (ct->ct_error.re_status); - } - if (reply_msg.rm_xid == x_id) -@@ -470,7 +456,7 @@ call_again: - if (refreshes-- && AUTH_REFRESH(cl->cl_auth, &reply_msg)) - goto call_again; - } /* end of unsuccessful completion */ -- release_fd_lock(ct->ct_fd, mask); -+ release_fd_lock(ct->ct_fd_lock, mask); - return (ct->ct_error.re_status); - } - -@@ -508,13 +494,15 @@ clnt_vc_freeres(cl, xdr_res, res_ptr) - sigfillset(&newmask); - thr_sigsetmask(SIG_SETMASK, &newmask, &mask); - mutex_lock(&clnt_fd_lock); -- while (vc_fd_locks[ct->ct_fd]) -- cond_wait(&vc_cv[ct->ct_fd], &clnt_fd_lock); -+ ct->ct_fd_lock->pending++; -+ while (ct->ct_fd_lock->active) -+ cond_wait(&ct->ct_fd_lock->cv, &clnt_fd_lock); - xdrs->x_op = XDR_FREE; - dummy = (*xdr_res)(xdrs, res_ptr); -- mutex_unlock(&clnt_fd_lock); -+ ct->ct_fd_lock->pending--; - thr_sigsetmask(SIG_SETMASK, &(mask), NULL); -- cond_signal(&vc_cv[ct->ct_fd]); -+ cond_signal(&ct->ct_fd_lock->cv); -+ mutex_unlock(&clnt_fd_lock); - - return dummy; - } -@@ -536,7 +524,6 @@ clnt_vc_control(cl, request, info) - void *infop = info; - sigset_t mask; - sigset_t newmask; -- int rpc_lock_value; - u_int32_t tmp; - u_int32_t ltmp; - -@@ -547,20 +534,20 @@ clnt_vc_control(cl, request, info) - sigfillset(&newmask); - thr_sigsetmask(SIG_SETMASK, &newmask, &mask); - mutex_lock(&clnt_fd_lock); -- while (vc_fd_locks[ct->ct_fd]) -- cond_wait(&vc_cv[ct->ct_fd], &clnt_fd_lock); -- rpc_lock_value = 1; -- vc_fd_locks[ct->ct_fd] = rpc_lock_value; -+ ct->ct_fd_lock->pending++; -+ while (ct->ct_fd_lock->active) -+ cond_wait(&ct->ct_fd_lock->cv, &clnt_fd_lock); -+ ct->ct_fd_lock->active = TRUE; - mutex_unlock(&clnt_fd_lock); - - switch (request) { - case CLSET_FD_CLOSE: - ct->ct_closeit = TRUE; -- release_fd_lock(ct->ct_fd, mask); -+ release_fd_lock(ct->ct_fd_lock, mask); - return (TRUE); - case CLSET_FD_NCLOSE: - ct->ct_closeit = FALSE; -- release_fd_lock(ct->ct_fd, mask); -+ release_fd_lock(ct->ct_fd_lock, mask); - return (TRUE); - default: - break; -@@ -568,13 +555,13 @@ clnt_vc_control(cl, request, info) - - /* for other requests which use info */ - if (info == NULL) { -- release_fd_lock(ct->ct_fd, mask); -+ release_fd_lock(ct->ct_fd_lock, mask); - return (FALSE); - } - switch (request) { - case CLSET_TIMEOUT: - if (time_not_ok((struct timeval *)info)) { -- release_fd_lock(ct->ct_fd, mask); -+ release_fd_lock(ct->ct_fd_lock, mask); - return (FALSE); - } - ct->ct_wait = *(struct timeval *)infop; -@@ -594,7 +581,7 @@ clnt_vc_control(cl, request, info) - *(struct netbuf *)info = ct->ct_addr; - break; - case CLSET_SVC_ADDR: /* set to new address */ -- release_fd_lock(ct->ct_fd, mask); -+ release_fd_lock(ct->ct_fd_lock, mask); - return (FALSE); - case CLGET_XID: - /* -@@ -648,10 +635,10 @@ clnt_vc_control(cl, request, info) - break; - - default: -- release_fd_lock(ct->ct_fd, mask); -+ release_fd_lock(ct->ct_fd_lock, mask); - return (FALSE); - } -- release_fd_lock(ct->ct_fd, mask); -+ release_fd_lock(ct->ct_fd_lock, mask); - return (TRUE); - } - -@@ -660,20 +647,24 @@ static void - clnt_vc_destroy(cl) - CLIENT *cl; - { -+ assert(cl != NULL); - struct ct_data *ct = (struct ct_data *) cl->cl_private; - int ct_fd = ct->ct_fd; -+ fd_lock_t *ct_fd_lock = ct->ct_fd_lock; - sigset_t mask; - sigset_t newmask; - -- assert(cl != NULL); -- -- ct = (struct ct_data *) cl->cl_private; -- - sigfillset(&newmask); - thr_sigsetmask(SIG_SETMASK, &newmask, &mask); - mutex_lock(&clnt_fd_lock); -- while (vc_fd_locks[ct_fd]) -- cond_wait(&vc_cv[ct_fd], &clnt_fd_lock); -+ /* wait until all pending operations on client are completed. */ -+ while (ct_fd_lock->pending > 0) { -+ /* If a blocked operation can be awakened, then do it. */ -+ if (ct_fd_lock->active == FALSE) -+ cond_signal(&ct_fd_lock->cv); -+ /* keep waiting... */ -+ cond_wait(&ct_fd_lock->cv, &clnt_fd_lock); -+ } - if (ct->ct_closeit && ct->ct_fd != -1) { - (void)close(ct->ct_fd); - } -@@ -686,9 +677,10 @@ clnt_vc_destroy(cl) - if (cl->cl_tp && cl->cl_tp[0]) - mem_free(cl->cl_tp, strlen(cl->cl_tp) +1); - mem_free(cl, sizeof(CLIENT)); -+ cond_signal(&ct_fd_lock->cv); -+ fd_lock_destroy(ct_fd, ct_fd_lock, vc_fd_locks); - mutex_unlock(&clnt_fd_lock); - thr_sigsetmask(SIG_SETMASK, &(mask), NULL); -- cond_signal(&vc_cv[ct_fd]); - } - - /* -diff --git a/src/getpublickey.c b/src/getpublickey.c -index 8cf4dc2..be37a24 100644 ---- a/src/getpublickey.c -+++ b/src/getpublickey.c -@@ -74,7 +74,7 @@ __getpublickey_real(netname, publickey) - return (0); - } - *p = '\0'; -- (void) strncpy(publickey, lookup, HEXKEYBYTES); -+ memcpy(publickey, lookup, HEXKEYBYTES); - publickey[HEXKEYBYTES] = '\0'; - return (1); - } -diff --git a/src/mt_misc.c b/src/mt_misc.c -index 5a49b78..3a2bc51 100644 ---- a/src/mt_misc.c -+++ b/src/mt_misc.c -@@ -13,7 +13,7 @@ pthread_rwlock_t svc_lock = PTHREAD_RWLOCK_INITIALIZER; - pthread_rwlock_t svc_fd_lock = PTHREAD_RWLOCK_INITIALIZER; - - /* protects the RPCBIND address cache */ --pthread_rwlock_t rpcbaddr_cache_lock = PTHREAD_RWLOCK_INITIALIZER; -+pthread_mutex_t rpcbaddr_cache_lock = PTHREAD_MUTEX_INITIALIZER; - - /* protects authdes cache (svcauth_des.c) */ - pthread_mutex_t authdes_lock = PTHREAD_MUTEX_INITIALIZER; -diff --git a/src/rpcb_clnt.c b/src/rpcb_clnt.c -index a5923cb..65ff43e 100644 ---- a/src/rpcb_clnt.c -+++ b/src/rpcb_clnt.c -@@ -85,7 +85,7 @@ static int cachesize; - - extern int __rpc_lowvers; - --static struct address_cache *check_cache(const char *, const char *); -+static struct address_cache *copy_of_cached(const char *, char *); - static void delete_cache(struct netbuf *); - static void add_cache(const char *, const char *, struct netbuf *, char *); - static CLIENT *getclnthandle(const char *, const struct netconfig *, char **); -@@ -94,6 +94,82 @@ static CLIENT *local_rpcb(void); - static struct netbuf *got_entry(rpcb_entry_list_ptr, const struct netconfig *); - #endif - -+/* -+ * Destroys a cached address entry structure. -+ * -+ */ -+static void -+destroy_addr(addr) -+ struct address_cache *addr; -+{ -+ if (addr == NULL) -+ return; -+ if(addr->ac_host != NULL) -+ free(addr->ac_host); -+ if(addr->ac_netid != NULL) -+ free(addr->ac_netid); -+ if(addr->ac_uaddr != NULL) -+ free(addr->ac_uaddr); -+ if(addr->ac_taddr != NULL) { -+ if(addr->ac_taddr->buf != NULL) -+ free(addr->ac_taddr->buf); -+ } -+ free(addr); -+} -+ -+/* -+ * Creates an unlinked copy of an address cache entry. If the argument is NULL -+ * or the new entry cannot be allocated then NULL is returned. -+ */ -+static struct address_cache * -+copy_addr(addr) -+ const struct address_cache *addr; -+{ -+ struct address_cache *copy; -+ -+ if (addr == NULL) -+ return (NULL); -+ -+ copy = calloc(1, sizeof(*addr)); -+ if (copy == NULL) -+ return (NULL); -+ -+ if (addr->ac_host != NULL) { -+ copy->ac_host = strdup(addr->ac_host); -+ if (copy->ac_host == NULL) -+ goto err; -+ } -+ if (addr->ac_netid != NULL) { -+ copy->ac_netid = strdup(addr->ac_netid); -+ if (copy->ac_netid == NULL) -+ goto err; -+ } -+ if (addr->ac_uaddr != NULL) { -+ copy->ac_uaddr = strdup(addr->ac_uaddr); -+ if (copy->ac_uaddr == NULL) -+ goto err; -+ } -+ -+ if (addr->ac_taddr == NULL) -+ return (copy); -+ -+ copy->ac_taddr = calloc(1, sizeof(*addr->ac_taddr)); -+ if (copy->ac_taddr == NULL) -+ goto err; -+ -+ memcpy(copy->ac_taddr, addr->ac_taddr, sizeof(*addr->ac_taddr)); -+ copy->ac_taddr->buf = malloc(addr->ac_taddr->len); -+ if (copy->ac_taddr->buf == NULL) -+ goto err; -+ -+ memcpy(copy->ac_taddr->buf, addr->ac_taddr->buf, addr->ac_taddr->len); -+ return (copy); -+ -+err: -+ destroy_addr(copy); -+ return (NULL); -+} -+ - /* - * This routine adjusts the timeout used for calls to the remote rpcbind. - * Also, this routine can be used to set the use of portmapper version 2 -@@ -125,17 +201,18 @@ __rpc_control(request, info) - } - - /* -- * It might seem that a reader/writer lock would be more reasonable here. -- * However because getclnthandle(), the only user of the cache functions, -- * may do a delete_cache() operation if a check_cache() fails to return an -- * address useful to clnt_tli_create(), we may as well use a mutex. -- */ --/* -- * As it turns out, if the cache lock is *not* a reader/writer lock, we will -- * block all clnt_create's if we are trying to connect to a host that's down, -- * since the lock will be held all during that time. -+ * Protect against concurrent access to the address cache and modifications -+ * (esp. deletions) of cache entries. -+ * -+ * Previously a bidirectional R/W lock was used. However, R/W locking is -+ * dangerous as it allows concurrent modification (e.g. deletion with write -+ * lock) at the same time as the deleted element is accessed via check_cache() -+ * and a read lock). We absolutely need a single mutex for all access to -+ * prevent cache corruption. If the mutexing is restricted to only the -+ * relevant code sections, deadlocking should be avoided even with recursed -+ * client creation. - */ --extern rwlock_t rpcbaddr_cache_lock; -+extern pthread_mutex_t rpcbaddr_cache_lock; - - /* - * The routines check_cache(), add_cache(), delete_cache() manage the -@@ -143,49 +220,52 @@ extern rwlock_t rpcbaddr_cache_lock; - */ - - static struct address_cache * --check_cache(host, netid) -- const char *host, *netid; -+copy_of_cached(host, netid) -+ const char *host; -+ char *netid; - { -- struct address_cache *cptr; -- -- /* READ LOCK HELD ON ENTRY: rpcbaddr_cache_lock */ -+ struct address_cache *cptr, *copy = NULL; - -+ mutex_lock(&rpcbaddr_cache_lock); - for (cptr = front; cptr != NULL; cptr = cptr->ac_next) { - if (!strcmp(cptr->ac_host, host) && - !strcmp(cptr->ac_netid, netid)) { - LIBTIRPC_DEBUG(3, ("check_cache: Found cache entry for %s: %s\n", - host, netid)); -- return (cptr); -+ copy = copy_addr(cptr); -+ break; - } - } -- return ((struct address_cache *) NULL); -+ mutex_unlock(&rpcbaddr_cache_lock); -+ return copy; - } - - static void - delete_cache(addr) - struct netbuf *addr; - { -- struct address_cache *cptr, *prevptr = NULL; -+ struct address_cache *cptr = NULL, *prevptr = NULL; -+ -+ /* LOCK HELD ON ENTRY: rpcbaddr_cache_lock */ -+ mutex_lock(&rpcbaddr_cache_lock); - -- /* WRITE LOCK HELD ON ENTRY: rpcbaddr_cache_lock */ - for (cptr = front; cptr != NULL; cptr = cptr->ac_next) { - if (!memcmp(cptr->ac_taddr->buf, addr->buf, addr->len)) { -- free(cptr->ac_host); -- free(cptr->ac_netid); -- free(cptr->ac_taddr->buf); -- free(cptr->ac_taddr); -+ /* Unlink from cache. We'll destroy it after releasing the mutex. */ - if (cptr->ac_uaddr) - free(cptr->ac_uaddr); - if (prevptr) - prevptr->ac_next = cptr->ac_next; - else - front = cptr->ac_next; -- free(cptr); - cachesize--; - break; - } - prevptr = cptr; - } -+ -+ mutex_unlock(&rpcbaddr_cache_lock); -+ destroy_addr(cptr); - } - - static void -@@ -217,7 +297,7 @@ add_cache(host, netid, taddr, uaddr) - - /* VARIABLES PROTECTED BY rpcbaddr_cache_lock: cptr */ - -- rwlock_wrlock(&rpcbaddr_cache_lock); -+ mutex_lock(&rpcbaddr_cache_lock); - if (cachesize < CACHESIZE) { - ad_cache->ac_next = front; - front = ad_cache; -@@ -250,7 +330,7 @@ add_cache(host, netid, taddr, uaddr) - } - free(cptr); - } -- rwlock_unlock(&rpcbaddr_cache_lock); -+ mutex_unlock(&rpcbaddr_cache_lock); - return; - - out_free: -@@ -261,6 +341,7 @@ out_free: - free(ad_cache); - } - -+ - /* - * This routine will return a client handle that is connected to the - * rpcbind. If targaddr is non-NULL, the "universal address" of the -@@ -275,11 +356,9 @@ getclnthandle(host, nconf, targaddr) - char **targaddr; - { - CLIENT *client; -- struct netbuf *addr, taddr; -- struct netbuf addr_to_delete; -+ struct netbuf taddr; - struct __rpc_sockinfo si; - struct addrinfo hints, *res, *tres; -- struct address_cache *ad_cache; - char *tmpaddr; - - if (nconf == NULL) { -@@ -294,47 +373,35 @@ getclnthandle(host, nconf, targaddr) - return NULL; - } - --/* VARIABLES PROTECTED BY rpcbaddr_cache_lock: ad_cache */ -+ - - /* Get the address of the rpcbind. Check cache first */ - client = NULL; - if (targaddr) - *targaddr = NULL; -- 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) { -- addr = ad_cache->ac_taddr; -- client = clnt_tli_create(RPC_ANYFD, nconf, addr, -- (rpcprog_t)RPCBPROG, (rpcvers_t)RPCBVERS4, 0, 0); -- if (client != NULL) { -- if (targaddr && ad_cache->ac_uaddr) -- *targaddr = strdup(ad_cache->ac_uaddr); -- rwlock_unlock(&rpcbaddr_cache_lock); -- return (client); -- } -- addr_to_delete.len = addr->len; -- addr_to_delete.buf = (char *)malloc(addr->len); -- if (addr_to_delete.buf == NULL) { -- addr_to_delete.len = 0; -- } else { -- memcpy(addr_to_delete.buf, addr->buf, addr->len); -+ -+ if (host != NULL) { -+ struct address_cache *ad_cache; -+ -+ /* Get an MT-safe copy of the cached address (if any) */ -+ ad_cache = copy_of_cached(host, nconf->nc_netid); -+ if (ad_cache != NULL) { -+ client = clnt_tli_create(RPC_ANYFD, nconf, ad_cache->ac_taddr, -+ (rpcprog_t)RPCBPROG, (rpcvers_t)RPCBVERS4, 0, 0); -+ if (client != NULL) { -+ if (targaddr && ad_cache->ac_uaddr) { -+ *targaddr = ad_cache->ac_uaddr; -+ ad_cache->ac_uaddr = NULL; /* De-reference before destruction */ -+ } -+ destroy_addr(ad_cache); -+ return (client); -+ } -+ -+ delete_cache(ad_cache->ac_taddr); -+ destroy_addr(ad_cache); - } - } -- rwlock_unlock(&rpcbaddr_cache_lock); -- if (addr_to_delete.len != 0) { -- /* -- * Assume this may be due to cache data being -- * outdated -- */ -- rwlock_wrlock(&rpcbaddr_cache_lock); -- delete_cache(&addr_to_delete); -- rwlock_unlock(&rpcbaddr_cache_lock); -- free(addr_to_delete.buf); -- } -+ - if (!__rpc_nconf2sockinfo(nconf, &si)) { - rpc_createerr.cf_stat = RPC_UNKNOWNPROTO; - assert(client == NULL); -diff --git a/tirpc/reentrant.h b/tirpc/reentrant.h -index 5f5c96e..5bb581a 100644 ---- a/tirpc/reentrant.h -+++ b/tirpc/reentrant.h -@@ -57,6 +57,7 @@ - #define mutex_unlock(m) pthread_mutex_unlock(m) - - #define cond_init(c, a, p) pthread_cond_init(c, a) -+#define cond_destroy(c) pthread_cond_destroy(c) - #define cond_signal(m) pthread_cond_signal(m) - #define cond_broadcast(m) pthread_cond_broadcast(m) - #define cond_wait(c, m) pthread_cond_wait(c, m) diff --git a/libtirpc-1.1.4-null-ptrs-not-reused-fixed.patch b/libtirpc-1.1.4-null-ptrs-not-reused-fixed.patch deleted file mode 100644 index 80b5a2c..0000000 --- a/libtirpc-1.1.4-null-ptrs-not-reused-fixed.patch +++ /dev/null @@ -1,23 +0,0 @@ -commit 6951a9c3139c9c7dbb0bdae70737996011fc7a37 -Author: Herb Wartens -Date: Mon Mar 18 11:07:15 2024 -0400 - - rpcb_clnt.c: memory leak in destroy_addr - - Piece was dropped from original fix. - - Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=2225226 - Signed-off-by: Steve Dickson - -diff --git a/src/rpcb_clnt.c b/src/rpcb_clnt.c -index 68fe69a..d909efc 100644 ---- a/src/rpcb_clnt.c -+++ b/src/rpcb_clnt.c -@@ -121,6 +121,7 @@ destroy_addr(addr) - free(addr->ac_taddr->buf); - addr->ac_taddr->buf = NULL; - } -+ free(addr->ac_taddr); - addr->ac_taddr = NULL; - } - free(addr); diff --git a/libtirpc-1.1.4-null-ptrs-not-reused.patch b/libtirpc-1.1.4-null-ptrs-not-reused.patch deleted file mode 100644 index f2fc9f2..0000000 --- a/libtirpc-1.1.4-null-ptrs-not-reused.patch +++ /dev/null @@ -1,48 +0,0 @@ -commit 89c63bdfd79b1c94384daaaa03a9e3582540f843 -Author: Herb Wartens -Date: Tue Aug 1 10:21:42 2023 -0400 - - rpcb_clnt.c: memory leak in destroy_addr - - Null pointers so they are not used again - - Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=2225226 - Signed-off-by: Steve Dickson - -diff --git a/src/rpcb_clnt.c b/src/rpcb_clnt.c -index d178d86..c0a9e12 100644 ---- a/src/rpcb_clnt.c -+++ b/src/rpcb_clnt.c -@@ -104,17 +104,27 @@ destroy_addr(addr) - { - if (addr == NULL) - return; -- if(addr->ac_host != NULL) -+ if (addr->ac_host != NULL) { - free(addr->ac_host); -- if(addr->ac_netid != NULL) -+ addr->ac_host = NULL; -+ } -+ if (addr->ac_netid != NULL) { - free(addr->ac_netid); -- if(addr->ac_uaddr != NULL) -+ addr->ac_netid = NULL; -+ } -+ if (addr->ac_uaddr != NULL) { - free(addr->ac_uaddr); -- if(addr->ac_taddr != NULL) { -- if(addr->ac_taddr->buf != NULL) -+ addr->ac_uaddr = NULL; -+ } -+ if (addr->ac_taddr != NULL) { -+ if(addr->ac_taddr->buf != NULL) { - free(addr->ac_taddr->buf); -+ addr->ac_taddr->buf = NULL; -+ } -+ addr->ac_taddr = NULL; - } - free(addr); -+ addr = NULL; - } - - /* diff --git a/libtirpc-1.1.4-v2proto-mech.patch b/libtirpc-1.1.4-v2proto-mech.patch deleted file mode 100644 index 024cf86..0000000 --- a/libtirpc-1.1.4-v2proto-mech.patch +++ /dev/null @@ -1,88 +0,0 @@ -diff -up libtirpc-1.1.4/man/rpcbind.3t.orig libtirpc-1.1.4/man/rpcbind.3t ---- libtirpc-1.1.4/man/rpcbind.3t.orig 2018-08-27 10:06:49.000000000 -0400 -+++ libtirpc-1.1.4/man/rpcbind.3t 2022-08-02 11:21:30.134642780 -0400 -@@ -187,6 +187,8 @@ in - .El - .Sh AVAILABILITY - These functions are part of libtirpc. -+.Sh ENVIRONMENT -+If RPCB_V2FIRST is defined, rpcbind protocol version tryout algorithm changes from v4,v2,v3 to v2,v4,v3. - .Sh SEE ALSO - .Xr rpc_clnt_calls 3 , - .Xr rpc_svc_calls 3 , -diff -up libtirpc-1.1.4/src/rpcb_clnt.c.orig libtirpc-1.1.4/src/rpcb_clnt.c ---- libtirpc-1.1.4/src/rpcb_clnt.c.orig 2022-08-02 11:20:42.795833195 -0400 -+++ libtirpc-1.1.4/src/rpcb_clnt.c 2022-08-02 11:21:30.135642797 -0400 -@@ -818,7 +818,8 @@ error: - * The algorithm used: If the transports is TCP or UDP, it first tries - * version 4 (srv4), then 3 and then fall back to version 2 (portmap). - * With this algorithm, we get performance as well as a plan for -- * obsoleting version 2. -+ * obsoleting version 2. This behaviour is reverted to old algorithm -+ * if RPCB_V2FIRST environment var is defined - * - * For all other transports, the algorithm remains as 4 and then 3. - * -@@ -839,6 +840,10 @@ __rpcb_findaddr_timed(program, version, - #ifdef NOTUSED - static bool_t check_rpcbind = TRUE; - #endif -+ -+#ifdef PORTMAP -+ static bool_t portmap_first = FALSE; -+#endif - CLIENT *client = NULL; - RPCB parms; - enum clnt_stat clnt_st; -@@ -895,8 +900,18 @@ __rpcb_findaddr_timed(program, version, - parms.r_addr = (char *) &nullstring[0]; - } - -- /* First try from start_vers(4) and then version 3 (RPCBVERS) */ -+ /* First try from start_vers(4) and then version 3 (RPCBVERS), except -+ * if env. var RPCB_V2FIRST is defined */ -+ -+#ifdef PORTMAP -+ if (getenv(V2FIRST)) { -+ portmap_first = TRUE; -+ LIBTIRPC_DEBUG(3, ("__rpcb_findaddr_timed: trying v2-port first\n")); -+ goto portmap; -+ } -+#endif - -+rpcbind: - CLNT_CONTROL(client, CLSET_RETRY_TIMEOUT, (char *) &rpcbrmttime); - for (vers = start_vers; vers >= RPCBVERS; vers--) { - /* Set the version */ -@@ -944,10 +959,17 @@ __rpcb_findaddr_timed(program, version, - } - - #ifdef PORTMAP /* Try version 2 for TCP or UDP */ -+ if (portmap_first) -+ goto error; /* we tried all versions if reached here */ -+portmap: - if (strcmp(nconf->nc_protofmly, NC_INET) == 0) { - address = __try_protocol_version_2(program, version, nconf, host, tp); -- if (address == NULL) -- goto error; -+ if (address == NULL) { -+ if (portmap_first) -+ goto rpcbind; -+ else -+ goto error; -+ } - } - #endif /* PORTMAP */ - -diff -up libtirpc-1.1.4/tirpc/rpc/pmap_prot.h.orig libtirpc-1.1.4/tirpc/rpc/pmap_prot.h ---- libtirpc-1.1.4/tirpc/rpc/pmap_prot.h.orig 2018-08-27 10:06:49.000000000 -0400 -+++ libtirpc-1.1.4/tirpc/rpc/pmap_prot.h 2022-08-02 11:21:30.135642797 -0400 -@@ -84,6 +84,8 @@ - #define PMAPPROC_DUMP ((u_long)4) - #define PMAPPROC_CALLIT ((u_long)5) - -+#define V2FIRST "RPCB_V2FIRST" -+ - struct pmap { - long unsigned pm_prog; - long unsigned pm_vers; diff --git a/libtirpc.spec b/libtirpc.spec index c7ce28c..fe43e16 100644 --- a/libtirpc.spec +++ b/libtirpc.spec @@ -1,62 +1,17 @@ %define _root_libdir /%{_lib} Name: libtirpc -Version: 1.1.4 -Release: 12%{?dist} +Version: 1.3.5 +Release: 1%{?dist} Summary: Transport Independent RPC Library -Group: System Environment/Libraries -License: SISSL and BSD +License: SISSL AND BSD-3-Clause URL: http://git.linux-nfs.org/?p=steved/libtirpc.git;a=summary Source0: http://downloads.sourceforge.net/libtirpc/libtirpc-%{version}.tar.bz2 -# -# RHEL 8.0 -# -# bz 1602598 -Patch001: libtirpc-1.1.4-covscan.patch -# bz 1631614 -Patch002: libtirpc-1.1.4-dup_ncp-bad-free.patch - -# -# RHEL 8.1 -# -# bz 1641875 -Patch003: libtirpc-1.1.4-fix-EOF-non-block.patch - -# -# RHEL 8.5 -# -# bz 1854147 -Patch004: libtirpc-1.1.4-blacklist.patch -# bz 1934866 -Patch005: libtirpc-1.1.4-disallow-auth_refresh.patch - -# -# RHEL 8.6 -# -# bz 1940341 -Patch006: libtirpc-1.1.4-dos-fix.patch - -# -# RHEL 8.7 -# -# bz 2042196 -Patch007: libtirpc-1.1.4-dgcall-free.patch -# bz 2107650 -Patch008: libtirpc-1.1.4-v2proto-mech.patch -# bz 2112116 -Patch009: libtirpc-1.1.4-multithr-cleanup.patch - -# -# RHEL 8.10 -# -Patch010: libtirpc-1.1.4-null-ptrs-not-reused.patch -Patch011: libtirpc-1.1.4-double-free.patch -Patch012: libtirpc-1.1.4-null-ptrs-not-reused-fixed.patch -Patch013: libtirpc-1.1.4-ip_local_reserved_ports.patch - BuildRequires: automake, autoconf, libtool, pkgconfig BuildRequires: krb5-devel +BuildRequires: gcc +BuildRequires: make %description This package contains SunLib's implementation of transport-independent @@ -72,9 +27,8 @@ by almost 70 vendors on all major operating systems. TS-RPC source code %package devel Summary: Development files for the libtirpc library -Group: Development/Libraries Requires: %{name}%{?_isa} = %{version}-%{release} -Requires: pkgconfig man-db +Requires: pkgconfig %description devel This package includes header files and libraries necessary for @@ -106,30 +60,14 @@ rm -f %{buildroot}%{_root_libdir}/*.{a,la} # Creat the man diretory mv %{buildroot}%{_mandir}/man3 %{buildroot}%{_mandir}/man3t -%post -p /sbin/ldconfig - -%postun -p /sbin/ldconfig - -%post devel -# Register the new man section -#if [ "$1" -eq 1 ]; then -# makewhatis -s 3t -#fi - -%postun devel -# Remove the existance of the man section -#makewhatis -s 3t - %files -%defattr(-,root,root) %doc AUTHORS ChangeLog NEWS README %{_root_libdir}/libtirpc.so.* %config(noreplace)%{_sysconfdir}/netconfig %config(noreplace)%{_sysconfdir}/bindresvport.blacklist %files devel -%defattr(0644,root,root,755) %{!?_licensedir:%global license %%doc} %license COPYING %dir %{_includedir}/tirpc @@ -174,49 +112,144 @@ mv %{buildroot}%{_mandir}/man3 %{buildroot}%{_mandir}/man3t %{_mandir}/*/* %changelog -* Fri Apr 26 2024 Steve Dickson 1.1.4-12 -- binddynport.c honor ip_local_reserved_ports (RHEL-27005) +* Tue Oct 29 2024 Troy Dawson - 1.3.5-1 +- Bump release for October 2024 mass rebuild: + Resolves: RHEL-64018 -* Tue Mar 19 2024 Steve Dickson 1.1.4-11 -- rpcb_clnt.c (fixed): Eliminate double frees in delete_cache() (RHEL-11293) +* Sat Jul 27 2024 Steve Dickson - 1.3.5-0 +- Updated to the latest upstream release: libtirpc-1_3_5 (RHEL-50728) -* Tue Mar 5 2024 Steve Dickson 1.1.4-10 -- rpcb_clnt.c: Eliminate double frees in delete_cache() (RHEL-11293) +* Mon Jun 24 2024 Troy Dawson - 1.3.4-1.rc2.3 +- Bump release for June 2024 mass rebuild -* Mon Mar 4 2024 Steve Dickson 1.1.4-9 -- Null pointers so they are not used again (RHEL-11370) +* Thu Jan 25 2024 Fedora Release Engineering - 1.3.4-1.rc2.2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild -* Wed Aug 3 2022 Steve Dickson 1.1.4-8 -- rpcb_clnt.c add mechanism to try v2 protocol first (bz 2107650) -- Multithreaded cleanup (bz 2112116) +* Sun Jan 21 2024 Fedora Release Engineering - 1.3.4-1.rc2.1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild -* Tue May 31 2022 Steve Dickson 1.1.4-7 -- clnt_dg_call: Fix use-after-free accessing the error number (bz 2042196) +* Fri Jan 5 2024 Steve Dickson - 1.3.4-1.rc2 +- Updated to the latest upstream RC release: libtirpc-1-3-5-rc2 -* Thu Dec 2 2021 Steve Dickson 1.1.4-6 -- Fix DoS vulnerability in libtirpc (bz 1940341) +* Wed Jan 3 2024 Steve Dickson - 1.3.4-1.rc1 +- Updated to the latest upstream RC release: libtirpc-1-3-5-rc1 -* Sat Apr 17 2021 Steve Dickson 1.1.4-5 -- blacklist: Add a few more well known ports (bz 1854147) -- Disallow calling auth_refresh from clnt_call with RPCSEC_GSS (bz 1934866) +* Mon Oct 16 2023 Pavel Reichl - 1.3.4-1 +- Convert License tag to SPDX format -* Wed Jul 24 2019 Steve Dickson 1.1.4-4 -- Enable gating using reverse dependency testing of nfs-utils (bz 1681965) -- Updated the URL (bz 1638671) -- Fix EOF detection on non-blocking socket (bz 1641875) +* Sat Oct 7 2023 Steve Dickson - 1.3.4-0 +- Updated to latest upstream release: libtirpc-1-3-4 -* Sat Oct 6 2018 Steve Dickson 1.1.4-3 -- Fixed bad free in dup_ncp() (bz 1631614) +* Mon Aug 7 2023 Steve Dickson - 1.3.3-1.rc2 +- Updated to the latest upstream RC release: libtirpc-1-3-4-rc2 -* Fri Sep 14 2018 Steve Dickson 1.1.4-2 -- Removed a false positive from the covscan (bz 1602598) +* Thu Jul 20 2023 Fedora Release Engineering - 1.3.3-1.rc1.1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild -* Tue Sep 11 2018 Steve Dickson 1.1.4-1 -- Fixed issues found by covscan (bz 1602598) +* Fri Apr 21 2023 Steve Dickson - 1.3.3-1.rc1 +- Updated to the latest upstream RC release: libtirpc-1-3-4-rc1 (bz 1725329) -* Fri Sep 7 2018 Steve Dickson 1.1.4-0 +* Thu Jan 19 2023 Fedora Release Engineering - 1.3.3-1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild + +* Sun Aug 7 2022 Steve Dickson - 1.3.3-0 +- Updated to latest upstream release: libtirpc-1-3-3 (bz 2116171) + +* Mon Aug 1 2022 Steve Dickson - 1.3.2-1.rc5 +- Updated to the latest upstream RC release: libtirpc-1-3-3-rc5 + +* Thu Jul 28 2022 Steve Dickson - 1.3.2-1.rc4 +- Updated to the latest upstream RC release: libtirpc-1-3-3-rc4 + +* Thu Jul 21 2022 Fedora Release Engineering - 1.3.2-1.rc1.2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild + +* Thu Jan 20 2022 Fedora Release Engineering - 1.3.2-1.rc1.1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild + +* Tue Sep 7 2021 Steve Dickson - 1.3.2-1.rc1 +- Updated to the latest upstream RC release: libtirpc-1-3-3-rc1 + +* Thu Jul 22 2021 Fedora Release Engineering - 1.3.2-1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild + +* Tue May 18 2021 Steve Dickson - 1.3.2-0 +- Updated to latest upstream release: libtirpc-1-3-2 (bz 1959147) + +* Wed Apr 7 2021 Steve Dickson - 1.3.1.rc2 +- Updated to the latest upstream RC release: libtirpc-1-3-2-rc2 + +* Tue Jan 26 2021 Fedora Release Engineering - 1.3.1-1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild + +* Thu Dec 03 2020 Steve Dickson - 1.3.1 +- Updated to latest upstream release: libtirpc-1-3-1 (bz 1903615) + +* Tue Aug 04 2020 Steve Dickson 1.2.6-1.rc4 +- Updated to the latest upstream RC release: libtirpc-1-2-7-rc4 + +* Tue Aug 04 2020 Tom Stellard - 1.2.6-2 +- Add BuildRequires: gcc +- https://docs.fedoraproject.org/en-US/packaging-guidelines/C_and_C++/#_packaging + +* Tue Jul 28 2020 Fedora Release Engineering - 1.2.6-1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild + +* Tue Apr 14 2020 Steve Dickson 1.2.6-0 +- Updated to the latest upstream release: libtirpc-1-2-6 (bz 1822751) + +* Tue Feb 18 2020 Steve Dickson 1.2.5-1.rc2 +- Updated to the latest upstream RC release: libtirpc-1-2-6-rc2 (bz 1799601) + +* Wed Jan 29 2020 Fedora Release Engineering - 1.2.5-1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild + +* Fri Dec 20 2019 Steve Dickson 1.2.5-0 + Updated to latest upstream release: libtirpc-1-2-5 (bz 1785684) + +* Fri Nov 01 2019 Petr Pisar - 1.1.4-3.rc3 +- Remove a useless dependency on man-db from libtirpc-devel package + (bug #1496422) + +* Thu Sep 05 2019 Steve Dickson 1.1.4-2.rc3 +- Updated to latest upstream RC release: libtirpc-1-1-5-rc3 + +* Thu Jul 25 2019 Fedora Release Engineering - 1.1.4-2.rc2.2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild + +* Fri Feb 01 2019 Fedora Release Engineering - 1.1.4-2.rc2.1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild + +* Thu Nov 8 2018 Steve Dickson 1.1.4-2.rc2 +- Updated to latest upstream RC release: libtirpc-1-1-5-rc2 + +* Tue Nov 6 2018 Steve Dickson 1.1.4-2.rc1 +- Remove ldconfig scriptlet (bz 1644103) + +* Thu Sep 13 2018 Steve Dickson 1.1.4-1.rc1 +- Removed a false positive from the covscan + +* Tue Sep 11 2018 Steve Dickson 1.1.4-0.rc1 +- Updated to latest upstream RC releasse (bz 1627832) + +* Mon Aug 27 2018 Steve Dickson 1.1.4 - Updated to latest upstream release: libtirpc-1-1-4 (bz 1585558) +* Tue Jul 31 2018 Florian Weimer - 1.0.3-4.rc2 +- Rebuild with fixed binutils + +* Sun Jul 29 2018 Steve Dickson 1.0.3-3.rc2 +- Update the libtirpc-1.0.4-rc2.patch to include big endian fixes (bz 1609208) + +* Fri Jul 20 2018 Steve Dickson 1.0.3-2.rc2 +- Updated to latest upstream RC release: libtirpc-1-0-4-rc2 + +* Fri Jul 13 2018 Fedora Release Engineering - 1.0.3-2.rc1.1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild + +* Tue Jul 10 2018 Steve Dickson 1.0.3-2.rc1 +- Updated the URL (bz 1599795) + * Wed Apr 18 2018 Steve Dickson 1.0.3-1.rc1 - Updated to latest upstream RC release: libtirpc-1-0-4-rc1 diff --git a/sources b/sources index e04296e..2319732 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (libtirpc-1.1.4.tar.bz2) = 392f391f9fc1bd68d81dc44e4058831a64b32790b5c8c37338b0ab416fad2ae4d16389e632596734dba09780347918cc65c6f134e0c1afd09e81ec250785ed23 +SHA512 (libtirpc-1.3.5.tar.bz2) = c80a953671c5692294efe7425e41c7f12bd4c430f473f9ea71883168cb4a69111f0018122bd0e7982e18f4576e45d4977ce0790743382faae006c446813d2a4f