submodule: ignore path and url attributes if they look like options These can be used to inject options in an implementation which performs a recursive clone by executing an external command via crafted url and path attributes such that it triggers a local executable to be run. The library is not vulnerable as we do not rely on external executables but a user of the library might be relying on that so we add this protection. This matches this aspect of git's fix for CVE-2018-17456.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
diff --git a/src/submodule.c b/src/submodule.c
index 9231f08..825e85a 100644
--- a/src/submodule.c
+++ b/src/submodule.c
@@ -1865,6 +1865,14 @@ static int get_value(const char **out, git_config *cfg, git_buf *buf, const char
return error;
}
+static bool looks_like_command_line_option(const char *s)
+{
+ if (s && s[0] == '-')
+ return true;
+
+ return false;
+}
+
static int submodule_read_config(git_submodule *sm, git_config *cfg)
{
git_buf key = GIT_BUF_INIT;
@@ -1878,24 +1886,31 @@ static int submodule_read_config(git_submodule *sm, git_config *cfg)
if ((error = get_value(&value, cfg, &key, sm->name, "path")) == 0) {
in_config = 1;
+ /* We would warn here if we had that API */
+ if (!looks_like_command_line_option(value)) {
/*
* TODO: if case insensitive filesystem, then the following strcmp
* should be strcasecmp
*/
- if (strcmp(sm->name, value) != 0) {
- if (sm->path != sm->name)
- git__free(sm->path);
- sm->path = git__strdup(value);
- GITERR_CHECK_ALLOC(sm->path);
+ if (strcmp(sm->name, value) != 0) {
+ if (sm->path != sm->name)
+ git__free(sm->path);
+ sm->path = git__strdup(value);
+ GITERR_CHECK_ALLOC(sm->path);
+ }
+
}
} else if (error != GIT_ENOTFOUND) {
goto cleanup;
}
if ((error = get_value(&value, cfg, &key, sm->name, "url")) == 0) {
- in_config = 1;
- sm->url = git__strdup(value);
- GITERR_CHECK_ALLOC(sm->url);
+ /* We would warn here if we had that API */
+ if (!looks_like_command_line_option(value)) {
+ in_config = 1;
+ sm->url = git__strdup(value);
+ GITERR_CHECK_ALLOC(sm->url);
+ }
} else if (error != GIT_ENOTFOUND) {
goto cleanup;
}