git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 09/23] builtin/clone: fix leaking repo state when cloning with bundle URIs

From
Patrick Steinhardt <ps@pks.im>
Date
Sep 30, 2024, 09:13 UTC
Message-ID
<2fa76a00fc0469d0c64c66e81b96d622844b8f0d.1727687410.git.ps@pks.im>
In-Reply-To
<cover.1727687410.git.ps@pks.im>

When cloning with bundle URIs we re-initialize `the_repository` after having fetched the bundle. This causes a bunch of memory leaks though because we do not release its previous state.

These leaks can be plugged by calling `repo_clear()` before we call `repo_init()`. But this causes another issue because the remote that we used is tied to the lifetime of the repository's remote state, which would also get released. We thus have to make sure that it does not get free'd under our feet.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
---
 builtin/clone.c                        | 27 ++++++++++++++++++++++++++
 t/t5730-protocol-v2-bundle-uri-file.sh |  1 +
 t/t5731-protocol-v2-bundle-uri-git.sh  |  1 +
 t/t5732-protocol-v2-bundle-uri-http.sh |  1 +
 4 files changed, 30 insertions(+)
diff --git a/builtin/clone.c b/builtin/clone.c
index e77339c847..59fcb317a6 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -1403,8 +1403,17 @@ int cmd_clone(int argc,
 	 * data from the --bundle-uri option.
 	 */
 	if (bundle_uri) {
+		struct remote_state *state;
 		int has_heuristic = 0;
 
+		/*
+		 * We need to save the remote state as our remote's lifetime is
+		 * tied to it.
+		 */
+		state = the_repository->remote_state;
+		the_repository->remote_state = NULL;
+		repo_clear(the_repository);
+
 		/* At this point, we need the_repository to match the cloned repo. */
 		if (repo_init(the_repository, git_dir, work_tree))
 			warning(_("failed to initialize the repo, skipping bundle URI"));
@@ -1413,6 +1422,10 @@ int cmd_clone(int argc,
 				bundle_uri);
 		else if (has_heuristic)
 			git_config_set_gently("fetch.bundleuri", bundle_uri);
+
+		remote_state_clear(the_repository->remote_state);
+		free(the_repository->remote_state);
+		the_repository->remote_state = state;
 	} else {
 		/*
 		* Populate transport->got_remote_bundle_uri and
@@ -1422,12 +1435,26 @@ int cmd_clone(int argc,
 
 		if (transport->bundles &&
 		    hashmap_get_size(&transport->bundles->bundles)) {
+			struct remote_state *state;
+
+			/*
+			 * We need to save the remote state as our remote's
+			 * lifetime is tied to it.
+			 */
+			state = the_repository->remote_state;
+			the_repository->remote_state = NULL;
+			repo_clear(the_repository);
+
 			/* At this point, we need the_repository to match the cloned repo. */
 			if (repo_init(the_repository, git_dir, work_tree))
 				warning(_("failed to initialize the repo, skipping bundle URI"));
 			else if (fetch_bundle_list(the_repository,
 						   transport->bundles))
 				warning(_("failed to fetch advertised bundles"));
+
+			remote_state_clear(the_repository->remote_state);
+			free(the_repository->remote_state);
+			the_repository->remote_state = state;
 		} else {
 			clear_bundle_list(transport->bundles);
 			FREE_AND_NULL(transport->bundles);
diff --git a/t/t5730-protocol-v2-bundle-uri-file.sh b/t/t5730-protocol-v2-bundle-uri-file.sh
index 37bdb725bc..38396df95b 100755
--- a/t/t5730-protocol-v2-bundle-uri-file.sh
+++ b/t/t5730-protocol-v2-bundle-uri-file.sh
@@ -7,6 +7,7 @@ TEST_NO_CREATE_REPO=1
 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
 
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 
 # Test protocol v2 with 'file://' transport
diff --git a/t/t5731-protocol-v2-bundle-uri-git.sh b/t/t5731-protocol-v2-bundle-uri-git.sh
index 8add1b37ab..c199e955fe 100755
--- a/t/t5731-protocol-v2-bundle-uri-git.sh
+++ b/t/t5731-protocol-v2-bundle-uri-git.sh
@@ -7,6 +7,7 @@ TEST_NO_CREATE_REPO=1
 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
 
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 
 # Test protocol v2 with 'git://' transport
diff --git a/t/t5732-protocol-v2-bundle-uri-http.sh b/t/t5732-protocol-v2-bundle-uri-http.sh
index 129daa0226..a9403e94c6 100755
--- a/t/t5732-protocol-v2-bundle-uri-http.sh
+++ b/t/t5732-protocol-v2-bundle-uri-http.sh
@@ -7,6 +7,7 @@ TEST_NO_CREATE_REPO=1
 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
 
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 
 # Test protocol v2 with 'http://' transport
-- 
2.46.2.852.g229c0bf0e5.dirty
Previous: Patrick SteinhardtNext: Patrick Steinhardt
Message 11 of 33 in “Memory leak fixes (pt.8)”
  1. 00/23 Memory leak fixes (pt.8)Patrick Steinhardt, Sep 30, 2024
  2. 01/23 builtin/annotate: fix leaking args vectorPatrick Steinhardt, Sep 30, 2024
  3. 02/23 read-cache: fix leaking hash context in `do_write_index()`Patrick Steinhardt, Sep 30, 2024
  4. Derrick StoleeSep 30, 2024
  5. 03/23 scalar: fix leaking repositoriesPatrick Steinhardt, Sep 30, 2024
  6. 04/23 shell: fix leaking stringsPatrick Steinhardt, Sep 30, 2024
  7. 05/23 wt-status: fix leaking buffer with sparse directoriesPatrick Steinhardt, Sep 30, 2024
  8. 06/23 submodule: fix leaking submodule entry listPatrick Steinhardt, Sep 30, 2024
  9. 07/23 builtin/stash: fix leaking `pathspec_from_file`Patrick Steinhardt, Sep 30, 2024
  10. 08/23 builtin/pack-redundant: fix various memory leaksPatrick Steinhardt, Sep 30, 2024
  11. 09/23 builtin/clone: fix leaking repo state when cloning with bundle URIsPatrick Steinhardt, Sep 30, 2024
  12. 10/23 t/helper: fix leaking repository in partial-clone helperPatrick Steinhardt, Sep 30, 2024
  13. 11/23 builtin/revert: fix leaking `gpg_sign` and `strategy` configPatrick Steinhardt, Sep 30, 2024
  14. 12/23 diff: improve lifecycle management of diff queuesPatrick Steinhardt, Sep 30, 2024
  15. 13/23 line-log: fix several memory leaksPatrick Steinhardt, Sep 30, 2024
  16. 14/23 pseudo-merge: fix various memory leaksPatrick Steinhardt, Sep 30, 2024
  17. Taylor BlauSep 30, 2024
  18. 15/23 pseudo-merge: fix leaking strmap keysPatrick Steinhardt, Sep 30, 2024
  19. Taylor BlauSep 30, 2024
  20. Patrick SteinhardtOct 7, 2024
  21. Jeff KingOct 8, 2024
  22. Patrick SteinhardtOct 9, 2024
  23. 16/23 pack-bitmap-write: fix leaking OID arrayPatrick Steinhardt, Sep 30, 2024
  24. Taylor BlauSep 30, 2024
  25. 17/23 midx-write: fix leaking bufferPatrick Steinhardt, Sep 30, 2024
  26. Taylor BlauSep 30, 2024
  27. Patrick SteinhardtOct 7, 2024
  28. 18/23 revision: fix memory leaks when rewriting parentsPatrick Steinhardt, Sep 30, 2024
  29. 19/23 revision: fix leaking saved parentsPatrick Steinhardt, Sep 30, 2024
  30. 20/23 pack-write: fix return parameter of `write_rev_file_order()`Patrick Steinhardt, Sep 30, 2024
  31. 21/23 t/helper: fix leaks in proc-receive helperPatrick Steinhardt, Sep 30, 2024
  32. 22/23 remote: fix leaking push reportsPatrick Steinhardt, Sep 30, 2024
  33. 23/23 builtin/send-pack: fix leaking list of push optionsPatrick Steinhardt, Sep 30, 2024

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.