Skip to content

Commit 554b3b9

Browse files
authored
Merge pull request libgit2#4996 from eaigner/master
Prevent reading out of bounds memory
2 parents 6eb4947 + 966b944 commit 554b3b9

File tree

3 files changed

+35
-1
lines changed

3 files changed

+35
-1
lines changed

AUTHORS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ Dmitry Kovega
2323
Emeric Fermas
2424
Emmanuel Rodriguez
2525
Eric Myhre
26+
Erik Aigner
2627
Florian Forster
2728
Holger Weiss
2829
Ingmar Vanhassel

src/apply.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ static int patch_image_init_fromstr(
5959
git_pool_init(&out->pool, sizeof(git_diff_line));
6060

6161
for (start = in; start < in + in_len; start = end) {
62-
end = memchr(start, '\n', in_len);
62+
end = memchr(start, '\n', in_len - (start - in));
6363

6464
if (end == NULL)
6565
end = in + in_len;

tests/apply/fromdiff.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,3 +333,36 @@ void test_apply_fromdiff__binary_delete(void)
333333
NULL, NULL,
334334
NULL, &binary_opts));
335335
}
336+
337+
void test_apply_fromdiff__patching_correctly_truncates_source(void)
338+
{
339+
git_buf original = GIT_BUF_INIT, patched = GIT_BUF_INIT;
340+
git_patch *patch;
341+
unsigned int mode;
342+
char *path;
343+
344+
cl_git_pass(git_patch_from_buffers(&patch,
345+
"foo\nbar", 7, "file.txt",
346+
"foo\nfoo", 7, "file.txt", NULL));
347+
348+
/*
349+
* Previously, we would fail to correctly truncate the source buffer if
350+
* the source has more than one line and ends with a non-newline
351+
* character. In the following call, we thus truncate the source string
352+
* in the middle of the second line. Without the bug fixed, we would
353+
* successfully apply the patch to the source and return success. With
354+
* the overflow being fixed, we should return an error.
355+
*/
356+
cl_git_fail_with(GIT_EAPPLYFAIL,
357+
git_apply__patch(&patched, &path, &mode,
358+
"foo\nbar\n", 5, patch, NULL));
359+
360+
/* Verify that the patch succeeds if we do not truncate */
361+
cl_git_pass(git_apply__patch(&patched, &path, &mode,
362+
"foo\nbar\n", 7, patch, NULL));
363+
364+
git_buf_dispose(&original);
365+
git_buf_dispose(&patched);
366+
git_patch_free(patch);
367+
git__free(path);
368+
}

0 commit comments

Comments
 (0)