summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2011-07-11 09:02:15 +0100
committerCaolán McNamara <caolanm@redhat.com>2011-07-11 09:06:54 +0100
commit00741c9434785b18bff32357568f733922ef6eab (patch)
treecaa2e726a085325bc36beeb1170f550d3533e398
parent500cbd2718901ea51b61de36d858cde650196a55 (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.docbin0 -> 98816 bytes
-rw-r--r--sw/qa/core/data/ww8/pass/CVE-2006-6561-1.docbin0 -> 26624 bytes
-rw-r--r--sw/source/filter/ww8/ww8par2.cxx18
-rw-r--r--sw/source/filter/ww8/ww8scan.cxx51
-rw-r--r--sw/source/filter/ww8/ww8scan.hxx2
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
new file mode 100644
index 000000000000..a1bf07a71a82
--- /dev/null
+++ b/sw/qa/core/data/ww8/fail/CVE-2006-2389-1.doc
Binary files differ
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
new file mode 100644
index 000000000000..240ea77bca12
--- /dev/null
+++ b/sw/qa/core/data/ww8/pass/CVE-2006-6561-1.doc
Binary files differ
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