Backport fsck tests for CVE-2018-17456, arbitrary code execution via submodule URL and path
Apply the changes v2.19.0..v2.19.1 from upstream.
This provides defense in depth by adding a second check for anyone who
has transfer.fsckobjects enabled.
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
diff --git a/debian/changelog b/debian/changelog
index 382d897..d61aaad 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -5,6 +5,8 @@
- submodule: ban submodule urls that start with a dash
- submodule: ban submodule paths that start with a dash
- submodule: use "--" to signal end of clone options
+ - fsck: detect submodule urls that start with a dash
+ - fsck: detect submodule paths that start with a dash
Thanks to joernchen of Phenoelit for discovering and reporting this
vulnerability and to Jeff King for fixing it.
diff --git a/debian/patches/fsck-detect-submodule-paths-starting-with-dash.diff b/debian/patches/fsck-detect-submodule-paths-starting-with-dash.diff
new file mode 100644
index 0000000..01c2a20
--- /dev/null
+++ b/debian/patches/fsck-detect-submodule-paths-starting-with-dash.diff
@@ -0,0 +1,89 @@
+From 374d157a8e6a539b56c93ed3d8cbcb09d99380d4 Mon Sep 17 00:00:00 2001
+From: Jeff King <peff@peff.net>
+Date: Mon, 24 Sep 2018 04:42:19 -0400
+Subject: fsck: detect submodule paths starting with dash
+
+commit 1a7fd1fb2998002da6e9ff2ee46e1bdd25ee8404 upstream.
+
+As with urls, submodule paths with dashes are ignored by
+git, but may end up confusing older versions. Detecting them
+via fsck lets us prevent modern versions of git from being a
+vector to spread broken .gitmodules to older versions.
+
+Compared to blocking leading-dash urls, though, this
+detection may be less of a good idea:
+
+ 1. While such paths provide confusing and broken results,
+ they don't seem to actually work as option injections
+ against anything except "cd". In particular, the
+ submodule code seems to canonicalize to an absolute
+ path before running "git clone" (so it passes
+ /your/clone/-sub).
+
+ 2. It's more likely that we may one day make such names
+ actually work correctly. Even after we revert this fsck
+ check, it will continue to be a hassle until hosting
+ servers are all updated.
+
+On the other hand, it's not entirely clear that the behavior
+in older versions is safe. And if we do want to eventually
+allow this, we may end up doing so with a special syntax
+anyway (e.g., writing "./-sub" in the .gitmodules file, and
+teaching the submodule code to canonicalize it when
+comparing).
+
+So on balance, this is probably a good protection.
+
+Signed-off-by: Jeff King <peff@peff.net>
+Signed-off-by: Junio C Hamano <gitster@pobox.com>
+Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
+---
+ fsck.c | 7 +++++++
+ t/t7417-submodule-path-url.sh | 8 ++++++++
+ 2 files changed, 15 insertions(+)
+
+diff --git a/fsck.c b/fsck.c
+index eebc89df61..def446a3e3 100644
+--- a/fsck.c
++++ b/fsck.c
+@@ -94,6 +94,7 @@ static int oidhash_contains(struct hashmap *h, const struct object_id *oid)
+ FUNC(GITMODULES_NAME, ERROR) \
+ FUNC(GITMODULES_SYMLINK, ERROR) \
+ FUNC(GITMODULES_URL, ERROR) \
++ FUNC(GITMODULES_PATH, ERROR) \
+ /* warnings */ \
+ FUNC(BAD_FILEMODE, WARN) \
+ FUNC(EMPTY_NAME, WARN) \
+@@ -975,6 +976,12 @@ static int fsck_gitmodules_fn(const char *var, const char *value, void *vdata)
+ FSCK_MSG_GITMODULES_URL,
+ "disallowed submodule url: %s",
+ value);
++ if (!strcmp(key, "path") && value &&
++ looks_like_command_line_option(value))
++ data->ret |= report(data->options, data->obj,
++ FSCK_MSG_GITMODULES_PATH,
++ "disallowed submodule path: %s",
++ value);
+ free(name);
+
+ return 0;
+diff --git a/t/t7417-submodule-path-url.sh b/t/t7417-submodule-path-url.sh
+index 894ed51685..53b09e5aa4 100755
+--- a/t/t7417-submodule-path-url.sh
++++ b/t/t7417-submodule-path-url.sh
+@@ -17,4 +17,12 @@ test_expect_success 'clone rejects unprotected dash' '
+ test_i18ngrep ignoring err
+ '
+
++test_expect_success 'fsck rejects unprotected dash' '
++ test_when_finished "rm -rf dst" &&
++ git init --bare dst &&
++ git -C dst config transfer.fsckObjects true &&
++ test_must_fail git push dst HEAD 2>err &&
++ grep gitmodulesPath err
++'
++
+ test_done
+--
+2.19.0.605.g01d371f741
+
diff --git a/debian/patches/fsck-detect-submodule-urls-starting-with-dash.diff b/debian/patches/fsck-detect-submodule-urls-starting-with-dash.diff
new file mode 100644
index 0000000..ec02279
--- /dev/null
+++ b/debian/patches/fsck-detect-submodule-urls-starting-with-dash.diff
@@ -0,0 +1,79 @@
+From 7fc71c564889486b09bf88e588c88cf51be58dd1 Mon Sep 17 00:00:00 2001
+From: Jeff King <peff@peff.net>
+Date: Mon, 24 Sep 2018 04:37:17 -0400
+Subject: fsck: detect submodule urls starting with dash
+
+commit a124133e1e6ab5c7a9fef6d0e6bcb084e3455b46 upstream.
+
+Urls with leading dashes can cause mischief on older
+versions of Git. We should detect them so that they can be
+rejected by receive.fsckObjects, preventing modern versions
+of git from being a vector by which attacks can spread.
+
+Signed-off-by: Jeff King <peff@peff.net>
+Signed-off-by: Junio C Hamano <gitster@pobox.com>
+Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
+---
+ fsck.c | 7 +++++++
+ t/t7416-submodule-dash-url.sh | 15 +++++++++++++++
+ 2 files changed, 22 insertions(+)
+
+diff --git a/fsck.c b/fsck.c
+index 921cd6a409..eebc89df61 100644
+--- a/fsck.c
++++ b/fsck.c
+@@ -93,6 +93,7 @@ static int oidhash_contains(struct hashmap *h, const struct object_id *oid)
+ FUNC(GITMODULES_PARSE, ERROR) \
+ FUNC(GITMODULES_NAME, ERROR) \
+ FUNC(GITMODULES_SYMLINK, ERROR) \
++ FUNC(GITMODULES_URL, ERROR) \
+ /* warnings */ \
+ FUNC(BAD_FILEMODE, WARN) \
+ FUNC(EMPTY_NAME, WARN) \
+@@ -968,6 +969,12 @@ static int fsck_gitmodules_fn(const char *var, const char *value, void *vdata)
+ FSCK_MSG_GITMODULES_NAME,
+ "disallowed submodule name: %s",
+ name);
++ if (!strcmp(key, "url") && value &&
++ looks_like_command_line_option(value))
++ data->ret |= report(data->options, data->obj,
++ FSCK_MSG_GITMODULES_URL,
++ "disallowed submodule url: %s",
++ value);
+ free(name);
+
+ return 0;
+diff --git a/t/t7416-submodule-dash-url.sh b/t/t7416-submodule-dash-url.sh
+index 459193c976..1cd2c1c1ea 100755
+--- a/t/t7416-submodule-dash-url.sh
++++ b/t/t7416-submodule-dash-url.sh
+@@ -20,6 +20,13 @@ test_expect_success 'clone can recurse submodule' '
+ test_cmp expect actual
+ '
+
++test_expect_success 'fsck accepts protected dash' '
++ test_when_finished "rm -rf dst" &&
++ git init --bare dst &&
++ git -C dst config transfer.fsckObjects true &&
++ git push dst HEAD
++'
++
+ test_expect_success 'remove ./ protection from .gitmodules url' '
+ perl -i -pe "s{\./}{}" .gitmodules &&
+ git commit -am "drop protection"
+@@ -31,4 +38,12 @@ test_expect_success 'clone rejects unprotected dash' '
+ test_i18ngrep ignoring err
+ '
+
++test_expect_success 'fsck rejects unprotected dash' '
++ test_when_finished "rm -rf dst" &&
++ git init --bare dst &&
++ git -C dst config transfer.fsckObjects true &&
++ test_must_fail git push dst HEAD 2>err &&
++ grep gitmodulesUrl err
++'
++
+ test_done
+--
+2.19.0.605.g01d371f741
+
diff --git a/debian/patches/series b/debian/patches/series
index 96fcb4a..1968fe9 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -39,3 +39,5 @@
submodule-helper-use-to-signal-end-of-clone-options.diff
submodule-config-ban-submodule-urls-that-start-with-d.diff
submodule-config-ban-submodule-paths-that-start-with-.diff
+fsck-detect-submodule-urls-starting-with-dash.diff
+fsck-detect-submodule-paths-starting-with-dash.diff