aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKarthik Nayak <karthik.188@gmail.com>2025-05-19 11:58:08 +0200
committerJunio C Hamano <gitster@pobox.com>2025-05-19 11:06:31 -0700
commit77188b5bbaf1f77963968ea3acedda3108102b18 (patch)
treeb27bdb95d5226a824195a91153b6bdaffdd669fe
parentfetch: use batched reference updates (diff)
downloadgit-77188b5bbaf1f77963968ea3acedda3108102b18.tar.gz
git-77188b5bbaf1f77963968ea3acedda3108102b18.zip
send-pack: fix memory leak around duplicate refs
The 'git-send-pack(1)' allows users to push objects to a remote repository and explicitly list the references to be pushed. The status of each reference pushed is captured into a list mapped by refname. If a reference fails to be updated, its error message is captured in the `ref->remote_status` field. While the command allows duplicate ref inputs, the list doesn't accommodate this behavior as a particular refname is linked to a single `struct ref*` element. So if the user inputs a reference twice like: git send-pack remote.git A:foo B:foo where the user is trying to update the same reference 'foo' twice and the reference fails to be updated, we first fill `ref->remote_status` with error message for the input 'A:foo' then we override the same field with the error message for 'B:foo'. This override happens without first free'ing the previous value. Fix this leak. The current tests already incorporate the above example, but in the test 'A:foo' succeeds while 'B:foo' fails, meaning that the memory leak isn't triggered. Add a new test with multiple duplicates. Signed-off-by: Karthik Nayak <karthik.188@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--send-pack.c7
-rwxr-xr-xt/t5408-send-pack-stdin.sh6
2 files changed, 13 insertions, 0 deletions
diff --git a/send-pack.c b/send-pack.c
index 86592ce526..e2faa25b98 100644
--- a/send-pack.c
+++ b/send-pack.c
@@ -257,6 +257,13 @@ static int receive_status(struct repository *r,
refname);
continue;
}
+
+ /*
+ * Clients sending duplicate refs can cause the same value
+ * to be overridden, causing a memory leak.
+ */
+ free(hint->remote_status);
+
if (!strcmp(head, "ng")) {
hint->status = REF_STATUS_REMOTE_REJECT;
if (p)
diff --git a/t/t5408-send-pack-stdin.sh b/t/t5408-send-pack-stdin.sh
index 526a675045..45fb20179b 100755
--- a/t/t5408-send-pack-stdin.sh
+++ b/t/t5408-send-pack-stdin.sh
@@ -73,6 +73,12 @@ test_expect_success 'cmdline refs written in order' '
verify_push A foo
'
+test_expect_success 'cmdline refs with multiple duplicates' '
+ clear_remote &&
+ test_must_fail git send-pack remote.git A:foo B:foo C:foo &&
+ verify_push A foo
+'
+
test_expect_success '--stdin refs come after cmdline' '
clear_remote &&
echo A:foo >input &&