Bug 1696638 (CVE-2019-10872)
| Summary: | CVE-2019-10872 poppler: heap-based buffer over-read in function Splash::blitTransparent in splash/Splash.cc | ||
|---|---|---|---|
| Product: | [Other] Security Response | Reporter: | Dhananjay Arunesh <darunesh> |
| Component: | vulnerability | Assignee: | Red Hat Product Security <security-response-team> |
| Status: | CLOSED NOTABUG | QA Contact: | |
| Severity: | medium | Docs Contact: | |
| Priority: | medium | ||
| Version: | unspecified | CC: | caillon+fedoraproject, feborges, gnome-sig, john.j5live, mclasen, mkasik, rdieter, rhughes, rstrode, sandmann |
| Target Milestone: | --- | Keywords: | Security |
| Target Release: | --- | ||
| Hardware: | All | ||
| OS: | Linux | ||
| Whiteboard: | |||
| Fixed In Version: | Doc Type: | If docs needed, set a value | |
| Doc Text: | Story Points: | --- | |
| Clone Of: | Environment: | ||
| Last Closed: | 2019-06-10 10:53:40 UTC | Type: | --- |
| Regression: | --- | Mount Type: | --- |
| Documentation: | --- | CRM: | |
| Verified Versions: | Category: | --- | |
| oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |
| Cloudforms Team: | --- | Target Upstream Version: | |
| Embargoed: | |||
| Bug Depends On: | 1696640 | ||
| Bug Blocks: | 1696639 | ||
|
Description
Dhananjay Arunesh
2019-04-05 10:38:15 UTC
Created poppler tracking bugs for this issue: Affects: fedora-all [bug 1696640] Couldn't reproduce this on any versions we ship, but it did spit out a mildly interesting out of memory error.
```
Error (7289): Illegal character <6f> in hex string
Error (7298): Illegal character <52> in hex string
Error (7301): Illegal character '>'
Error: font resource is not a dictionary
Out of memory
```
Rebuilt with address sanitizer and we get:
```
Syntax Error (7301): Illegal character '>'
Syntax Error: font resource is not a dictionary
==8038== ERROR: AddressSanitizer failed to allocate 0x80002000 (2147491840) bytes of LargeMmapAllocator: Cannot allocate memory
==8038== Process memory map follows:
0x000000400000-0x000000408000 /usr/bin/pdftoppm
0x000000608000-0x000000609000 /usr/bin/pdftoppm
0x000000609000-0x00000060b000 /usr/bin/pdftoppm
```
Asan BT:
```
#0 0x7ffff4e5db9a (/usr/lib64/libasan.so.0.0.0+0x12b9a)
#1 0x7ffff4e64e03 (/usr/lib64/libasan.so.0.0.0+0x19e03)
#2 0x7ffff4e674f3 (/usr/lib64/libasan.so.0.0.0+0x1c4f3)
#3 0x7ffff4e53ee8 (/usr/lib64/libasan.so.0.0.0+0x8ee8)
#4 0x7ffff4e60f21 (/usr/lib64/libasan.so.0.0.0+0x15f21)
#5 0x7ffff499164b (/usr/lib64/libpoppler.so.46.0.0+0x3fd64b) // gmalloc
#6 0x7ffff499187a (/usr/lib64/libpoppler.so.46.0.0+0x3fd87a) // inline static void *gmallocn(int nObjs, int objSize, bool checkoverflow) {
#7 0x7ffff499189e (/usr/lib64/libpoppler.so.46.0.0+0x3fd89e) // void *gmallocn(int nObjs, int objSize) {
#8 0x7ffff4a0fd75 (/usr/lib64/libpoppler.so.46.0.0+0x47bd75) // alpha = (Guchar *)gmallocn(width, height);
#9 0x7ffff4725779 (/usr/lib64/libpoppler.so.46.0.0+0x191779)
#10 0x7ffff47f402e (/usr/lib64/libpoppler.so.46.0.0+0x26002e)
#11 0x7ffff47f2eb0 (/usr/lib64/libpoppler.so.46.0.0+0x25eeb0)
```
Seems like a correctly handled out of memory condition. Size of 2147491840 is a bit suspect.
gmalloc throws the error in goo/gmem.cc.
```c
if (!(p = malloc(size))) {
fprintf(stderr, "Out of memory\n");
if (checkoverflow) return NULL;
else exit(1);
}
```
which is called by: `inline static void *gmallocn(int nObjs, int objSize, bool checkoverflow) {`
which is eventually called by splash/SplashBitmap.cc in SplashBitmap::SplashBitmap:
```c
if (alphaA) {
alpha = (Guchar *)gmallocn(width, height);
} else {
alpha = NULL;
}
```
Looks like SplashBitmap is getting constructed with a widthA of a large value (widthA=2147482383). See this backtrace before the malloc fails:
```
(gdb) bt
#0 SplashBitmap::SplashBitmap (this=0x600800120a90, widthA=2147482383, heightA=1, rowPadA=4, modeA=splashModeMono1, alphaA=true,
topDown=true, separationListA=0x60060003b3b0) at SplashBitmap.cc:57
#1 0x00007ffff472577a in SplashOutputDev::beginTransparencyGroup (this=0x602c0000fe00, state=0x603e0000da00, bbox=0x7fffffffcbd0,
blendingColorSpace=0x0, isolated=false, knockout=false, forSoftMask=false) at SplashOutputDev.cc:3851
#2 0x00007ffff47f402f in Gfx::drawForm (this=0x60240001e180, str=0x7fffffffcda0, resDict=0x600e000277e0, matrix=0x7fffffffcc10,
bbox=0x7fffffffcbd0, transpGroup=true, softMask=false, blendingColorSpace=0x0, isolated=false, knockout=false, alpha=false,
transferFunc=0x0, backdropColor=0x0) at Gfx.cc:4910
#3 0x00007ffff47f2eb1 in Gfx::doForm (this=0x60240001e180, str=0x7fffffffcda0) at Gfx.cc:4845
#4 0x00007ffff47eedd3 in Gfx::opXObject (this=0x60240001e180, args=0x7fffffffd0a0, numArgs=1) at Gfx.cc:4199
#5 0x00007ffff47c8aaf in Gfx::execOp (this=0x60240001e180, cmd=0x7fffffffd000, args=0x7fffffffd0a0, numArgs=1) at Gfx.cc:904
#6 0x00007ffff47c7c42 in Gfx::go (this=0x60240001e180, topLevel=false) at Gfx.cc:763
#7 0x00007ffff47c7854 in Gfx::display (this=0x60240001e180, obj=0x7fffffffd8e0, topLevel=false) at Gfx.cc:729
#8 0x00007ffff47f41fe in Gfx::drawForm (this=0x60240001e180, str=0x7fffffffd8e0, resDict=0x600e00005650, matrix=0x7fffffffd750,
bbox=0x7fffffffd710, transpGroup=true, softMask=false, blendingColorSpace=0x0, isolated=false, knockout=false, alpha=false,
transferFunc=0x0, backdropColor=0x0) at Gfx.cc:4922
#9 0x00007ffff47f2eb1 in Gfx::doForm (this=0x60240001e180, str=0x7fffffffd8e0) at Gfx.cc:4845
#10 0x00007ffff47eedd3 in Gfx::opXObject (this=0x60240001e180, args=0x7fffffffdbe0, numArgs=1) at Gfx.cc:4199
#11 0x00007ffff47c8aaf in Gfx::execOp (this=0x60240001e180, cmd=0x7fffffffdb40, args=0x7fffffffdbe0, numArgs=1) at Gfx.cc:904
#12 0x00007ffff47c7c42 in Gfx::go (this=0x60240001e180, topLevel=true) at Gfx.cc:763
#13 0x00007ffff47c7854 in Gfx::display (this=0x60240001e180, obj=0x7fffffffe040, topLevel=true) at Gfx.cc:729
#14 0x00007ffff48ab19f in Page::displaySlice (this=0x60220001fa80, out=0x602c0000fe00, hDPI=150, vDPI=150, rotate=0,
useMediaBox=false, crop=false, sliceX=0, sliceY=0, sliceW=1275, sliceH=1651, printing=false, abortCheckCbk=0x0,
abortCheckCbkData=0x0, annotDisplayDecideCbk=0x0, annotDisplayDecideCbkData=0x0, copyXRef=false) at Page.cc:585
#15 0x00007ffff48b2bbc in PDFDoc::displayPageSlice (this=0x601c0000df60, out=0x602c0000fe00, page=2, hDPI=150, vDPI=150, rotate=0,
useMediaBox=false, crop=false, printing=false, sliceX=0, sliceY=0, sliceW=1275, sliceH=1651, abortCheckCbk=0x0,
abortCheckCbkData=0x0, annotDisplayDecideCbk=0x0, annotDisplayDecideCbkData=0x0, copyXRef=false) at PDFDoc.cc:503
#16 0x0000000000401cfe in savePageSlice (doc=0x601c0000df60, splashOut=0x602c0000fe00, pg=2, x=0, y=0, w=1275, h=1651, pg_w=1275,
pg_h=1650.0000000000002, ppmFile=0x0) at pdftoppm.cc:222
#17 0x0000000000403098 in main (argc=2, argv=0x7fffffffe428) at pdftoppm.cc:521
```
Behavior seems fine then. Large value is passed to a memory allocation, it fails, it is checked, execution terminates after the failure.
To summarize this: Unable to reproduce the heap-overread in any version shipped. Explored the out-of-memory error, looks benign. |