Re: glibc vulnerability
Dagmar d'Surreal <[email protected]>
| Newsgroups | gmane.linux.lfs.security |
|---|---|
| Message-ID | <[email protected]> |
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: [email protected]
glibc-xdmem_getbytes_overflow.patch
(text/plain, 5.9 KB)
! 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