summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNguyễn Thái Ngọc Duy <pclouds@gmail.com>2016-12-06 19:53:36 +0700
committerJunio C Hamano <gitster@pobox.com>2016-12-07 15:44:31 -0800
commitf2386c6b77e236fc104d3a024e5d314c23a941eb (patch)
tree6f74f54c2d4da4eead1715f8d3e27fcae5ef0125
parent6bc3d8c5ec04cdfaa7dc14aed1993f3bb376d9ae (diff)
downloadgit-f2386c6b77e236fc104d3a024e5d314c23a941eb.tar.gz
shallow.c: make paint_alloc slightly more robust
paint_alloc() allocates a big block of memory and splits it into smaller, fixed size, chunks of memory whenever it's called. Each chunk contains enough bits to present all "new refs" [1] in a fetch from a shallow repository. We do not check if the new "big block" is smaller than the requested memory chunk though. If it happens, we'll happily pass back a memory region smaller than expected. Which will lead to problems eventually. A normal fetch may add/update a dozen new refs. Let's stay on the "reasonably extreme" side and say we need 16k refs (or bits from paint_alloc's perspective). Each chunk of memory would be 2k, much smaller than the memory pool (512k). So, normally, the under-allocation situation should never happen. A bad guy, however, could make a fetch that adds more than 4m new/updated refs to this code which results in a memory chunk larger than pool size. Check this case and abort. Noticed-by: Rasmus Villemoes <rv@rasmusvillemoes.dk> Reviewed-by: Jeff King <peff@peff.net> [1] Details are in commit message of 58babff (shallow.c: the 8 steps to select new commits for .git/shallow - 2013-12-05), step 6. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Reviewed-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--shallow.c3
1 files changed, 3 insertions, 0 deletions
diff --git a/shallow.c b/shallow.c
index 91aa59d4b8..7d5ea0cd39 100644
--- a/shallow.c
+++ b/shallow.c
@@ -369,6 +369,9 @@ static uint32_t *paint_alloc(struct paint_info *info)
unsigned size = nr * sizeof(uint32_t);
void *p;
if (!info->pool_count || info->free + size > info->end) {
+ if (size > POOL_SIZE)
+ die("BUG: pool size too small for %d in paint_alloc()",
+ size);
info->pool_count++;
REALLOC_ARRAY(info->pools, info->pool_count);
info->free = xmalloc(POOL_SIZE);