Skip to content

Commit

Permalink
commit-graph.c: handle corrupt/missing trees
Browse files Browse the repository at this point in the history
Apply similar treatment as in the previous commit to handle an unchecked
call to 'get_commit_tree_oid()'. Previously, a NULL return value from
this function would be immediately dereferenced with '->hash', and then
cause a segfault.

Before dereferencing to access the 'hash' member, check the return value
of 'get_commit_tree_oid()' to make sure that it is not NULL.

To make this check correct, a related change is also needed in
'commit.c', which is to check the return value of 'get_commit_tree'
before taking its address. If 'get_commit_tree' returns NULL, we
encounter an undefined behavior when taking the address of the return
value of 'get_commit_tree' and then taking '->object.oid'. (On my system,
this is memory address 0x8, which is obviously wrong).

Fix this by making sure that 'get_commit_tree' returns something
non-NULL before digging through a structure that is not there, thus
preventing a segfault down the line in the commit graph code.

Signed-off-by: Taylor Blau <[email protected]>
Signed-off-by: Junio C Hamano <[email protected]>
  • Loading branch information
ttaylorr authored and gitster committed Sep 9, 2019
1 parent 16749b8 commit 806278d
Show file tree
Hide file tree
Showing 3 changed files with 9 additions and 3 deletions.
7 changes: 6 additions & 1 deletion commit-graph.c
Original file line number Diff line number Diff line change
Expand Up @@ -839,14 +839,19 @@ static void write_graph_chunk_data(struct hashfile *f, int hash_len,

while (list < last) {
struct commit_list *parent;
struct object_id *tree;
int edge_value;
uint32_t packedDate[2];
display_progress(ctx->progress, ++ctx->progress_cnt);

if (parse_commit_no_graph(*list))
die(_("unable to parse commit %s"),
oid_to_hex(&(*list)->object.oid));
hashwrite(f, get_commit_tree_oid(*list)->hash, hash_len);
tree = get_commit_tree_oid(*list);
if (!tree)
die(_("unable to get tree for %s"),
oid_to_hex(&(*list)->object.oid));
hashwrite(f, tree->hash, hash_len);

parent = (*list)->parents;

Expand Down
3 changes: 2 additions & 1 deletion commit.c
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,8 @@ struct tree *repo_get_commit_tree(struct repository *r,

struct object_id *get_commit_tree_oid(const struct commit *commit)
{
return &get_commit_tree(commit)->object.oid;
struct tree *tree = get_commit_tree(commit);
return tree ? &tree->object.oid : NULL;
}

void release_commit_memory(struct parsed_object_pool *pool, struct commit *c)
Expand Down
2 changes: 1 addition & 1 deletion t/t5318-commit-graph.sh
Original file line number Diff line number Diff line change
Expand Up @@ -607,7 +607,7 @@ test_expect_success 'corrupt commit-graph write (broken parent)' '
)
'

test_expect_failure 'corrupt commit-graph write (missing tree)' '
test_expect_success 'corrupt commit-graph write (missing tree)' '
rm -rf repo &&
git init repo &&
(
Expand Down

0 comments on commit 806278d

Please sign in to comment.