Skip to content

Commit 3611f74

Browse files
avargitster
authored andcommitted
for-each-repo: with bad config, don't conflate <path> and <cmd>
Fix a logic error in 4950b2a (for-each-repo: run subcommands on configured repos, 2020-09-11). Due to assuming that elements returned from the repo_config_get_value_multi() call wouldn't be "NULL" we'd conflate the <path> and <command> part of the argument list when running commands. As noted in the preceding commit the fix is to move to a safer "*_string_multi()" version of the *_multi() API. This change is separated from the rest because those all segfaulted. In this change we ended up with different behavior. When using the "--config=<config>" form we take each element of the list as a path to a repository. E.g. with a configuration like: [repo] list = /some/repo We would, with this command: git for-each-repo --config=repo.list status builtin Run a "git status" in /some/repo, as: git -C /some/repo status builtin I.e. ask "status" to report on the "builtin" directory. But since a configuration such as this would result in a "struct string_list *" with one element, whose "string" member is "NULL": [repo] list We would, when constructing our command-line in "builtin/for-each-repo.c"... strvec_pushl(&child.args, "-C", path, NULL); for (i = 0; i < argc; i++) strvec_push(&child.args, argv[i]); ...have that "path" be "NULL", and as strvec_pushl() stops when it sees NULL we'd end with the first "argv" element as the argument to the "-C" option, e.g.: git -C status builtin I.e. we'd run the command "builtin" in the "status" directory. In another context this might be an interesting security vulnerability, but I think that this amounts to a nothingburger on that front. A hypothetical attacker would need to be able to write config for the victim to run, if they're able to do that there's more interesting attack vectors. See the "safe.directory" facility added in 8d1a744 (setup.c: create `safe.bareRepository`, 2022-07-14). An even more unlikely possibility would be an attacker able to generate the config used for "for-each-repo --config=<key>", but nothing else (e.g. an automated system producing that list). Even in that case the attack vector is limited to the user running commands whose name matches a directory that's interesting to the attacker (e.g. a "log" directory in a repository). The second argument (if any) of the command is likely to make git die without doing anything interesting (e.g. "-p" to "log", there being no "-p" built-in command to run). Signed-off-by: Ævar Arnfjörð Bjarmason <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 9e2d884 commit 3611f74

File tree

2 files changed

+14
-1
lines changed

2 files changed

+14
-1
lines changed

builtin/for-each-repo.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ int cmd_for_each_repo(int argc, const char **argv, const char *prefix)
4646
if (!config_key)
4747
die(_("missing --config=<config>"));
4848

49-
err = repo_config_get_value_multi(the_repository, config_key, &values);
49+
err = repo_config_get_string_multi(the_repository, config_key, &values);
5050
if (err < 0)
5151
usage_msg_optf(_("got bad config --config=%s"),
5252
for_each_repo_usage, options, config_key);

t/t0068-for-each-repo.sh

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,4 +45,17 @@ test_expect_success 'error on bad config keys' '
4545
test_expect_code 129 git for-each-repo --config="'\''.b"
4646
'
4747

48+
test_expect_success 'error on NULL value for config keys' '
49+
cat >>.git/config <<-\EOF &&
50+
[empty]
51+
key
52+
EOF
53+
cat >expect <<-\EOF &&
54+
error: missing value for '\''empty.key'\''
55+
EOF
56+
test_expect_code 129 git for-each-repo --config=empty.key 2>actual.raw &&
57+
grep ^error actual.raw >actual &&
58+
test_cmp expect actual
59+
'
60+
4861
test_done

0 commit comments

Comments
 (0)