Merge pull request #5312 from pks-t/pks/patch-base85-overflow patch_parse: fix out-of-bounds reads caused by integer underflow
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
diff --git a/src/patch_parse.c b/src/patch_parse.c
index dad1813..7e2cc63 100644
--- a/src/patch_parse.c
+++ b/src/patch_parse.c
@@ -808,7 +808,7 @@ static int parse_patch_binary_side(
encoded_len = ((decoded_len / 4) + !!(decoded_len % 4)) * 5;
- if (encoded_len > ctx->parse_ctx.line_len - 1) {
+ if (!encoded_len || !ctx->parse_ctx.line_len || encoded_len > ctx->parse_ctx.line_len - 1) {
error = git_parse_err("truncated binary data at line %"PRIuZ, ctx->parse_ctx.line_num);
goto done;
}
diff --git a/tests/patch/parse.c b/tests/patch/parse.c
index 0c4eccc..3f89eb5 100644
--- a/tests/patch/parse.c
+++ b/tests/patch/parse.c
@@ -184,6 +184,14 @@ void test_patch_parse__binary_file_path_without_body_paths(void)
strlen(PATCH_BINARY_FILE_PATH_WITHOUT_BODY_PATHS), NULL));
}
+void test_patch_parse__binary_file_with_truncated_delta(void)
+{
+ git_patch *patch;
+ cl_git_fail(git_patch_from_buffer(&patch, PATCH_BINARY_FILE_WITH_TRUNCATED_DELTA,
+ strlen(PATCH_BINARY_FILE_WITH_TRUNCATED_DELTA), NULL));
+ cl_assert_equal_s(git_error_last()->message, "truncated binary data at line 5");
+}
+
void test_patch_parse__memory_leak_on_multiple_paths(void)
{
git_patch *patch;
diff --git a/tests/patch/patch_common.h b/tests/patch/patch_common.h
index 6601685..7315247 100644
--- a/tests/patch/patch_common.h
+++ b/tests/patch/patch_common.h
@@ -974,6 +974,13 @@
"+++ \n" \
"Binary files a b c and d e f differ"
+#define PATCH_BINARY_FILE_WITH_TRUNCATED_DELTA \
+ "diff --git a/file b/file\n" \
+ "index 1420..b71f\n" \
+ "GIT binary patch\n" \
+ "delta 7\n" \
+ "d"
+
#define PATCH_MULTIPLE_OLD_PATHS \
"diff --git \n" \
"--- \n" \