From: Patrick Steinhardt <ps@pks.im>
To: "René Scharfe" <l.s.r@web.de>
Cc: Git List <git@vger.kernel.org>
Subject: Re: [PATCH 2/4] reftable: fix allocation count on realloc error
Date: Fri, 27 Dec 2024 11:33:58 +0100 [thread overview]
Message-ID: <Z26ClnvVH1cg3CGQ@pks.im> (raw)
In-Reply-To: <33bbacc7-1727-4efd-9cbf-3c9abfa94d8c@web.de>
On Wed, Dec 25, 2024 at 07:38:35PM +0100, René Scharfe wrote:
> 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.
Okay, this change goes into the direction I was wondering about with the
preceding commit, good.
> diff --git a/reftable/basics.h b/reftable/basics.h
> index 259f4c274c..fa5d75868b 100644
> --- a/reftable/basics.h
> +++ b/reftable/basics.h
> @@ -120,22 +120,35 @@ char *reftable_strdup(const char *str);
> #define REFTABLE_ALLOC_ARRAY(x, alloc) (x) = reftable_malloc(st_mult(sizeof(*(x)), (alloc)))
> #define REFTABLE_CALLOC_ARRAY(x, alloc) (x) = reftable_calloc((alloc), sizeof(*(x)))
> #define REFTABLE_REALLOC_ARRAY(x, alloc) (x) = reftable_realloc((x), st_mult(sizeof(*(x)), (alloc)))
> -#define REFTABLE_ALLOC_GROW(x, nr, alloc) \
> - do { \
> - if ((nr) > alloc) { \
> - alloc = 2 * (alloc) + 1; \
> - if (alloc < (nr)) \
> - alloc = (nr); \
> - REFTABLE_REALLOC_ARRAY(x, alloc); \
> - } \
> - } while (0)
> +
> +static inline void *reftable_alloc_grow(void *p, size_t nelem, size_t elsize,
> + size_t *allocp)
> +{
> + void *new_p;
> + size_t alloc = *allocp * 2 + 1;
> + if (alloc < nelem)
> + alloc = nelem;
> + new_p = reftable_realloc(p, st_mult(elsize, alloc));
> + if (!new_p)
> + return p;
> + *allocp = alloc;
> + return new_p;
> +}
> +
> +#define REFTABLE_ALLOC_GROW(x, nr, alloc) ( \
> + (nr) > (alloc) && ( \
> + (x) = reftable_alloc_grow((x), (nr), sizeof(*(x)), &(alloc)), \
> + (nr) > (alloc) \
> + ) \
> +)
Do we even need this macro? I don't really think it serves much of a
purpose anymore.
Patrick
next prev parent reply other threads:[~2024-12-27 10:34 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-12-25 18:33 [PATCH 0/4] reftable: fix realloc error handling René Scharfe
2024-12-25 18:38 ` [PATCH 1/4] reftable: avoid leaks on realloc error René Scharfe
2024-12-27 5:39 ` Junio C Hamano
2024-12-27 10:33 ` Patrick Steinhardt
2024-12-27 20:16 ` René Scharfe
2024-12-30 6:29 ` Patrick Steinhardt
2024-12-25 18:38 ` [PATCH 2/4] reftable: fix allocation count " René Scharfe
2024-12-27 10:33 ` Patrick Steinhardt [this message]
2024-12-27 20:16 ` René Scharfe
2024-12-27 20:16 ` René Scharfe
2024-12-25 18:38 ` [PATCH 3/4] reftable: handle realloc error in parse_names() René Scharfe
2024-12-25 18:38 ` [PATCH 4/4] t-reftable-merged: check realloc errors René Scharfe
2024-12-27 5:46 ` Junio C Hamano
2024-12-27 10:34 ` Patrick Steinhardt
2024-12-27 20:16 ` René Scharfe
2024-12-27 10:34 ` [PATCH 0/4] reftable: fix realloc error handling Patrick Steinhardt
2024-12-27 16:02 ` Junio C Hamano
2024-12-28 9:43 ` [PATCH v2 " René Scharfe
2024-12-28 9:47 ` [PATCH v2 1/4] reftable: avoid leaks on realloc error René Scharfe
2024-12-30 7:25 ` Patrick Steinhardt
2024-12-28 9:48 ` [PATCH v2 2/4] reftable: fix allocation count " René Scharfe
2024-12-28 9:48 ` [PATCH v2 3/4] reftable: handle realloc error in parse_names() René Scharfe
2024-12-30 7:25 ` Patrick Steinhardt
2024-12-28 9:49 ` [PATCH v2 4/4] t-reftable-merged: handle realloc errors René Scharfe
2024-12-30 7:25 ` [PATCH v2 0/4] reftable: fix realloc error handling Patrick Steinhardt
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=Z26ClnvVH1cg3CGQ@pks.im \
--to=ps@pks.im \
--cc=git@vger.kernel.org \
--cc=l.s.r@web.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).