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]

Reply via email to