Hello community, here is the log from the commit of package libtirpc for openSUSE:11.4 checked in at Tue Feb 22 17:35:14 CET 2011.
-------- --- old-versions/11.4/all/libtirpc/libtirpc.changes 2010-10-31 19:03:51.000000000 +0100 +++ 11.4/libtirpc/libtirpc.changes 2011-02-22 06:08:51.000000000 +0100 @@ -1,0 +2,6 @@ +Tue Feb 22 05:07:13 UTC 2011 - [email protected] + +- Use correct source address on replies [bnc#587934,bnc#587811] +- Prevent bindresvport from binding to blacklisted ports [bnc#579315] + +------------------------------------------------------------------- calling whatdependson for 11.4-i586 New: ---- libtirpc-bindresvport_blacklist.patch libtirpc-use-correct-source-addr-on-replies.patch ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ libtirpc.spec ++++++ --- /var/tmp/diff_new_pack.FcI9Sw/_old 2011-02-22 17:34:37.000000000 +0100 +++ /var/tmp/diff_new_pack.FcI9Sw/_new 2011-02-22 17:34:37.000000000 +0100 @@ -1,7 +1,7 @@ # -# spec file for package libtirpc (Version 0.2.1_git201005272057) +# spec file for package libtirpc # -# Copyright (c) 2010 SUSE LINUX Products GmbH, Nuernberg, Germany. +# Copyright (c) 2011 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 @@ -24,7 +24,7 @@ Group: System/Libraries AutoReqProv: on Version: 0.2.1_git201005272057 -Release: 4 +Release: 7.<RELEASE2> Summary: Transport Independent RPC Library Url: http://sourceforge.net/projects/libtirpc/ Source: %{name}-%{version}.tar.bz2 @@ -32,6 +32,8 @@ Patch22: libtirpc-rpc_broadcast_misformed_replies.patch Patch31: libtirpc-getpmaphandle.patch Patch32: libtirpc-pmap-setunset.patch +Patch33: libtirpc-use-correct-source-addr-on-replies.patch +Patch34: libtirpc-bindresvport_blacklist.patch BuildRoot: %{_tmppath}/%{name}-%{version}-build %define debug_package_requires libtirpc1 = %{version}-%{release} @@ -91,6 +93,8 @@ %patch22 -p1 %patch31 -p1 %patch32 -p1 +%patch33 -p1 +%patch34 -p1 %build mkdir m4 #bug ++++++ libtirpc-bindresvport_blacklist.patch ++++++ From: Olaf Kirch <[email protected]> Subject: make libtirpc honor /etc/bindresvport.blacklist Signed-off-by: Olaf Kirch <[email protected]> Index: libtirpc-0.1.9/src/bindresvport.c =================================================================== --- libtirpc-0.1.9.orig/src/bindresvport.c +++ libtirpc-0.1.9/src/bindresvport.c @@ -40,7 +40,10 @@ #include <netinet/in.h> +#include <stdio.h> +#include <ctype.h> #include <errno.h> +#include <stdlib.h> #include <string.h> #include <unistd.h> @@ -66,6 +69,80 @@ bindresvport(sd, sin) #define ENDPORT (IPPORT_RESERVED - 1) #define NPORTS (ENDPORT - STARTPORT + 1) +/* + * Read the file /etc/bindresvport.blacklist, so that we don't bind + * to these ports. + */ + +static int blacklist_read; +static int *list; +static int list_size = 0; + +static void +load_blacklist (void) +{ + FILE *fp; + char *buf = NULL; + size_t buflen = 0; + int size = 0, ptr = 0; + + blacklist_read = 1; + + fp = fopen ("/etc/bindresvport.blacklist", "r"); + if (NULL == fp) + return; + + while (!feof (fp)) + { + unsigned long port; + char *tmp, *cp; + ssize_t n = getline (&buf, &buflen, fp); + if (n < 1) + break; + + cp = buf; + tmp = strchr (cp, '#'); /* remove comments */ + if (tmp) + *tmp = '\0'; + while (isspace ((int)*cp)) /* remove spaces and tabs */ + ++cp; + if (*cp == '\0') /* ignore empty lines */ + continue; + if (cp[strlen (cp) - 1] == '\n') + cp[strlen (cp) - 1] = '\0'; + + port = strtoul (cp, &tmp, 0); + while (isspace(*tmp)) + ++tmp; + if (*tmp != '\0' || (port == ULONG_MAX && errno == ERANGE)) + continue; + + /* Don't bother with out-of-range ports */ + if (port < LOWPORT || port > ENDPORT) + continue; + + if (ptr >= size) + { + size += 10; + list = realloc (list, size * sizeof (int)); + if (list == NULL) + { + free (buf); + return; + } + } + + list[ptr++] = port; + } + + fclose (fp); + + if (buf) + free (buf); + + list_size = ptr; +} + int bindresvport_sa(sd, sa) int sd; @@ -85,6 +162,9 @@ bindresvport_sa(sd, sa) int endport = ENDPORT; int i; + if (!blacklist_read) + load_blacklist(); + if (sa == NULL) { salen = sizeof(myaddr); sa = (struct sockaddr *)&myaddr; @@ -125,12 +205,21 @@ bindresvport_sa(sd, sa) errno = EADDRINUSE; again: for (i = 0; i < nports; ++i) { - *portp = htons(port++); - if (port > endport) - port = startport; - res = bind(sd, sa, salen); + int j; + + /* Check if this port is not blacklisted. */ + for (j = 0; j < list_size; j++) + if (port == list[j]) + goto try_next_port; + + *portp = htons(port); + res = bind(sd, sa, salen); if (res >= 0 || errno != EADDRINUSE) break; + +try_next_port: + if (++port > endport) + port = startport; } if (i == nports && startport != LOWPORT) { startport = LOWPORT; ++++++ libtirpc-use-correct-source-addr-on-replies.patch ++++++ Patch by Olaf Kirch and Leonardo Chiquitto as attached with id 348693 at https://bugzilla.novell.com/show_bug.cgi?id=587934 diff --git a/src/svc_dg.c b/src/svc_dg.c index 7df470e..edf7d17 100644 --- a/src/svc_dg.c +++ b/src/svc_dg.c @@ -76,6 +76,8 @@ static bool_t svc_dg_control(SVCXPRT *, const u_int, void *); static int cache_get(SVCXPRT *, struct rpc_msg *, char **, size_t *); static void cache_set(SVCXPRT *, size_t); int svc_dg_enablecache(SVCXPRT *, u_int); +static void svc_dg_enable_pktinfo(int, const struct __rpc_sockinfo *); +static int svc_dg_valid_pktinfo(struct msghdr *); /* * Usage: @@ -142,6 +144,9 @@ svc_dg_create(fd, sendsize, recvsize) goto freedata; __rpc_set_netbuf(&xprt->xp_ltaddr, &ss, slen); + /* Enable reception of IP*_PKTINFO control msgs */ + svc_dg_enable_pktinfo(fd, &si); + xprt_register(xprt); return (xprt); freedata: @@ -171,19 +176,37 @@ svc_dg_recv(xprt, msg) XDR *xdrs = &(su->su_xdrs); char *reply; struct sockaddr_storage ss; + struct msghdr *mesgp; + struct iovec iov; socklen_t alen; size_t replylen; ssize_t rlen; again: - alen = sizeof (struct sockaddr_storage); - rlen = recvfrom(xprt->xp_fd, rpc_buffer(xprt), su->su_iosz, 0, - (struct sockaddr *)(void *)&ss, &alen); + iov.iov_base = rpc_buffer(xprt); + iov.iov_len = su->su_iosz; + mesgp = &su->su_msghdr; + memset(mesgp, 0, sizeof(*mesgp)); + mesgp->msg_iov = &iov; + mesgp->msg_iovlen = 1; + mesgp->msg_name = (struct sockaddr *)(void *) &ss; + mesgp->msg_namelen = sizeof (struct sockaddr_storage); + mesgp->msg_control = su->su_cmsg; + mesgp->msg_controllen = sizeof(su->su_cmsg); + + rlen = recvmsg(xprt->xp_fd, mesgp, 0); if (rlen == -1 && errno == EINTR) goto again; if (rlen == -1 || (rlen < (ssize_t)(4 * sizeof (u_int32_t)))) return (FALSE); - __rpc_set_netbuf(&xprt->xp_rtaddr, &ss, alen); + __rpc_set_netbuf(&xprt->xp_rtaddr, &ss, mesgp->msg_namelen); + + /* Check whether there's an IP_PKTINFO or IP6_PKTINFO control message. + * If yes, preserve it for svc_dg_reply; otherwise just zap an cmsgs */ + if (!svc_dg_valid_pktinfo(mesgp)) { + mesgp->msg_control = NULL; + mesgp->msg_controllen = 0; + } __xprt_set_raddr(xprt, &ss); xdrs->x_op = XDR_DECODE; @@ -194,8 +217,9 @@ again: su->su_xid = msg->rm_xid; if (su->su_cache != NULL) { if (cache_get(xprt, msg, &reply, &replylen)) { - (void)sendto(xprt->xp_fd, reply, replylen, 0, - (struct sockaddr *)(void *)&ss, alen); + iov.iov_base = reply; + iov.iov_len = replylen; + (void) sendmsg(xprt->xp_fd, mesgp, 0); return (FALSE); } } @@ -216,10 +240,18 @@ svc_dg_reply(xprt, msg) XDR_SETPOS(xdrs, 0); msg->rm_xid = su->su_xid; if (xdr_replymsg(xdrs, msg)) { - slen = XDR_GETPOS(xdrs); - if (sendto(xprt->xp_fd, rpc_buffer(xprt), slen, 0, - (struct sockaddr *)xprt->xp_rtaddr.buf, - (socklen_t)xprt->xp_rtaddr.len) == (ssize_t) slen) { + struct msghdr *msg = &su->su_msghdr; + struct iovec iov; + + iov.iov_base = rpc_buffer(xprt); + iov.iov_len = slen = XDR_GETPOS(xdrs); + msg->msg_iov = &iov; + msg->msg_iovlen = 1; + msg->msg_name = (struct sockaddr *)(void *) xprt->xp_rtaddr.buf; + msg->msg_namelen = xprt->xp_rtaddr.len; + /* cmsg already set in svc_dg_recv */ + + if (sendmsg(xprt->xp_fd, msg, 0) == (ssize_t) slen) { stat = TRUE; if (su->su_cache) cache_set(xprt, slen); @@ -583,3 +615,76 @@ cache_get(xprt, msg, replyp, replylenp) mutex_unlock(&dupreq_lock); return (0); } + +/* + * Enable reception of PKTINFO control messages + */ +void +svc_dg_enable_pktinfo(int fd, const struct __rpc_sockinfo *si) +{ + int val = 1; + + switch (si->si_af) { + case AF_INET: + (void) setsockopt(fd, SOL_IP, IP_PKTINFO, &val, sizeof(val)); + break; + + case AF_INET6: + (void) setsockopt(fd, SOL_IPV6, IPV6_PKTINFO, &val, sizeof(val)); + break; + } +} + +/* + * When given a control message received from the socket + * layer, check whether it contains valid PKTINFO data matching + * the address family of the peer address. + */ +int +svc_dg_valid_pktinfo(struct msghdr *msg) +{ + struct cmsghdr *cmsg; + + if (!msg->msg_name) + return 0; + + if (msg->msg_flags & MSG_CTRUNC) + return 0; + + cmsg = CMSG_FIRSTHDR(msg); + if (cmsg == NULL || CMSG_NXTHDR(msg, cmsg) != NULL) + return 0; + + switch (((struct sockaddr *) msg->msg_name)->sa_family) { + case AF_INET: + if (cmsg->cmsg_level != SOL_IP + || cmsg->cmsg_type != IP_PKTINFO + || cmsg->cmsg_len < CMSG_LEN(sizeof (struct in_pktinfo))) { + return 0; + } else { + struct in_pktinfo *pkti; + + pkti = (struct in_pktinfo *) CMSG_DATA (cmsg); + pkti->ipi_ifindex = 0; + } + break; + + case AF_INET6: + if (cmsg->cmsg_level != SOL_IPV6 + || cmsg->cmsg_type != IPV6_PKTINFO + || cmsg->cmsg_len < CMSG_LEN(sizeof (struct in6_pktinfo))) { + return 0; + } else { + struct in6_pktinfo *pkti; + + pkti = (struct in6_pktinfo *) CMSG_DATA (cmsg); + pkti->ipi6_ifindex = 0; + } + break; + + default: + return 0; + } + + return 1; +} diff --git a/tirpc/rpc/svc_dg.h b/tirpc/rpc/svc_dg.h index 67d2564..88e7df7 100644 --- a/tirpc/rpc/svc_dg.h +++ b/tirpc/rpc/svc_dg.h @@ -46,6 +46,9 @@ struct svc_dg_data { XDR su_xdrs; /* XDR handle */ char su_verfbody[MAX_AUTH_BYTES]; /* verifier body */ void *su_cache; /* cached data, NULL if none */ + + struct msghdr su_msghdr; /* msghdr received from clnt */ + unsigned char su_cmsg[64]; /* cmsghdr received from clnt */ }; #define __rpcb_get_dg_xidp(x) (&((struct svc_dg_data *)(x)->xp_p2)->su_xid) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Remember to have fun... -- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
