All of lore.kernel.org
 help / color / mirror / Atom feed
From: "René Scharfe" <l.s.r@web.de>
To: Ori Bernstein <ori@eigenstate.org>, git@vger.kernel.org
Subject: Re: [PATCH] Avoid infinite loop in malformed packfiles
Date: Sun, 23 Aug 2020 08:26:14 +0200	[thread overview]
Message-ID: <672843a1-b98c-7567-a078-a2dacd4b7074@web.de> (raw)
In-Reply-To: <20200823031151.10985-1-ori@eigenstate.org>

Am 23.08.20 um 05:11 schrieb Ori Bernstein:
> In packfile.c:1680, there's an infinite loop that tries to get
> to the base of a packfile. With offset deltas, the offset needs
> to be greater than 0, so it's always walking backwards, and the
> search is guaranteed to terminate.
>
> With reference deltas, there's no check for a cycle in the
> references, so a cyclic reference will cause git to loop
> infinitely, growing the delta_stack infinitely, which will
> cause it to consume all available memory as as a full CPU
> core.

"as as"?  Perhaps "and"?

> This change puts an arbitrary limit of 10,000 on the number
> of iterations we make when chasing down a base commit, to
> prevent looping forever, using all available memory growing
> the delta stack.
>
> Signed-off-by: Ori Bernstein <ori@eigenstate.org>
> ---
>  packfile.c | 7 +++++++
>  1 file changed, 7 insertions(+)
>
> diff --git a/packfile.c b/packfile.c
> index 6ab5233613..321e002c50 100644
> --- a/packfile.c
> +++ b/packfile.c
> @@ -1633,6 +1633,7 @@ static void write_pack_access_log(struct packed_git *p, off_t obj_offset)
>
>  int do_check_packed_object_crc;
>
> +#define UNPACK_ENTRY_STACK_LIMIT 10000

b5c0cbd8083 (pack-objects: use bitfield for object_entry::depth,
2018-04-14) limited the delta depth for new packs to 4095, so 10000
seems reasonable.  Users with unreasonable packs would need to repack
them with an older version of Git, though.  Not sure if that would
affect anyone in practice.

>  #define UNPACK_ENTRY_STACK_PREALLOC 64

Hmm, setting a hard limit may allow to allocate the whole stack on the,
ehm, stack.  That would get rid of the hybrid stack/heap allocation and
thus simplify the code a bit.  10000 entries with 24 bytes each would be
quite big, though, but that might be OK without recursion.  (And not in
this patch anyway, of course.)

>  struct unpack_entry_stack_ent {
>  	off_t obj_offset;
> @@ -1715,6 +1716,12 @@ void *unpack_entry(struct repository *r, struct packed_git *p, off_t obj_offset,
>  			break;
>  		}
>
> +		if (delta_stack_nr > UNPACK_ENTRY_STACK_LIMIT) {
> +			error("overlong delta chain at offset %jd from %s",
> +			      (uintmax_t)curpos, p->pack_name);
> +			goto out;
> +		}

Other error handlers in this loop set data to NULL.  That's actually
unnecessary because it's NULL to begin with and the loop is exited after
setting it to some other value.  So not doing it here is fine.  (And a
separate cleanup patch could remove the dead stores in the other
handlers.)

> +
>  		/* push object, proceed to base */
>  		if (delta_stack_nr >= delta_stack_alloc
>  		    && delta_stack == small_delta_stack) {
>


  reply	other threads:[~2020-08-23  6:26 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-08-23  0:52 [PATCH] Avoid infinite loop in malformed packfiles Ori Bernstein
2020-08-23  2:52 ` ori
2020-08-23  3:08 ` Eric Sunshine
2020-08-23  3:11 ` Ori Bernstein
2020-08-23  6:26   ` René Scharfe [this message]
2020-08-23 20:41     ` Ori Bernstein
2020-08-24 16:06       ` René Scharfe
2020-08-24 20:12         ` Jeff King
2020-08-24 20:38           ` Junio C Hamano
2020-08-24 20:52             ` Jeff King
2020-08-24 21:22               ` Junio C Hamano
2020-08-30  3:33                 ` ori
2020-08-30 10:56                   ` René Scharfe
2020-08-30 16:15                     ` Junio C Hamano
2020-08-31  9:29                       ` Jeff King
2020-08-31 16:32                         ` Junio C Hamano
2020-08-31 19:23                           ` Jeff King
2020-08-31 16:50                         ` ori
2020-08-24 17:33   ` Junio C Hamano
2020-08-24 20:30 ` Junio C Hamano

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=672843a1-b98c-7567-a078-a2dacd4b7074@web.de \
    --to=l.s.r@web.de \
    --cc=git@vger.kernel.org \
    --cc=ori@eigenstate.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.