Invalid memory access in GAtomicCounter gAtomicIncrement( ) - xpdf-4.01
Loginsoft-2019-1102
26 February, 2019
CVE Number
CVE-2019-9588
CWE
CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer
Product Details
Xpdf is a free PDF viewer and toolkit, including a text extractor, image converter, HTML converter, and more. Most of the tools are available as open source.
URL: https://www.xpdfreader.com/download.html
Vulnerable Versions
4.01
Vulnerability Details
During our research there is aInvalid memory access in GAtomicCounter gAtomicIncrement( ) located at GMutex.h in xpdf-4.01. The same be triggered by sending a crafted pdf file to the pdftops binary. It allows an attacker to cause Denial of Service (Segmentation fault) or possibly have unspecified other impact.
SYNOPSIS
In Progress
Vulnerable Source Code
static inline GAtomicCounter gAtomicIncrement(GAtomicCounter *counter) {
GAtomicCounter newVal;
Analysis
DEBUG:
GDB:
[ Legend: Modified register | Code | Heap | Stack | String ]
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── registers ────
$rax : 0x000060400000c5f0 → 0x0000000000015519
$rbx : 0x0000611000009c80 → 0x000060700000dfb0 → 0x000060200000fed0 → 0xbebebebe00000008
$rcx : 0x00007fffff7ff1b0 → 0x0000000000000007
$rdx : 0x000060400000c5d0 → 0x000061d00001cc80 → 0x000061300000de80 → 0x00000000005b1dc8 → 0x0000000000518dd8 → push rbp
$rsp : 0x00007fffff7ff000 → 0x000000000049d89c → leave
$rbp : 0x00007fffff7ff010 → 0x00007fffff7ff030 → 0x00007fffff7ff0e0 → 0x00007fffff7ff110 → 0x00007fffff7ff140 → 0x00007fffff7ff170 → 0x00007fffff7ff1d0 → 0x00007fffff7ff230
$rsi : 0x00007fffff7ff1b0 → 0x0000000000000007
$rdi : 0x000060400000c5f0 → 0x0000000000015519
$rip : 0x000000000049d220 → <_ZL16gAtomicIncrementPl+0> push rbp
$r8 : 0x000061d00001d4d8 → 0x0000000000000001
$r9 : 0x1aefa
$r10 : 0x80
$r11 : 0x00007ffff7e41ef8 → 0x0000000000000000
$r12 : 0x000000000044ca40 → <_start+0> xor ebp, ebp
$r13 : 0x00007fffffffde30 → 0x0000000000000012
$r14 : 0x0
$r15 : 0x0
$eflags: [carry PARITY adjust zero sign trap INTERRUPT direction overflow RESUME virtualx86 identification]
$cs: 0x0033 $ss: 0x002b $ds: 0x0000 $es: 0x0000 $fs: 0x0000 $gs: 0x0000
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── stack ────
0x00007fffff7ff000│+0x0000: 0x000000000049d89c → leave ← $rsp
0x00007fffff7ff008│+0x0008: 0x000060400000c5d0 → 0x000061d00001cc80 → 0x000061300000de80 → 0x00000000005b1dc8 → 0x0000000000518dd8 → push rbp
0x00007fffff7ff010│+0x0010: 0x00007fffff7ff030 → 0x00007fffff7ff0e0 → 0x00007fffff7ff110 → 0x00007fffff7ff140 → 0x00007fffff7ff170 → 0x00007fffff7ff1d0 → 0x00007fffff7ff230 ← $rbp
0x00007fffff7ff018│+0x0018: 0x000000000050953f → jmp 0x50958b
0x00007fffff7ff020│+0x0020: 0x00007fffff7ff1b0 → 0x0000000000000007
0x00007fffff7ff028│+0x0028: 0x000061d00001d360 → 0x0000000000000007
0x00007fffff7ff030│+0x0030: 0x00007fffff7ff0e0 → 0x00007fffff7ff110 → 0x00007fffff7ff140 → 0x00007fffff7ff170 → 0x00007fffff7ff1d0 → 0x00007fffff7ff230 → 0x00007fffff7ff290
0x00007fffff7ff038│+0x0038: 0x000000000053a6f8 → mov rax, QWORD PTR [rbp-0x88]
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:64 ────
0x49d21a mov rax, QWORD PTR [rbp-0x8]
0x49d21e pop rbp
0x49d21f ret
→ 0x49d220 <_ZL16gAtomicIncrementPl+0> push rbp
0x49d221 <_ZL16gAtomicIncrementPl+1> mov rbp, rsp
0x49d224 <_ZL16gAtomicIncrementPl+4> mov QWORD PTR [rbp-0x18], rdi
0x49d228 <_ZL16gAtomicIncrementPl+8> mov rdx, QWORD PTR [rbp-0x18]
0x49d22c <_ZL16gAtomicIncrementPl+12> mov eax, 0x1
0x49d231 <_ZL16gAtomicIncrementPl+17> lock xadd QWORD PTR [rdx], rax
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── source:/home/aceteam/Downloads/sources/xpdf-4.01/goo/GMutex.h+66 ────
61 // NB: this must be "long" to work on Windows
62 typedef long GAtomicCounter;
63
64 // Increment *counter by one and return the final value (after the
65 // increment).
// counter=0x00007fffff7fefe0
→ 66 static inline GAtomicCounter gAtomicIncrement(GAtomicCounter *counter) {
67 GAtomicCounter newVal;
68
69 #if defined(_WIN32)
70 newVal = _InterlockedIncrement(counter);
71 #elif defined(__GNUC__) || defined(__xlC__)
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── threads ────
[#0] Id 1, Name: "pdftops", stopped, reason: SIGSEGV
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── trace ────
[!] Cannot access memory at address 0x7fffff7fefe0
gef➤ ptype counter
type = long *
gef➤ p/d 0x7fffff7fefe0
$2 = 140737479962592
gef➤ x *counter
Cannot access memory at address 0x7fffff7fefe0
Proof of Concept
pdftops -f 2 -l 4 -level2 -noembt1 -preload -nocrop -noshrink -nocenter -pagecrop -userunit -duplex -upw rome $POC out.ps
POC FILE: REPRODUCER
Timeline
Vendor Disclosure: 2019-2-26
Public Disclosure:
Credit
Discovered by ACE Team - Loginsoft