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

[PATCH] builtin/gc: fix crash when running `git maintenance start`

From
Patrick Steinhardt <ps@pks.im>
Date
Oct 8, 2024, 12:15 UTC
Message-ID
<976c97081af7c62960bd71d1b70039657e7cb711.1728389731.git.ps@pks.im>
In-Reply-To
<CAG=Um+0mJW-oAH+YLC3dWEU64JwS-zMkkTiFWYBe4g6HMbe-iA@mail.gmail.com>

It was reported on the mailing list that running `git maintenance start` immediately segfaults starting with b6c3f8e12c (builtin/maintenance: fix leak in `get_schedule_cmd()`, 2024-09-26). And indeed, this segfault is trivial to reproduce up to a point where one is scratching their head why we didn't catch this regression in our test suite.

The root cause of this error is `get_schedule_cmd()`, which does not populate the `out` parameter in all cases anymore starting with the mentioned commit. Callers do assume it to always be populated though and will e.g. call `strvec_split()` on the returned value, which will of course segfault when the variable is uninitialized.

So why didn't we catch this trivial regression? The reason is that our tests always set up the "GIT_TEST_MAINT_SCHEDULER" environment variable via "t/test-lib.sh", which allows us to override the scheduler command with a custom one so that we don't accidentally modify the developer's system. But the faulty code where we don't set the `out` parameter will only get hit in case that environment variable is _not_ set, which is never the case when executing our tests.

Fix the regression by again unconditionally allocating the value in the `out` parameter, if provided. Add a test that unsets the environment variable to catch future regressions in this area.

Reported-by: Shubham Kanodia <shubham.kanodia10@gmail.com>
Signed-off-by: Patrick Steinhardt <ps@pks.im>
---
 builtin/gc.c           |  7 +++++--
 t/t7900-maintenance.sh | 16 ++++++++++++++++
 2 files changed, 21 insertions(+), 2 deletions(-)
diff --git a/builtin/gc.c b/builtin/gc.c
index 6a7a2da006..d52735354c 100644
--- a/builtin/gc.c
+++ b/builtin/gc.c
@@ -1832,7 +1832,7 @@ static const char *get_extra_launchctl_strings(void) {
  *     | Input |                     Output                      |
  *     | *cmd  | return code |       *out        | *is_available |
  *     +-------+-------------+-------------------+---------------+
- *     | "foo" |    false    | NULL              |  (unchanged)  |
+ *     | "foo" |    false    | "foo" (allocated) |  (unchanged)  |
  *     +-------+-------------+-------------------+---------------+
  *
  *   GIT_TEST_MAINT_SCHEDULER set to “foo:./mock_foo.sh,bar:./mock_bar.sh”
@@ -1850,8 +1850,11 @@ static int get_schedule_cmd(const char *cmd, int *is_available, char **out)
 	struct string_list_item *item;
 	struct string_list list = STRING_LIST_INIT_NODUP;
 
-	if (!testing)
+	if (!testing) {
+		if (out)
+			*out = xstrdup(cmd);
 		return 0;
+	}
 
 	if (is_available)
 		*is_available = 0;
diff --git a/t/t7900-maintenance.sh b/t/t7900-maintenance.sh
index a66d0e089d..4008e4e45e 100755
--- a/t/t7900-maintenance.sh
+++ b/t/t7900-maintenance.sh
@@ -646,6 +646,22 @@ test_expect_success !MINGW 'register and unregister with regex metacharacters' '
 		maintenance.repo "$(pwd)/$META"
 '
 
+test_expect_success 'start without GIT_TEST_MAINT_SCHEDULER' '
+	test_when_finished "rm -rf crontab.log script repo" &&
+	mkdir script &&
+	write_script script/crontab <<-EOF &&
+	echo "\$*" >>"$(pwd)"/crontab.log
+	EOF
+	git init repo &&
+	(
+		cd repo &&
+		sane_unset GIT_TEST_MAINT_SCHEDULER &&
+		PATH="$(pwd)/../script:$PATH" git maintenance start --scheduler=crontab
+	) &&
+	test_grep -- -l crontab.log &&
+	test_grep -- git_cron_edit_tmp crontab.log
+'
+
 test_expect_success 'start --scheduler=<scheduler>' '
 	test_expect_code 129 git maintenance start --scheduler=foo 2>err &&
 	test_grep "unrecognized --scheduler argument" err &&
-- 
2.47.0.rc1.33.g90fe3800b9.dirty
Previous: Patrick SteinhardtNext: Derrick Stolee
Message 3 of 19 in “Bug: `git maintenance start` is likely broken in 2.47”
  1. Shubham KanodiaOct 8, 2024
  2. Patrick SteinhardtOct 8, 2024
  3. builtin/gc: fix crash when running `git maintenance start`Patrick Steinhardt, Oct 8, 2024
  4. Derrick StoleeOct 8, 2024
  5. Derrick StoleeOct 9, 2024
  6. Patrick SteinhardtOct 9, 2024
  7. Junio C HamanoOct 8, 2024
  8. Junio C HamanoOct 9, 2024
  9. Patrick SteinhardtOct 10, 2024
  10. Patrick SteinhardtOct 10, 2024
  11. builtin/gc: fix crash when running `git maintenance start`Patrick Steinhardt, Oct 9, 2024
  12. Derrick StoleeOct 9, 2024
  13. Junio C HamanoOct 9, 2024
  14. Junio C HamanoOct 9, 2024
  15. builtin/gc: fix crash when running `git maintenance start`Patrick Steinhardt, Oct 10, 2024
  16. Junio C HamanoOct 10, 2024
  17. Shubham KanodiaOct 14, 2024
  18. Patrick SteinhardtOct 14, 2024
  19. Taylor BlauOct 15, 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.