Browse code

Fix CVE-2017-8779 in libtirpc, rpcbind.

Change-Id: I259781ef79eee1a5149a8dbc30f7f8537a3aeb80
Reviewed-on: http://photon-jenkins.eng.vmware.com:8082/2713
Tested-by: gerrit-photon <photon-checkins@vmware.com>
Reviewed-by: Xiaolin Li <xiaolinl@vmware.com>

Vinay Kulkarni authored on 2017/05/19 09:52:24
Showing 4 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,255 @@
0
+diff --git a/src/rpc_generic.c b/src/rpc_generic.c
1
+index 2f09a8f..589cbd5 100644
2
+--- a/src/rpc_generic.c
3
+@@ -615,6 +615,9 @@ __rpc_taddr2uaddr_af(int af, const struct netbuf *nbuf)
4
+ 
5
+ 	switch (af) {
6
+ 	case AF_INET:
7
++		if (nbuf->len < sizeof(*sin)) {
8
++			return NULL;
9
++		}
10
+ 		sin = nbuf->buf;
11
+ 		if (inet_ntop(af, &sin->sin_addr, namebuf, sizeof namebuf)
12
+ 		    == NULL)
13
+@@ -626,6 +629,9 @@ __rpc_taddr2uaddr_af(int af, const struct netbuf *nbuf)
14
+ 		break;
15
+ #ifdef INET6
16
+ 	case AF_INET6:
17
++		if (nbuf->len < sizeof(*sin6)) {
18
++			return NULL;
19
++		}
20
+ 		sin6 = nbuf->buf;
21
+ 		if (inet_ntop(af, &sin6->sin6_addr, namebuf6, sizeof namebuf6)
22
+ 		    == NULL)
23
+@@ -667,6 +673,8 @@ __rpc_uaddr2taddr_af(int af, const char *uaddr)
24
+ 
25
+ 	port = 0;
26
+ 	sin = NULL;
27
++	if (uaddr == NULL)
28
++		return NULL;
29
+ 	addrstr = strdup(uaddr);
30
+ 	if (addrstr == NULL)
31
+ 		return NULL;
32
+diff --git a/src/rpcb_prot.c b/src/rpcb_prot.c
33
+index 43fd385..a923c8e 100644
34
+--- a/src/rpcb_prot.c
35
+@@ -41,6 +41,7 @@
36
+ #include <rpc/types.h>
37
+ #include <rpc/xdr.h>
38
+ #include <rpc/rpcb_prot.h>
39
++#include "rpc_com.h"
40
+ 
41
+ bool_t
42
+ xdr_rpcb(xdrs, objp)
43
+@@ -53,13 +54,13 @@ xdr_rpcb(xdrs, objp)
44
+ 	if (!xdr_u_int32_t(xdrs, &objp->r_vers)) {
45
+ 		return (FALSE);
46
+ 	}
47
+-	if (!xdr_string(xdrs, &objp->r_netid, (u_int)~0)) {
48
++	if (!xdr_string(xdrs, &objp->r_netid, RPC_MAXDATASIZE)) {
49
+ 		return (FALSE);
50
+ 	}
51
+-	if (!xdr_string(xdrs, &objp->r_addr, (u_int)~0)) {
52
++	if (!xdr_string(xdrs, &objp->r_addr, RPC_MAXDATASIZE)) {
53
+ 		return (FALSE);
54
+ 	}
55
+-	if (!xdr_string(xdrs, &objp->r_owner, (u_int)~0)) {
56
++	if (!xdr_string(xdrs, &objp->r_owner, RPC_MAXDATASIZE)) {
57
+ 		return (FALSE);
58
+ 	}
59
+ 	return (TRUE);
60
+@@ -159,19 +160,19 @@ xdr_rpcb_entry(xdrs, objp)
61
+ 	XDR *xdrs;
62
+ 	rpcb_entry *objp;
63
+ {
64
+-	if (!xdr_string(xdrs, &objp->r_maddr, (u_int)~0)) {
65
++	if (!xdr_string(xdrs, &objp->r_maddr, RPC_MAXDATASIZE)) {
66
+ 		return (FALSE);
67
+ 	}
68
+-	if (!xdr_string(xdrs, &objp->r_nc_netid, (u_int)~0)) {
69
++	if (!xdr_string(xdrs, &objp->r_nc_netid, RPC_MAXDATASIZE)) {
70
+ 		return (FALSE);
71
+ 	}
72
+ 	if (!xdr_u_int32_t(xdrs, &objp->r_nc_semantics)) {
73
+ 		return (FALSE);
74
+ 	}
75
+-	if (!xdr_string(xdrs, &objp->r_nc_protofmly, (u_int)~0)) {
76
++	if (!xdr_string(xdrs, &objp->r_nc_protofmly, RPC_MAXDATASIZE)) {
77
+ 		return (FALSE);
78
+ 	}
79
+-	if (!xdr_string(xdrs, &objp->r_nc_proto, (u_int)~0)) {
80
++	if (!xdr_string(xdrs, &objp->r_nc_proto, RPC_MAXDATASIZE)) {
81
+ 		return (FALSE);
82
+ 	}
83
+ 	return (TRUE);
84
+@@ -292,7 +293,7 @@ xdr_rpcb_rmtcallres(xdrs, p)
85
+ 	bool_t dummy;
86
+ 	struct r_rpcb_rmtcallres *objp = (struct r_rpcb_rmtcallres *)(void *)p;
87
+ 
88
+-	if (!xdr_string(xdrs, &objp->addr, (u_int)~0)) {
89
++	if (!xdr_string(xdrs, &objp->addr, RPC_MAXDATASIZE)) {
90
+ 		return (FALSE);
91
+ 	}
92
+ 	if (!xdr_u_int(xdrs, &objp->results.results_len)) {
93
+@@ -312,6 +313,11 @@ xdr_netbuf(xdrs, objp)
94
+ 	if (!xdr_u_int32_t(xdrs, (u_int32_t *) &objp->maxlen)) {
95
+ 		return (FALSE);
96
+ 	}
97
++
98
++	if (objp->maxlen > RPC_MAXDATASIZE) {
99
++		return (FALSE);
100
++	}
101
++
102
+ 	dummy = xdr_bytes(xdrs, (char **)&(objp->buf),
103
+ 			(u_int *)&(objp->len), objp->maxlen);
104
+ 	return (dummy);
105
+diff --git a/src/rpcb_st_xdr.c b/src/rpcb_st_xdr.c
106
+index 08db745..28e6a48 100644
107
+--- a/src/rpcb_st_xdr.c
108
+@@ -37,6 +37,7 @@
109
+ 
110
+ 
111
+ #include <rpc/rpc.h>
112
++#include "rpc_com.h"
113
+ 
114
+ /* Link list of all the stats about getport and getaddr */
115
+ 
116
+@@ -58,7 +59,7 @@ xdr_rpcbs_addrlist(xdrs, objp)
117
+ 	    if (!xdr_int(xdrs, &objp->failure)) {
118
+ 		return (FALSE);
119
+ 	    }
120
+-	    if (!xdr_string(xdrs, &objp->netid, (u_int)~0)) {
121
++	    if (!xdr_string(xdrs, &objp->netid, RPC_MAXDATASIZE)) {
122
+ 		return (FALSE);
123
+ 	    }
124
+ 
125
+@@ -109,7 +110,7 @@ xdr_rpcbs_rmtcalllist(xdrs, objp)
126
+ 		IXDR_PUT_INT32(buf, objp->failure);
127
+ 		IXDR_PUT_INT32(buf, objp->indirect);
128
+ 	}
129
+-	if (!xdr_string(xdrs, &objp->netid, (u_int)~0)) {
130
++	if (!xdr_string(xdrs, &objp->netid, RPC_MAXDATASIZE)) {
131
+ 		return (FALSE);
132
+ 	}
133
+ 	if (!xdr_pointer(xdrs, (char **)&objp->next,
134
+@@ -147,7 +148,7 @@ xdr_rpcbs_rmtcalllist(xdrs, objp)
135
+ 		objp->failure = (int)IXDR_GET_INT32(buf);
136
+ 		objp->indirect = (int)IXDR_GET_INT32(buf);
137
+ 	}
138
+-	if (!xdr_string(xdrs, &objp->netid, (u_int)~0)) {
139
++	if (!xdr_string(xdrs, &objp->netid, RPC_MAXDATASIZE)) {
140
+ 		return (FALSE);
141
+ 	}
142
+ 	if (!xdr_pointer(xdrs, (char **)&objp->next,
143
+@@ -175,7 +176,7 @@ xdr_rpcbs_rmtcalllist(xdrs, objp)
144
+ 	if (!xdr_int(xdrs, &objp->indirect)) {
145
+ 		return (FALSE);
146
+ 	}
147
+-	if (!xdr_string(xdrs, &objp->netid, (u_int)~0)) {
148
++	if (!xdr_string(xdrs, &objp->netid, RPC_MAXDATASIZE)) {
149
+ 		return (FALSE);
150
+ 	}
151
+ 	if (!xdr_pointer(xdrs, (char **)&objp->next,
152
+diff --git a/src/xdr.c b/src/xdr.c
153
+index f3fb9ad..b9a1558 100644
154
+--- a/src/xdr.c
155
+@@ -42,8 +42,10 @@
156
+ #include <stdlib.h>
157
+ #include <string.h>
158
+ 
159
++#include <rpc/rpc.h>
160
+ #include <rpc/types.h>
161
+ #include <rpc/xdr.h>
162
++#include <rpc/rpc_com.h>
163
+ 
164
+ typedef quad_t          longlong_t;     /* ANSI long long type */
165
+ typedef u_quad_t        u_longlong_t;   /* ANSI unsigned long long type */
166
+@@ -53,7 +55,6 @@ typedef u_quad_t        u_longlong_t;   /* ANSI unsigned long long type */
167
+  */
168
+ #define XDR_FALSE	((long) 0)
169
+ #define XDR_TRUE	((long) 1)
170
+-#define LASTUNSIGNED	((u_int) 0-1)
171
+ 
172
+ /*
173
+  * for unit alignment
174
+@@ -629,6 +630,7 @@ xdr_bytes(xdrs, cpp, sizep, maxsize)
175
+ {
176
+ 	char *sp = *cpp;  /* sp is the actual string pointer */
177
+ 	u_int nodesize;
178
++	bool_t ret, allocated = FALSE;
179
+ 
180
+ 	/*
181
+ 	 * first deal with the length since xdr bytes are counted
182
+@@ -652,6 +654,7 @@ xdr_bytes(xdrs, cpp, sizep, maxsize)
183
+ 		}
184
+ 		if (sp == NULL) {
185
+ 			*cpp = sp = mem_alloc(nodesize);
186
++			allocated = TRUE;
187
+ 		}
188
+ 		if (sp == NULL) {
189
+ 			warnx("xdr_bytes: out of memory");
190
+@@ -660,7 +663,14 @@ xdr_bytes(xdrs, cpp, sizep, maxsize)
191
+ 		/* FALLTHROUGH */
192
+ 
193
+ 	case XDR_ENCODE:
194
+-		return (xdr_opaque(xdrs, sp, nodesize));
195
++		ret = xdr_opaque(xdrs, sp, nodesize);
196
++		if ((xdrs->x_op == XDR_DECODE) && (ret == FALSE)) {
197
++			if (allocated == TRUE) {
198
++				free(sp);
199
++				*cpp = NULL;
200
++			}
201
++		}
202
++		return (ret);
203
+ 
204
+ 	case XDR_FREE:
205
+ 		if (sp != NULL) {
206
+@@ -754,6 +764,7 @@ xdr_string(xdrs, cpp, maxsize)
207
+ 	char *sp = *cpp;  /* sp is the actual string pointer */
208
+ 	u_int size;
209
+ 	u_int nodesize;
210
++	bool_t ret, allocated = FALSE;
211
+ 
212
+ 	/*
213
+ 	 * first deal with the length since xdr strings are counted-strings
214
+@@ -793,8 +804,10 @@ xdr_string(xdrs, cpp, maxsize)
215
+ 	switch (xdrs->x_op) {
216
+ 
217
+ 	case XDR_DECODE:
218
+-		if (sp == NULL)
219
++		if (sp == NULL) {
220
+ 			*cpp = sp = mem_alloc(nodesize);
221
++			allocated = TRUE;
222
++		}
223
+ 		if (sp == NULL) {
224
+ 			warnx("xdr_string: out of memory");
225
+ 			return (FALSE);
226
+@@ -803,7 +816,14 @@ xdr_string(xdrs, cpp, maxsize)
227
+ 		/* FALLTHROUGH */
228
+ 
229
+ 	case XDR_ENCODE:
230
+-		return (xdr_opaque(xdrs, sp, size));
231
++		ret = xdr_opaque(xdrs, sp, size);
232
++		if ((xdrs->x_op == XDR_DECODE) && (ret == FALSE)) {
233
++			if (allocated == TRUE) {
234
++				free(sp);
235
++				*cpp = NULL;
236
++			}
237
++		}
238
++		return (ret);
239
+ 
240
+ 	case XDR_FREE:
241
+ 		mem_free(sp, nodesize);
242
+@@ -823,7 +843,7 @@ xdr_wrapstring(xdrs, cpp)
243
+ 	XDR *xdrs;
244
+ 	char **cpp;
245
+ {
246
+-	return xdr_string(xdrs, cpp, LASTUNSIGNED);
247
++	return xdr_string(xdrs, cpp, RPC_MAXDATASIZE);
248
+ }
249
+ 
250
+ /*
... ...
@@ -1,10 +1,11 @@
1 1
 Summary:	Libraries for Transport Independent RPC
2 2
 Name:		libtirpc
3 3
 Version:	1.0.1
4
-Release:	3%{?dist}
4
+Release:	4%{?dist}
5 5
 Source0:	http://downloads.sourceforge.net/project/libtirpc/libtirpc/0.3.2/%{name}-%{version}.tar.bz2
6 6
 %define sha1 libtirpc=8da1636f98b5909c0d587e7534bc1e91f5c1a970
7 7
 Patch0:         libtirpc-1.0.1-bindrsvport-blacklist.patch
8
+Patch1:         libtirpc-CVE-2017-8779.patch
8 9
 License:	BSD
9 10
 Group:		System Environment/Libraries
10 11
 URL:		http://nfsv4.bullopensource.org/
... ...
@@ -37,6 +38,7 @@ This package includes header files and libraries necessary for developing progra
37 37
 %prep
38 38
 %setup -q
39 39
 %patch0
40
+%patch1 -p1
40 41
 
41 42
 %build
42 43
 ./configure --prefix=%{_prefix} --sysconfdir=%{_sysconfdir}
... ...
@@ -67,6 +69,8 @@ make install DESTDIR=%{buildroot}
67 67
    
68 68
 
69 69
 %changelog
70
+*	Thu May 18 2017 Vinay Kulkarni <kulkarniv@vmware.com> 1.0.1-4
71
+-	Fix CVE-2017-8779
70 72
 *	Tue May 24 2016 Priyesh Padmavilasom <ppadmavilasom@vmware.com> 1.0.1-3
71 73
 -	GA - Bump release of all rpms
72 74
 * 	Mon Feb 08 2016 Anish Swaminathan <anishs@vmware.com>  1.0.1-2
73 75
new file mode 100644
... ...
@@ -0,0 +1,21 @@
0
+diff --git a/src/rpcb_svc_com.c b/src/rpcb_svc_com.c
1
+index 5862c26..e11f61b 100644
2
+--- a/src/rpcb_svc_com.c
3
+@@ -48,6 +48,7 @@
4
+ #include <rpc/rpc.h>
5
+ #include <rpc/rpcb_prot.h>
6
+ #include <rpc/svc_dg.h>
7
++#include <rpc/rpc_com.h>
8
+ #include <netconfig.h>
9
+ #include <errno.h>
10
+ #include <syslog.h>
11
+@@ -432,7 +433,7 @@ rpcbproc_taddr2uaddr_com(void *arg, struct svc_req *rqstp /*__unused*/,
12
+ static bool_t
13
+ xdr_encap_parms(XDR *xdrs, struct encap_parms *epp)
14
+ {
15
+-	return (xdr_bytes(xdrs, &(epp->args), (u_int *) &(epp->arglen), ~0));
16
++	return (xdr_bytes(xdrs, &(epp->args), (u_int *) &(epp->arglen), RPC_MAXDATASIZE));
17
+ }
18
+ 
19
+ /*
... ...
@@ -1,30 +1,35 @@
1
-Summary:	RPC program number mapper
2
-Name:		rpcbind
3
-Version:	0.2.3
4
-Release:	7%{?dist}
5
-License:	BSD
6
-URL:		http://nfsv4.bullopensource.org
7
-Group:	    Applications/Daemons
8
-Source0:    http://downloads.sourceforge.net/rpcbind/%{name}-%{version}.tar.bz2
1
+Summary:        RPC program number mapper
2
+Name:           rpcbind
3
+Version:        0.2.3
4
+Release:        8%{?dist}
5
+License:        BSD
6
+URL:            http://nfsv4.bullopensource.org
7
+Group:          Applications/Daemons
8
+Source0:        http://downloads.sourceforge.net/rpcbind/%{name}-%{version}.tar.bz2
9 9
 %define sha1 rpcbind=e79974a99d09b6d6fff9d86bf00225dc33723ce2
10
-Source1:    rpcbind.service
11
-Source2:    rpcbind.socket
12
-Source3:    rpcbind.sysconfig
13
-Patch0:     http://www.linuxfromscratch.org/patches/blfs/svn/rpcbind-0.2.3-tirpc_fix-1.patch
14
-Vendor:     VMware, Inc.
10
+Source1:        rpcbind.service
11
+Source2:        rpcbind.socket
12
+Source3:        rpcbind.sysconfig
13
+Patch0:         http://www.linuxfromscratch.org/patches/blfs/svn/rpcbind-0.2.3-tirpc_fix-1.patch
14
+Patch1:         rpcbind-CVE-2017-8779.patch
15
+Vendor:         VMware, Inc.
15 16
 Distribution:   Photon
16
-BuildRequires:	libtirpc-devel
17
+BuildRequires:  libtirpc-devel
17 18
 BuildRequires:  systemd
18 19
 Requires:       libtirpc
19 20
 Requires:       systemd
20 21
 Requires(pre):  shadow
21 22
 Requires(preun):shadow
22 23
 Requires(post): coreutils
24
+
23 25
 %description
24 26
 The rpcbind program is a replacement for portmap. It is required for import or export of Network File System (NFS) shared directories. The rpcbind utility is a server that converts RPC program numbers into universal addresses
27
+
25 28
 %prep
26 29
 %setup -q
27 30
 %patch0 -p1
31
+%patch1 -p1
32
+
28 33
 %build
29 34
 sed -i "/servname/s:rpcbind:sunrpc:" src/rpcbind.c
30 35
 ./configure --prefix=%{_prefix}      \
... ...
@@ -34,6 +39,7 @@ sed -i "/servname/s:rpcbind:sunrpc:" src/rpcbind.c
34 34
             --with-statedir=%{_localstatedir}/lib/rpcbind \
35 35
             --with-rpcuser=rpc
36 36
 make
37
+
37 38
 %install
38 39
 make DESTDIR=%{buildroot} install
39 40
 mkdir -p %{buildroot}%{_localstatedir}/lib/rpcbind
... ...
@@ -58,7 +64,7 @@ make -k check |& tee %{_specdir}/%{name}-check-log || %{nocheck}
58 58
 rpcid=`getent passwd rpc | cut -d: -f 3`
59 59
 if [ -n "$rpcid" -a "$rpcid" != "31" ]; then
60 60
 	userdel  rpc 2> /dev/null || :
61
-	groupdel rpc 2> /dev/null || : 
61
+	groupdel rpc 2> /dev/null || :
62 62
 fi
63 63
 if [ -z "$rpcid" -o "$rpcid" != "31" ]; then
64 64
 	groupadd -g 31 rpc > /dev/null 2>&1
... ...
@@ -84,7 +90,10 @@ fi
84 84
 
85 85
 %clean
86 86
 rm -rf %{buildroot}/*
87
+
87 88
 %changelog
89
+*	Thu May 18 2017 Vinay Kulkarni <kulkarniv@vmware.com> 0.2.3-8
90
+-	Fix CVE-2017-8779
88 91
 *	Fri May 05 2017 Priyesh Padmavilasom <ppadmavilasom@vmware.com> 0.2.3-7
89 92
 -	add shadow and coreutils to requires
90 93
 *	Tue May 24 2016 Priyesh Padmavilasom <ppadmavilasom@vmware.com> 0.2.3-6