Message ID | 042a8ba8b2a98c269f9cd1a8e88488b80d686f0d.1567720960.git.me@ttaylorr.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | commit-graph: harden against various corruptions | expand |
On 9/5/2019 6:04 PM, Taylor Blau wrote: > When invoking 'git commit-graph' in a corrupt repository, one can cause > a segfault when ancestral commits are corrupt in one way or another. > This is due to two function calls in the 'commit-graph.c' code that may > return NULL, but are not checked for NULL-ness before dereferencing. > > Before fixing the bug, introduce two failing tests that demonstrate the > problem. The first test corrupts an ancestral commit's parent to point > to a non-existent object. The second test instead corrupts an ancestral > tree by removing the 'tree' information entirely from the commit. Both > of these cases cause segfaults, each at different lines. Thanks for the tests! And marking them as "test_expect_failure" avoids issues with 'git bisect' in the future. -Stolee > > Signed-off-by: Taylor Blau <me@ttaylorr.com> > --- > t/t5318-commit-graph.sh | 43 +++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 43 insertions(+) > > diff --git a/t/t5318-commit-graph.sh b/t/t5318-commit-graph.sh > index ab3eccf0fa..c855f81930 100755 > --- a/t/t5318-commit-graph.sh > +++ b/t/t5318-commit-graph.sh > @@ -585,4 +585,47 @@ test_expect_success 'get_commit_tree_in_graph works for non-the_repository' ' > test_cmp expect actual > ' > > +test_expect_failure 'corrupt commit-graph write (broken parent)' ' > + rm -rf repo && > + git init repo && > + ( > + cd repo && > + empty="$(git mktree </dev/null)" && > + cat >broken <<-EOF && > + tree $empty > + parent 0000000000000000000000000000000000000000 > + author whatever <whatever@example.com> 1234 -0000 > + committer whatever <whatever@example.com> 1234 -0000 > + > + broken commit > + EOF > + broken="$(git hash-object -w -t commit --literally broken)" && > + git commit-tree -p "$broken" -m "good commit" "$empty" >good && > + test_must_fail git commit-graph write --stdin-commits \ > + <good 2>test_err && > + test_i18ngrep "unable to parse commit" test_err > + ) > +' > + > +test_expect_failure 'corrupt commit-graph write (missing tree)' ' > + rm -rf repo && > + git init repo && > + ( > + cd repo && > + tree="$(git mktree </dev/null)" && > + cat >broken <<-EOF && > + parent 0000000000000000000000000000000000000000 > + author whatever <whatever@example.com> 1234 -0000 > + committer whatever <whatever@example.com> 1234 -0000 > + > + broken commit > + EOF > + broken="$(git hash-object -w -t commit --literally broken)" && > + git commit-tree -p "$broken" -m "good" "$tree" >good && > + test_must_fail git commit-graph write --stdin-commits \ > + <good 2>test_err && > + test_i18ngrep "unable to get tree for" test_err > + ) > +' > + > test_done >
diff --git a/t/t5318-commit-graph.sh b/t/t5318-commit-graph.sh index ab3eccf0fa..c855f81930 100755 --- a/t/t5318-commit-graph.sh +++ b/t/t5318-commit-graph.sh @@ -585,4 +585,47 @@ test_expect_success 'get_commit_tree_in_graph works for non-the_repository' ' test_cmp expect actual ' +test_expect_failure 'corrupt commit-graph write (broken parent)' ' + rm -rf repo && + git init repo && + ( + cd repo && + empty="$(git mktree </dev/null)" && + cat >broken <<-EOF && + tree $empty + parent 0000000000000000000000000000000000000000 + author whatever <whatever@example.com> 1234 -0000 + committer whatever <whatever@example.com> 1234 -0000 + + broken commit + EOF + broken="$(git hash-object -w -t commit --literally broken)" && + git commit-tree -p "$broken" -m "good commit" "$empty" >good && + test_must_fail git commit-graph write --stdin-commits \ + <good 2>test_err && + test_i18ngrep "unable to parse commit" test_err + ) +' + +test_expect_failure 'corrupt commit-graph write (missing tree)' ' + rm -rf repo && + git init repo && + ( + cd repo && + tree="$(git mktree </dev/null)" && + cat >broken <<-EOF && + parent 0000000000000000000000000000000000000000 + author whatever <whatever@example.com> 1234 -0000 + committer whatever <whatever@example.com> 1234 -0000 + + broken commit + EOF + broken="$(git hash-object -w -t commit --literally broken)" && + git commit-tree -p "$broken" -m "good" "$tree" >good && + test_must_fail git commit-graph write --stdin-commits \ + <good 2>test_err && + test_i18ngrep "unable to get tree for" test_err + ) +' + test_done
When invoking 'git commit-graph' in a corrupt repository, one can cause a segfault when ancestral commits are corrupt in one way or another. This is due to two function calls in the 'commit-graph.c' code that may return NULL, but are not checked for NULL-ness before dereferencing. Before fixing the bug, introduce two failing tests that demonstrate the problem. The first test corrupts an ancestral commit's parent to point to a non-existent object. The second test instead corrupts an ancestral tree by removing the 'tree' information entirely from the commit. Both of these cases cause segfaults, each at different lines. Signed-off-by: Taylor Blau <me@ttaylorr.com> --- t/t5318-commit-graph.sh | 43 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+)