Skip to content

Commit 15a4cc9

Browse files
avargitster
authored andcommitted
sequencer.c: fix overflow & segfault in parse_strategy_opts()
The split_cmdline() function introduced in [1] returns an "int". If it's negative it signifies an error. The option parsing in [2] didn't account for this, and assigned the value directly to the "size_t xopts_nr". We'd then attempt to loop over all of these elements, and access uninitialized memory. There's a few things that use this for option parsing, but one way to trigger it is with a bad value to "-X <strategy-option>", e.g: git rebase -X"bad argument\"" In another context this might be a security issue, but in this case someone who's already able to inject arguments directly to our commands would be past other defenses, making this potential escalation a moot point. As the example above & test case shows the error reporting leaves something to be desired. The function will loop over the whitespace-split values, but when it encounters an error we'll only report the first element, which is OK, not the second "argument\"" whose quote is unbalanced. This is an inherent limitation of the current API, and the issue affects other API users. Let's not attempt to fix that now. If and when that happens these tests will need to be adjusted to assert the new output. 1. 2b11e31 (If you have a config containing something like this:, 2006-06-05) 2. ca6c6b4 (sequencer (rebase -i): respect strategy/strategy_opts settings, 2017-01-02) Signed-off-by: Ævar Arnfjörð Bjarmason <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 768bb23 commit 15a4cc9

File tree

2 files changed

+25
-2
lines changed

2 files changed

+25
-2
lines changed

sequencer.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2876,13 +2876,18 @@ static int populate_opts_cb(const char *key, const char *value, void *data)
28762876
void parse_strategy_opts(struct replay_opts *opts, char *raw_opts)
28772877
{
28782878
int i;
2879+
int count;
28792880
char *strategy_opts_string = raw_opts;
28802881

28812882
if (*strategy_opts_string == ' ')
28822883
strategy_opts_string++;
28832884

2884-
opts->xopts_nr = split_cmdline(strategy_opts_string,
2885-
(const char ***)&opts->xopts);
2885+
count = split_cmdline(strategy_opts_string,
2886+
(const char ***)&opts->xopts);
2887+
if (count < 0)
2888+
die(_("could not split '%s': %s"), strategy_opts_string,
2889+
split_cmdline_strerror(count));
2890+
opts->xopts_nr = count;
28862891
for (i = 0; i < opts->xopts_nr; i++) {
28872892
const char *arg = opts->xopts[i];
28882893

t/t3436-rebase-more-options.sh

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,24 @@ test_expect_success 'setup' '
4040
EOF
4141
'
4242

43+
test_expect_success 'bad -X <strategy-option> arguments: unclosed quote' '
44+
cat >expect <<-\EOF &&
45+
fatal: could not split '\''--bad'\'': unclosed quote
46+
EOF
47+
test_expect_code 128 git rebase -X"bad argument\"" side main >out 2>actual &&
48+
test_must_be_empty out &&
49+
test_cmp expect actual
50+
'
51+
52+
test_expect_success 'bad -X <strategy-option> arguments: bad escape' '
53+
cat >expect <<-\EOF &&
54+
fatal: could not split '\''--bad'\'': cmdline ends with \
55+
EOF
56+
test_expect_code 128 git rebase -X"bad escape \\" side main >out 2>actual &&
57+
test_must_be_empty out &&
58+
test_cmp expect actual
59+
'
60+
4361
test_expect_success '--ignore-whitespace works with apply backend' '
4462
test_must_fail git rebase --apply main side &&
4563
git rebase --abort &&

0 commit comments

Comments
 (0)