glibc vulnerability

Dagmar d'Surreal dagmar.wants at nospam.com
Sun Jun 1 15:03:21 PDT 2003


On Sun, 2003-06-01 at 15:22, Dagmar d'Surreal wrote:
> On Wed, 2003-05-28 at 07:51, Jochen Schroeder wrote:
> > Suse has released a patch for glibc to fix a security hole in the XDR 
> > code, see here for details:
> > http://www.suse.de/de/security/2003_027_glibc.html
> 
> Umm... Took them long enough.  Glibc-2.3.2 doesn't have this problem.

..and more to the point, here's an annotated diff that people should
start applying to glibc.  It was assembled directly from the components
listed in CERT Advisory CA-2003-10.  Since glibc-2.3.2 is not vulnerable
to this, if you are currently building using the current CVS tree of
LFS, you don't need to worry about it.  Everyone else using any version
of glibc previous to 2.3.2 (2.3.1, 2.2.5, etc) should apply this patch
to their glibc sources and rebuild to eliminate the vulnerability from
their system.



-- 
The email address above is just as phony as it looks, and for obvious reasons.
Instant messaging contact nfo: AIM: evilDagmar  Jabber: evilDagmar at jabber.org
-------------- next part --------------
! This patch is to address the buffer overflow to the xdrmem_getbytes()
! function in the XDR library as discovered by the eEye Digital Security Team.
! This vulnerability is tracked by CERT as Vulnerability note VU#516825
! found at http://www.kb.cert.org/vuls/id/516825.  All versions of glibc
! previous to 2.3.2 should have this patch applied to fix the vulnerability.
! 
--- libc/sunrpc/rpc/xdr.h	1999/10/09 21:26:03	1.26
+++ libc/sunrpc/rpc/xdr.h	2002/12/16 02:05:49	1.27
@@ -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 */
   };
 
 /*
--- libc/sunrpc/xdr_mem.c	2002/02/26 01:43:56	1.13
+++ libc/sunrpc/xdr_mem.c	2002/12/16 10:25:27	1.15
@@ -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;
--- libc/sunrpc/xdr_rec.c	2002/08/04 20:49:36	1.26
+++ libc/sunrpc/xdr_rec.c	2002/12/16 10:25:28	1.27
@@ -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;
--- libc/sunrpc/xdr_sizeof.c	2001/01/28 17:52:48	1.5
+++ libc/sunrpc/xdr_sizeof.c	2002/12/16 02:05:48	1.6
@@ -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;
 }
--- libc/sunrpc/xdr_stdio.c	2002/09/17 10:58:04	1.15
+++ libc/sunrpc/xdr_stdio.c	2002/12/16 10:25:28	1.16
@@ -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


More information about the lfs-security mailing list