diff options
author | Caolán McNamara <caolanm@redhat.com> | 2011-07-11 09:02:15 +0100 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2011-07-11 09:06:54 +0100 |
commit | 00741c9434785b18bff32357568f733922ef6eab (patch) | |
tree | caa2e726a085325bc36beeb1170f550d3533e398 | |
parent | 500cbd2718901ea51b61de36d858cde650196a55 (diff) |
check that seeks succeed, sanity check count of styles against recorded length
-rw-r--r-- | sw/qa/core/data/ww8/fail/CVE-2006-2389-1.doc | bin | 0 -> 98816 bytes | |||
-rw-r--r-- | sw/qa/core/data/ww8/pass/CVE-2006-6561-1.doc | bin | 0 -> 26624 bytes | |||
-rw-r--r-- | sw/source/filter/ww8/ww8par2.cxx | 18 | ||||
-rw-r--r-- | sw/source/filter/ww8/ww8scan.cxx | 51 | ||||
-rw-r--r-- | sw/source/filter/ww8/ww8scan.hxx | 2 |
5 files changed, 45 insertions, 26 deletions
diff --git a/sw/qa/core/data/ww8/fail/CVE-2006-2389-1.doc b/sw/qa/core/data/ww8/fail/CVE-2006-2389-1.doc Binary files differnew file mode 100644 index 000000000000..a1bf07a71a82 --- /dev/null +++ b/sw/qa/core/data/ww8/fail/CVE-2006-2389-1.doc diff --git a/sw/qa/core/data/ww8/pass/CVE-2006-6561-1.doc b/sw/qa/core/data/ww8/pass/CVE-2006-6561-1.doc Binary files differnew file mode 100644 index 000000000000..240ea77bca12 --- /dev/null +++ b/sw/qa/core/data/ww8/pass/CVE-2006-6561-1.doc diff --git a/sw/source/filter/ww8/ww8par2.cxx b/sw/source/filter/ww8/ww8par2.cxx index aadcce0b74de..c843d3e48564 100644 --- a/sw/source/filter/ww8/ww8par2.cxx +++ b/sw/source/filter/ww8/ww8par2.cxx @@ -3680,14 +3680,13 @@ void WW8RStyle::ImportSprms(sal_Size nPosFc, short nLen, bool bPap) if (!nLen) return; - sal_uInt8 *pSprms = new sal_uInt8[nLen]; - - pStStrm->Seek(nPosFc); - pStStrm->Read(pSprms, nLen); - - ImportSprms(pSprms, nLen, bPap); - - delete[] pSprms; + if (checkSeek(*pStStrm, nPosFc)) + { + sal_uInt8 *pSprms = new sal_uInt8[nLen]; + nLen = pStStrm->Read(pSprms, nLen); + ImportSprms(pSprms, nLen, bPap); + delete[] pSprms; + } } static inline short WW8SkipOdd(SvStream* pSt ) @@ -3714,8 +3713,6 @@ static inline short WW8SkipEven(SvStream* pSt ) short WW8RStyle::ImportUPX(short nLen, bool bPAP, bool bOdd) { - sal_Int16 cbUPX; - if( 0 < nLen ) // Empty ? { if (bOdd) @@ -3723,6 +3720,7 @@ short WW8RStyle::ImportUPX(short nLen, bool bPAP, bool bOdd) else nLen = nLen - WW8SkipOdd( pStStrm ); + sal_Int16 cbUPX(0); *pStStrm >> cbUPX; nLen-=2; diff --git a/sw/source/filter/ww8/ww8scan.cxx b/sw/source/filter/ww8/ww8scan.cxx index 03c79af21c8f..e2c65b1ab439 100644 --- a/sw/source/filter/ww8/ww8scan.cxx +++ b/sw/source/filter/ww8/ww8scan.cxx @@ -5940,23 +5940,35 @@ WW8Style::WW8Style(SvStream& rStream, WW8Fib& rFibPara) stiMaxWhenSaved(0), istdMaxFixedWhenSaved(0), nVerBuiltInNamesWhenSaved(0), ftcAsci(0), ftcFE(0), ftcOther(0), ftcBi(0) { - nStyleStart = rFib.fcStshf; - nStyleLen = rFib.lcbStshf; - - rSt.Seek(nStyleStart); + if (!checkSeek(rSt, rFib.fcStshf)) + return; sal_uInt16 cbStshi = 0; // 2 bytes size of the following STSHI structure + sal_uInt32 nRemaining = rFib.lcbStshf; + const sal_uInt32 nMinValidStshi = 4; if (rFib.GetFIBVersion() <= ww::eWW2) { cbStshi = 0; cstd = 256; } - else if (rFib.nFib < 67) // old Version ? (need to find this again to fix) - cbStshi = 4; // -> Laengenfeld fehlt - else // neue Version: - // lies die Laenge der in der Datei gespeicherten Struktur - rSt >> cbStshi; + else + { + if (rFib.nFib < 67) // old Version ? (need to find this again to fix) + cbStshi = nMinValidStshi; + else // new version + { + if (nRemaining < sizeof(cbStshi)) + return; + // lies die Laenge der in der Datei gespeicherten Struktur + rSt >> cbStshi; + nRemaining-=2; + } + } + + cbStshi = std::min(static_cast<sal_uInt32>(cbStshi), nRemaining); + if (cbStshi < nMinValidStshi) + return; sal_uInt16 nRead = cbStshi; do @@ -6003,10 +6015,16 @@ WW8Style::WW8Style(SvStream& rStream, WW8Fib& rFibPara) while( !this ); // Trick: obiger Block wird genau einmal durchlaufen // und kann vorzeitig per "break" verlassen werden. - if( 0 != rSt.GetError() ) - { - // wie denn nun den Error melden? - } + nRemaining -= cbStshi; + + //There will be stshi.cstd (cbSTD, STD) pairs in the file following the + //STSHI. Note that styles can be empty, i.e. cbSTD == 0 + const sal_uInt32 nMinRecordSize = sizeof(sal_uInt16); + sal_uInt16 nMaxPossibleRecords = nRemaining/nMinRecordSize; + + OSL_ENSURE(cstd <= nMaxPossibleRecords, + "allegedly more styles that available data\n"); + cstd = std::min(cstd, nMaxPossibleRecords); } // Read1STDFixed() liest ein Style ein. Wenn der Style vollstaendig vorhanden @@ -6017,7 +6035,7 @@ WW8_STD* WW8Style::Read1STDFixed( short& rSkip, short* pcbStd ) { WW8_STD* pStd = 0; - sal_uInt16 cbStd; + sal_uInt16 cbStd(0); rSt >> cbStd; // lies Laenge sal_uInt16 nRead = cbSTDBaseInFile; @@ -6034,6 +6052,7 @@ WW8_STD* WW8Style::Read1STDFixed( short& rSkip, short* pcbStd ) sal_uInt16 a16Bit; if( 2 > nRead ) break; + a16Bit = 0; rSt >> a16Bit; pStd->sti = a16Bit & 0x0fff ; pStd->fScratch = 0 != ( a16Bit & 0x1000 ); @@ -6042,20 +6061,24 @@ WW8_STD* WW8Style::Read1STDFixed( short& rSkip, short* pcbStd ) pStd->fMassCopy = 0 != ( a16Bit & 0x8000 ); if( 4 > nRead ) break; + a16Bit = 0; rSt >> a16Bit; pStd->sgc = a16Bit & 0x000f ; pStd->istdBase = ( a16Bit & 0xfff0 ) >> 4; if( 6 > nRead ) break; + a16Bit = 0; rSt >> a16Bit; pStd->cupx = a16Bit & 0x000f ; pStd->istdNext = ( a16Bit & 0xfff0 ) >> 4; if( 8 > nRead ) break; + a16Bit = 0; rSt >> pStd->bchUpe; // ab Ver8 sollten diese beiden Felder dazukommen: if(10 > nRead ) break; + a16Bit = 0; rSt >> a16Bit; pStd->fAutoRedef = a16Bit & 0x0001 ; pStd->fHidden = ( a16Bit & 0x0002 ) >> 2; diff --git a/sw/source/filter/ww8/ww8scan.hxx b/sw/source/filter/ww8/ww8scan.hxx index fcc4babed459..78454f50fe1e 100644 --- a/sw/source/filter/ww8/ww8scan.hxx +++ b/sw/source/filter/ww8/ww8scan.hxx @@ -1457,8 +1457,6 @@ class WW8Style protected: WW8Fib& rFib; SvStream& rSt; - long nStyleStart; - long nStyleLen; sal_uInt16 cstd; // Count of styles in stylesheet sal_uInt16 cbSTDBaseInFile; // Length of STD Base as stored in a file |