From: NitroCao via GitGitGadget Date: Tue, 03 Feb 2026 11:56:13 GMT Subject: [PATCH v2] clone: fix segfault when using --revision and v0/v1 protocol Message-ID: In-Reply-To: From: Nitro Cao When `git clone` is used with `--revision` and the protocol version is v0 or v1, the client segfaults if the revision does not specify a peer reference (e.g. `--revision master` instead of `--revision refs/heads/master:master`). This occurs because `update_remote_refs()` assumes that if `remote_head_points_at` is set, `remote_head_points_at->peer_ref` is also valid. However, for v0/v1 protocols, all references are fetched without filtering, and if the revision lacks a peer reference, `peer_ref` remains NULL. Add a check for `remote_head_points_at->peer_ref` before dereferencing it to prevent the segmentation fault. Signed-off-by: Nitro Cao --- fix(clone): segment fault when using --revision and protocol v0/v1 git clone command would segment fault when satisfying the following conditions at the same time: * Use HTTP protocol v0 or v1 to interact with remote servers. * The value of --revision doesn't specify the peer reference, like --revision master instead of --revision refs/heads/master:master When using protocol v2, git client can use ref-prefix param of ls-refs command to fetch wanted references based on --revision. But for protocol v0/v1, git client just fetch all references and doesn't filter them. In this case, the value of remote_head variable is not NULL, which leads to the value of remote_head_points_at not NULL too. But we don't specify the peer reference in --revsion, remote_head_points_at->peer_ref would be NULL. So git client would boom when update_remote_refs. Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-2185%2FNitroCao%2Ffix%2Fsegment-fault-with-revision-param-v2 Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-2185/NitroCao/fix/segment-fault-with-revision-param-v2 Pull-Request: https://github.com/git/git/pull/2185 Range-diff vs v1: 1: f75b1f7e2e ! 1: b3ab27f977 fix(clone): segment fault when using --revision and protocol v0/v1 @@ Metadata Author: Nitro Cao ## Commit message ## - fix(clone): segment fault when using --revision and protocol v0/v1 + clone: fix segfault when using --revision and v0/v1 protocol - git clone command would segment fault when satisfying the following - conditions at the same time: - - Use HTTP protocol v0 or v1 to interact with remote servers. - - The value of `--revision` doesn't specify the peer reference, like - `--revision master` instead of `--revision refs/heads/master:master` + When `git clone` is used with `--revision` and the protocol version is + v0 or v1, the client segfaults if the revision does not specify a peer + reference (e.g. `--revision master` instead of + `--revision refs/heads/master:master`). - When using protocol v2, git client can use `ref-prefix` param of - `ls-refs` command to fetch wanted references based on `--revision`. - But for protocol v0/v1, git client just fetch all references and - doesn't filter them. - In this case, the value of `remote_head` variable is not NULL, - which leads to the value of `remote_head_points_at` not NULL too. - But we don't specify the peer reference in `--revsion`, - `remote_head_points_at->peer_ref` would be NULL. So git client would - boom when `update_remote_refs`. + This occurs because `update_remote_refs()` assumes that if + `remote_head_points_at` is set, `remote_head_points_at->peer_ref` is + also valid. However, for v0/v1 protocols, all references are fetched + without filtering, and if the revision lacks a peer reference, + `peer_ref` remains NULL. + + Add a check for `remote_head_points_at->peer_ref` before dereferencing + it to prevent the segmentation fault. Signed-off-by: Nitro Cao builtin/clone.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builtin/clone.c b/builtin/clone.c index b40cee5968..ba8de92563 100644 --- a/builtin/clone.c +++ b/builtin/clone.c @@ -558,7 +558,7 @@ static void update_remote_refs(const struct ref *refs, write_followtags(refs, msg); } - if (remote_head_points_at && !option_bare) { + if (remote_head_points_at && remote_head_points_at->peer_ref && !option_bare) { struct strbuf head_ref = STRBUF_INIT; strbuf_addstr(&head_ref, branch_top); strbuf_addstr(&head_ref, "HEAD"); base-commit: 67ad42147a7acc2af6074753ebd03d904476118f -- gitgitgadget