diff options
author | Nick Alcock <nick.alcock@oracle.com> | 2024-04-26 18:19:15 +0100 |
---|---|---|
committer | Nick Alcock <nick.alcock@oracle.com> | 2024-05-17 12:58:18 +0100 |
commit | 37ed36fc8b6e766824c7a4aab20b866c5b7a3ff1 (patch) | |
tree | 5eee194ad5037320d757ca19261eab0e1aad0ed5 /include/opcode/rx.h | |
parent | 8c59ec70063f697e2088ac58ba350fa6ea8d8680 (diff) | |
download | gdb-37ed36fc8b6e766824c7a4aab20b866c5b7a3ff1.zip gdb-37ed36fc8b6e766824c7a4aab20b866c5b7a3ff1.tar.gz gdb-37ed36fc8b6e766824c7a4aab20b866c5b7a3ff1.tar.bz2 |
libctf: fix leak of entire dict when dict opening fails
Ever since commit 1fa7a0c24e78e7f ("libctf: sort out potential refcount
loops") ctf_dict_close has only freed anything if the refcount on entry
to the function is precisely 1. >1 obviously just decrements the
refcount, but the linker machinery can sometimes cause freeing to recurse
from a dict to another dict and then back to the first dict again, so
we interpret a refcount of 0 as an indication that this is a recursive call
and we should just return, because a caller is already freeing this dict.
Unfortunately there is one situation in which this is not true: the bad:
codepath in ctf_bufopen entered when opening fails. Because the refcount is
bumped only at the very end of ctf_bufopen, any failure causes
ctf_dict_close to be entered with a refcount of zero, and it frees nothing
and we leak the entire dict.
The solution is to bump the refcount to 1 right before freeing... but this
codepath is clearly delicate enough that we need to properly validate it,
so we add a test that uses malloc interposition to count allocations and
frees, creates a dict, writes it out, intentionally corrupts it (by setting
a bunch of bytes after the header to a value high enough that it is
definitely not a valid CTF type kind), then tries to open it again and
counts the malloc/free pairs to make sure they're matched. (Test run only
on *-linux-gnu, because malloc interposition is not a thing you can rely
upon working everywhere, and this test is not arch-dependent so if it
passes on one arch it can be assumed to pass on all of them.)
libctf/
* ctf-open.c (ctf_bufopen): Bump the refcount on failure.
* testsuite/libctf-regression/open-error-free.*: New test.
Diffstat (limited to 'include/opcode/rx.h')
0 files changed, 0 insertions, 0 deletions