From e00b09358fc22ded8aaf528f6c140b05af2bd767 Mon Sep 17 00:00:00 2001 From: fuanan <2385803914@qq.com> Date: Fri, 20 May 2022 11:19:47 +0800 Subject: [PATCH] Fix CVE-2022-24765 --- backport-0001-CVE-2022-24765.patch | 118 +++++++++++ backport-0002-CVE-2022-24765.patch | 187 ++++++++++++++++++ backport-0003-CVE-2022-24765.patch | 174 ++++++++++++++++ backport-0004-CVE-2022-24765.patch | 66 +++++++ backport-0005-CVE-2022-24765.patch | 48 +++++ backport-0006-CVE-2022-24765.patch | 88 +++++++++ ...t-t0033-add-tests-for-safe.directory.patch | 72 +++++++ git.spec | 15 +- 8 files changed, 767 insertions(+), 1 deletion(-) create mode 100644 backport-0001-CVE-2022-24765.patch create mode 100644 backport-0002-CVE-2022-24765.patch create mode 100644 backport-0003-CVE-2022-24765.patch create mode 100644 backport-0004-CVE-2022-24765.patch create mode 100644 backport-0005-CVE-2022-24765.patch create mode 100644 backport-0006-CVE-2022-24765.patch create mode 100644 backport-t0033-add-tests-for-safe.directory.patch diff --git a/backport-0001-CVE-2022-24765.patch b/backport-0001-CVE-2022-24765.patch new file mode 100644 index 0000000..aaaabfe --- /dev/null +++ b/backport-0001-CVE-2022-24765.patch @@ -0,0 +1,118 @@ +From fdcad5a53e14bd397e4fa323e7fd0c3bf16dd373 Mon Sep 17 00:00:00 2001 +From: Johannes Schindelin +Date: Wed, 23 Mar 2022 23:00:41 +0100 +Subject: [PATCH] Fix `GIT_CEILING_DIRECTORIES` with `C:\` and the likes + +When determining the length of the longest ancestor of a given path with +respect to to e.g. `GIT_CEILING_DIRECTORIES`, we special-case the root +directory by returning 0 (i.e. we pretend that the path `/` does not end +in a slash by virtually stripping it). + +That is the correct behavior because when normalizing paths, the root +directory is special: all other directory paths have their trailing +slash stripped, but not the root directory's path (because it would +become the empty string, which is not a legal path). + +However, this special-casing of the root directory in +`longest_ancestor_length()` completely forgets about Windows-style root +directories, e.g. `C:\`. These _also_ get normalized with a trailing +slash (because `C:` would actually refer to the current directory on +that drive, not necessarily to its root directory). + +In fc56c7b34b (mingw: accomodate t0060-path-utils for MSYS2, +2016-01-27), we almost got it right. We noticed that +`longest_ancestor_length()` expects a slash _after_ the matched prefix, +and if the prefix already ends in a slash, the normalized path won't +ever match and -1 is returned. + +But then that commit went astray: The correct fix is not to adjust the +_tests_ to expect an incorrect -1 when that function is fed a prefix +that ends in a slash, but instead to treat such a prefix as if the +trailing slash had been removed. + +Likewise, that function needs to handle the case where it is fed a path +that ends in a slash (not only a prefix that ends in a slash): if it +matches the prefix (plus trailing slash), we still need to verify that +the path does not end there, otherwise the prefix is not actually an +ancestor of the path but identical to it (and we need to return -1 in +that case). + +With these two adjustments, we no longer need to play games in t0060 +where we only add `$rootoff` if the passed prefix is different from the +MSYS2 pseudo root, instead we also add it for the MSYS2 pseudo root +itself. We do have to be careful to skip that logic entirely for Windows +paths, though, because they do are not subject to that MSYS2 pseudo root +treatment. + +This patch fixes the scenario where a user has set +`GIT_CEILING_DIRECTORIES=C:\`, which would be ignored otherwise. + +Signed-off-by: Johannes Schindelin +--- + path.c | 14 +++++++++----- + t/t0060-path-utils.sh | 20 ++++++++++++++------ + 2 files changed, 23 insertions(+), 11 deletions(-) + +diff --git a/path.c b/path.c +index 7b385e5eb28227..853e7165c89fd0 100644 +--- a/path.c ++++ b/path.c +@@ -1218,11 +1218,15 @@ int longest_ancestor_length(const char *path, struct string_list *prefixes) + const char *ceil = prefixes->items[i].string; + int len = strlen(ceil); + +- if (len == 1 && ceil[0] == '/') +- len = 0; /* root matches anything, with length 0 */ +- else if (!strncmp(path, ceil, len) && path[len] == '/') +- ; /* match of length len */ +- else ++ /* ++ * For root directories (`/`, `C:/`, `//server/share/`) ++ * adjust the length to exclude the trailing slash. ++ */ ++ if (len > 0 && ceil[len - 1] == '/') ++ len--; ++ ++ if (strncmp(path, ceil, len) || ++ path[len] != '/' || !path[len + 1]) + continue; /* no match */ + + if (len > max_len) +diff --git a/t/t0060-path-utils.sh b/t/t0060-path-utils.sh +index 56db5c8abab62e..f538264cdd3382 100755 +--- a/t/t0060-path-utils.sh ++++ b/t/t0060-path-utils.sh +@@ -55,12 +55,15 @@ fi + ancestor() { + # We do some math with the expected ancestor length. + expected=$3 +- if test -n "$rootoff" && test "x$expected" != x-1; then +- expected=$(($expected-$rootslash)) +- test $expected -lt 0 || +- expected=$(($expected+$rootoff)) +- fi +- test_expect_success "longest ancestor: $1 $2 => $expected" \ ++ case "$rootoff,$expected,$2" in ++ *,*,//*) ;; # leave UNC paths alone ++ [0-9]*,[0-9]*,/*) ++ # On Windows, expect MSYS2 pseudo root translation for ++ # Unix-style absolute paths ++ expected=$(($expected-$rootslash+$rootoff)) ++ ;; ++ esac ++ test_expect_success $4 "longest ancestor: $1 $2 => $expected" \ + "actual=\$(test-tool path-utils longest_ancestor_length '$1' '$2') && + test \"\$actual\" = '$expected'" + } +@@ -156,6 +159,11 @@ ancestor /foo/bar /foo 4 + ancestor /foo/bar /foo:/bar 4 + ancestor /foo/bar /bar -1 + ++# Windows-specific: DOS drives, network shares ++ancestor C:/Users/me C:/ 2 MINGW ++ancestor D:/Users/me C:/ -1 MINGW ++ancestor //server/share/my-directory //server/share/ 14 MINGW ++ + test_expect_success 'strip_path_suffix' ' + test c:/msysgit = $(test-tool path-utils strip_path_suffix \ + c:/msysgit/libexec//git-core libexec/git-core) diff --git a/backport-0002-CVE-2022-24765.patch b/backport-0002-CVE-2022-24765.patch new file mode 100644 index 0000000..4d79778 --- /dev/null +++ b/backport-0002-CVE-2022-24765.patch @@ -0,0 +1,187 @@ +From 8959555cee7ec045958f9b6dd62e541affb7e7d9 Mon Sep 17 00:00:00 2001 +From: Johannes Schindelin +Date: Wed, 2 Mar 2022 12:23:04 +0100 +Subject: [PATCH] setup_git_directory(): add an owner check for the top-level + directory + +It poses a security risk to search for a git directory outside of the +directories owned by the current user. + +For example, it is common e.g. in computer pools of educational +institutes to have a "scratch" space: a mounted disk with plenty of +space that is regularly swiped where any authenticated user can create +a directory to do their work. Merely navigating to such a space with a +Git-enabled `PS1` when there is a maliciously-crafted `/scratch/.git/` +can lead to a compromised account. + +The same holds true in multi-user setups running Windows, as `C:\` is +writable to every authenticated user by default. + +To plug this vulnerability, we stop Git from accepting top-level +directories owned by someone other than the current user. We avoid +looking at the ownership of each and every directories between the +current and the top-level one (if there are any between) to avoid +introducing a performance bottleneck. + +This new default behavior is obviously incompatible with the concept of +shared repositories, where we expect the top-level directory to be owned +by only one of its legitimate users. To re-enable that use case, we add +support for adding exceptions from the new default behavior via the +config setting `safe.directory`. + +The `safe.directory` config setting is only respected in the system and +global configs, not from repository configs or via the command-line, and +can have multiple values to allow for multiple shared repositories. + +We are particularly careful to provide a helpful message to any user +trying to use a shared repository. + +Signed-off-by: Johannes Schindelin +--- + Documentation/config.txt | 2 ++ + Documentation/config/safe.txt | 21 +++++++++++++ + setup.c | 57 ++++++++++++++++++++++++++++++++++- + 3 files changed, 79 insertions(+), 1 deletion(-) + create mode 100644 Documentation/config/safe.txt + +diff --git a/Documentation/config.txt b/Documentation/config.txt +index 6ba50b1104aa79..34e6d477d669f1 100644 +--- a/Documentation/config.txt ++++ b/Documentation/config.txt +@@ -438,6 +438,8 @@ include::config/rerere.txt[] + + include::config/reset.txt[] + ++include::config/safe.txt[] ++ + include::config/sendemail.txt[] + + include::config/sequencer.txt[] +diff --git a/Documentation/config/safe.txt b/Documentation/config/safe.txt +new file mode 100644 +index 00000000000000..63597b2df8f80f +--- /dev/null ++++ b/Documentation/config/safe.txt +@@ -0,0 +1,21 @@ ++safe.directory:: ++ These config entries specify Git-tracked directories that are ++ considered safe even if they are owned by someone other than the ++ current user. By default, Git will refuse to even parse a Git ++ config of a repository owned by someone else, let alone run its ++ hooks, and this config setting allows users to specify exceptions, ++ e.g. for intentionally shared repositories (see the `--shared` ++ option in linkgit:git-init[1]). +++ ++This is a multi-valued setting, i.e. you can add more than one directory ++via `git config --add`. To reset the list of safe directories (e.g. to ++override any such directories specified in the system config), add a ++`safe.directory` entry with an empty value. +++ ++This config setting is only respected when specified in a system or global ++config, not when it is specified in a repository config or via the command ++line option `-c safe.directory=`. +++ ++The value of this setting is interpolated, i.e. `~/` expands to a ++path relative to the home directory and `%(prefix)/` expands to a ++path relative to Git's (runtime) prefix. +diff --git a/setup.c b/setup.c +index c04cd25a30dfe0..95d5b00940a87e 100644 +--- a/setup.c ++++ b/setup.c +@@ -5,6 +5,7 @@ + #include "string-list.h" + #include "chdir-notify.h" + #include "promisor-remote.h" ++#include "quote.h" + + static int inside_git_dir = -1; + static int inside_work_tree = -1; +@@ -1024,6 +1025,42 @@ static int canonicalize_ceiling_entry(struct string_list_item *item, + } + } + ++struct safe_directory_data { ++ const char *path; ++ int is_safe; ++}; ++ ++static int safe_directory_cb(const char *key, const char *value, void *d) ++{ ++ struct safe_directory_data *data = d; ++ ++ if (!value || !*value) ++ data->is_safe = 0; ++ else { ++ const char *interpolated = NULL; ++ ++ if (!git_config_pathname(&interpolated, key, value) && ++ !fspathcmp(data->path, interpolated ? interpolated : value)) ++ data->is_safe = 1; ++ ++ free((char *)interpolated); ++ } ++ ++ return 0; ++} ++ ++static int ensure_valid_ownership(const char *path) ++{ ++ struct safe_directory_data data = { .path = path }; ++ ++ if (is_path_owned_by_current_user(path)) ++ return 1; ++ ++ read_very_early_config(safe_directory_cb, &data); ++ ++ return data.is_safe; ++} ++ + enum discovery_result { + GIT_DIR_NONE = 0, + GIT_DIR_EXPLICIT, +@@ -1032,7 +1069,8 @@ enum discovery_result { + /* these are errors */ + GIT_DIR_HIT_CEILING = -1, + GIT_DIR_HIT_MOUNT_POINT = -2, +- GIT_DIR_INVALID_GITFILE = -3 ++ GIT_DIR_INVALID_GITFILE = -3, ++ GIT_DIR_INVALID_OWNERSHIP = -4 + }; + + /* +@@ -1122,11 +1160,15 @@ static enum discovery_result setup_git_directory_gently_1(struct strbuf *dir, + } + 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; + } + + if (is_git_directory(dir->buf)) { ++ if (!ensure_valid_ownership(dir->buf)) ++ return GIT_DIR_INVALID_OWNERSHIP; + strbuf_addstr(gitdir, "."); + return GIT_DIR_BARE; + } +@@ -1253,6 +1295,19 @@ const char *setup_git_directory_gently(int *nongit_ok) + dir.buf); + *nongit_ok = 1; + break; ++ case GIT_DIR_INVALID_OWNERSHIP: ++ if (!nongit_ok) { ++ struct strbuf quoted = STRBUF_INIT; ++ ++ sq_quote_buf_pretty("ed, dir.buf); ++ die(_("unsafe repository ('%s' is owned by someone else)\n" ++ "To add an exception for this directory, call:\n" ++ "\n" ++ "\tgit config --global --add safe.directory %s"), ++ dir.buf, quoted.buf); ++ } ++ *nongit_ok = 1; ++ break; + case GIT_DIR_NONE: + /* + * As a safeguard against setup_git_directory_gently_1 returning diff --git a/backport-0003-CVE-2022-24765.patch b/backport-0003-CVE-2022-24765.patch new file mode 100644 index 0000000..e81f2f6 --- /dev/null +++ b/backport-0003-CVE-2022-24765.patch @@ -0,0 +1,174 @@ +From bdc77d1d685be9c10b88abb281a42bc620548595 Mon Sep 17 00:00:00 2001 +From: Johannes Schindelin +Date: Wed, 2 Mar 2022 11:06:24 +0100 +Subject: [PATCH] Add a function to determine whether a path is owned by the + current user + +This function will be used in the next commit to prevent +`setup_git_directory()` from discovering a repository in a directory +that is owned by someone other than the current user. + +Note: We cannot simply use `st.st_uid` on Windows just like we do on +Linux and other Unix-like platforms: according to +https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/stat-functions +this field is always zero on Windows (because Windows' idea of a user ID +does not fit into a single numerical value). Therefore, we have to do +something a little involved to replicate the same functionality there. + +Also note: On Windows, a user's home directory is not actually owned by +said user, but by the administrator. For all practical purposes, it is +under the user's control, though, therefore we pretend that it is owned +by the user. + +Signed-off-by: Johannes Schindelin +--- + compat/mingw.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++ + compat/mingw.h | 7 ++++ + git-compat-util.h | 12 +++++++ + 3 files changed, 106 insertions(+) + +diff --git a/compat/mingw.c b/compat/mingw.c +index abb4d26ce940f3..38ac35913df78e 100644 +--- a/compat/mingw.c ++++ b/compat/mingw.c +@@ -1,5 +1,6 @@ + #include "../git-compat-util.h" + #include "win32.h" ++#include + #include + #include + #include "../strbuf.h" +@@ -2601,6 +2602,92 @@ static void setup_windows_environment(void) + } + } + ++static PSID get_current_user_sid(void) ++{ ++ HANDLE token; ++ DWORD len = 0; ++ PSID result = NULL; ++ ++ if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token)) ++ return NULL; ++ ++ if (!GetTokenInformation(token, TokenUser, NULL, 0, &len)) { ++ TOKEN_USER *info = xmalloc((size_t)len); ++ if (GetTokenInformation(token, TokenUser, info, len, &len)) { ++ len = GetLengthSid(info->User.Sid); ++ result = xmalloc(len); ++ if (!CopySid(len, result, info->User.Sid)) { ++ error(_("failed to copy SID (%ld)"), ++ GetLastError()); ++ FREE_AND_NULL(result); ++ } ++ } ++ FREE_AND_NULL(info); ++ } ++ CloseHandle(token); ++ ++ return result; ++} ++ ++int is_path_owned_by_current_sid(const char *path) ++{ ++ WCHAR wpath[MAX_PATH]; ++ PSID sid = NULL; ++ PSECURITY_DESCRIPTOR descriptor = NULL; ++ DWORD err; ++ ++ static wchar_t home[MAX_PATH]; ++ ++ int result = 0; ++ ++ if (xutftowcs_path(wpath, path) < 0) ++ return 0; ++ ++ /* ++ * On Windows, the home directory is owned by the administrator, but for ++ * all practical purposes, it belongs to the user. Do pretend that it is ++ * owned by the user. ++ */ ++ if (!*home) { ++ DWORD size = ARRAY_SIZE(home); ++ DWORD len = GetEnvironmentVariableW(L"HOME", home, size); ++ if (!len || len > size) ++ wcscpy(home, L"::N/A::"); ++ } ++ if (!wcsicmp(wpath, home)) ++ return 1; ++ ++ /* Get the owner SID */ ++ err = GetNamedSecurityInfoW(wpath, SE_FILE_OBJECT, ++ OWNER_SECURITY_INFORMATION | ++ DACL_SECURITY_INFORMATION, ++ &sid, NULL, NULL, NULL, &descriptor); ++ ++ if (err != ERROR_SUCCESS) ++ error(_("failed to get owner for '%s' (%ld)"), path, err); ++ else if (sid && IsValidSid(sid)) { ++ /* Now, verify that the SID matches the current user's */ ++ static PSID current_user_sid; ++ ++ if (!current_user_sid) ++ current_user_sid = get_current_user_sid(); ++ ++ if (current_user_sid && ++ IsValidSid(current_user_sid) && ++ EqualSid(sid, current_user_sid)) ++ result = 1; ++ } ++ ++ /* ++ * We can release the security descriptor struct only now because `sid` ++ * actually points into this struct. ++ */ ++ if (descriptor) ++ LocalFree(descriptor); ++ ++ return result; ++} ++ + int is_valid_win32_path(const char *path, int allow_literal_nul) + { + const char *p = path; +diff --git a/compat/mingw.h b/compat/mingw.h +index af8eddd73edb2b..f6bab548f4cf44 100644 +--- a/compat/mingw.h ++++ b/compat/mingw.h +@@ -452,6 +452,13 @@ char *mingw_query_user_email(void); + #include + #endif + ++/** ++ * Verifies that the specified path is owned by the user running the ++ * current process. ++ */ ++int is_path_owned_by_current_sid(const char *path); ++#define is_path_owned_by_current_user is_path_owned_by_current_sid ++ + /** + * Verifies that the given path is a valid one on Windows. + * +diff --git a/git-compat-util.h b/git-compat-util.h +index 3da9f975e27712..63ba89dd31d947 100644 +--- a/git-compat-util.h ++++ b/git-compat-util.h +@@ -392,6 +392,18 @@ static inline int git_offset_1st_component(const char *path) + #define is_valid_path(path) 1 + #endif + ++#ifndef is_path_owned_by_current_user ++static inline int is_path_owned_by_current_uid(const char *path) ++{ ++ struct stat st; ++ if (lstat(path, &st)) ++ return 0; ++ return st.st_uid == geteuid(); ++} ++ ++#define is_path_owned_by_current_user is_path_owned_by_current_uid ++#endif ++ + #ifndef find_last_dir_sep + static inline char *git_find_last_dir_sep(const char *path) + { diff --git a/backport-0004-CVE-2022-24765.patch b/backport-0004-CVE-2022-24765.patch new file mode 100644 index 0000000..18011b1 --- /dev/null +++ b/backport-0004-CVE-2022-24765.patch @@ -0,0 +1,66 @@ +From 6e7ad1e4c22e7038975ba37c7413374fe566b064 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Carlo=20Marcelo=20Arenas=20Bel=C3=B3n?= +Date: Sat, 27 Nov 2021 10:15:32 +0000 +Subject: [PATCH] mingw: avoid fallback for {local,gm}time_r() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +mingw-w64's pthread_unistd.h had a bug that mistakenly (because there is +no support for the *lockfile() functions required[1]) defined +_POSIX_THREAD_SAFE_FUNCTIONS and that was being worked around since +3ecd153a3b (compat/mingw: support MSys2-based MinGW build, 2016-01-14). + +The bug was fixed in winphtreads, but as a side effect, leaves the +reentrant functions from time.h no longer visible and therefore breaks +the build. + +Since the intention all along was to avoid using the fallback functions, +formalize the use of POSIX by setting the corresponding feature flag and +compile out the implementation for the fallback functions. + +[1] https://unix.org/whitepapers/reentrant.html + +Signed-off-by: Carlo Marcelo Arenas Belón +Acked-by: Johannes Schindelin +Signed-off-by: Junio C Hamano +--- + compat/mingw.c | 2 ++ + git-compat-util.h | 4 +++- + 2 files changed, 5 insertions(+), 1 deletion(-) + +diff --git a/compat/mingw.c b/compat/mingw.c +index a43599841c6c6b..abb4d26ce940f3 100644 +--- a/compat/mingw.c ++++ b/compat/mingw.c +@@ -1060,6 +1060,7 @@ int pipe(int filedes[2]) + return 0; + } + ++#ifndef __MINGW64__ + struct tm *gmtime_r(const time_t *timep, struct tm *result) + { + if (gmtime_s(result, timep) == 0) +@@ -1073,6 +1074,7 @@ struct tm *localtime_r(const time_t *timep, struct tm *result) + return result; + return NULL; + } ++#endif + + char *mingw_getcwd(char *pointer, int len) + { +diff --git a/git-compat-util.h b/git-compat-util.h +index 7d3db43f11d049..3da9f975e27712 100644 +--- a/git-compat-util.h ++++ b/git-compat-util.h +@@ -127,7 +127,9 @@ + /* Approximation of the length of the decimal representation of this type. */ + #define decimal_length(x) ((int)(sizeof(x) * 2.56 + 0.5) + 1) + +-#if defined(__sun__) ++#ifdef __MINGW64__ ++#define _POSIX_C_SOURCE 1 ++#elif defined(__sun__) + /* + * On Solaris, when _XOPEN_EXTENDED is set, its header file + * forces the programs to be XPG4v2, defeating any _XOPEN_SOURCE diff --git a/backport-0005-CVE-2022-24765.patch b/backport-0005-CVE-2022-24765.patch new file mode 100644 index 0000000..60f6701 --- /dev/null +++ b/backport-0005-CVE-2022-24765.patch @@ -0,0 +1,48 @@ +From bb50ec3cc300eeff3aba7a2bea145aabdb477d31 Mon Sep 17 00:00:00 2001 +From: Matheus Valadares +Date: Wed, 13 Apr 2022 15:32:30 +0000 +Subject: [PATCH] setup: fix safe.directory key not being checked + +It seems that nothing is ever checking to make sure the safe directories +in the configs actually have the key safe.directory, so some unrelated +config that has a value with a certain directory would also make it a +safe directory. + +Signed-off-by: Matheus Valadares +Signed-off-by: Derrick Stolee +Signed-off-by: Junio C Hamano +--- + setup.c | 3 +++ + t/t0033-safe-directory.sh | 5 +++++ + 2 files changed, 8 insertions(+) + +diff --git a/setup.c b/setup.c +index 3c6ed17af9566a..4b9f073617c2c6 100644 +--- a/setup.c ++++ b/setup.c +@@ -1034,6 +1034,9 @@ static int safe_directory_cb(const char *key, const char *value, void *d) + { + struct safe_directory_data *data = d; + ++ if (strcmp(key, "safe.directory")) ++ return 0; ++ + if (!value || !*value) + data->is_safe = 0; + else { +diff --git a/t/t0033-safe-directory.sh b/t/t0033-safe-directory.sh +index 9380ff3d017096..6f33c0dfefaaf3 100755 +--- a/t/t0033-safe-directory.sh ++++ b/t/t0033-safe-directory.sh +@@ -21,6 +21,11 @@ test_expect_success 'safe.directory does not match' ' + expect_rejected_dir + ' + ++test_expect_success 'path exist as different key' ' ++ git config --global foo.bar "$(pwd)" && ++ expect_rejected_dir ++' ++ + test_expect_success 'safe.directory matches' ' + git config --global --add safe.directory "$(pwd)" && + git status diff --git a/backport-0006-CVE-2022-24765.patch b/backport-0006-CVE-2022-24765.patch new file mode 100644 index 0000000..4d1b750 --- /dev/null +++ b/backport-0006-CVE-2022-24765.patch @@ -0,0 +1,88 @@ +From 0f85c4a30b072a26d74af8bbf63cc8f6a5dfc1b8 Mon Sep 17 00:00:00 2001 +From: Derrick Stolee +Date: Wed, 13 Apr 2022 15:32:31 +0000 +Subject: [PATCH] setup: opt-out of check with safe.directory=* + +With the addition of the safe.directory in 8959555ce +(setup_git_directory(): add an owner check for the top-level directory, +2022-03-02) released in v2.35.2, we are receiving feedback from a +variety of users about the feature. + +Some users have a very large list of shared repositories and find it +cumbersome to add this config for every one of them. + +In a more difficult case, certain workflows involve running Git commands +within containers. The container boundary prevents any global or system +config from communicating `safe.directory` values from the host into the +container. Further, the container almost always runs as a different user +than the owner of the directory in the host. + +To simplify the reactions necessary for these users, extend the +definition of the safe.directory config value to include a possible '*' +value. This value implies that all directories are safe, providing a +single setting to opt-out of this protection. + +Note that an empty assignment of safe.directory clears all previous +values, and this is already the case with the "if (!value || !*value)" +condition. + +Signed-off-by: Derrick Stolee +Signed-off-by: Junio C Hamano +--- + Documentation/config/safe.txt | 7 +++++++ + setup.c | 6 ++++-- + t/t0033-safe-directory.sh | 10 ++++++++++ + 3 files changed, 21 insertions(+), 2 deletions(-) + +diff --git a/Documentation/config/safe.txt b/Documentation/config/safe.txt +index 63597b2df8f80f..6d764fe0ccf3a8 100644 +--- a/Documentation/config/safe.txt ++++ b/Documentation/config/safe.txt +@@ -19,3 +19,10 @@ line option `-c safe.directory=`. + The value of this setting is interpolated, i.e. `~/` expands to a + path relative to the home directory and `%(prefix)/` expands to a + path relative to Git's (runtime) prefix. +++ ++To completely opt-out of this security check, set `safe.directory` to the ++string `*`. This will allow all repositories to be treated as if their ++directory was listed in the `safe.directory` list. If `safe.directory=*` ++is set in system config and you want to re-enable this protection, then ++initialize your list with an empty value before listing the repositories ++that you deem safe. +diff --git a/setup.c b/setup.c +index 4b9f073617c2c6..aad9ace0af97ef 100644 +--- a/setup.c ++++ b/setup.c +@@ -1037,9 +1037,11 @@ static int safe_directory_cb(const char *key, const char *value, void *d) + if (strcmp(key, "safe.directory")) + return 0; + +- if (!value || !*value) ++ if (!value || !*value) { + data->is_safe = 0; +- else { ++ } else if (!strcmp(value, "*")) { ++ data->is_safe = 1; ++ } else { + const char *interpolated = NULL; + + if (!git_config_pathname(&interpolated, key, value) && +diff --git a/t/t0033-safe-directory.sh b/t/t0033-safe-directory.sh +index 6f33c0dfefaaf3..239d93f4d21141 100755 +--- a/t/t0033-safe-directory.sh ++++ b/t/t0033-safe-directory.sh +@@ -36,4 +36,14 @@ test_expect_success 'safe.directory matches, but is reset' ' + expect_rejected_dir + ' + ++test_expect_success 'safe.directory=*' ' ++ git config --global --add safe.directory "*" && ++ git status ++' ++ ++test_expect_success 'safe.directory=*, but is reset' ' ++ git config --global --add safe.directory "" && ++ expect_rejected_dir ++' ++ + test_done diff --git a/backport-t0033-add-tests-for-safe.directory.patch b/backport-t0033-add-tests-for-safe.directory.patch new file mode 100644 index 0000000..474f5e6 --- /dev/null +++ b/backport-t0033-add-tests-for-safe.directory.patch @@ -0,0 +1,72 @@ +From e47363e5a8bdf5144059d664c45c0975243ef05b Mon Sep 17 00:00:00 2001 +From: Derrick Stolee +Date: Wed, 13 Apr 2022 15:32:29 +0000 +Subject: [PATCH] t0033: add tests for safe.directory + +It is difficult to change the ownership on a directory in our test +suite, so insert a new GIT_TEST_ASSUME_DIFFERENT_OWNER environment +variable to trick Git into thinking we are in a differently-owned +directory. This allows us to test that the config is parsed correctly. + +Signed-off-by: Derrick Stolee +Signed-off-by: Junio C Hamano +--- + setup.c | 3 ++- + t/t0033-safe-directory.sh | 34 ++++++++++++++++++++++++++++++++++ + 2 files changed, 36 insertions(+), 1 deletion(-) + create mode 100755 t/t0033-safe-directory.sh + +diff --git a/setup.c b/setup.c +index 95d5b00940a87e..3c6ed17af9566a 100644 +--- a/setup.c ++++ b/setup.c +@@ -1053,7 +1053,8 @@ static int ensure_valid_ownership(const char *path) + { + struct safe_directory_data data = { .path = path }; + +- if (is_path_owned_by_current_user(path)) ++ if (!git_env_bool("GIT_TEST_ASSUME_DIFFERENT_OWNER", 0) && ++ is_path_owned_by_current_user(path)) + return 1; + + read_very_early_config(safe_directory_cb, &data); +diff --git a/t/t0033-safe-directory.sh b/t/t0033-safe-directory.sh +new file mode 100755 +index 00000000000000..9380ff3d017096 +--- /dev/null ++++ b/t/t0033-safe-directory.sh +@@ -0,0 +1,34 @@ ++#!/bin/sh ++ ++test_description='verify safe.directory checks' ++ ++. ./test-lib.sh ++ ++GIT_TEST_ASSUME_DIFFERENT_OWNER=1 ++export GIT_TEST_ASSUME_DIFFERENT_OWNER ++ ++expect_rejected_dir () { ++ test_must_fail git status 2>err && ++ grep "safe.directory" err ++} ++ ++test_expect_success 'safe.directory is not set' ' ++ expect_rejected_dir ++' ++ ++test_expect_success 'safe.directory does not match' ' ++ git config --global safe.directory bogus && ++ expect_rejected_dir ++' ++ ++test_expect_success 'safe.directory matches' ' ++ git config --global --add safe.directory "$(pwd)" && ++ git status ++' ++ ++test_expect_success 'safe.directory matches, but is reset' ' ++ git config --global --add safe.directory "" && ++ expect_rejected_dir ++' ++ ++test_done diff --git a/git.spec b/git.spec index 8dfa440..a0d4eb7 100644 --- a/git.spec +++ b/git.spec @@ -1,7 +1,7 @@ %global gitexecdir %{_libexecdir}/git-core Name: git Version: 2.27.0 -Release: 6 +Release: 7 Summary: A popular and widely used Version Control System License: GPLv2+ or LGPLv2.1 URL: https://git-scm.com/ @@ -16,6 +16,13 @@ Patch1: backport-CVE-2021-21300.patch Patch2: backport-t4210-detect-REG_ILLSEQ-dynamically-and-skip-affecte.patch Patch3: backport-CVE-2021-29468-cygwin-disallow-backslashes-in-file-names.patch Patch4: backport-CVE-2021-40330.patch +Patch5: backport-0001-CVE-2022-24765.patch +Patch6: backport-0002-CVE-2022-24765.patch +Patch7: backport-0003-CVE-2022-24765.patch +Patch8: backport-0004-CVE-2022-24765.patch +Patch9: backport-t0033-add-tests-for-safe.directory.patch +Patch10: backport-0005-CVE-2022-24765.patch +Patch11: backport-0006-CVE-2022-24765.patch BuildRequires: gcc gettext BuildRequires: openssl-devel libcurl-devel expat-devel systemd asciidoc xmlto glib2-devel libsecret-devel pcre-devel desktop-file-utils @@ -265,6 +272,12 @@ make %{?_smp_mflags} test %{_mandir}/man7/git*.7.* %changelog +* Fri May 20 2022 fuanan - 2.27.0-7 +- Type:CVE +- ID:CVE-2022-24765 +- SUG:NA +- DESC:Fix CVE-2022-24765 + * Tue Feb 15 2022 panxiaohe - 2.27.0-6 - Optimize compilation time -- Gitee