diff --git a/Documentation/RelNotes/2.30.5.txt b/Documentation/RelNotes/2.30.5.txt new file mode 100644 index 0000000000..5191cab3ae --- /dev/null +++ b/Documentation/RelNotes/2.30.5.txt @@ -0,0 +1,12 @@ +Git v2.30.5 Release Notes +========================= + +This release contains minor fix-ups for the changes that went into +Git 2.30.3 and 2.30.4, addressing CVE-2022-29187. + + * The safety check that verifies a safe ownership of the Git + worktree is now extended to also cover the ownership of the Git + directory (and the `.git` file, if there is any). + +Carlo Marcelo Arenas Belón (1): + setup: tighten ownership checks post CVE-2022-24765 diff --git a/Documentation/RelNotes/2.31.4.txt b/Documentation/RelNotes/2.31.4.txt new file mode 100644 index 0000000000..97a91fd07a --- /dev/null +++ b/Documentation/RelNotes/2.31.4.txt @@ -0,0 +1,6 @@ +Git v2.31.4 Release Notes +========================= + +This release merges up the fixes that appear in v2.30.5 to address +the security issue CVE-2022-29187; see the release notes for that +version for details. diff --git a/Documentation/RelNotes/2.32.3.txt b/Documentation/RelNotes/2.32.3.txt new file mode 100644 index 0000000000..583fabe684 --- /dev/null +++ b/Documentation/RelNotes/2.32.3.txt @@ -0,0 +1,6 @@ +Git v2.32.3 Release Notes +========================= + +This release merges up the fixes that appear in v2.30.5 and +v2.31.4 to address the security issue CVE-2022-29187; see the +release notes for these versions for details. diff --git a/Documentation/RelNotes/2.33.4.txt b/Documentation/RelNotes/2.33.4.txt new file mode 100644 index 0000000000..a145cc25de --- /dev/null +++ b/Documentation/RelNotes/2.33.4.txt @@ -0,0 +1,6 @@ +Git v2.33.4 Release Notes +========================= + +This release merges up the fixes that appear in v2.30.5, v2.31.4 +and v2.32.3 to address the security issue CVE-2022-29187; see +the release notes for these versions for details. diff --git a/Documentation/RelNotes/2.34.4.txt b/Documentation/RelNotes/2.34.4.txt new file mode 100644 index 0000000000..2a6b223403 --- /dev/null +++ b/Documentation/RelNotes/2.34.4.txt @@ -0,0 +1,6 @@ +Git v2.34.4 Release Notes +========================= + +This release merges up the fixes that appear in v2.30.5, v2.31.4, +v2.32.3 and v2.33.4 to address the security issue CVE-2022-29187; +see the release notes for these versions for details. diff --git a/Documentation/RelNotes/2.35.4.txt b/Documentation/RelNotes/2.35.4.txt new file mode 100644 index 0000000000..47abd5ad45 --- /dev/null +++ b/Documentation/RelNotes/2.35.4.txt @@ -0,0 +1,7 @@ +Git v2.35.4 Release Notes +========================= + +This release merges up the fixes that appear in v2.30.5, +v2.31.4, v2.32.3, v2.33.4 and v2.34.4 to address the security +issue CVE-2022-29187; see the release notes for these versions +for details. diff --git a/Documentation/RelNotes/2.36.2.txt b/Documentation/RelNotes/2.36.2.txt index ba5d5acd07..958f5b4102 100644 --- a/Documentation/RelNotes/2.36.2.txt +++ b/Documentation/RelNotes/2.36.2.txt @@ -1,10 +1,16 @@ Git v2.36.2 Release Notes ========================= -This maintenance release is primarily to merge down updates to the -build and CI procedures from the 'master' front, in order to ensure -that we can cut healthy maintenance releases in the future. It also -contains a handful of small and trivially-correct bugfixes. +This release merges up the fixes that appear in v2.30.5, v2.31.4, +v2.32.3, v2.33.4, v2.34.4 and v2.35.4 to address the security +issue CVE-2022-29187; see the release notes for these versions +for details. + +Apart from that, this maintenance release is primarily to merge down +updates to the build and CI procedures from the 'master' front, in +order to ensure that we can cut healthy maintenance releases in the +future. It also contains a handful of small and trivially-correct +bugfixes. Fixes since v2.36.1 ------------------- diff --git a/setup.c b/setup.c index faf5095e44..7f64f34477 100644 --- a/setup.c +++ b/setup.c @@ -1129,14 +1129,32 @@ static int safe_directory_cb(const char *key, const char *value, void *d) return 0; } -static int ensure_valid_ownership(const char *path) +/* + * Check if a repository is safe, by verifying the ownership of the + * worktree (if any), the git directory, and the gitfile (if any). + * + * Exemptions for known-safe repositories can be added via `safe.directory` + * config settings; for non-bare repositories, their worktree needs to be + * added, for bare ones their git directory. + */ +static int ensure_valid_ownership(const char *gitfile, + const char *worktree, const char *gitdir) { - struct safe_directory_data data = { .path = path }; + struct safe_directory_data data = { + .path = worktree ? worktree : gitdir + }; if (!git_env_bool("GIT_TEST_ASSUME_DIFFERENT_OWNER", 0) && - is_path_owned_by_current_user(path)) + (!gitfile || is_path_owned_by_current_user(gitfile)) && + (!worktree || is_path_owned_by_current_user(worktree)) && + (!gitdir || is_path_owned_by_current_user(gitdir))) return 1; + /* + * data.path is the "path" that identifies the repository and it is + * constant regardless of what failed above. data.is_safe should be + * initialized to false, and might be changed by the callback. + */ read_very_early_config(safe_directory_cb, &data); return data.is_safe; @@ -1224,6 +1242,8 @@ static enum discovery_result setup_git_directory_gently_1(struct strbuf *dir, current_device = get_device_or_die(dir->buf, NULL, 0); for (;;) { int offset = dir->len, error_code = 0; + char *gitdir_path = NULL; + char *gitfile = NULL; if (offset > min_offset) strbuf_addch(dir, '/'); @@ -1234,21 +1254,50 @@ static enum discovery_result setup_git_directory_gently_1(struct strbuf *dir, if (die_on_error || error_code == READ_GITFILE_ERR_NOT_A_FILE) { /* NEEDSWORK: fail if .git is not file nor dir */ - if (is_git_directory(dir->buf)) + if (is_git_directory(dir->buf)) { gitdirenv = DEFAULT_GIT_DIR_ENVIRONMENT; + gitdir_path = xstrdup(dir->buf); + } } else if (error_code != READ_GITFILE_ERR_STAT_FAILED) return GIT_DIR_INVALID_GITFILE; - } + } else + gitfile = xstrdup(dir->buf); + /* + * Earlier, we tentatively added DEFAULT_GIT_DIR_ENVIRONMENT + * to check that directory for a repository. + * Now trim that tentative addition away, because we want to + * focus on the real directory we are in. + */ strbuf_setlen(dir, offset); if (gitdirenv) { - if (!ensure_valid_ownership(dir->buf)) - return GIT_DIR_INVALID_OWNERSHIP; - strbuf_addstr(gitdir, gitdirenv); - return GIT_DIR_DISCOVERED; + enum discovery_result ret; + + if (ensure_valid_ownership(gitfile, + dir->buf, + (gitdir_path ? gitdir_path : gitdirenv))) { + strbuf_addstr(gitdir, gitdirenv); + ret = GIT_DIR_DISCOVERED; + } else + ret = GIT_DIR_INVALID_OWNERSHIP; + + /* + * Earlier, during discovery, we might have allocated + * string copies for gitdir_path or gitfile so make + * sure we don't leak by freeing them now, before + * leaving the loop and function. + * + * Note: gitdirenv will be non-NULL whenever these are + * allocated, therefore we need not take care of releasing + * them outside of this conditional block. + */ + free(gitdir_path); + free(gitfile); + + return ret; } if (is_git_directory(dir->buf)) { - if (!ensure_valid_ownership(dir->buf)) + if (!ensure_valid_ownership(NULL, NULL, dir->buf)) return GIT_DIR_INVALID_OWNERSHIP; strbuf_addstr(gitdir, "."); return GIT_DIR_BARE; @@ -1386,7 +1435,7 @@ const char *setup_git_directory_gently(int *nongit_ok) struct strbuf quoted = STRBUF_INIT; sq_quote_buf_pretty("ed, dir.buf); - die(_("unsafe repository ('%s' is owned by someone else)\n" + die(_("detected dubious ownership in repository at '%s'\n" "To add an exception for this directory, call:\n" "\n" "\tgit config --global --add safe.directory %s"), diff --git a/t/t0033-safe-directory.sh b/t/t0033-safe-directory.sh index 238b25f91a..3908597d42 100755 --- a/t/t0033-safe-directory.sh +++ b/t/t0033-safe-directory.sh @@ -9,7 +9,7 @@ export GIT_TEST_ASSUME_DIFFERENT_OWNER expect_rejected_dir () { test_must_fail git status 2>err && - grep "unsafe repository" err + grep "dubious ownership" err } test_expect_success 'safe.directory is not set' ' @@ -18,7 +18,7 @@ test_expect_success 'safe.directory is not set' ' test_expect_success 'ignoring safe.directory on the command line' ' test_must_fail git -c safe.directory="$(pwd)" status 2>err && - grep "unsafe repository" err + grep "dubious ownership" err ' test_expect_success 'ignoring safe.directory in the environment' ' @@ -26,14 +26,14 @@ test_expect_success 'ignoring safe.directory in the environment' ' GIT_CONFIG_KEY_0="safe.directory" \ GIT_CONFIG_VALUE_0="$(pwd)" \ git status 2>err && - grep "unsafe repository" err + grep "dubious ownership" err ' test_expect_success 'ignoring safe.directory in GIT_CONFIG_PARAMETERS' ' test_must_fail env \ GIT_CONFIG_PARAMETERS="${SQ}safe.directory${SQ}=${SQ}$(pwd)${SQ}" \ git status 2>err && - grep "unsafe repository" err + grep "dubious ownership" err ' test_expect_success 'ignoring safe.directory in repo config' '