From 234347a70dec6e5cafbabe3cd2341361c79f5b68 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Fri, 5 Apr 2019 01:43:07 +0000 Subject: dvi and tfm parsing checks, reports from Andy Nguyen of ETH Zurich (with help from afl-fuzz in one case) git-svn-id: svn://tug.org/texlive/trunk@50773 c570f23f-e606-0410-a88d-b1316a301751 --- Build/source/texk/dvipng/dvipng-src/ChangeLog | 9 +++++++++ Build/source/texk/dvipng/dvipng-src/dvi.c | 6 ++++++ Build/source/texk/dvipng/dvipng-src/tfm.c | 17 +++++++++++++++-- 3 files changed, 30 insertions(+), 2 deletions(-) (limited to 'Build') diff --git a/Build/source/texk/dvipng/dvipng-src/ChangeLog b/Build/source/texk/dvipng/dvipng-src/ChangeLog index 6fb7cd99a5e..55954f623ed 100644 --- a/Build/source/texk/dvipng/dvipng-src/ChangeLog +++ b/Build/source/texk/dvipng/dvipng-src/ChangeLog @@ -1,3 +1,12 @@ +2019-04-04 Karl Berry + + * tfm.c (ReadTFM): check for reading outside file bounds. + Report from Andy Nguyen of ETH Zurich. + + * dvi.c (DVIGetCommand): check for (unsigned value) overflow + so we don't fail to realloc buffer if needed. + Report from Andy Nguyen of ETH Zurich, found using afl-fuzz. + 2015-03-01 Jan-Åke Larsson * RELEASE: Release 1.15 diff --git a/Build/source/texk/dvipng/dvipng-src/dvi.c b/Build/source/texk/dvipng/dvipng-src/dvi.c index 7221c315c00..283088d8188 100644 --- a/Build/source/texk/dvipng/dvipng-src/dvi.c +++ b/Build/source/texk/dvipng/dvipng-src/dvi.c @@ -208,6 +208,12 @@ unsigned char* DVIGetCommand(struct dvi_data* dvi) break; } if (strlength > 0) { /* Read string */ + if (strlength == UINT32_MAX + || strlength+1 > UINT32_MAX - (uint32_t)length) { + /* Have to check else we might not realloc buffer. */ + Fatal("strlength %u + 1 + length %u would overflow", + strlength, (uint32_t)length); + } if (strlength+1 + (uint32_t)length > commlen) { /* string + command length exceeds that of buffer */ commlen=strlength+1 + (uint32_t)length; diff --git a/Build/source/texk/dvipng/dvipng-src/tfm.c b/Build/source/texk/dvipng/dvipng-src/tfm.c index 05c4b8a5d8b..549ef214fab 100644 --- a/Build/source/texk/dvipng/dvipng-src/tfm.c +++ b/Build/source/texk/dvipng/dvipng-src/tfm.c @@ -36,6 +36,9 @@ bool ReadTFM(struct font_entry * tfontp, char* tfmname) ("\n OPEN METRICS:\t'%s'", tfmname)); if (MmapFile(tfmname,&fmmap)) return(false); position=(unsigned char*)fmmap.data; + if (fmmap.size < 10) { + Fatal("tfm file %s much too short (%u)", tfmname,fmmap.size); + } lh = UNumRead(position+2,2); bc = UNumRead(position+4,2); ec = UNumRead(position+6,2); @@ -45,6 +48,9 @@ bool ReadTFM(struct font_entry * tfontp, char* tfmname) if ((width=malloc(nw*sizeof(dviunits)))==NULL) Fatal("cannot allocate memory for TFM widths"); c=0; + if (fmmap.size < 24+(lh+ec-bc+1)*4) { + Fatal("tfm file %s ends in width table (size %u)", tfmname,fmmap.size); + } position=position+24+(lh+ec-bc+1)*4; while( c < nw ) { width[c] = SNumRead(position,4); @@ -53,6 +59,9 @@ bool ReadTFM(struct font_entry * tfontp, char* tfmname) } /* Read char widths */ c=bc; + if (fmmap.size < 24+lh*4) { + Fatal("tfm file %s ends in widths (size %u)", tfmname,fmmap.size); + } position=(unsigned char*)fmmap.data+24+lh*4; while(c <= ec) { DEBUG_PRINT(DEBUG_TFM,("\n@%ld TFM METRICS:\t", @@ -60,13 +69,17 @@ bool ReadTFM(struct font_entry * tfontp, char* tfmname) if ((tcharptr=malloc(sizeof(struct char_entry)))==NULL) Fatal("cannot allocate memory for TFM char entry"); tcharptr->data=NULL; - tcharptr->tfmw=width[*position]; + if (*position < nw) { + tcharptr->tfmw=width[*position]; + } else { + Fatal("position out of bounds for width %u, char %u",*position,c); + } DEBUG_PRINT(DEBUG_TFM,("%d [%d] %d",c,*position,tcharptr->tfmw)); tcharptr->tfmw = (dviunits) ((int64_t) tcharptr->tfmw * tfontp->s / (1 << 20)); DEBUG_PRINT(DEBUG_TFM,(" (%d)",tcharptr->tfmw)); if (c >= NFNTCHARS) /* Only positive for now */ - Fatal("tfm file %s exceeds char numbering limit",tfmname); + Fatal("tfm file %s exceeds char numbering limit %u",tfmname,NFNTCHARS); tfontp->chr[c] = tcharptr; c++; position += 4; -- cgit v1.2.3