Author: branden Date: 2003-09-02 20:08:23 -0500 (Tue, 02 Sep 2003) New Revision: 473
Added: branches/4.1.0/woody/debian/patches/072_SECURITY_fix_font_service_overflows.diff Modified: branches/4.1.0/woody/debian/changelog Log: debian/patches/072_SECURITY_fix_font_service_overflows.diff: new; fixes for integer overflows in font libraries from upstream CVS: - fixes for potential integer overflows in font libraries (blexim, Matthieu Herrb). - For integer overflow tests, use SIZE_MAX which is more standard than SIZE_T_MAX, and default to ULONG_MAX for the case of LP64 systems. Based on reports by Matthias Scheler and Alan Coopersmith (Bugzilla #646). Modified: branches/4.1.0/woody/debian/changelog =================================================================== --- branches/4.1.0/woody/debian/changelog 2003-09-03 01:00:00 UTC (rev 472) +++ branches/4.1.0/woody/debian/changelog 2003-09-03 01:08:23 UTC (rev 473) @@ -6,6 +6,10 @@ + CAN-2002-0164 (flaw in X server's MIT-SHM extension can user owning X session to read and write arbitrary shared memory segments) + + CAN-2003-0730 (multiple integer overflows in the font libraries for + XFree86 allow local or remote attackers to cause a denial + of service or execute arbitrary code via heap-based and + stack-based buffer overflow attacks) * patch #069: new; disable xterm's window title reporting escape sequence @@ -21,9 +25,17 @@ The original fix did not cover the case where the X server is started from an X display manager such as xdm. + * patch #072: new; fixes for integer overflows in font libraries from + upstream CVS: + - fixes for potential integer overflows in font libraries (blexim, Matthieu + Herrb). + - For integer overflow tests, use SIZE_MAX which is more standard than + SIZE_T_MAX, and default to ULONG_MAX for the case of LP64 systems. Based + on reports by Matthias Scheler and Alan Coopersmith (Bugzilla #646). + * patch #400: resynced offsets in the wake of patch #071 - -- Branden Robinson <[EMAIL PROTECTED]> Tue, 2 Sep 2003 19:58:50 -0500 + -- Branden Robinson <[EMAIL PROTECTED]> Tue, 2 Sep 2003 20:00:37 -0500 xfree86 (4.1.0-16) unstable; urgency=high Added: branches/4.1.0/woody/debian/patches/072_SECURITY_fix_font_service_overflows.diff =================================================================== --- branches/4.1.0/woody/debian/patches/072_SECURITY_fix_font_service_overflows.diff 2003-09-03 01:00:00 UTC (rev 472) +++ branches/4.1.0/woody/debian/patches/072_SECURITY_fix_font_service_overflows.diff 2003-09-03 01:08:23 UTC (rev 473) @@ -0,0 +1,326 @@ +Fixes for potential integer overflows in font libraries. (blexim, Matthieu +Herrb). + +For integer overflow tests, use SIZE_MAX which is more standard than +SIZE_T_MAX, and default to ULONG_MAX for the case of LP64 systems. Based +on reports by Matthias Scheler and Alan Coopersmith (Bugzilla #646). + +Backported from XFree86 CVS HEAD. + +diff -urN xc/lib~/FS/FSFontInfo.c xc/lib/FS/FSFontInfo.c +--- xc/lib~/FS/FSFontInfo.c 2001-01-16 17:05:39.000000000 -0500 ++++ xc/lib/FS/FSFontInfo.c 2003-09-02 19:46:40.000000000 -0500 +@@ -61,7 +61,7 @@ + long nbytes; + int i, + j; +- int size = 0; ++ size_t size = 0; + FSXFontInfoHeader **fhdr = (FSXFontInfoHeader **) 0; + FSPropInfo **pi = (FSPropInfo **) 0; + FSPropOffset **po = (FSPropOffset **) 0; +@@ -119,8 +119,14 @@ + if (reply.nameLength == 0) /* got last reply in version 1 */ + break; + if ((i + reply.nReplies) >= size) { ++ ++ if (reply.nReplies > SIZE_MAX - i - 1) ++ goto badmem; + size = i + reply.nReplies + 1; + ++ if (size > SIZE_MAX / sizeof(char *)) ++ goto badmem; ++ + if (fhdr) { + FSXFontInfoHeader **tmp_fhdr = (FSXFontInfoHeader **) + FSrealloc((char *) fhdr, +@@ -233,6 +239,9 @@ + pi[i]->num_offsets = local_pi.num_offsets; + pi[i]->data_len = local_pi.data_len; + ++ if (pi[i]->num_offsets > SIZE_MAX / sizeof(FSPropOffset)) ++ goto badmem; ++ + po[i] = (FSPropOffset *) + FSmalloc(pi[i]->num_offsets * sizeof(FSPropOffset)); + if (!po[i]) { +@@ -278,6 +287,10 @@ + nbytes = pi[i]->data_len + reply.nameLength; + _FSEatData(svr, (unsigned long) (((nbytes+3)&~3) - nbytes)); + } ++ /* avoid integer overflow */ ++ if (i > INT_MAX - 1) { ++ goto badmem; ++ } + } + *info = fhdr; + *count = i; +diff -urN xc/lib~/FS/FSFtNames.c xc/lib/FS/FSFtNames.c +--- xc/lib~/FS/FSFtNames.c 2001-01-16 17:05:39.000000000 -0500 ++++ xc/lib/FS/FSFtNames.c 2003-09-02 19:46:40.000000000 -0500 +@@ -74,7 +74,8 @@ + (SIZEOF(fsListFontsReply) - SIZEOF(fsGenericReply)) >> 2, fsFalse)) + return (char **) 0; + +- if (rep.nFonts) { ++ if (rep.nFonts && rep.nFonts <= SIZE_MAX / sizeof(char *) ++ && rep.length <= ((SIZE_MAX + SIZEOF(fsListFontsReply) - 1) >> 2)) { + flist = (char **) FSmalloc((unsigned) rep.nFonts * sizeof(char *)); + rlen = (rep.length << 2) - SIZEOF(fsListFontsReply); + c = (char *) FSmalloc((unsigned) (rlen + 1)); +diff -urN xc/lib~/FS/FSGetCats.c xc/lib/FS/FSGetCats.c +--- xc/lib~/FS/FSGetCats.c 2001-01-16 17:05:40.000000000 -0500 ++++ xc/lib/FS/FSGetCats.c 2003-09-02 19:46:40.000000000 -0500 +@@ -68,9 +68,10 @@ + SyncHandle(); + return (char **) NULL; + } +- if (rep.num_catalogues) { ++ if (rep.num_catalogues && rep.num_catalogues <= SIZE_MAX/sizeof(char *) ++ && rep.length <= ((SIZE_MAX + SIZEOF(fsGetCataloguesReply) - 1)>>2)) { + list = (char **) +- FSmalloc((unsigned) (rep.num_catalogues * sizeof(char *))); ++ FSmalloc((unsigned) (rep.num_catalogues * sizeof(char *))); + rlen = (rep.length << 2) - SIZEOF(fsGetCataloguesReply); + c = (char *) FSmalloc((unsigned) rlen + 1); + if ((!list) || (!c)) { +diff -urN xc/lib~/FS/FSListCats.c xc/lib/FS/FSListCats.c +--- xc/lib~/FS/FSListCats.c 2001-01-16 17:05:41.000000000 -0500 ++++ xc/lib/FS/FSListCats.c 2003-09-02 19:46:40.000000000 -0500 +@@ -74,7 +74,8 @@ + (SIZEOF(fsListCataloguesReply) - SIZEOF(fsGenericReply)) >> 2, fsFalse)) + return (char **) 0; + +- if (rep.num_catalogues) { ++ if (rep.num_catalogues && rep.num_catalogues <= SIZE_MAX/sizeof(char *) ++ && rep.length <= ((SIZE_MAX+SIZEOF(fsListCataloguesReply)+1)>>2)) { + clist = (char **) + FSmalloc((unsigned) rep.num_catalogues * sizeof(char *)); + rlen = (rep.length << 2) - SIZEOF(fsListCataloguesReply); +diff -urN xc/lib~/FS/FSListExt.c xc/lib/FS/FSListExt.c +--- xc/lib~/FS/FSListExt.c 2001-01-16 17:05:41.000000000 -0500 ++++ xc/lib/FS/FSListExt.c 2003-09-02 19:46:40.000000000 -0500 +@@ -68,7 +68,8 @@ + SyncHandle(); + return (char **) NULL; + } +- if (rep.nExtensions) { ++ if (rep.nExtensions && rep.nExtensions <= SIZE_MAX / sizeof(char *) ++ && rep.length <= ((SIZE_MAX+SIZEOF(fsListExtensionsReply)+1)>>2)) { + list = (char **) FSmalloc((unsigned)(rep.nExtensions * sizeof(char *))); + rlen = (rep.length << 2) - SIZEOF(fsListExtensionsReply); + c = (char *) FSmalloc((unsigned) rlen + 1); +diff -urN xc/lib~/FS/FSOpenServ.c xc/lib/FS/FSOpenServ.c +--- xc/lib~/FS/FSOpenServ.c 2001-01-17 14:41:28.000000000 -0500 ++++ xc/lib/FS/FSOpenServ.c 2003-09-02 19:34:25.000000000 -0500 +@@ -114,7 +114,7 @@ + AlternateServer *alts; + int altlen; + char *vendor_string; +- long setuplength; ++ unsigned long setuplength; + #ifdef X_NOT_STDC_ENV + extern char *getenv(); + #endif +@@ -152,7 +152,8 @@ + _FSRead(svr, (char *) &prefix, (long) SIZEOF(fsConnSetup)); + + setuplength = prefix.alternate_len << 2; +- if ((alt_data = (char *) ++ if (setuplength > (SIZE_MAX>>2) ++ || (alt_data = (char *) + (setup = FSmalloc((unsigned) setuplength))) == NULL) { + errno = ENOMEM; + FSfree((char *) svr); +@@ -161,6 +162,10 @@ + _FSRead(svr, (char *) alt_data, setuplength); + ad = alt_data; + ++ if (prefix.num_alternates > SIZE_MAX / sizeof(AlternateServer)) { ++ errno = ENOMEM; ++ return (FSServer *) 0; ++ } + alts = (AlternateServer *) + FSmalloc(sizeof(AlternateServer) * prefix.num_alternates); + if (!alts) { +@@ -192,7 +197,8 @@ + svr->num_alternates = prefix.num_alternates; + + setuplength = prefix.auth_len << 2; +- if ((auth_data = (char *) ++ if (prefix.auth_len > (SIZE_MAX>>2) ++ || (auth_data = (char *) + (setup = FSmalloc((unsigned) setuplength))) == NULL) { + errno = ENOMEM; + FSfree((char *) svr); +diff -urN xc/lib~/FS/FSQGlyphs.c xc/lib/FS/FSQGlyphs.c +--- xc/lib~/FS/FSQGlyphs.c 2001-01-16 17:05:44.000000000 -0500 ++++ xc/lib/FS/FSQGlyphs.c 2003-09-02 19:46:40.000000000 -0500 +@@ -81,12 +81,20 @@ + (SIZEOF(fsQueryXBitmaps8Reply) - SIZEOF(fsGenericReply)) >> 2, fsFalse)) + return FSBadAlloc; + ++ if (reply.num_chars > SIZE_MAX / sizeof(FSOffset)) ++ return FSBadAlloc; ++ + offs = (FSOffset *) FSmalloc(sizeof(FSOffset) * reply.num_chars); + *offsets = offs; + if (!offs) + return FSBadAlloc; + left = (reply.length << 2) - SIZEOF(fsQueryXBitmaps8Reply) + - (SIZEOF(fsOffset32) * reply.num_chars); ++ /* XXX This thest is incomplete */ ++ if (reply.length > (SIZE_MAX >> 2)) { ++ FSfree((char *) offs); ++ return FSBadAlloc; ++ } + gd = (unsigned char *) FSmalloc(left); + *glyphdata = gd; + if (!gd) { +@@ -137,6 +145,8 @@ + int i; + fsChar2b_version1 *swapped_str; + ++ if (str_len > SIZE_MAX/SIZEOF(fsChar2b_version1)) ++ return FSBadAlloc; + swapped_str = (fsChar2b_version1 *) + FSmalloc(SIZEOF(fsChar2b_version1) * str_len); + if (!swapped_str) +@@ -156,12 +166,19 @@ + fsFalse)) + return FSBadAlloc; + ++ if(reply.num_chars > SIZE_MAX/sizeof(FSOffset)) ++ return FSBadAlloc; + offs = (FSOffset *) FSmalloc(sizeof(FSOffset) * reply.num_chars); + *offsets = offs; + if (!offs) + return FSBadAlloc; + left = (reply.length << 2) - SIZEOF(fsQueryXBitmaps16Reply) + - (SIZEOF(fsOffset32) * reply.num_chars); ++ /* XXX - this test is incomplete */ ++ if (reply.length > (SIZE_MAX>>2)) { ++ FSfree((char *) offs); ++ return FSBadAlloc; ++ } + gd = (unsigned char *) FSmalloc(left); + *glyphdata = gd; + if (!gd) { +diff -urN xc/lib~/FS/FSQXExt.c xc/lib/FS/FSQXExt.c +--- xc/lib~/FS/FSQXExt.c 2001-01-17 14:41:28.000000000 -0500 ++++ xc/lib/FS/FSQXExt.c 2003-09-02 19:39:46.000000000 -0500 +@@ -89,6 +89,9 @@ + fsFalse)) + return FSBadAlloc; + ++ if (reply.num_extents > SIZE_MAX / sizeof(FSXCharInfo)) ++ return FSBadAlloc; ++ + ext = (FSXCharInfo *) FSmalloc(sizeof(FSXCharInfo) * reply.num_extents); + *extents = ext; + if (!ext) +@@ -145,6 +148,9 @@ + fsFalse)) + return FSBadAlloc; + ++ if (reply.num_extents > SIZE_MAX/sizeof(FSXCharInfo)) ++ return FSBadAlloc; ++ + ext = (FSXCharInfo *) FSmalloc(sizeof(FSXCharInfo) * reply.num_extents); + *extents = ext; + if (!ext) +diff -urN xc/lib~/FS/FSQXInfo.c xc/lib/FS/FSQXInfo.c +--- xc/lib~/FS/FSQXInfo.c 2001-01-16 17:05:45.000000000 -0500 ++++ xc/lib/FS/FSQXInfo.c 2003-09-02 19:46:40.000000000 -0500 +@@ -87,6 +87,9 @@ + props->num_offsets = local_pi.num_offsets; + props->data_len = local_pi.data_len; + ++ if (props->num_offsets > SIZE_MAX / sizeof(FSPropOffset)) ++ return FSBadAlloc; ++ + /* prepare for prop data */ + offset_data = (FSPropOffset *) + FSmalloc(props->num_offsets * sizeof(FSPropOffset)); +diff -urN xc/lib~/FS/FSlibos.h xc/lib/FS/FSlibos.h +--- xc/lib~/FS/FSlibos.h 2001-01-17 14:41:28.000000000 -0500 ++++ xc/lib/FS/FSlibos.h 2003-09-02 19:40:48.000000000 -0500 +@@ -72,6 +72,13 @@ + #undef _POSIX_SOURCE + #endif + #endif ++#ifndef SIZE_MAX ++# ifdef ULONG_MAX ++# define SIZE_MAX ULONG_MAX ++# else ++# define SIZE_MAX UINT_MAX ++# endif ++#endif + #ifndef OPEN_MAX + #ifdef SVR4 + #define OPEN_MAX 256 +diff -urN xc/lib~/font/fc/fsconvert.c xc/lib/font/fc/fsconvert.c +--- xc/lib~/font/fc/fsconvert.c 2001-01-17 14:43:28.000000000 -0500 ++++ xc/lib/font/fc/fsconvert.c 2003-09-02 19:41:47.000000000 -0500 +@@ -36,6 +36,7 @@ + #include "fontstruct.h" + #include "fservestr.h" + #include "fontutil.h" ++#include "fslibos.h" + + extern char _fs_glyph_undefined; + extern char _fs_glyph_requested; +@@ -102,6 +103,10 @@ + + nprops = pfi->nprops = pi->num_offsets; + ++ if (nprops < 0 ++ || nprops > SIZE_MAX/(sizeof(FontPropRec) + sizeof(char))) ++ return -1; ++ + dprop = (FontPropPtr) xalloc(sizeof(FontPropRec) * nprops + + sizeof (char) * nprops); + if (!dprop) +diff -urN xc/lib~/font/fc/fserve.c xc/lib/font/fc/fserve.c +--- xc/lib~/font/fc/fserve.c 2001-04-05 12:42:27.000000000 -0500 ++++ xc/lib/font/fc/fserve.c 2003-09-02 19:43:56.000000000 -0500 +@@ -1512,7 +1512,7 @@ + if (conn->blockState & FS_GIVE_UP) + return BadFontName; + +- if (namelen > sizeof (buf) - 1) ++ if (namelen <= 0 || namelen > sizeof (buf) - 1) + return BadFontName; + + /* +diff -urN xc/lib~/font/fc/fslibos.h xc/lib/font/fc/fslibos.h +--- xc/lib~/font/fc/fslibos.h 2001-01-17 14:43:29.000000000 -0500 ++++ xc/lib/font/fc/fslibos.h 2003-09-02 19:45:21.000000000 -0500 +@@ -44,13 +44,20 @@ + #ifndef FONT_OPEN_MAX + + #ifndef X_NOT_POSIX +-#ifdef _POSIX_SOURCE +-#include <limits.h> +-#else +-#define _POSIX_SOURCE +-#include <limits.h> +-#undef _POSIX_SOURCE +-#endif ++# ifdef _POSIX_SOURCE ++# include <limits.h> ++# else ++# define _POSIX_SOURCE ++# include <limits.h> ++# undef _POSIX_SOURCE ++# endif ++#endif ++#ifndef SIZE_MAX ++# ifdef ULONG_MAX ++# define SIZE_MAX ULONG_MAX ++# else ++# define SIZE_MAX UINT_MAX ++# endif + #endif + #ifndef OPEN_MAX + #if defined(SVR4) || defined(__EMX__) -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]