Add more bounds checking

This commit is contained in:
simon987 2022-03-17 15:07:32 -04:00
parent 62ae66db99
commit b9afdb0561
6 changed files with 1349 additions and 1313 deletions

View File

@ -253,7 +253,7 @@
#define BUF_AUC 1 #define BUF_AUC 1
extern void setBufferSize(ULONG size); extern void setBufferSize(ULONG size);
extern BOOL isOutOfBounds(ULONG offset); extern BOOL isOutOfBounds(ULONG offset, size_t size);
/* Prototypes */ /* Prototypes */

View File

@ -514,6 +514,7 @@ vMove2NextPage(diagram_type *pDiag, BOOL bNewSection)
vAddHeader(pDiag); vAddHeader(pDiag);
} /* end of vMove2NextPage */ } /* end of vMove2NextPage */
#define VMOVETO_MAX_DEPTH 300
/* /*
* vMoveTo - move to the specified X,Y coordinates * vMoveTo - move to the specified X,Y coordinates
* *
@ -527,7 +528,24 @@ vMoveTo(diagram_type *pDiag, long lLastVerticalMovement)
fail(pDiag->pOutFile == NULL); fail(pDiag->pOutFile == NULL);
if (pDiag->lYtop <= lFooterHeight + PS_BOTTOM_MARGIN && !bInFtrSpace) { if (pDiag->lYtop <= lFooterHeight + PS_BOTTOM_MARGIN && !bInFtrSpace) {
vMove2NextPage(pDiag, FALSE);
// NOTE: SIST2: only output the first page
vAddFooter(pDiag);
vEndPageObject(pDiag->pOutFile);
iObjectNumberCurr++;
vSetLocation(iObjectNumberCurr);
vFillNextPageObject();
vFPprintf(pDiag->pOutFile, "%d 0 obj\n", iObjectNumberCurr);
vFPprintf(pDiag->pOutFile, "<<\n");
vFPprintf(pDiag->pOutFile, "/Type /Page\n");
vFPprintf(pDiag->pOutFile, "/Parent 3 0 R\n");
vFPprintf(pDiag->pOutFile, "/Resources 17 0 R\n");
vFPprintf(pDiag->pOutFile, "/Contents %d 0 R\n", iObjectNumberCurr + 1);
vFPprintf(pDiag->pOutFile, ">>\n");
vFPprintf(pDiag->pOutFile, "endobj\n");
// ^^^
/* Repeat the last vertical movement on the new page */ /* Repeat the last vertical movement on the new page */
pDiag->lYtop -= lLastVerticalMovement; pDiag->lYtop -= lLastVerticalMovement;
} }
@ -978,6 +996,7 @@ static void
vPrintPDF(FILE *pFile, const char *szString, size_t tStringLength, vPrintPDF(FILE *pFile, const char *szString, size_t tStringLength,
USHORT usFontstyle) USHORT usFontstyle)
{ {
const UCHAR *aucBytes; const UCHAR *aucBytes;
double dMove; double dMove;
size_t tCount; size_t tCount;

View File

@ -22,23 +22,30 @@
* iGet8InfoLength - the length of the information for Word 8/9/10/11 files * iGet8InfoLength - the length of the information for Word 8/9/10/11 files
*/ */
static int static int
iGet8InfoLength(int iByteNbr, const UCHAR *aucGrpprl) iGet8InfoLength(int iByteNbr, const UCHAR *aucGrpprl) {
{
int iTmp, iDel, iAdd; int iTmp, iDel, iAdd;
USHORT usOpCode; USHORT usOpCode;
usOpCode = usGetWord(iByteNbr, aucGrpprl); usOpCode = usGetWord(iByteNbr, aucGrpprl);
switch (usOpCode & 0xe000) { switch (usOpCode & 0xe000) {
case 0x0000: case 0x2000: case 0x0000:
case 0x2000:
return 3; return 3;
case 0x4000: case 0x8000: case 0xa000: case 0x4000:
case 0x8000:
case 0xa000:
return 4; return 4;
case 0xe000: case 0xe000:
return 5; return 5;
case 0x6000: case 0x6000:
return 6; return 6;
case 0xc000: case 0xc000:
// HOTFIX for buffer overflow (fuzzing)
if (iByteNbr + 2 >= sizeof(section_block_type) - 1) {
return 1;
}
iTmp = (int) ucGetByte(iByteNbr + 2, aucGrpprl); iTmp = (int) ucGetByte(iByteNbr + 2, aucGrpprl);
if (usOpCode == 0xc615 && iTmp == 255) { if (usOpCode == 0xc615 && iTmp == 255) {
iDel = (int) ucGetByte(iByteNbr + 3, aucGrpprl); iDel = (int) ucGetByte(iByteNbr + 3, aucGrpprl);
@ -63,8 +70,7 @@ static UCHAR *
aucFillInfoBuffer(FILE *pFile, const pps_type *pTable, aucFillInfoBuffer(FILE *pFile, const pps_type *pTable,
const ULONG *aulBBD, size_t tBBDLen, const ULONG *aulBBD, size_t tBBDLen,
const ULONG *aulSBD, size_t tSBDLen, const ULONG *aulSBD, size_t tSBDLen,
ULONG ulBeginInfo, size_t tInfoLen) ULONG ulBeginInfo, size_t tInfoLen) {
{
const ULONG *aulBlockDepot; const ULONG *aulBlockDepot;
UCHAR *aucBuffer; UCHAR *aucBuffer;
size_t tBlockDepotLen, tBlockSize; size_t tBlockDepotLen, tBlockSize;
@ -108,8 +114,7 @@ void
vGet8DopInfo(FILE *pFile, const pps_type *pTable, vGet8DopInfo(FILE *pFile, const pps_type *pTable,
const ULONG *aulBBD, size_t tBBDLen, const ULONG *aulBBD, size_t tBBDLen,
const ULONG *aulSBD, size_t tSBDLen, const ULONG *aulSBD, size_t tSBDLen,
const UCHAR *aucHeader) const UCHAR *aucHeader) {
{
document_block_type tDocument; document_block_type tDocument;
UCHAR *aucBuffer; UCHAR *aucBuffer;
ULONG ulBeginDocpInfo, ulTmp; ULONG ulBeginDocpInfo, ulTmp;
@ -153,8 +158,7 @@ vGet8DopInfo(FILE *pFile, const pps_type *pTable,
*/ */
static void static void
vGet8SectionInfo(const UCHAR *aucGrpprl, size_t tBytes, vGet8SectionInfo(const UCHAR *aucGrpprl, size_t tBytes,
section_block_type *pSection) section_block_type *pSection) {
{
UINT uiIndex; UINT uiIndex;
int iFodoOff, iInfoLen, iSize, iTmp; int iFodoOff, iInfoLen, iSize, iTmp;
USHORT usCcol; USHORT usCcol;
@ -220,8 +224,7 @@ void
vGet8SepInfo(FILE *pFile, const pps_info_type *pPPS, vGet8SepInfo(FILE *pFile, const pps_info_type *pPPS,
const ULONG *aulBBD, size_t tBBDLen, const ULONG *aulBBD, size_t tBBDLen,
const ULONG *aulSBD, size_t tSBDLen, const ULONG *aulSBD, size_t tSBDLen,
const UCHAR *aucHeader) const UCHAR *aucHeader) {
{
section_block_type tSection; section_block_type tSection;
ULONG *aulSectPage, *aulCharPos; ULONG *aulSectPage, *aulCharPos;
UCHAR *aucBuffer, *aucFpage; UCHAR *aucBuffer, *aucFpage;
@ -313,8 +316,7 @@ void
vGet8HdrFtrInfo(FILE *pFile, const pps_type *pTable, vGet8HdrFtrInfo(FILE *pFile, const pps_type *pTable,
const ULONG *aulBBD, size_t tBBDLen, const ULONG *aulBBD, size_t tBBDLen,
const ULONG *aulSBD, size_t tSBDLen, const ULONG *aulSBD, size_t tSBDLen,
const UCHAR *aucHeader) const UCHAR *aucHeader) {
{
ULONG *aulCharPos; ULONG *aulCharPos;
UCHAR *aucBuffer; UCHAR *aucBuffer;
ULONG ulHdrFtrOffset, ulBeginHdrFtrInfo; ULONG ulHdrFtrOffset, ulBeginHdrFtrInfo;
@ -363,8 +365,7 @@ vGet8HdrFtrInfo(FILE *pFile, const pps_type *pTable,
*/ */
row_info_enum row_info_enum
eGet8RowInfo(int iFodo, eGet8RowInfo(int iFodo,
const UCHAR *aucGrpprl, int iBytes, row_block_type *pRow) const UCHAR *aucGrpprl, int iBytes, row_block_type *pRow) {
{
int iFodoOff, iInfoLen; int iFodoOff, iInfoLen;
int iIndex, iSize, iCol; int iIndex, iSize, iCol;
int iPosCurr, iPosPrev; int iPosCurr, iPosPrev;
@ -387,6 +388,12 @@ eGet8RowInfo(int iFodo,
bFoundd608 = FALSE; bFoundd608 = FALSE;
while (iBytes >= iFodoOff + 2) { while (iBytes >= iFodoOff + 2) {
iInfoLen = 0; iInfoLen = 0;
// HOTFIX for buffer overflow (fuzzing)
if (iFodo + iFodoOff >= BIG_BLOCK_SIZE - 4) {
break;
}
switch (usGetWord(iFodo + iFodoOff, aucGrpprl)) { switch (usGetWord(iFodo + iFodoOff, aucGrpprl)) {
case 0x2416: /* fInTable */ case 0x2416: /* fInTable */
if (odd(ucGetByte(iFodo + iFodoOff + 2, aucGrpprl))) { if (odd(ucGetByte(iFodo + iFodoOff + 2, aucGrpprl))) {
@ -528,8 +535,7 @@ eGet8RowInfo(int iFodo,
*/ */
void void
vGet8StyleInfo(int iFodo, vGet8StyleInfo(int iFodo,
const UCHAR *aucGrpprl, int iBytes, style_block_type *pStyle) const UCHAR *aucGrpprl, int iBytes, style_block_type *pStyle) {
{
list_block_type tList6; list_block_type tList6;
const list_block_type *pList; const list_block_type *pList;
int iFodoOff, iInfoLen; int iFodoOff, iInfoLen;
@ -547,6 +553,12 @@ vGet8StyleInfo(int iFodo,
iFodoOff = 0; iFodoOff = 0;
while (iBytes >= iFodoOff + 2) { while (iBytes >= iFodoOff + 2) {
iInfoLen = 0; iInfoLen = 0;
// HOTFIX for buffer overflow (fuzzing)
if (iFodo + iFodoOff >= BIG_BLOCK_SIZE - 4) {
break;
}
usOpCode = usGetWord(iFodo + iFodoOff, aucGrpprl); usOpCode = usGetWord(iFodo + iFodoOff, aucGrpprl);
switch (usOpCode) { switch (usOpCode) {
case 0x2403: /* jc */ case 0x2403: /* jc */
@ -689,8 +701,7 @@ vGet8StyleInfo(int iFodo,
* Returns the value when found, otherwise 0 * Returns the value when found, otherwise 0
*/ */
static short static short
sGetLeftIndent(const UCHAR *aucGrpprl, size_t tBytes) sGetLeftIndent(const UCHAR *aucGrpprl, size_t tBytes) {
{
int iOffset, iInfoLen; int iOffset, iInfoLen;
USHORT usOpCode, usTmp; USHORT usOpCode, usTmp;
@ -720,8 +731,7 @@ void
vGet8LstInfo(FILE *pFile, const pps_info_type *pPPS, vGet8LstInfo(FILE *pFile, const pps_info_type *pPPS,
const ULONG *aulBBD, size_t tBBDLen, const ULONG *aulBBD, size_t tBBDLen,
const ULONG *aulSBD, size_t tSBDLen, const ULONG *aulSBD, size_t tSBDLen,
const UCHAR *aucHeader) const UCHAR *aucHeader) {
{
list_block_type tList; list_block_type tList;
const ULONG *aulBlockDepot; const ULONG *aulBlockDepot;
UCHAR *aucLfoInfo, *aucLstfInfo, *aucPapx, *aucXString; UCHAR *aucLfoInfo, *aucLstfInfo, *aucPapx, *aucXString;
@ -937,8 +947,7 @@ void
vGet8PapInfo(FILE *pFile, const pps_info_type *pPPS, vGet8PapInfo(FILE *pFile, const pps_info_type *pPPS,
const ULONG *aulBBD, size_t tBBDLen, const ULONG *aulBBD, size_t tBBDLen,
const ULONG *aulSBD, size_t tSBDLen, const ULONG *aulSBD, size_t tSBDLen,
const UCHAR *aucHeader) const UCHAR *aucHeader) {
{
row_block_type tRow; row_block_type tRow;
style_block_type tStyle; style_block_type tStyle;
ULONG *aulParfPage; ULONG *aulParfPage;
@ -999,6 +1008,12 @@ vGet8PapInfo(FILE *pFile, const pps_info_type *pPPS,
NO_DBG_DEC(iRun); NO_DBG_DEC(iRun);
for (iIndex2 = 0; iIndex2 < iRun; iIndex2++) { for (iIndex2 = 0; iIndex2 < iRun; iIndex2++) {
NO_DBG_HEX(ulGetLong(iIndex2 * 4, aucFpage)); NO_DBG_HEX(ulGetLong(iIndex2 * 4, aucFpage));
// HOTFIX for buffer overflow (fuzzing)
if ((iRun + 1) * 4 + iIndex2 * 13 >= BIG_BLOCK_SIZE - 1) {
break;
}
iFodo = 2 * (int) ucGetByte( iFodo = 2 * (int) ucGetByte(
(iRun + 1) * 4 + iIndex2 * 13, aucFpage); (iRun + 1) * 4 + iIndex2 * 13, aucFpage);
if (iFodo <= 0) { if (iFodo <= 0) {
@ -1011,6 +1026,11 @@ vGet8PapInfo(FILE *pFile, const pps_info_type *pPPS,
iLen = 2 * (int) ucGetByte(iFodo, aucFpage); iLen = 2 * (int) ucGetByte(iFodo, aucFpage);
} }
// HOTFIX for buffer overflow (fuzzing)
if (iFodo + 1 >= BIG_BLOCK_SIZE - sizeof(short)) {
break;
}
usIstd = usGetWord(iFodo + 1, aucFpage); usIstd = usGetWord(iFodo + 1, aucFpage);
vFillStyleFromStylesheet(usIstd, &tStyle); vFillStyleFromStylesheet(usIstd, &tStyle);
vGet8StyleInfo(iFodo, aucFpage + 3, iLen - 3, &tStyle); vGet8StyleInfo(iFodo, aucFpage + 3, iLen - 3, &tStyle);
@ -1067,8 +1087,7 @@ vGet8PapInfo(FILE *pFile, const pps_info_type *pPPS,
*/ */
void void
vGet8FontInfo(int iFodo, USHORT usIstd, vGet8FontInfo(int iFodo, USHORT usIstd,
const UCHAR *aucGrpprl, int iBytes, font_block_type *pFont) const UCHAR *aucGrpprl, int iBytes, font_block_type *pFont) {
{
long lTmp; long lTmp;
int iFodoOff, iInfoLen; int iFodoOff, iInfoLen;
USHORT usFtc0, usFtc1, usFtc2, usTmp; USHORT usFtc0, usFtc1, usFtc2, usTmp;
@ -1348,8 +1367,7 @@ vGet8FontInfo(int iFodo, USHORT usIstd,
*/ */
static BOOL static BOOL
bGet8PicInfo(int iFodo, bGet8PicInfo(int iFodo,
const UCHAR *aucGrpprl, int iBytes, picture_block_type *pPicture) const UCHAR *aucGrpprl, int iBytes, picture_block_type *pPicture) {
{
ULONG ulTmp; ULONG ulTmp;
int iFodoOff, iInfoLen; int iFodoOff, iInfoLen;
BOOL bFound; BOOL bFound;
@ -1405,8 +1423,7 @@ void
vGet8ChrInfo(FILE *pFile, const pps_info_type *pPPS, vGet8ChrInfo(FILE *pFile, const pps_info_type *pPPS,
const ULONG *aulBBD, size_t tBBDLen, const ULONG *aulBBD, size_t tBBDLen,
const ULONG *aulSBD, size_t tSBDLen, const ULONG *aulSBD, size_t tSBDLen,
const UCHAR *aucHeader) const UCHAR *aucHeader) {
{
font_block_type tFont; font_block_type tFont;
picture_block_type tPicture; picture_block_type tPicture;
ULONG *aulCharPage; ULONG *aulCharPage;

View File

@ -63,7 +63,7 @@ vAdd2PropModList(const UCHAR *aucPropMod)
NO_DBG_DEC(tNextFree); NO_DBG_DEC(tNextFree);
tLen = 2 + (size_t)usGetWord(0, aucPropMod); tLen = 2 + (size_t)usGetWord(0, aucPropMod);
if (isOutOfBounds(tLen)) { if (isOutOfBounds(tLen, sizeof(short))) {
return; return;
} }
NO_DBG_HEX(tLen); NO_DBG_HEX(tLen);

View File

@ -2,8 +2,8 @@
static __thread ULONG buffer; static __thread ULONG buffer;
BOOL isOutOfBounds(ULONG offset) { BOOL isOutOfBounds(ULONG offset, size_t size) {
return offset > buffer; return offset >= buffer - size;
} }
void setBufferSize(ULONG size) { void setBufferSize(ULONG size) {

View File

@ -220,7 +220,7 @@ vAnalyseSummaryInfo(const UCHAR *aucBuffer)
ulOffset = ulGetLong(12 + tIndex * 8, aucBuffer); ulOffset = ulGetLong(12 + tIndex * 8, aucBuffer);
NO_DBG_DEC(tPropID); NO_DBG_DEC(tPropID);
NO_DBG_HEX(ulOffset); NO_DBG_HEX(ulOffset);
if (isOutOfBounds(ulOffset)) { if (isOutOfBounds(ulOffset, sizeof(long))) {
return FALSE; return FALSE;
} }
tPropType = (size_t)ulGetLong(ulOffset, aucBuffer); tPropType = (size_t)ulGetLong(ulOffset, aucBuffer);
@ -280,7 +280,7 @@ vAnalyseDocumentSummaryInfo(const UCHAR *aucBuffer)
ulOffset = ulGetLong(12 + tIndex * 8, aucBuffer); ulOffset = ulGetLong(12 + tIndex * 8, aucBuffer);
NO_DBG_DEC(tPropID); NO_DBG_DEC(tPropID);
NO_DBG_HEX(ulOffset); NO_DBG_HEX(ulOffset);
if (isOutOfBounds(ulOffset)) { if (isOutOfBounds(ulOffset, sizeof(long))) {
return; return;
} }
tPropType = (size_t)ulGetLong(ulOffset, aucBuffer); tPropType = (size_t)ulGetLong(ulOffset, aucBuffer);