Skip to content

Commit 96a6621

Browse files
peffgitster
authored andcommitted
fetch-pack: fix segfault when fscking without --lock-pack
The fetch-pack internals have multiple options related to creating ".keep" lock-files for the received pack: - if args.lock_pack is set, then we tell index-pack to create a .keep file. In the fetch-pack plumbing command, this is triggered by passing "-k" twice. - if the caller passes in a pack_lockfiles string list, then we use it to record the path of the keep-file created by index-pack. We get that name by reading the stdout of index-pack. In the fetch-pack command, this is triggered by passing the (undocumented) --lock-pack option; without it, we pass in a NULL string list. So it's possible to ask index-pack to create the lock-file (using "-k -k") but not ask to record it (by avoiding "--lock-pack"). This worked fine until 5476e1e (fetch-pack: print and use dangling .gitmodules, 2021-02-22), but now it causes a segfault. Before that commit, if pack_lockfiles was NULL, we wouldn't bother reading the output from index-pack at all. But since that commit, index-pack may produce extra output if we asked it to fsck. So even if nobody cares about the lockfile path, we still need to read it to skip to the output we do care about. We correctly check that we didn't get a NULL lockfile path (which can happen if we did not ask it to create a .keep file at all), but we missed the case where the lockfile path is not NULL (due to "-k -k") but the pack_lockfiles string_list is NULL (because nobody passed "--lock-pack"), and segfault trying to add to the NULL string-list. We can fix this by skipping the append to the string list when either the value or the list is NULL. In that case we must also free the lockfile path to avoid leaking it when it's non-NULL. Nobody noticed the bug for so long because the transport code used by "git fetch" always passes in a pack_lockfiles pointer, and remote-curl (the main user of the fetch-pack plumbing command) always passes --lock-pack. Reported-by: Kirill Smelkov <[email protected]> Signed-off-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 3c2a3fd commit 96a6621

File tree

2 files changed

+13
-1
lines changed

2 files changed

+13
-1
lines changed

fetch-pack.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1041,8 +1041,10 @@ static int get_pack(struct fetch_pack_args *args,
10411041

10421042
if (!is_well_formed)
10431043
die(_("fetch-pack: invalid index-pack output"));
1044-
if (pack_lockfile)
1044+
if (pack_lockfiles && pack_lockfile)
10451045
string_list_append_nodup(pack_lockfiles, pack_lockfile);
1046+
else
1047+
free(pack_lockfile);
10461048
parse_gitmodules_oids(cmd.out, gitmodules_oids);
10471049
close(cmd.out);
10481050
}

t/t5500-fetch-pack.sh

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -993,6 +993,16 @@ test_expect_success 'ensure bogus fetch.negotiationAlgorithm yields error' '
993993
fetch origin server_has both_have_2
994994
'
995995

996+
test_expect_success 'fetch-pack with fsckObjects and keep-file does not segfault' '
997+
rm -rf server client &&
998+
test_create_repo server &&
999+
test_commit -C server one &&
1000+
1001+
test_create_repo client &&
1002+
git -c fetch.fsckObjects=true \
1003+
-C client fetch-pack -k -k ../server HEAD
1004+
'
1005+
9961006
test_expect_success 'filtering by size' '
9971007
rm -rf server client &&
9981008
test_create_repo server &&

0 commit comments

Comments
 (0)