From 309840505122928323a015f18e93d7e9f216ae96 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Dec 04 2021 06:55:13 +0000 Subject: import libtirpc-1.1.4-6.el8 --- diff --git a/SOURCES/libtirpc-1.1.4-dos-fix.patch b/SOURCES/libtirpc-1.1.4-dos-fix.patch new file mode 100644 index 0000000..4b2c8eb --- /dev/null +++ b/SOURCES/libtirpc-1.1.4-dos-fix.patch @@ -0,0 +1,154 @@ +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/SPECS/libtirpc.spec b/SPECS/libtirpc.spec index 259fee5..ff7f46c 100644 --- a/SPECS/libtirpc.spec +++ b/SPECS/libtirpc.spec @@ -2,7 +2,7 @@ Name: libtirpc Version: 1.1.4 -Release: 5%{?dist} +Release: 6%{?dist} Summary: Transport Independent RPC Library Group: System Environment/Libraries License: SISSL and BSD @@ -31,6 +31,12 @@ 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 + BuildRequires: automake, autoconf, libtool, pkgconfig BuildRequires: krb5-devel @@ -150,6 +156,9 @@ mv %{buildroot}%{_mandir}/man3 %{buildroot}%{_mandir}/man3t %{_mandir}/*/* %changelog +* Thu Dec 2 2021 Steve Dickson 1.1.4-6 +- Fix DoS vulnerability in libtirpc (bz 1940341) + * 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)