glibc-2.3.1 SunRPC vuln

Kelledin <[email protected]>
Newsgroups gmane.linux.lfs.security
Message-ID <[email protected]>
http://www.cert.org/advisories/CA-2003-10.html

Supposedly this is fixed for glibc-2.3.2, but I don't have 2.3.2
and thus can't be arsed to check.  Some of us may want to stick
with glibc-2.3.1 anyways.

Attached patch is a merge of all single-file patches listed on
the above page.

--
Kelledin
"If a server crashes in a server farm and no one pings it, does
it still cost four figures to fix?"
glibc-2.3.1-sunrpc.patch (text/x-diff, 6.1 KB)
diff -Naur glibc-2.3.1/sunrpc/rpc/xdr.h glibc-2.3.1-sunrpc/sunrpc/rpc/xdr.h
--- glibc-2.3.1/sunrpc/rpc/xdr.h	1999-10-09 14:19:33.000000000 -0500
+++ glibc-2.3.1-sunrpc/sunrpc/rpc/xdr.h	2003-03-19 17:43:33.000000000 -0600
@@ -126,7 +126,7 @@
 	/* returns bytes off from beginning */
 	bool_t (*x_setpostn) (XDR *__xdrs, u_int __pos);
 	/* lets you reposition the stream */
-	int32_t *(*x_inline) (XDR *__xdrs, int __len);
+	int32_t *(*x_inline) (XDR *__xdrs, u_int __len);
 	/* buf quick ptr to buffered data */
 	void (*x_destroy) (XDR *__xdrs);
 	/* free privates of this xdr_stream */
@@ -139,7 +139,7 @@
     caddr_t x_public;		/* users' data */
     caddr_t x_private;		/* pointer to private data */
     caddr_t x_base;		/* private used for position info */
-    int x_handy;		/* extra private word */
+    u_int x_handy;		/* extra private word */
   };
 
 /*
diff -Naur glibc-2.3.1/sunrpc/xdr_mem.c glibc-2.3.1-sunrpc/sunrpc/xdr_mem.c
--- glibc-2.3.1/sunrpc/xdr_mem.c	2002-02-25 03:10:49.000000000 -0600
+++ glibc-2.3.1-sunrpc/sunrpc/xdr_mem.c	2003-03-19 17:43:43.000000000 -0600
@@ -39,6 +39,7 @@
  */
 
 #include <string.h>
+#include <limits.h>
 #include <rpc/rpc.h>
 
 static bool_t xdrmem_getlong (XDR *, long *);
@@ -47,7 +48,7 @@
 static bool_t xdrmem_putbytes (XDR *, const char *, u_int);
 static u_int xdrmem_getpos (const XDR *);
 static bool_t xdrmem_setpos (XDR *, u_int);
-static int32_t *xdrmem_inline (XDR *, int);
+static int32_t *xdrmem_inline (XDR *, u_int);
 static void xdrmem_destroy (XDR *);
 static bool_t xdrmem_getint32 (XDR *, int32_t *);
 static bool_t xdrmem_putint32 (XDR *, const int32_t *);
@@ -100,8 +101,9 @@
 static bool_t
 xdrmem_getlong (XDR *xdrs, long *lp)
 {
-  if ((xdrs->x_handy -= 4) < 0)
+  if (xdrs->x_handy < 4)
     return FALSE;
+  xdrs->x_handy -= 4;
   *lp = (int32_t) ntohl ((*((int32_t *) (xdrs->x_private))));
   xdrs->x_private += 4;
   return TRUE;
@@ -115,8 +117,9 @@
 static bool_t
 xdrmem_putlong (XDR *xdrs, const long *lp)
 {
-  if ((xdrs->x_handy -= 4) < 0)
+  if (xdrs->x_handy < 4)
     return FALSE;
+  xdrs->x_handy -= 4;
   *(int32_t *) xdrs->x_private = htonl (*lp);
   xdrs->x_private += 4;
   return TRUE;
@@ -131,8 +134,9 @@
 static bool_t
 xdrmem_getbytes (XDR *xdrs, caddr_t addr, u_int len)
 {
-  if ((xdrs->x_handy -= len) < 0)
+  if (xdrs->x_handy < len)
     return FALSE;
+  xdrs->x_handy -= len;
   memcpy (addr, xdrs->x_private, len);
   xdrs->x_private += len;
   return TRUE;
@@ -145,8 +149,9 @@
 static bool_t
 xdrmem_putbytes (XDR *xdrs, const char *addr, u_int len)
 {
-  if ((xdrs->x_handy -= len) < 0)
+  if (xdrs->x_handy < len)
     return FALSE;
+  xdrs->x_handy -= len;
   memcpy (xdrs->x_private, addr, len);
   xdrs->x_private += len;
   return TRUE;
@@ -173,7 +178,9 @@
   caddr_t newaddr = xdrs->x_base + pos;
   caddr_t lastaddr = xdrs->x_private + xdrs->x_handy;
 
-  if ((long) newaddr > (long) lastaddr)
+  if ((long) newaddr > (long) lastaddr
+      || (UINT_MAX < LONG_MAX
+	  && (long) UINT_MAX < (long) lastaddr - (long) newaddr))
     return FALSE;
   xdrs->x_private = newaddr;
   xdrs->x_handy = (long) lastaddr - (long) newaddr;
@@ -184,7 +191,7 @@
  * xdrs modified
  */
 static int32_t *
-xdrmem_inline (XDR *xdrs, int len)
+xdrmem_inline (XDR *xdrs, u_int len)
 {
   int32_t *buf = 0;
 
@@ -205,8 +212,9 @@
 static bool_t
 xdrmem_getint32 (XDR *xdrs, int32_t *ip)
 {
-  if ((xdrs->x_handy -= 4) < 0)
+  if (xdrs->x_handy < 4)
     return FALSE;
+  xdrs->x_handy -= 4;
   *ip = ntohl ((*((int32_t *) (xdrs->x_private))));
   xdrs->x_private += 4;
   return TRUE;
@@ -220,8 +228,9 @@
 static bool_t
 xdrmem_putint32 (XDR *xdrs, const int32_t *ip)
 {
-  if ((xdrs->x_handy -= 4) < 0)
+  if (xdrs->x_handy < 4)
     return FALSE;
+  xdrs->x_handy -= 4;
   *(int32_t *) xdrs->x_private = htonl (*ip);
   xdrs->x_private += 4;
   return TRUE;
diff -Naur glibc-2.3.1/sunrpc/xdr_rec.c glibc-2.3.1-sunrpc/sunrpc/xdr_rec.c
--- glibc-2.3.1/sunrpc/xdr_rec.c	2002-08-04 13:21:34.000000000 -0500
+++ glibc-2.3.1-sunrpc/sunrpc/xdr_rec.c	2003-03-19 17:43:49.000000000 -0600
@@ -61,7 +61,7 @@
 static bool_t xdrrec_putbytes (XDR *, const char *, u_int);
 static u_int xdrrec_getpos (const XDR *);
 static bool_t xdrrec_setpos (XDR *, u_int);
-static int32_t *xdrrec_inline (XDR *, int);
+static int32_t *xdrrec_inline (XDR *, u_int);
 static void xdrrec_destroy (XDR *);
 static bool_t xdrrec_getint32 (XDR *, int32_t *);
 static bool_t xdrrec_putint32 (XDR *, const int32_t *);
@@ -373,7 +373,7 @@
 }
 
 static int32_t *
-xdrrec_inline (XDR *xdrs, int len)
+xdrrec_inline (XDR *xdrs, u_int len)
 {
   RECSTREAM *rstrm = (RECSTREAM *) xdrs->x_private;
   int32_t *buf = NULL;
diff -Naur glibc-2.3.1/sunrpc/xdr_sizeof.c glibc-2.3.1-sunrpc/sunrpc/xdr_sizeof.c
--- glibc-2.3.1/sunrpc/xdr_sizeof.c	2001-01-28 11:51:49.000000000 -0600
+++ glibc-2.3.1-sunrpc/sunrpc/xdr_sizeof.c	2003-03-19 17:43:59.000000000 -0600
@@ -71,13 +71,13 @@
 }
 
 static int32_t *
-x_inline (XDR *xdrs, int len)
+x_inline (XDR *xdrs, u_int len)
 {
   if (len == 0)
     return NULL;
   if (xdrs->x_op != XDR_ENCODE)
     return NULL;
-  if (len < (int) (long int) xdrs->x_base)
+  if (len < (u_int) (long int) xdrs->x_base)
     {
       /* x_private was already allocated */
       xdrs->x_handy += len;
@@ -159,5 +159,5 @@
   stat = func (&x, data);
   if (x.x_private)
     free (x.x_private);
-  return stat == TRUE ? (unsigned) x.x_handy : 0;
+  return stat == TRUE ? x.x_handy : 0;
 }
diff -Naur glibc-2.3.1/sunrpc/xdr_stdio.c glibc-2.3.1-sunrpc/sunrpc/xdr_stdio.c
--- glibc-2.3.1/sunrpc/xdr_stdio.c	2002-09-17 11:45:58.000000000 -0500
+++ glibc-2.3.1-sunrpc/sunrpc/xdr_stdio.c	2003-03-19 17:44:04.000000000 -0600
@@ -55,7 +55,7 @@
 static bool_t xdrstdio_putbytes (XDR *, const char *, u_int);
 static u_int xdrstdio_getpos (const XDR *);
 static bool_t xdrstdio_setpos (XDR *, u_int);
-static int32_t *xdrstdio_inline (XDR *, int);
+static int32_t *xdrstdio_inline (XDR *, u_int);
 static void xdrstdio_destroy (XDR *);
 static bool_t xdrstdio_getint32 (XDR *, int32_t *);
 static bool_t xdrstdio_putint32 (XDR *, const int32_t *);
@@ -157,7 +157,7 @@
 }
 
 static int32_t *
-xdrstdio_inline (XDR *xdrs, int len)
+xdrstdio_inline (XDR *xdrs, u_int len)
 {
   /*
    * Must do some work to implement this: must insure
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.