CVE-2024-2961: iconv Buffer Overflow

Vulnerability Summary

FieldValue
CVECVE-2024-2961
CVSS8.8 (High)
Affectedglibc <= 2.39
Disclosed2024-04-17
TypeOut-of-bounds write in iconv()

The iconv() function in glibc overflows the output buffer by 1-3 bytes when converting strings to the ISO-2022-CN-EXT character set. The overflow occurs because escape sequence writes for SS2 and SS3 designations lack bounds checks.

Exploitation Technique

In real-world exploitation (the CNEXT exploit chain against PHP), attackers use this 1-3 byte overflow to corrupt tcache forward pointers in adjacent freed heap chunks:

  1. Groom the heap so a freed chunk sits immediately after the iconv output buffer
  2. Trigger the iconv overflow to modify the low byte(s) of the tcache fd pointer
  3. The corrupted pointer redirects a subsequent malloc() to an attacker-controlled address
  4. Write to that address to overwrite __free_hook or a GOT entry
  5. Trigger the hook to achieve remote code execution

This technique -- tcache poisoning via buffer overflow -- works because glibc stores freelist metadata (the fd pointer) inline within freed chunks, directly adjacent to user data.

Proof of Concept

Source: tests/cve/tcache_poison.c

The PoC demonstrates the exploitation technique (1-byte write past the requested allocation size) rather than calling iconv() directly. This keeps it simple and version-independent.

gcc -o /tmp/tcache_poison tests/cve/tcache_poison.c

glibc output

=== Tcache Poisoning via 1-Byte Overflow Demo ===
    (CVE-2024-2961 exploitation technique)

[1] chunk_a = malloc(50) => 0x...
[2] chunk_b = malloc(50) => 0x...
    distance: 64 bytes

[3] free(chunk_b) => chunk_b enters tcache
[4] chunk_b tcache fd = 0x...

[5] Simulating 1-byte overflow from chunk_a into chunk_b...
[6] free(chunk_a) => queued for deferred canary check
[7] Triggering batch flush (70 frees)...

[!] 1-byte overflow was NOT detected.

Under glibc, writing 1 byte past the requested 50-byte allocation lands within glibc's usable 56-byte region of the 64-byte chunk. No detection occurs. In the real CVE, larger overflows (1-3 bytes into adjacent chunks) corrupt the tcache fd pointer.

compatmalloc output

=== Tcache Poisoning via 1-Byte Overflow Demo ===
    (CVE-2024-2961 exploitation technique)

[1] chunk_a = malloc(50) => 0x...
[2] chunk_b = malloc(50) => 0x...
    distance: -46784 bytes

[3] free(chunk_b) => chunk_b enters tcache
[4] chunk_b tcache fd = 0x4242424242424242

[5] Simulating 1-byte overflow from chunk_a into chunk_b...
[6] free(chunk_a) => queued for deferred canary check
[7] Triggering batch flush (70 frees)...
compatmalloc: heap buffer overflow detected (canary corrupted)

compatmalloc aborts immediately when the canary check detects the overflow.

What compatmalloc catches

Two independent layers of defense apply:

  1. Canary bytes. compatmalloc places canary bytes in the padding between the requested size and the slot size. For malloc(50) in a 64-byte slot, bytes [50..64) contain canary values. The 1-byte write at offset 50 corrupts the canary, which is detected on free().

  2. Out-of-band metadata. Even without canaries, compatmalloc stores all freelist metadata in a separate mmap region -- not inline within freed chunks. There are no fd pointers adjacent to user data to corrupt. The fundamental prerequisite of tcache poisoning (corruptible inline metadata) does not exist.

  3. Slot randomization. Allocations are not placed adjacently in predictable order, making heap grooming significantly harder.

What compatmalloc does NOT catch

  • The overflow is not detected at the moment it happens. Canary checks run on free() (specifically during deferred batch verification). If the overflowed buffer is never freed, detection is delayed.
  • compatmalloc does not fix the iconv() bug itself. It prevents the exploitation technique (tcache poisoning) from succeeding, but the overflow still occurs in iconv().
  • Intra-slot overflows between adjacent slots in the same slab are caught by canaries, not guard pages. Guard pages only protect slab boundaries.

References