From: mike Date: Thu, 9 Oct 2008 20:13:21 +0000 (+0000) Subject: Security-related integer overflow fixes (STR #2911, STR #2918, and X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=6d496d63d9d6505bfedcd3c2e82d12f156d44f57;p=thirdparty%2Fcups.git Security-related integer overflow fixes (STR #2911, STR #2918, and STR #2919) git-svn-id: svn+ssh://src.apple.com/svn/cups/cups.org/trunk@8040 7a7537e8-13f0-0310-91df-b6672ffda945 --- diff --git a/CHANGES-1.3.txt b/CHANGES-1.3.txt index 5448f0cdd2..173fbfe2a4 100644 --- a/CHANGES-1.3.txt +++ b/CHANGES-1.3.txt @@ -3,7 +3,14 @@ CHANGES-1.3.txt CHANGES IN CUPS V1.3.9 + - SECURITY: The HP-GL/2 filter did not range check pen numbers + (STR #2911) + - SECURITY: The SGI image file reader did not range check + 16-bit run lengths (STR #2918) + - SECURITY: The text filter did not range check cpi, lpi, or + column values (STR #2919) - Documentation updates (STR #2904, STR #2944) + - The French web admin page was never updated (STR #2963) - The IPP backend did not retry print jobs when the printer reported itself as busy or unavailable (STR #2951) - The "Set Allowed Users" web interface did not handle trailing diff --git a/filter/hpgl-attr.c b/filter/hpgl-attr.c index 8eb6291987..abfc1dd647 100644 --- a/filter/hpgl-attr.c +++ b/filter/hpgl-attr.c @@ -197,8 +197,18 @@ NP_number_pens(int num_params, /* I - Number of parameters */ if (num_params == 0) PenCount = 8; - else if (num_params == 1 && params[0].value.number <= 1024) - PenCount = (int)params[0].value.number; + else if (num_params == 1) + { + if (params[0].value.number < 1 || params[0].value.number > MAX_PENS) + { + fprintf(stderr, + "DEBUG: HP-GL/2 \'NP\' command with invalid number of " + "pens (%d)!\n", (int)params[0].value.number); + PenCount = 8; + } + else + PenCount = (int)params[0].value.number; + } else fprintf(stderr, "DEBUG: HP-GL/2 \'NP\' command with invalid number of " @@ -235,7 +245,7 @@ PC_pen_color(int num_params, /* I - Number of parameters */ if (num_params == 0) { - for (i = 0; i <= PenCount; i ++) + for (i = 0; i < PenCount; i ++) if (i < 8) { Pens[i].rgb[0] = standard_colors[i][0]; @@ -256,7 +266,14 @@ PC_pen_color(int num_params, /* I - Number of parameters */ } else if (num_params == 1 || num_params == 4) { - i = (int)params[0].value.number; + i = (int)params[0].value.number - 1; + + if (i < 0 || i >= PenCount) + { + fprintf(stderr, + "DEBUG: HP-GL/2 \'PC\' command with invalid pen (%d)!\n", i + 1); + return; + } if (num_params == 1) { @@ -330,7 +347,15 @@ PW_pen_width(int num_params, /* I - Number of parameters */ if (num_params == 2) { - pen = (int)params[1].value.number; + pen = (int)params[1].value.number - 1; + + if (pen < 0 || pen >= PenCount) + { + fprintf(stderr, + "DEBUG: HP-GL/2 \'PW\' command with invalid pen (%d)!\n", + pen + 1); + return; + } Pens[pen].width = w; @@ -345,7 +370,7 @@ PW_pen_width(int num_params, /* I - Number of parameters */ * Set width for all pens... */ - for (pen = 0; pen <= PenCount; pen ++) + for (pen = 0; pen < PenCount; pen ++) Pens[pen].width = w; if (PageDirty) @@ -399,14 +424,16 @@ SP_select_pen(int num_params, /* I - Number of parameters */ param_t *params) /* I - Parameters */ { if (num_params == 0) - PenNumber = 1; - else if (params[0].value.number <= PenCount) - PenNumber = (int)params[0].value.number; - else + PenNumber = 0; + else if (num_params > 1) fprintf(stderr, - "DEBUG: HP-GL/2 \'SP\' command with invalid number or value " - "of parameters (%d, %d)!\n", num_params, + "DEBUG: HP-GL/2 \'SP\' command with invalid number of parameters " + "(%d)!\n", num_params); + else if (params[0].value.number <= 0 || params[0].value.number >= PenCount) + fprintf(stderr, "DEBUG: HP-GL/2 \'SP\' command with invalid pen (%d)!\n", (int)params[0].value.number); + else + PenNumber = (int)params[0].value.number - 1; if (PageDirty) printf("%.3f %.3f %.3f %.2f SP\n", Pens[PenNumber].rgb[0], diff --git a/filter/hpgltops.h b/filter/hpgltops.h index 16604d7844..e262975dc3 100644 --- a/filter/hpgltops.h +++ b/filter/hpgltops.h @@ -26,6 +26,14 @@ # define M_PI 3.14159265358979323846 #endif /* M_PI */ + +/* + * Maximum number of pens we emulate... + */ + +#define MAX_PENS 1024 + + /* * Parameter value structure... */ @@ -108,10 +116,10 @@ VAR float PenPosition[2] VALUE2(0.0f, 0.0f), /* Current pen position */ PenScaling VALUE(1.0f), /* Pen width scaling factor */ PenWidth VALUE(1.0f); /* Default pen width */ -VAR pen_t Pens[1024]; /* State of each pen */ +VAR pen_t Pens[MAX_PENS]; /* State of each pen */ VAR int PenMotion VALUE(0), /* 0 = absolute, 1 = relative */ PenValid VALUE(0), /* 1 = valid position, 0 = undefined */ - PenNumber VALUE(1), /* Current pen number */ + PenNumber VALUE(0), /* Current pen number */ PenCount VALUE(8), /* Number of pens */ PenDown VALUE(0), /* 0 = pen up, 1 = pen down */ PolygonMode VALUE(0), /* Drawing polygons? */ diff --git a/filter/image-sgilib.c b/filter/image-sgilib.c index 14888ca45d..afa132e3a8 100644 --- a/filter/image-sgilib.c +++ b/filter/image-sgilib.c @@ -640,13 +640,14 @@ read_rle8(FILE *fp, /* I - File to read from */ if (ch & 128) { for (i = 0; i < count; i ++, row ++, xsize --, length ++) - *row = getc(fp); + if (xsize > 0) + *row = getc(fp); } else { ch = getc(fp); length ++; - for (i = 0; i < count; i ++, row ++, xsize --) + for (i = 0; i < count && xsize > 0; i ++, row ++, xsize --) *row = ch; } } @@ -685,14 +686,15 @@ read_rle16(FILE *fp, /* I - File to read from */ if (ch & 128) { for (i = 0; i < count; i ++, row ++, xsize --, length ++) - *row = getshort(fp); + if (xsize > 0) + *row = getshort(fp); } else { ch = getshort(fp); length ++; - for (i = 0; i < count; i ++, row ++, xsize --) - *row = ch; + for (i = 0; i < count && xsize > 0; i ++, row ++, xsize --) + *row = ch; } } diff --git a/filter/textcommon.c b/filter/textcommon.c index afcec062cd..167eb590e7 100644 --- a/filter/textcommon.c +++ b/filter/textcommon.c @@ -3,7 +3,7 @@ * * Common text filter routines for the Common UNIX Printing System (CUPS). * - * Copyright 2007 by Apple Inc. + * Copyright 2007-2008 by Apple Inc. * Copyright 1997-2007 by Easy Software Products. * * These coded instructions, statements, and computer programs are the @@ -606,14 +606,38 @@ TextMain(const char *name, /* I - Name of filter */ !strcasecmp(val, "yes"); if ((val = cupsGetOption("columns", num_options, options)) != NULL) + { PageColumns = atoi(val); + if (PageColumns < 1) + { + _cupsLangPrintf(stderr, _("ERROR: Bad columns value %d!\n"), PageColumns); + return (1); + } + } + if ((val = cupsGetOption("cpi", num_options, options)) != NULL) + { CharsPerInch = atof(val); + if (CharsPerInch <= 0.0) + { + _cupsLangPrintf(stderr, _("ERROR: Bad cpi value %f!\n"), CharsPerInch); + return (1); + } + } + if ((val = cupsGetOption("lpi", num_options, options)) != NULL) + { LinesPerInch = atof(val); + if (LinesPerInch <= 0.0) + { + _cupsLangPrintf(stderr, _("ERROR: Bad lpi value %f!\n"), LinesPerInch); + return (1); + } + } + if (PrettyPrint) PageTop -= 216.0f / LinesPerInch; diff --git a/filter/texttops.c b/filter/texttops.c index aad75c1a2d..c08ff86446 100644 --- a/filter/texttops.c +++ b/filter/texttops.c @@ -173,6 +173,14 @@ WriteProlog(const char *title, /* I - Title of job */ SizeColumns = (PageRight - PageLeft) / 72.0 * CharsPerInch; SizeLines = (PageTop - PageBottom) / 72.0 * LinesPerInch; + if (SizeColumns <= 0 || SizeColumns > 32767 || + SizeLines <= 0 || SizeLines > 32767) + { + _cupsLangPrintf(stderr, _("ERROR: Unable to print %dx%d text page!\n"), + SizeColumns, SizeLines); + exit(1); + } + Page = calloc(sizeof(lchar_t *), SizeLines); Page[0] = calloc(sizeof(lchar_t), SizeColumns * SizeLines); for (i = 1; i < SizeLines; i ++) @@ -187,6 +195,13 @@ WriteProlog(const char *title, /* I - Title of job */ else ColumnWidth = SizeColumns; + if (ColumnWidth <= 0) + { + _cupsLangPrintf(stderr, _("ERROR: Unable to print %d text columns!\n"), + PageColumns); + exit(1); + } + /* * Output the DSC header... */