From 9bf9eed093561f50091014faa7164c0325ea9ced Mon Sep 17 00:00:00 2001 From: Jeff King Date: Mon, 19 Jan 2026 00:22:08 -0500 Subject: 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 Signed-off-by: Junio C Hamano --- remote.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'remote.c') diff --git a/remote.c b/remote.c index fc5894e949..041f9ceb52 100644 --- a/remote.c +++ b/remote.c @@ -1945,9 +1945,11 @@ static const char *branch_get_push_1(struct repository *repo, cur = tracking_for_push_dest(remote, branch->refname, err); if (!cur) return NULL; - if (strcmp(cur, up)) + if (strcmp(cur, up)) { + free(cur); return error_buf(err, _("cannot resolve 'simple' push to a single destination")); + } return cur; } } -- cgit v1.3