https://sourceware.org/bugzilla/show_bug.cgi?id=34275
Bug ID: 34275
Summary: [Vulnerability Report] Double-Free in libctf:
ctf_link_deduplicating_per_cu
Product: binutils
Version: 2.47 (HEAD)
Status: UNCONFIRMED
Severity: normal
Priority: P2
Component: libctf
Assignee: unassigned at sourceware dot org
Reporter: rigelyoung at icloud dot com
Target Milestone: ---
**Summary:**
A double-free vulnerability exists in `libctf` within the
`ctf_link_deduplicating_per_cu` function (located in `libctf/ctf-link.c`). When
an error occurs during the opening of deduplicating inputs, an iterator is
explicitly destroyed before jumping to an error-handling label that destroys
the same iterator again. This leads to memory corruption and potential crashes
when processing malformed CTF data.
**Bug Detail:**
The vulnerability is caused by a redundant call to `ctf_next_destroy()`
combined with a `goto` statement.
1. **Allocation (`libctf/ctf-link.c:1103`):** In
`ctf_link_deduplicating_per_cu`, the iterator `i` is allocated internally when
calling `ctf_dynhash_next()`.
2. **First Free (`libctf/ctf-link.c:1191`):** If the call to
`ctf_link_deduplicating_open_inputs()` fails (returns `NULL`), the code
explicitly calls `ctf_next_destroy(i)` to free the iterator, and then executes
`goto err_open_inputs;` at line 1192.
3. **Second Free (`libctf/ctf-link.c:1301`):** The control flow jumps to the
`err_open_inputs` label. This label serves as the common cleanup block for the
function and unconditionally calls `ctf_next_destroy(i)` again.
4. **Root Cause (`libctf/ctf-util.c:267`):** The function
`ctf_next_destroy(ctf_next_t *i)` accepts the pointer by value and executes
`free(i)` internally without nullifying the caller's pointer. Consequently, the
second call to `ctf_next_destroy(i)` attempts to free the already-freed heap
memory, triggering a double-free.
**Impact:**
Processing maliciously crafted object files or archives with tools relying on
`libctf` (such as the linker `ld` or `objdump`) can trigger this double-free.
This primarily leads to a Denial of Service (DoS) due to an immediate program
crash. Depending on the heap layout and the underlying malloc state, this could
theoretically be exploited for arbitrary code execution (ACE), although the
context of a build utility makes DoS the most immediate and likely consequence.
**Proposed Fix:**
The fix is straightforward. Since the `err_open_inputs` label is already
responsible for cleaning up the iterator `i`, the redundant
`ctf_next_destroy(i)` call before the `goto` statement should be removed.
Here is the proposed diff:
```Diff
--- a/libctf/ctf-link.c
+++ b/libctf/ctf-link.c
@@ -1186,7 +1186,6 @@ ctf_link_deduplicating_per_cu (ctf_dict_t *fp)
if ((inputs = ctf_link_deduplicating_open_inputs (fp, in, ninputs,
&parents)) == NULL)
{
- ctf_next_destroy (i);
goto err_open_inputs;
}
```
Reporter: Xuqing Yang
--
You are receiving this mail because:
You are on the CC list for the bug.