CVE-2023-6246: syslog Heap Buffer Overflow
Vulnerability Summary
| Field | Value |
|---|---|
| CVE | CVE-2023-6246 |
| CVSS | 7.8 (High) |
| Affected | glibc >= 2.36 |
| Disclosed | 2024-01-30 |
| Type | Heap-based buffer overflow in __vsyslog_internal() |
A heap-based buffer overflow in glibc's __vsyslog_internal() function, called by syslog() and vsyslog(). When openlog() is not called (or called with ident set to NULL) and the program name (argv[0]) exceeds 1024 bytes, the function overflows a heap buffer. Discovered by Qualys.
Exploitation Technique
The exploit targets su, a common SUID-root program:
- Execute
suwith an extremely longargv[0](> 1024 bytes) - PAM calls
syslog()on authentication failure without callingopenlog()first __vsyslog_internal()copies the program name into a heap buffer without proper bounds checking- The overflow corrupts adjacent heap chunk metadata (size, flags, prev_size)
- Subsequent heap operations trigger controlled writes via techniques like unsafe unlink
- Achieve local privilege escalation to root
The key enabler: glibc stores malloc metadata (chunk headers) inline, directly adjacent to user data. An overflow from one allocation silently corrupts the metadata of the next chunk.
Proof of Concept
Source: tests/cve/heap_overflow.c
The PoC simulates the syslog overflow pattern: allocate a buffer and write past its end.
gcc -o /tmp/heap_overflow tests/cve/heap_overflow.c
glibc output
=== Heap Buffer Overflow Detection Demo ===
(CVE-2023-6246 pattern)
[1] malloc(100) => 0x...
[2] memset(0x..., 'X', 120) => overflow by 20 bytes!
[3] free(0x...) => queued for deferred canary check
[4] Triggering batch flush (70 frees)...
[!] Heap overflow was NOT detected on free().
Under glibc, the adjacent chunk's metadata may be
silently corrupted, enabling exploitation.
glibc does not detect the overflow. The 20 extra bytes silently overwrite whatever follows the allocation in memory.
compatmalloc output
=== Heap Buffer Overflow Detection Demo ===
(CVE-2023-6246 pattern)
[1] malloc(100) => 0x...
[2] memset(0x..., 'X', 120) => overflow by 20 bytes!
[3] free(0x...) => queued for deferred canary check
[4] Triggering batch flush (70 frees)...
compatmalloc: heap buffer overflow detected (canary corrupted)
compatmalloc detects the overflow when the canary bytes are checked during batch verification.
What compatmalloc catches
-
Canary bytes. For
malloc(100), compatmalloc returns a 112-byte slot. Bytes[100..112)contain canary values derived from a cryptographic secret. The 20-byte overflow destroys these canaries. Onfree(), the canary check detects the corruption and aborts. -
Out-of-band metadata. Even if the overflow extends past the slot boundary, it cannot corrupt allocator metadata because metadata is stored in a separate
mmapregion. The fundamental unsafe-unlink exploitation technique (corrupting inline chunk headers) is not possible. -
Guard pages. For overflows that extend past the end of a slab region, guard pages (
PROT_NONE) trigger a hardware fault (SIGSEGV). This provides immediate detection without waiting forfree().
What compatmalloc does NOT catch
- The overflow is detected on
free(), not at the moment of the write. Between the overflow and the canary check, the program continues executing with corrupted memory. If exploitation completes beforefree()is called, the canary check may come too late. - compatmalloc does not fix the
syslog()bug. Using compatmalloc asLD_PRELOADprevents heap corruption from being exploitable, but the buffer overflow in__vsyslog_internal()still occurs. - Intra-slab overflows between adjacent slots in the same slab are detected by canaries, not guard pages. An overflow that exactly fills the canary gap and stops would not be detected (though this is difficult to achieve in practice without knowing the canary secret).