Accepting request 62427 from Base:System
Accepted submit request 62427 from user neilbrown OBS-URL: https://build.opensuse.org/request/show/62427 OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/libtirpc?expand=0&rev=19
This commit is contained in:
commit
bf0d2d0ccf
137
libtirpc-bindresvport_blacklist.patch
Normal file
137
libtirpc-bindresvport_blacklist.patch
Normal file
@ -0,0 +1,137 @@
|
||||
From: Olaf Kirch <okir@suse.de>
|
||||
Subject: make libtirpc honor /etc/bindresvport.blacklist
|
||||
|
||||
Signed-off-by: Olaf Kirch <okir@suse.de>
|
||||
|
||||
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;
|
195
libtirpc-use-correct-source-addr-on-replies.patch
Normal file
195
libtirpc-use-correct-source-addr-on-replies.patch
Normal file
@ -0,0 +1,195 @@
|
||||
|
||||
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)
|
@ -1,3 +1,9 @@
|
||||
-------------------------------------------------------------------
|
||||
Tue Feb 22 05:07:13 UTC 2011 - nfbrown@novell.com
|
||||
|
||||
- Use correct source address on replies [bnc#587934,bnc#587811]
|
||||
- Prevent bindresvport from binding to blacklisted ports [bnc#579315]
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Sun Oct 31 12:37:02 UTC 2010 - jengelh@medozas.de
|
||||
|
||||
|
@ -32,6 +32,8 @@ Patch21: libtirpc-clnt_broadcast_fix.patch
|
||||
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 @@ Authors:
|
||||
%patch22 -p1
|
||||
%patch31 -p1
|
||||
%patch32 -p1
|
||||
%patch33 -p1
|
||||
%patch34 -p1
|
||||
|
||||
%build
|
||||
mkdir m4 #bug
|
||||
|
Loading…
Reference in New Issue
Block a user