Dear Maintainer,
I am reporting on behalf of an engineer at Quarkslab, a heap out-of-bounds write in antiword 0.37-17 when processing a malformed font-family name from a Word document.
The issue occurs in unincpy in misc.c.
unincpy copies n translated characters into its destination while reading two bytes from the source for every iteration:
for (pcDest = s1, tLen = 0; tLen < n; pcDest++, tLen++) {
usUni = usGetWord(tLen * 2, s2);
...
*pcDest = (char)ulChar;
}
In the vulnerable path, the source is the document-controlled aucFont font-name data and the destination is the fixed-size szWordFontname field.
There is no validation that the source contains 2*n bytes or that the destination has capacity for n output bytes.
A malformed font-family name can therefore cause both an out-of-bounds read of the source and writes past the destination font-name buffer.
CWE: CWE-787 (Out-of-bounds Write)
CWE-120 (Buffer Copy without Checking Size of Input)
Security impact
===============
The destination overflow corrupts adjacent heap memory. Our analysis indicates that the resulting heap corruption could potentially be used toward code execution with appropriate heap layout/grooming. Reliable arbitrary code execution has not been demonstrated.
Reproduction
============
With the attached PoC document:
antiword -a a4 ./sample_oob_write_2.doc
Expected behavior:
antiword should validate both the source length and destination capacity before performing the conversion.
The issue was reproduced with antiword 0.37-17.
I have attached the PoC document and a detailed technical report.
Regards,
Salwa Souaf
Quarkslab VulnReport Team
This seems to be the case.
However this doesn't seem to be true to me. You don't explicitly give
the source location, but the only call which fits is this one in fonts.c:
(void)unincpy(pFontTableRecord->szWordFontname,
aucFont,
sizeof(pFontTableRecord->szWordFontname) - 1);
The value passed for n is one less than the size of the fixed szWordFontname
field.
I think you've misunderstood what's happening here. The problem actually seems
to be that pFontTableRecord is past the end of pFontTable. If I apply this
patch then antiword exists with "XXX":
--- a/fonts.c
+++ b/fonts.c
@@ -865,6 +865,9 @@ vCreate8FontTable(FILE *pFile, const pps_info_type *pPPS,
NO_DBG_UNICODE(aucFont);
NO_DBG_UNICODE(aucAltFont);
}
+ if (pTmp - pFontTable >= tFontTableRecords) {
+ werr(1, "XXX\n");
+ }
vFontname2Table(aucFont, aucAltFont, 2, iEmphasis,
ucFFN, szWordFont, szOurFont, pTmp);
pTmp += 4;
[...]
When reporting a bug to Debian please test using Debian's packages not those of
a derived distribution.
Cheers,
Olly
Control: tag 1144645 + pending
Control: clone 1144645 -1
Control: retitle -1 antiword: heap out-of-bounds read during Unicode font-name conversion
Control: severity -1 normal
I have a fix for this (and two similar cases for the font table handling
for other versions of the file format).
The OOB read is not really the same problem so I've split that into a
new bug.
Cheers,
Olly