]> git.ipfire.org Git - thirdparty/git.git/commitdiff
send-pack: fix memory leak around duplicate refs
authorKarthik Nayak <karthik.188@gmail.com>
Mon, 19 May 2025 09:58:08 +0000 (11:58 +0200)
committerJunio C Hamano <gitster@pobox.com>
Mon, 19 May 2025 18:06:31 +0000 (11:06 -0700)
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>
send-pack.c
t/t5408-send-pack-stdin.sh

index 86592ce526db95bb4b13c2c6b19d604a464755ff..e2faa25b98e3c4bdfa7a51a5138d8c286b1d6634 100644 (file)
@@ -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)
index 526a6750459514df0cadbb9120250ba825fca573..45fb20179b77b5d6b1071f97ee43d2add1a4e40d 100755 (executable)
@@ -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 &&