This is a combination of three patches: 1) Taken from https://salsa.debian.org/debian/libtirpc/-/raw/master/debian/patches/03-kfreebsd.diff Description: Fix build on non Linux architectures Author: Andreas Beckmann Last-Update: 2025-03-17 2) Taken from https://salsa.debian.org/debian/libtirpc/-/raw/master/debian/patches/05-hurd-port.diff Description: Get source building on Hurd - Look for before using it. - Define MAXHOSTNAMELEN to 64 if missing. - Bind sockets on Hurd like on Linux. Author: Petter Reinholdtsen Last-Update: 2025-03-17 3) Taken from https://salsa.debian.org/debian/libtirpc/-/raw/master/debian/patches/06-hurd-client-port.diff Description: Fix client code for hurd, avoiding malloc overflow When trying to setup a inet connection, it happens the following: - in libtirp, src/clnt_vc.c, clnt_vc_create gets called - when trying to allocate vc_fd_locks, __rpc_dtbsize() is used as size for that array of fd locks - __rpc_dtbsize(), in src/rpc_generic.c, queries using rlimit the maximum (rlim_max) number of file descriptors (RLIMIT_NOFILE): - on Linux, the default is { rlim_cur = 1024, rlim_max = 4096 } - on kFreeBSD, the default is { rlim_cur = 1024, rlim_max = 1024 } - on Hurd, the default is { rlim_cur = 1024, rlim_max = RLIM_INFINITY } meaning that on Hurd the memory allocation fails (as __rpc_dtbsize() * sizeof(int) overflows and is negative) Change libtiprc so __rpc_dtbsize falls back on rlim_cur if rlim_max is unlimited. This patch fixes the client connection using inet sockets; local unix sockets are not working, for two reasons so far: - getpeername on them gives EOPNOTSUPP - SO_REUSEADDR is not implemented for them Author: Pino Toscano Bug-Debian: http://bugs.debian.org/739674 Last-Update: 2020-03-03 --- a/src/svc_dg.c +++ b/src/svc_dg.c @@ -650,6 +650,7 @@ void svc_dg_enable_pktinfo(int fd, const struct __rpc_sockinfo *si) { +#ifdef __linux__ int val = 1; switch (si->si_af) { @@ -662,6 +663,7 @@ break; #endif } +#endif } /* @@ -672,6 +674,7 @@ int svc_dg_valid_pktinfo(struct msghdr *msg) { +#ifdef __linux__ struct cmsghdr *cmsg; if (!msg->msg_name) @@ -718,4 +721,7 @@ } return 1; +#else + return 0; +#endif } --- a/src/clnt_vc.c +++ b/src/clnt_vc.c @@ -76,10 +76,12 @@ #define MCALL_MSG_SIZE 24 #define CMGROUP_MAX 16 -#define SCM_CREDS 0x03 /* process creds (struct cmsgcred) */ #undef rpc_createerr /* make it clear it is a thread safe variable */ +#ifndef SCM_CREDS +#define SCM_CREDS 0x03 /* process creds (struct cmsgcred) */ + /* * Credentials structure, used to verify the identity of a peer * process that has sent us a message. This is allocated by the @@ -95,6 +97,7 @@ short cmcred_ngroups; /* number or groups */ gid_t cmcred_groups[CMGROUP_MAX]; /* groups */ }; +#endif struct cmessage { struct cmsghdr cmsg; --- a/src/getpeereid.c +++ b/src/getpeereid.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -40,12 +41,22 @@ int getpeereid(int s, uid_t *euid, gid_t *egid) { +#ifdef XUCRED_VERSION + struct xucred uc; +#define uid cr_uid +#define gid cr_gid +#else struct ucred uc; +#endif socklen_t uclen; int error; uclen = sizeof(uc); +#ifdef XUCRED_VERSION + error = getsockopt(s, 0, LOCAL_PEERCRED, &uc, &uclen); +#else error = getsockopt(s, SOL_SOCKET, SO_PEERCRED, &uc, &uclen); /* SCM_CREDENTIALS */ +#endif if (error != 0) return (error); // if (uc.cr_version != XUCRED_VERSION) --- a/tirpc/reentrant.h +++ b/tirpc/reentrant.h @@ -36,6 +36,6 @@ * These definitions are only guaranteed to be valid on Linux. */ -#if defined(__linux__) || defined(__APPLE__) +#if defined(__linux__) || defined(__GLIBC__) #include --- a/src/auth_unix.c +++ b/src/auth_unix.c @@ -56,6 +56,11 @@ #include #include +/* Workaround for Hurd */ +#ifndef MAXHOSTNAMELEN +# define MAXHOSTNAMELEN 64 +#endif + /* auth_unix.c */ static void authunix_nextverf (AUTH *); static bool_t authunix_marshal (AUTH *, XDR *); --- a/src/bindresvport.c +++ b/src/bindresvport.c @@ -64,7 +64,7 @@ return bindresvport_sa(sd, (struct sockaddr *)sin); } -#ifdef __linux__ +#if defined(__linux__) || defined(__GNU__) #define STARTPORT 600 #define LOWPORT 512 --- a/src/getpeereid.c +++ b/src/getpeereid.c @@ -28,10 +28,14 @@ #include "config.h" #endif +#include "config.h" + #include #include #include -#include +#ifdef HAVE_SYS_USER_H +# include +#endif /* HAVE_SYS_USER_H */ #include #include @@ -41,6 +45,9 @@ int getpeereid(int s, uid_t *euid, gid_t *egid) { +#ifndef HAVE_SYS_USER_H + return(-1); +#else #ifdef XUCRED_VERSION struct xucred uc; #define uid cr_uid @@ -64,6 +71,7 @@ *euid = uc.uid; *egid = uc.gid; return (0); +#endif /* HAVE_SYS_USER_H */ } #endif --- a/configure.ac +++ b/configure.ac @@ -200,7 +200,7 @@ AC_CHECK_HEADERS([arpa/inet.h fcntl.h libintl.h limits.h locale.h netdb.h netinet/in.h stddef.h stdint.h stdlib.h string.h sys/ioctl.h sys/param.h sys/socket.h sys/time.h syslog.h unistd.h features.h -gssapi/gssapi_ext.h endian.h machine/endian.h]) +gssapi/gssapi_ext.h endian.h machine/endian.h sys/user.h]) AX_PTHREAD AC_CHECK_FUNCS([getpeereid getrpcbyname getrpcbynumber setrpcent endrpcent getrpcent]) --- a/src/rpc_generic.c +++ b/src/rpc_generic.c @@ -107,12 +107,17 @@ { static int tbsize; struct rlimit rl; + rlim_t lim; if (tbsize) { return (tbsize); } if (getrlimit(RLIMIT_NOFILE, &rl) == 0) { - return (tbsize = (int)rl.rlim_cur); + lim = rl.rlim_max; + if (lim == RLIM_INFINITY) { + lim = rl.rlim_cur; + } + return (tbsize = (int)lim); } /* * Something wrong. I'll try to save face by returning a