diff -Nru git-2.17.1/debian/changelog git-2.17.1/debian/changelog --- git-2.17.1/debian/changelog 2018-10-05 23:27:58.000000000 +0000 +++ git-2.17.1/debian/changelog 2018-11-26 14:20:24.000000000 +0000 @@ -1,3 +1,12 @@ +git (1:2.17.1-1ubuntu0.4) bionic-security; urgency=medium + + * SECURITY UPDATE: Unsafe command execution + - debian/patches/CVE-2018-19486.patch: fix in + run-command.c, t/t0061-run-command.sh. + - CVE-2018-19486 + + -- Leonidas S. Barbosa Mon, 26 Nov 2018 11:20:24 -0300 + git (1:2.17.1-1ubuntu0.3) bionic-security; urgency=medium * SECURITY UPDATE: arbitrary code execution via submodule URLs and diff -Nru git-2.17.1/debian/patches/CVE-2018-19486.patch git-2.17.1/debian/patches/CVE-2018-19486.patch --- git-2.17.1/debian/patches/CVE-2018-19486.patch 1970-01-01 00:00:00.000000000 +0000 +++ git-2.17.1/debian/patches/CVE-2018-19486.patch 2018-11-26 14:19:40.000000000 +0000 @@ -0,0 +1,127 @@ +From 321fd82389742398d2924640ce3a61791fd27d60 Mon Sep 17 00:00:00 2001 +From: Jeff King +Date: Wed, 24 Oct 2018 03:38:00 -0400 +Subject: run-command: mark path lookup errors with ENOENT + +Since commit e3a434468f (run-command: use the +async-signal-safe execv instead of execvp, 2017-04-19), +prepare_cmd() does its own PATH lookup for any commands we +run (on non-Windows platforms). + +However, its logic does not match the old execvp call when +we fail to find a matching entry in the PATH. Instead of +feeding the name directly to execv, execvp would consider +that an ENOENT error. By continuing and passing the name +directly to execv, we effectively behave as if "." was +included at the end of the PATH. This can have confusing and +even dangerous results. + +The fix itself is pretty straight-forward. There's a new +test in t0061 to cover this explicitly, and I've also added +a duplicate of the ENOENT test to ensure that we return the +correct errno for this case. + +Signed-off-by: Jeff King +Signed-off-by: Junio C Hamano +diff --git a/run-command.c b/run-command.c +index a483d59..e4839c3 100644 +--- a/run-command.c ++++ b/run-command.c +@@ -380,7 +380,7 @@ static void child_err_spew(struct child_process *cmd, struct child_err *cerr) + set_error_routine(old_errfn); + } + +-static void prepare_cmd(struct argv_array *out, const struct child_process *cmd) ++static int prepare_cmd(struct argv_array *out, const struct child_process *cmd) + { + if (!cmd->argv[0]) + die("BUG: command is empty"); +@@ -403,16 +403,22 @@ static void prepare_cmd(struct argv_array *out, const struct child_process *cmd) + /* + * If there are no '/' characters in the command then perform a path + * lookup and use the resolved path as the command to exec. If there +- * are no '/' characters or if the command wasn't found in the path, +- * have exec attempt to invoke the command directly. ++ * are '/' characters, we have exec attempt to invoke the command ++ * directly. + */ + if (!strchr(out->argv[1], '/')) { + char *program = locate_in_PATH(out->argv[1]); + if (program) { + free((char *)out->argv[1]); + out->argv[1] = program; ++ } else { ++ argv_array_clear(out); ++ errno = ENOENT; ++ return -1; + } + } ++ ++ return 0; + } + + static char **prep_childenv(const char *const *deltaenv) +@@ -722,6 +728,12 @@ int start_command(struct child_process *cmd) + struct child_err cerr; + struct atfork_state as; + ++ if (prepare_cmd(&argv, cmd) < 0) { ++ failed_errno = errno; ++ cmd->pid = -1; ++ goto end_of_spawn; ++ } ++ + if (pipe(notify_pipe)) + notify_pipe[0] = notify_pipe[1] = -1; + +@@ -732,7 +744,6 @@ int start_command(struct child_process *cmd) + set_cloexec(null_fd); + } + +- prepare_cmd(&argv, cmd); + childenv = prep_childenv(cmd->env); + atfork_prepare(&as); + +@@ -860,6 +871,8 @@ int start_command(struct child_process *cmd) + argv_array_clear(&argv); + free(childenv); + } ++end_of_spawn: ++ + #else + { + int fhin = 0, fhout = 1, fherr = 2; +diff --git a/t/t0061-run-command.sh b/t/t0061-run-command.sh +index 24c92b6..8d43866 100755 +--- a/t/t0061-run-command.sh ++++ b/t/t0061-run-command.sh +@@ -13,10 +13,14 @@ cat >hello-script <<-EOF + EOF + >empty + +-test_expect_success 'start_command reports ENOENT' ' ++test_expect_success 'start_command reports ENOENT (slash)' ' + test-run-command start-command-ENOENT ./does-not-exist + ' + ++test_expect_success 'start_command reports ENOENT (no slash)' ' ++ test-run-command start-command-ENOENT does-not-exist ++' ++ + test_expect_success 'run_command can run a command' ' + cat hello-script >hello.sh && + chmod +x hello.sh && +@@ -26,6 +30,13 @@ test_expect_success 'run_command can run a command' ' + test_cmp empty err + ' + ++test_expect_success 'run_command is restricted to PATH' ' ++ write_script should-not-run <<-\EOF && ++ echo yikes ++ EOF ++ test_must_fail test-run-command run-command should-not-run ++' ++ + test_expect_success !MINGW 'run_command can run a script without a #! line' ' + cat >hello <<-\EOF && + cat hello-script diff -Nru git-2.17.1/debian/patches/series git-2.17.1/debian/patches/series --- git-2.17.1/debian/patches/series 2018-10-05 23:27:47.000000000 +0000 +++ git-2.17.1/debian/patches/series 2018-11-26 14:19:40.000000000 +0000 @@ -3,3 +3,4 @@ 0003-submodule-config-ban-submodule-paths-that-start-with.patch 0004-fsck-detect-submodule-urls-starting-with-dash.patch 0005-fsck-detect-submodule-paths-starting-with-dash.patch +CVE-2018-19486.patch