Thread (40 messages) 40 messages, 4 authors, 2026-03-23

[PATCH 2/3] remote-curl: fix memory leak in show_http_message()

flat view
STALE202d

From: Vaidas Pilkauskas via GitGitGadget <hidden>
Date: 2025-11-26 12:30:35
Subsystem: the rest · Maintainer: Linus Torvalds

Revision v1 of 4 in this series.

Revisions (4)
  1. v1 current
  2. v2 [diff vs current]
  3. v5 [diff vs current]
  4. v6 [diff vs current]
From: Vaidas Pilkauskas <redacted>

Fix a memory leak in show_http_message() that was triggered when
displaying HTTP error messages before die(). The function would call
strbuf_reencode() which modifies the caller's strbuf in place,
allocating new memory for the re-encoded string. Since this function
is only called immediately before die(), the allocated memory was
never explicitly freed, causing leak detectors to report it.

The leak became visible when HTTP 429 rate limit retry support was
added, which introduced the HTTP_RATE_LIMITED error case. However,
the issue existed in pre-existing error paths as well
(HTTP_MISSING_TARGET, HTTP_NOAUTH, HTTP_NOMATCHPUBLICKEY) - the new
retry logic just made it more visible in tests because retries
exercise the error paths more frequently.

The leak was detected by LeakSanitizer in t5584 tests that enable
retries (maxRetries > 0). Tests with retries disabled passed because
they took a different code path or timing.

Fix this by making show_http_message() work on a local copy of the
message buffer instead of modifying the caller's buffer in place:

1. Create a local strbuf and copy the message into it
2. Perform re-encoding on the local copy if needed
3. Display the message from the local copy
4. Properly release the local copy before returning

This ensures all memory allocated by strbuf_reencode() is freed
before the function returns, even though die() is called immediately
after, eliminating the leak.

Signed-off-by: Vaidas Pilkauskas <redacted>
---
 remote-curl.c | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/remote-curl.c b/remote-curl.c
index 5959461cd3..dd0680e5ae 100644
--- a/remote-curl.c
+++ b/remote-curl.c
@@ -371,6 +371,7 @@ static int show_http_message(struct strbuf *type, struct strbuf *charset,
 			     struct strbuf *msg)
 {
 	const char *p, *eol;
+	struct strbuf msgbuf = STRBUF_INIT;
 
 	/*
 	 * We only show text/plain parts, as other types are likely
@@ -378,19 +379,24 @@ static int show_http_message(struct strbuf *type, struct strbuf *charset,
 	 */
 	if (strcmp(type->buf, "text/plain"))
 		return -1;
+
+	strbuf_addbuf(&msgbuf, msg);
 	if (charset->len)
-		strbuf_reencode(msg, charset->buf, get_log_output_encoding());
+		strbuf_reencode(&msgbuf, charset->buf, get_log_output_encoding());
 
-	strbuf_trim(msg);
-	if (!msg->len)
+	strbuf_trim(&msgbuf);
+	if (!msgbuf.len) {
+		strbuf_release(&msgbuf);
 		return -1;
+	}
 
-	p = msg->buf;
+	p = msgbuf.buf;
 	do {
 		eol = strchrnul(p, '\n');
 		fprintf(stderr, "remote: %.*s\n", (int)(eol - p), p);
 		p = eol + 1;
 	} while(*eol);
+	strbuf_release(&msgbuf);
 	return 0;
 }
 
-- 
gitgitgadget
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help