summaryrefslogtreecommitdiff
path: root/send-pack.c
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 /send-pack.c
parent0e358de64a9e014575d11ef884bfc9beb931e37f (diff)
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>
Diffstat (limited to 'send-pack.c')
-rw-r--r--send-pack.c7
1 files changed, 7 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)