Re: [PATCH] Avoid infinite loop in malformed packfiles
- From
- Ori Bernstein <ori@eigenstate.org>
- Date
- Aug 23, 2020, 20:41 UTC
- Message-ID
- <20200823134144.d57c80322f479eb554bab9d1@eigenstate.org>
- In-Reply-To
- <672843a1-b98c-7567-a078-a2dacd4b7074@web.de>
On Sun, 23 Aug 2020 08:26:14 +0200, René Scharfe <l.s.r@web.de> wrote:
Show 13 quoted lines
> 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"?
I think I meant 'As well as' -- will fix.
Show 32 quoted lines
>
> 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.)Is there anything you'd like me to do in this patch, other than fixing the typo?
--
Ori Bernstein