Page MenuHome GnuPG
Authored By
werner
Fri, Feb 13, 11:30 AM
Size
3 KB
Subscribers
None
FINDING 1: Heap Out-of-Bounds Read in parse_rdn()
==================================================
Severity: Medium (memory safety violation + potential info disclosure)
CWE: CWE-125 (Out-of-bounds Read)
Location: src/dn.c, parse_rdn(), line 909
Since: ~2002
Root Cause
----------
The hex-escape parsing loop in parse_rdn() has a double increment:
for (; hexdigitp (s); s++)
s++; /* <-- BUG: extra increment */
The for-statement increments s at the end of each iteration, AND
the loop body also increments s, so the pointer advances by 2 per
iteration instead of 1. When the hex string has an odd number of
characters, or when the double-stepping causes the pointer to skip
past the null terminator, parse_rdn() reads past the end of the
heap-allocated buffer.
Trigger
-------
Any RFC 2253 DN string containing a hex-escape (#-syntax) with an
odd number of hex digits triggers the bug:
C=#b
CN=#abc
O=#12345
The minimal reproducer is 4 bytes: C=#b
Reproducer Commands
-------------------
# Using public API:
echo -n 'C=#b' | ksba_dn_str2der
# Using fuzz harness:
echo -n 'C=#b' > crash.txt && ./fuzz_ksba_dn crash.txt
ASAN Output
-----------
==PID==ERROR: AddressSanitizer: heap-buffer-overflow on address
READ of size 1 at 0x502000000015
#0 parse_rdn src/dn.c:909:14
#1 _ksba_dn_from_str src/dn.c:1076:13
0x502000000015 is located 0 bytes after 5-byte region
[0x502000000010,0x502000000015)
Impact Analysis
---------------
1. DENIAL OF SERVICE: With ASAN, the OOB read triggers an immediate
abort. Without ASAN, behavior depends on heap layout:
- If the over-read hits an unmapped page: SIGSEGV crash
- If the over-read stays within mapped memory: silent corruption
2. INFORMATION DISCLOSURE: Without ASAN, the over-read bytes are
consumed by hexdigitp() and may be incorporated into the parsed
DN output string. If the caller returns, logs, or displays the
DN (e.g., showing certificate subject in gpgsm), adjacent heap
contents could leak into the output.
3. HEAP METADATA CORRUPTION: Fuzzing produced 62 crashes that
decompose into three crash sites:
- dn.c:909 (primary OOB read)
- dn.c:949 (secondary access on corrupted pointer state)
- malloc() (ASAN detects corrupted heap metadata on next alloc)
The malloc() crashes prove the OOB read damages heap state
beyond a simple one-byte over-read. Depending on allocator
layout, this could be leveraged for further exploitation.
Reachability in GnuPG
---------------------
_ksba_dn_from_str() is called from ksba_dn_str2der(), the public
API for converting RFC 2253 DN strings to DER encoding. This is
reachable in GnuPG when:
- Importing certificates with DN attributes
- Processing certificate requests
- Any gpgsm operation handling user-supplied DNs
- dirmngr processing certificate data from network sources
Crash Corpus Summary
--------------------
62 total crashes found, all sharing the same root cause.
Three distinct crash sites (by ASAN #0 frame):
- parse_rdn at dn.c:909 (~16 unique inputs)
- parse_rdn at dn.c:949 (~30 unique inputs)
- malloc interceptor (~16 unique inputs)
All enter through: main → _ksba_dn_from_str (dn.c:1076) → parse_rdn
Suggested Fix
-------------
Remove the extra s++ from the loop body:
/* BEFORE (buggy): */
for (; hexdigitp (s); s++)
s++;
/* AFTER (fixed): */
for (; hexdigitp (s); s++)
; /* just count hex digits */
/* Or equivalently: */
while (hexdigitp (s))
s++;
This is a one-character change with zero risk of regression. The
loop's purpose is to advance past hex digits; the for-statement's
s++ already handles that.

File Metadata

Mime Type
text/plain
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
45/10/207cd788acfac92ed3bed6b1d0f4

Event Timeline