]> git.ipfire.org Git - thirdparty/git.git/commit
remote: fix leak in branch_get_push_1() with invalid "simple" config
authorJeff King <peff@peff.net>
Mon, 19 Jan 2026 05:22:08 +0000 (00:22 -0500)
committerJunio C Hamano <gitster@pobox.com>
Tue, 20 Jan 2026 00:24:02 +0000 (16:24 -0800)
commit9bf9eed093561f50091014faa7164c0325ea9ced
tree0bc01fd62890ff5802d4b65c66ac51592c6c0630
parent782a719e99b8a66ef7e05481a481ddfc329985b5
remote: fix leak in branch_get_push_1() with invalid "simple" config

Most of the code paths in branch_get_push_1() allocate a string for the
@{push} value. We then return the result, which is stored in a "struct
branch", so the value is not leaked.

But there's one path that does leak: when we are in the "simple" push
mode, we have to check that the @{push} value matches what we'd get for
@{upstream}. If it doesn't, we return an error, but forget to free the
@{push} value we computed.

Curiously, the existing tests don't trigger this with LSan, even though
they do exercise the code path. As far as I can tell, it should be
triggered via:

  git -c push.default=simple \
      -c branch.foo.remote=origin \
      -c branch.foo.merge=refs/heads/not-foo \
      rev-parse foo@{push}

which will complain that the upstream ("not-foo") does not match the
push destination ("foo"). We do die() shortly after this, but not until
after returning from branch_get_push_1(), which is where the leak
happens.

So it seems like a false negative in LSan. However, I can trigger it
reliably by printing the @{push} value using for-each-ref. This takes a
little more setup (because we need "foo" to actually exist to iterate
over it with for-each-ref), but we can piggy-back on the existing repo
config in t6300.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
remote.c
t/for-each-ref-tests.sh