git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 4/5] patch-delta: consistently report corruption

From
Jeff King <peff@peff.net>
Date
Aug 30, 2018, 07:10 UTC
Message-ID
<20180830071026.GD15420@sigill.intra.peff.net>
In-Reply-To
<20180830070548.GA15081@sigill.intra.peff.net>
From: Jann Horn <jannh@google.com>

When applying a delta, if we see an opcode that cannot be fulfilled (e.g., asking to write more bytes than the destination has left), we break out of our parsing loop but don't signal an explicit error. We rely on the sanity check after the loop to see if we have leftover delta bytes or didn't fill our result buffer.

This can silently ignore corruption when the delta buffer ends with a bogus command and the destination buffer is already full. Instead, let's jump into the error handler directly when we see this case.

Note that the tests also cover the "bad opcode" case, which already handles this correctly.

Signed-off-by: Jann Horn <jannh@google.com>
Signed-off-by: Jeff King <peff@peff.net>
---
 patch-delta.c                         |  5 +++--
 t/t5303-pack-corruption-resilience.sh | 30 +++++++++++++++++++++++++++
 2 files changed, 33 insertions(+), 2 deletions(-)
diff --git a/patch-delta.c b/patch-delta.c
index b937afd2c9..283fb4b759 100644
--- a/patch-delta.c
+++ b/patch-delta.c
@@ -51,13 +51,13 @@ void *patch_delta(const void *src_buf, unsigned long src_size,
 			if (unsigned_add_overflows(cp_off, cp_size) ||
 			    cp_off + cp_size > src_size ||
 			    cp_size > size)
-				break;
+				goto bad_length;
 			memcpy(out, (char *) src_buf + cp_off, cp_size);
 			out += cp_size;
 			size -= cp_size;
 		} else if (cmd) {
 			if (cmd > size || cmd > top - data)
-				break;
+				goto bad_length;
 			memcpy(out, data, cmd);
 			out += cmd;
 			data += cmd;
@@ -75,6 +75,7 @@ void *patch_delta(const void *src_buf, unsigned long src_size,
 
 	/* sanity check */
 	if (data != top || size != 0) {
+		bad_length:
 		error("delta replay has gone wild");
 		bad:
 		free(dst_buf);
diff --git a/t/t5303-pack-corruption-resilience.sh b/t/t5303-pack-corruption-resilience.sh
index 7114c31ade..41dc947d3f 100755
--- a/t/t5303-pack-corruption-resilience.sh
+++ b/t/t5303-pack-corruption-resilience.sh
@@ -370,4 +370,34 @@ test_expect_failure \
      echo base >base &&
      test_must_fail test-tool delta -p base truncated_copy_delta /dev/null'
 
+# \0 - empty base
+# \1 - one byte in result
+# \1 - one literal byte (X)
+# \1 - trailing garbage command
+test_expect_success \
+    'apply delta with trailing garbage literal' \
+    'printf "\0\1\1X\1" > tail_garbage_literal &&
+     test_must_fail test-tool delta -p /dev/null tail_garbage_literal /dev/null'
+
+# \5 - five bytes in base
+# \1 - one byte in result
+# \1 - one literal byte (X)
+# \221 - copy, one byte offset, one byte size
+#   \0 - copy from offset 0
+#   \1 - copy 1 byte
+test_expect_success \
+    'apply delta with trailing garbage copy' \
+    'printf "\5\1\1X\221\0\1" > tail_garbage_copy &&
+     echo base >base &&
+     test_must_fail test-tool delta -p /dev/null tail_garbage_copy /dev/null'
+
+# \0 - empty base
+# \1 - one byte in result
+# \1 - one literal byte (X)
+# \0 - bogus opcode
+test_expect_success \
+    'apply delta with trailing garbage opcode' \
+    'printf "\0\1\1X\0" > tail_garbage_opcode &&
+     test_must_fail test-tool delta -p /dev/null tail_garbage_opcode /dev/null'
+
 test_done
-- 
2.19.0.rc1.539.g3876d0831e
Previous: Jeff KingNext: Jeff King
Message 28 of 31 in “patch-delta: fix oob read”
  1. 1/3 patch-delta: fix oob readJann Horn, Aug 29, 2018
  2. 2/3 t/helper/test-delta: segfault on OOB accessJann Horn, Aug 29, 2018
  3. Jeff KingAug 29, 2018
  4. Jann HornAug 29, 2018
  5. Jeff KingAug 29, 2018
  6. Jeff KingAug 29, 2018
  7. 3/3 t5303: add tests for corrupted deltasJann Horn, Aug 29, 2018
  8. Jeff KingAug 29, 2018
  9. Jeff KingAug 29, 2018
  10. Jeff KingAug 29, 2018
  11. Jeff KingAug 29, 2018
  12. 0/5 handle corruption in patch-deltaJeff King, Aug 30, 2018
  13. 1/5 test-delta: read input into a heap bufferJeff King, Aug 30, 2018
  14. 2/5 t5303: test some corrupt deltasJeff King, Aug 30, 2018
  15. Junio C HamanoAug 30, 2018
  16. Jeff KingAug 30, 2018
  17. Jeff KingAug 30, 2018
  18. Junio C HamanoAug 30, 2018
  19. Jeff KingAug 30, 2018
  20. Johannes SchindelinAug 31, 2018
  21. Junio C HamanoAug 31, 2018
  22. Jeff KingAug 31, 2018
  23. Junio C HamanoAug 31, 2018
  24. Johannes SchindelinAug 31, 2018
  25. Jeff KingAug 31, 2018
  26. Junio C HamanoAug 31, 2018
  27. 3/5 patch-delta: fix oob readJeff King, Aug 30, 2018
  28. 4/5 patch-delta: consistently report corruptionJeff King, Aug 30, 2018
  29. 5/5 patch-delta: handle truncated copy parametersJeff King, Aug 30, 2018
  30. Jann HornAug 30, 2018
  31. Nicolas PitreAug 30, 2018

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.