summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Steinhardt <ps@pks.im>2018-07-05 13:30:46 +0200
committerPatrick Steinhardt <ps@pks.im>2018-07-05 13:42:14 +0200
commite087c0de70f43956125cb4deacdc8dd2a8687367 (patch)
treee2f2c4b7b5fb14c198bd9da4ab7eedb92953be4a
parent24597812220325f1cb38f61e56b095ff38d1b1cb (diff)
downloadlibgit2-e087c0de70f43956125cb4deacdc8dd2a8687367.tar.gz
delta: fix overflow when computing limit
When checking whether a delta base offset and length fit into the base we have in memory already, we can trigger an overflow which breaks the check. This would subsequently result in us reading memory from out of bounds of the base. The issue is easily fixed by checking for overflow when adding `off` and `len`, thus guaranteeting that we are never indexing beyond `base_len`. This corresponds to the git patch 8960844a7 (check patch_delta bounds more carefully, 2006-04-07), which adds these overflow checks. Reported-by: Riccardo Schirone <rschiron@redhat.com>
-rw-r--r--src/delta.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/src/delta.c b/src/delta.c
index 8676e7a8f..b9352b8ee 100644
--- a/src/delta.c
+++ b/src/delta.c
@@ -566,7 +566,7 @@ int git_delta_apply(
unsigned char cmd = *delta++;
if (cmd & 0x80) {
/* cmd is a copy instruction; copy from the base. */
- size_t off = 0, len = 0;
+ size_t off = 0, len = 0, end;
#define ADD_DELTA(o, shift) { if (delta < delta_end) (o) |= ((unsigned) *delta++ << shift); else goto fail; }
if (cmd & 0x01) ADD_DELTA(off, 0UL);
@@ -580,8 +580,10 @@ int git_delta_apply(
if (!len) len = 0x10000;
#undef ADD_DELTA
- if (base_len < off + len || res_sz < len)
+ if (GIT_ADD_SIZET_OVERFLOW(&end, off, len) ||
+ base_len < end || res_sz < len)
goto fail;
+
memcpy(res_dp, base + off, len);
res_dp += len;
res_sz -= len;