]> git.ipfire.org Git - thirdparty/git.git/commit
reftable: fix allocation count on realloc error
authorRené Scharfe <l.s.r@web.de>
Sat, 28 Dec 2024 09:48:00 +0000 (10:48 +0100)
committerJunio C Hamano <gitster@pobox.com>
Sat, 28 Dec 2024 16:00:44 +0000 (08:00 -0800)
commit2cca185e85171c462166839cfd6ee57c09573160
treee768f5c93812fe2976a52319c0454d7c99b75248
parent8db127d43f5b0eff254a851f9c966b7b85d91992
reftable: fix allocation count on realloc error

When realloc(3) fails, it returns NULL and keeps the original allocation
intact.  REFTABLE_ALLOC_GROW overwrites both the original pointer and
the allocation count variable in that case, simultaneously leaking the
original allocation and misrepresenting the number of storable items.

parse_names() avoids the leak by keeping the original pointer if
reallocation fails, but still increase the allocation count in such a
case as if it succeeded.  That's OK, because the error handling code
just frees everything and doesn't look at names_cap anymore.

reftable_buf_add() does the same, but here it is a problem as it leaves
the reftable_buf in a broken state, with ->alloc being roughly twice as
big as the actually allocated memory, allowing out-of-bounds writes in
subsequent calls.

Reimplement REFTABLE_ALLOC_GROW to avoid leaks, keep allocation counts
in sync and still signal failures to callers while avoiding code
duplication in callers.  Make it an expression that evaluates to 0 if no
reallocation is needed or it succeeded and 1 on failure while keeping
the original pointer and allocation counter values.

Adjust REFTABLE_ALLOC_GROW_OR_NULL to the new calling convention for
REFTABLE_ALLOC_GROW, but keep its support for non-size_t alloc variables
for now.

Signed-off-by: René Scharfe <l.s.r@web.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
reftable/basics.c
reftable/basics.h
t/unit-tests/t-reftable-basics.c