Tue Jan 7 18:07:17 2014 UTC ()
xsrc/external/mit/libXfont/dist/src/bitmap/bdfread.c	patch
xsrc/xfree/xc/lib/font/bitmap/bdfread.c			patch

	Fix CVE-2013-6462: scanf without field width limits can crash
	with huge input data.
	[wiz, ticket #1896]


(bouyer)
diff -r1.1.1.1.2.1 -r1.1.1.1.2.2 xsrc/external/mit/libXfont/dist/src/bitmap/bdfread.c
diff -r1.2 -r1.2.2.1 xsrc/xfree/xc/lib/font/bitmap/bdfread.c

cvs diff -r1.1.1.1.2.1 -r1.1.1.1.2.2 xsrc/external/mit/libXfont/dist/src/bitmap/bdfread.c (expand / switch to unified diff)

--- xsrc/external/mit/libXfont/dist/src/bitmap/bdfread.c 2009/09/17 03:33:14 1.1.1.1.2.1
+++ xsrc/external/mit/libXfont/dist/src/bitmap/bdfread.c 2014/01/07 18:07:17 1.1.1.1.2.2
@@ -62,26 +62,27 @@ from The Open Group. @@ -62,26 +62,27 @@ from The Open Group.
62/* use bitmap structure */ 62/* use bitmap structure */
63#include <X11/fonts/bitmap.h> 63#include <X11/fonts/bitmap.h>
64#include <X11/fonts/bdfint.h> 64#include <X11/fonts/bdfint.h>
65 65
66#if HAVE_STDINT_H 66#if HAVE_STDINT_H
67#include <stdint.h> 67#include <stdint.h>
68#elif !defined(INT32_MAX) 68#elif !defined(INT32_MAX)
69#define INT32_MAX 0x7fffffff 69#define INT32_MAX 0x7fffffff
70#endif 70#endif
71 71
72#define INDICES 256 72#define INDICES 256
73#define MAXENCODING 0xFFFF 73#define MAXENCODING 0xFFFF
74#define BDFLINELEN 1024 74#define BDFLINELEN 1024
 75#define BDFLINESTR "%1023s" /* scanf specifier to read a BDFLINELEN string */
75 76
76static Bool bdfPadToTerminal(FontPtr pFont); 77static Bool bdfPadToTerminal(FontPtr pFont);
77extern int bdfFileLineNum; 78extern int bdfFileLineNum;
78 79
79/***====================================================================***/ 80/***====================================================================***/
80 81
81static Bool 82static Bool
82bdfReadBitmap(CharInfoPtr pCI, FontFilePtr file, int bit, int byte,  83bdfReadBitmap(CharInfoPtr pCI, FontFilePtr file, int bit, int byte,
83 int glyph, int scan, CARD32 *sizes) 84 int glyph, int scan, CARD32 *sizes)
84{ 85{
85 int widthBits, 86 int widthBits,
86 widthBytes, 87 widthBytes,
87 widthHexChars; 88 widthHexChars;
@@ -331,27 +332,27 @@ bdfReadCharacters(FontFilePtr file, Font @@ -331,27 +332,27 @@ bdfReadCharacters(FontFilePtr file, Font
331 int t; 332 int t;
332 int wx; /* x component of width */ 333 int wx; /* x component of width */
333 int wy; /* y component of width */ 334 int wy; /* y component of width */
334 int bw; /* bounding-box width */ 335 int bw; /* bounding-box width */
335 int bh; /* bounding-box height */ 336 int bh; /* bounding-box height */
336 int bl; /* bounding-box left */ 337 int bl; /* bounding-box left */
337 int bb; /* bounding-box bottom */ 338 int bb; /* bounding-box bottom */
338 int enc, 339 int enc,
339 enc2; /* encoding */ 340 enc2; /* encoding */
340 unsigned char *p; /* temp pointer into line */ 341 unsigned char *p; /* temp pointer into line */
341 char charName[100]; 342 char charName[100];
342 int ignore; 343 int ignore;
343 344
344 if (sscanf((char *) line, "STARTCHAR %s", charName) != 1) { 345 if (sscanf((char *) line, "STARTCHAR %99s", charName) != 1) {
345 bdfError("bad character name in BDF file\n"); 346 bdfError("bad character name in BDF file\n");
346 goto BAILOUT; /* bottom of function, free and return error */ 347 goto BAILOUT; /* bottom of function, free and return error */
347 } 348 }
348 if (bitmapExtra) 349 if (bitmapExtra)
349 bitmapExtra->glyphNames[ndx] = bdfForceMakeAtom(charName, NULL); 350 bitmapExtra->glyphNames[ndx] = bdfForceMakeAtom(charName, NULL);
350 351
351 line = bdfGetLine(file, lineBuf, BDFLINELEN); 352 line = bdfGetLine(file, lineBuf, BDFLINELEN);
352 if (!line || (t = sscanf((char *) line, "ENCODING %d %d", &enc, &enc2)) < 1) { 353 if (!line || (t = sscanf((char *) line, "ENCODING %d %d", &enc, &enc2)) < 1) {
353 bdfError("bad 'ENCODING' in BDF file\n"); 354 bdfError("bad 'ENCODING' in BDF file\n");
354 goto BAILOUT; 355 goto BAILOUT;
355 } 356 }
356 if (enc < -1 || (t == 2 && enc2 < -1)) { 357 if (enc < -1 || (t == 2 && enc2 < -1)) {
357 bdfError("bad ENCODING value"); 358 bdfError("bad ENCODING value");
@@ -537,33 +538,38 @@ BAILOUT: @@ -537,33 +538,38 @@ BAILOUT:
537 return (FALSE); 538 return (FALSE);
538} 539}
539 540
540/***====================================================================***/ 541/***====================================================================***/
541 542
542static Bool 543static Bool
543bdfReadHeader(FontFilePtr file, bdfFileState *pState) 544bdfReadHeader(FontFilePtr file, bdfFileState *pState)
544{ 545{
545 unsigned char *line; 546 unsigned char *line;
546 char namebuf[BDFLINELEN]; 547 char namebuf[BDFLINELEN];
547 unsigned char lineBuf[BDFLINELEN]; 548 unsigned char lineBuf[BDFLINELEN];
548 549
549 line = bdfGetLine(file, lineBuf, BDFLINELEN); 550 line = bdfGetLine(file, lineBuf, BDFLINELEN);
550 if (!line || sscanf((char *) line, "STARTFONT %s", namebuf) != 1 || 551 if (!line ||
 552 sscanf((char *) line, "STARTFONT " BDFLINESTR, namebuf) != 1 ||
551 !bdfStrEqual(namebuf, "2.1")) { 553 !bdfStrEqual(namebuf, "2.1")) {
552 bdfError("bad 'STARTFONT'\n"); 554 bdfError("bad 'STARTFONT'\n");
553 return (FALSE); 555 return (FALSE);
554 } 556 }
555 line = bdfGetLine(file, lineBuf, BDFLINELEN); 557 line = bdfGetLine(file, lineBuf, BDFLINELEN);
556 if (!line || sscanf((char *) line, "FONT %[^\n]", pState->fontName) != 1) { 558#if MAXFONTNAMELEN != 1024
 559# error "need to adjust sscanf length limit to be MAXFONTNAMELEN - 1"
 560#endif
 561 if (!line ||
 562 sscanf((char *) line, "FONT %1023[^\n]", pState->fontName) != 1) {
557 bdfError("bad 'FONT'\n"); 563 bdfError("bad 'FONT'\n");
558 return (FALSE); 564 return (FALSE);
559 } 565 }
560 line = bdfGetLine(file, lineBuf, BDFLINELEN); 566 line = bdfGetLine(file, lineBuf, BDFLINELEN);
561 if (!line || !bdfIsPrefix(line, "SIZE")) { 567 if (!line || !bdfIsPrefix(line, "SIZE")) {
562 bdfError("missing 'SIZE'\n"); 568 bdfError("missing 'SIZE'\n");
563 return (FALSE); 569 return (FALSE);
564 } 570 }
565 if (sscanf((char *) line, "SIZE %f%d%d", &pState->pointSize, 571 if (sscanf((char *) line, "SIZE %f%d%d", &pState->pointSize,
566 &pState->resolution_x, &pState->resolution_y) != 3) { 572 &pState->resolution_x, &pState->resolution_y) != 3) {
567 bdfError("bad 'SIZE'\n"); 573 bdfError("bad 'SIZE'\n");
568 return (FALSE); 574 return (FALSE);
569 } 575 }
@@ -626,27 +632,29 @@ bdfReadProperties(FontFilePtr file, Font @@ -626,27 +632,29 @@ bdfReadProperties(FontFilePtr file, Font
626 632
627 nextProp = 0; 633 nextProp = 0;
628 props_left = nProps; 634 props_left = nProps;
629 while (props_left-- > 0) { 635 while (props_left-- > 0) {
630 line = bdfGetLine(file, lineBuf, BDFLINELEN); 636 line = bdfGetLine(file, lineBuf, BDFLINELEN);
631 if (line == NULL || bdfIsPrefix(line, "ENDPROPERTIES")) { 637 if (line == NULL || bdfIsPrefix(line, "ENDPROPERTIES")) {
632 bdfError("\"STARTPROPERTIES %d\" followed by only %d properties\n", 638 bdfError("\"STARTPROPERTIES %d\" followed by only %d properties\n",
633 nProps, nProps - props_left - 1); 639 nProps, nProps - props_left - 1);
634 goto BAILOUT; 640 goto BAILOUT;
635 } 641 }
636 while (*line && isspace(*line)) 642 while (*line && isspace(*line))
637 line++; 643 line++;
638 644
639 switch (sscanf((char *) line, "%s%s%s", namebuf, secondbuf, thirdbuf)) { 645 switch (sscanf((char *) line,
 646 BDFLINESTR BDFLINESTR BDFLINESTR,
 647 namebuf, secondbuf, thirdbuf)) {
640 default: 648 default:
641 bdfError("missing '%s' parameter value\n", namebuf); 649 bdfError("missing '%s' parameter value\n", namebuf);
642 goto BAILOUT; 650 goto BAILOUT;
643 651
644 case 2: 652 case 2:
645 /* 653 /*
646 * Possibilites include: valid quoted string with no white space 654 * Possibilites include: valid quoted string with no white space
647 * valid integer value invalid value 655 * valid integer value invalid value
648 */ 656 */
649 if (secondbuf[0] == '"') { 657 if (secondbuf[0] == '"') {
650 stringProps[nextProp] = TRUE; 658 stringProps[nextProp] = TRUE;
651 props[nextProp].value = 659 props[nextProp].value =
652 bdfGetPropertyValue((char *)line + strlen(namebuf) + 1); 660 bdfGetPropertyValue((char *)line + strlen(namebuf) + 1);

cvs diff -r1.2 -r1.2.2.1 xsrc/xfree/xc/lib/font/bitmap/Attic/bdfread.c (expand / switch to unified diff)

--- xsrc/xfree/xc/lib/font/bitmap/Attic/bdfread.c 2007/04/03 20:10:34 1.2
+++ xsrc/xfree/xc/lib/font/bitmap/Attic/bdfread.c 2014/01/07 18:07:17 1.2.2.1
@@ -60,26 +60,27 @@ from The Open Group. @@ -60,26 +60,27 @@ from The Open Group.
60/* use bitmap structure */ 60/* use bitmap structure */
61#include "bitmap.h" 61#include "bitmap.h"
62#include "bdfint.h" 62#include "bdfint.h"
63 63
64#if HAVE_STDINT_H 64#if HAVE_STDINT_H
65#include <stdint.h> 65#include <stdint.h>
66#elif !defined(INT32_MAX) 66#elif !defined(INT32_MAX)
67#define INT32_MAX 0x7fffffff 67#define INT32_MAX 0x7fffffff
68#endif 68#endif
69 69
70#define INDICES 256 70#define INDICES 256
71#define MAXENCODING 0xFFFF 71#define MAXENCODING 0xFFFF
72#define BDFLINELEN 1024 72#define BDFLINELEN 1024
 73#define BDFLINESTR "%1023s" /* scanf specifier to read a BDFLINELEN string */
73 74
74static Bool bdfPadToTerminal(FontPtr pFont); 75static Bool bdfPadToTerminal(FontPtr pFont);
75extern int bdfFileLineNum; 76extern int bdfFileLineNum;
76 77
77/***====================================================================***/ 78/***====================================================================***/
78 79
79static Bool 80static Bool
80bdfReadBitmap(CharInfoPtr pCI, FontFilePtr file, int bit, int byte,  81bdfReadBitmap(CharInfoPtr pCI, FontFilePtr file, int bit, int byte,
81 int glyph, int scan, CARD32 *sizes) 82 int glyph, int scan, CARD32 *sizes)
82{ 83{
83 int widthBits, 84 int widthBits,
84 widthBytes, 85 widthBytes,
85 widthHexChars; 86 widthHexChars;
@@ -330,27 +331,27 @@ bdfReadCharacters(FontFilePtr file, Font @@ -330,27 +331,27 @@ bdfReadCharacters(FontFilePtr file, Font
330 int t; 331 int t;
331 int wx; /* x component of width */ 332 int wx; /* x component of width */
332 int wy; /* y component of width */ 333 int wy; /* y component of width */
333 int bw; /* bounding-box width */ 334 int bw; /* bounding-box width */
334 int bh; /* bounding-box height */ 335 int bh; /* bounding-box height */
335 int bl; /* bounding-box left */ 336 int bl; /* bounding-box left */
336 int bb; /* bounding-box bottom */ 337 int bb; /* bounding-box bottom */
337 int enc, 338 int enc,
338 enc2; /* encoding */ 339 enc2; /* encoding */
339 unsigned char *p; /* temp pointer into line */ 340 unsigned char *p; /* temp pointer into line */
340 char charName[100]; 341 char charName[100];
341 int ignore; 342 int ignore;
342 343
343 if (sscanf((char *) line, "STARTCHAR %s", charName) != 1) { 344 if (sscanf((char *) line, "STARTCHAR %99s", charName) != 1) {
344 bdfError("bad character name in BDF file\n"); 345 bdfError("bad character name in BDF file\n");
345 goto BAILOUT; /* bottom of function, free and return error */ 346 goto BAILOUT; /* bottom of function, free and return error */
346 } 347 }
347 if (bitmapExtra) 348 if (bitmapExtra)
348 bitmapExtra->glyphNames[ndx] = bdfForceMakeAtom(charName, NULL); 349 bitmapExtra->glyphNames[ndx] = bdfForceMakeAtom(charName, NULL);
349 350
350 line = bdfGetLine(file, lineBuf, BDFLINELEN); 351 line = bdfGetLine(file, lineBuf, BDFLINELEN);
351 if (!line || (t = sscanf((char *) line, "ENCODING %d %d", &enc, &enc2)) < 1) { 352 if (!line || (t = sscanf((char *) line, "ENCODING %d %d", &enc, &enc2)) < 1) {
352 bdfError("bad 'ENCODING' in BDF file\n"); 353 bdfError("bad 'ENCODING' in BDF file\n");
353 goto BAILOUT; 354 goto BAILOUT;
354 } 355 }
355 if (enc < -1 || (t == 2 && enc2 < -1)) { 356 if (enc < -1 || (t == 2 && enc2 < -1)) {
356 bdfError("bad ENCODING value"); 357 bdfError("bad ENCODING value");
@@ -539,33 +540,38 @@ BAILOUT: @@ -539,33 +540,38 @@ BAILOUT:
539 return (FALSE); 540 return (FALSE);
540} 541}
541 542
542/***====================================================================***/ 543/***====================================================================***/
543 544
544static Bool 545static Bool
545bdfReadHeader(FontFilePtr file, bdfFileState *pState) 546bdfReadHeader(FontFilePtr file, bdfFileState *pState)
546{ 547{
547 unsigned char *line; 548 unsigned char *line;
548 char namebuf[BDFLINELEN]; 549 char namebuf[BDFLINELEN];
549 unsigned char lineBuf[BDFLINELEN]; 550 unsigned char lineBuf[BDFLINELEN];
550 551
551 line = bdfGetLine(file, lineBuf, BDFLINELEN); 552 line = bdfGetLine(file, lineBuf, BDFLINELEN);
552 if (!line || sscanf((char *) line, "STARTFONT %s", namebuf) != 1 || 553 if (!line ||
 554 sscanf((char *) line, "STARTFONT " BDFLINESTR, namebuf) != 1 ||
553 !bdfStrEqual(namebuf, "2.1")) { 555 !bdfStrEqual(namebuf, "2.1")) {
554 bdfError("bad 'STARTFONT'\n"); 556 bdfError("bad 'STARTFONT'\n");
555 return (FALSE); 557 return (FALSE);
556 } 558 }
557 line = bdfGetLine(file, lineBuf, BDFLINELEN); 559 line = bdfGetLine(file, lineBuf, BDFLINELEN);
558 if (!line || sscanf((char *) line, "FONT %[^\n]", pState->fontName) != 1) { 560#if MAXFONTNAMELEN != 1024
 561# error "need to adjust sscanf length limit to be MAXFONTNAMELEN - 1"
 562#endif
 563 if (!line ||
 564 sscanf((char *) line, "FONT %1023[^\n]", pState->fontName) != 1) {
559 bdfError("bad 'FONT'\n"); 565 bdfError("bad 'FONT'\n");
560 return (FALSE); 566 return (FALSE);
561 } 567 }
562 line = bdfGetLine(file, lineBuf, BDFLINELEN); 568 line = bdfGetLine(file, lineBuf, BDFLINELEN);
563 if (!line || !bdfIsPrefix(line, "SIZE")) { 569 if (!line || !bdfIsPrefix(line, "SIZE")) {
564 bdfError("missing 'SIZE'\n"); 570 bdfError("missing 'SIZE'\n");
565 return (FALSE); 571 return (FALSE);
566 } 572 }
567 if (sscanf((char *) line, "SIZE %f%d%d", &pState->pointSize, 573 if (sscanf((char *) line, "SIZE %f%d%d", &pState->pointSize,
568 &pState->resolution_x, &pState->resolution_y) != 3) { 574 &pState->resolution_x, &pState->resolution_y) != 3) {
569 bdfError("bad 'SIZE'\n"); 575 bdfError("bad 'SIZE'\n");
570 return (FALSE); 576 return (FALSE);
571 } 577 }
@@ -629,27 +635,29 @@ bdfReadProperties(FontFilePtr file, Font @@ -629,27 +635,29 @@ bdfReadProperties(FontFilePtr file, Font
629 635
630 nextProp = 0; 636 nextProp = 0;
631 props_left = nProps; 637 props_left = nProps;
632 while (props_left-- > 0) { 638 while (props_left-- > 0) {
633 line = bdfGetLine(file, lineBuf, BDFLINELEN); 639 line = bdfGetLine(file, lineBuf, BDFLINELEN);
634 if (line == NULL || bdfIsPrefix(line, "ENDPROPERTIES")) { 640 if (line == NULL || bdfIsPrefix(line, "ENDPROPERTIES")) {
635 bdfError("\"STARTPROPERTIES %d\" followed by only %d properties\n", 641 bdfError("\"STARTPROPERTIES %d\" followed by only %d properties\n",
636 nProps, nProps - props_left - 1); 642 nProps, nProps - props_left - 1);
637 goto BAILOUT; 643 goto BAILOUT;
638 } 644 }
639 while (*line && isspace(*line)) 645 while (*line && isspace(*line))
640 line++; 646 line++;
641 647
642 switch (sscanf((char *) line, "%s%s%s", namebuf, secondbuf, thirdbuf)) { 648 switch (sscanf((char *) line,
 649 BDFLINESTR BDFLINESTR BDFLINESTR,
 650 namebuf, secondbuf, thirdbuf)) {
643 default: 651 default:
644 bdfError("missing '%s' parameter value\n", namebuf); 652 bdfError("missing '%s' parameter value\n", namebuf);
645 goto BAILOUT; 653 goto BAILOUT;
646 654
647 case 2: 655 case 2:
648 /* 656 /*
649 * Possibilites include: valid quoted string with no white space 657 * Possibilites include: valid quoted string with no white space
650 * valid integer value invalid value 658 * valid integer value invalid value
651 */ 659 */
652 if (secondbuf[0] == '"') { 660 if (secondbuf[0] == '"') {
653 stringProps[nextProp] = TRUE; 661 stringProps[nextProp] = TRUE;
654 props[nextProp].value = 662 props[nextProp].value =
655 bdfGetPropertyValue((char *)line + strlen(namebuf) + 1); 663 bdfGetPropertyValue((char *)line + strlen(namebuf) + 1);