update version to 2.36.1
This commit is contained in:
parent
70c380e324
commit
b573e48c15
@ -1,118 +0,0 @@
|
|||||||
From fdcad5a53e14bd397e4fa323e7fd0c3bf16dd373 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Johannes Schindelin <johannes.schindelin@gmx.de>
|
|
||||||
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 <johannes.schindelin@gmx.de>
|
|
||||||
---
|
|
||||||
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)
|
|
||||||
@ -1,187 +0,0 @@
|
|||||||
From 8959555cee7ec045958f9b6dd62e541affb7e7d9 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Johannes Schindelin <johannes.schindelin@gmx.de>
|
|
||||||
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 <johannes.schindelin@gmx.de>
|
|
||||||
---
|
|
||||||
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=<path>`.
|
|
||||||
++
|
|
||||||
+The value of this setting is interpolated, i.e. `~/<path>` expands to a
|
|
||||||
+path relative to the home directory and `%(prefix)/<path>` 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
|
|
||||||
@ -1,174 +0,0 @@
|
|||||||
From bdc77d1d685be9c10b88abb281a42bc620548595 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Johannes Schindelin <johannes.schindelin@gmx.de>
|
|
||||||
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 <johannes.schindelin@gmx.de>
|
|
||||||
---
|
|
||||||
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 <aclapi.h>
|
|
||||||
#include <conio.h>
|
|
||||||
#include <wchar.h>
|
|
||||||
#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 <inttypes.h>
|
|
||||||
#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)
|
|
||||||
{
|
|
||||||
@ -1,66 +0,0 @@
|
|||||||
From 6e7ad1e4c22e7038975ba37c7413374fe566b064 Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?Carlo=20Marcelo=20Arenas=20Bel=C3=B3n?= <carenas@gmail.com>
|
|
||||||
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 <carenas@gmail.com>
|
|
||||||
Acked-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
|
|
||||||
Signed-off-by: Junio C Hamano <gitster@pobox.com>
|
|
||||||
---
|
|
||||||
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
|
|
||||||
@ -1,48 +0,0 @@
|
|||||||
From bb50ec3cc300eeff3aba7a2bea145aabdb477d31 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Matheus Valadares <me@m28.io>
|
|
||||||
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 <me@m28.io>
|
|
||||||
Signed-off-by: Derrick Stolee <derrickstolee@github.com>
|
|
||||||
Signed-off-by: Junio C Hamano <gitster@pobox.com>
|
|
||||||
---
|
|
||||||
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
|
|
||||||
@ -1,88 +0,0 @@
|
|||||||
From 0f85c4a30b072a26d74af8bbf63cc8f6a5dfc1b8 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Derrick Stolee <derrickstolee@github.com>
|
|
||||||
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 <derrickstolee@github.com>
|
|
||||||
Signed-off-by: Junio C Hamano <gitster@pobox.com>
|
|
||||||
---
|
|
||||||
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=<path>`.
|
|
||||||
The value of this setting is interpolated, i.e. `~/<path>` expands to a
|
|
||||||
path relative to the home directory and `%(prefix)/<path>` 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
|
|
||||||
@ -1,72 +0,0 @@
|
|||||||
From e47363e5a8bdf5144059d664c45c0975243ef05b Mon Sep 17 00:00:00 2001
|
|
||||||
From: Derrick Stolee <derrickstolee@github.com>
|
|
||||||
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 <derrickstolee@github.com>
|
|
||||||
Signed-off-by: Junio C Hamano <gitster@pobox.com>
|
|
||||||
---
|
|
||||||
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
|
|
||||||
Binary file not shown.
Binary file not shown.
BIN
git-2.36.1.tar.sign
Normal file
BIN
git-2.36.1.tar.sign
Normal file
Binary file not shown.
BIN
git-2.36.1.tar.xz
Normal file
BIN
git-2.36.1.tar.xz
Normal file
Binary file not shown.
18
git.spec
18
git.spec
@ -1,7 +1,7 @@
|
|||||||
%global gitexecdir %{_libexecdir}/git-core
|
%global gitexecdir %{_libexecdir}/git-core
|
||||||
Name: git
|
Name: git
|
||||||
Version: 2.33.0
|
Version: 2.36.1
|
||||||
Release: 3
|
Release: 1
|
||||||
Summary: A popular and widely used Version Control System
|
Summary: A popular and widely used Version Control System
|
||||||
License: GPLv2+ or LGPLv2.1
|
License: GPLv2+ or LGPLv2.1
|
||||||
URL: https://git-scm.com/
|
URL: https://git-scm.com/
|
||||||
@ -12,14 +12,6 @@ Source100: git-gui.desktop
|
|||||||
Source101: git@.service.in
|
Source101: git@.service.in
|
||||||
Source102: git.socket
|
Source102: git.socket
|
||||||
|
|
||||||
Patch0: backport-0001-CVE-2022-24765.patch
|
|
||||||
Patch1: backport-0002-CVE-2022-24765.patch
|
|
||||||
Patch2: backport-0003-CVE-2022-24765.patch
|
|
||||||
Patch3: backport-0004-CVE-2022-24765.patch
|
|
||||||
Patch4: backport-t0033-add-tests-for-safe.directory.patch
|
|
||||||
Patch5: backport-0005-CVE-2022-24765.patch
|
|
||||||
Patch6: backport-0006-CVE-2022-24765.patch
|
|
||||||
|
|
||||||
BuildRequires: gcc gettext
|
BuildRequires: gcc gettext
|
||||||
BuildRequires: openssl-devel libcurl-devel expat-devel systemd asciidoc xmlto glib2-devel libsecret-devel pcre-devel desktop-file-utils
|
BuildRequires: openssl-devel libcurl-devel expat-devel systemd asciidoc xmlto glib2-devel libsecret-devel pcre-devel desktop-file-utils
|
||||||
BuildRequires: python3-devel perl-generators perl-interpreter perl-Error perl(Test::More) perl-MailTools perl(Test)
|
BuildRequires: python3-devel perl-generators perl-interpreter perl-Error perl(Test::More) perl-MailTools perl(Test)
|
||||||
@ -299,6 +291,12 @@ make %{?_smp_mflags} test
|
|||||||
%{_mandir}/man7/git*.7.*
|
%{_mandir}/man7/git*.7.*
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Fri Jul 01 2022 fuanan <fuanan3@h-partners.com> - 2.36.1-1
|
||||||
|
- Type:enhancement
|
||||||
|
- ID:NA
|
||||||
|
- SUG:NA
|
||||||
|
- DESC:update version to 2.36.1
|
||||||
|
|
||||||
* Fri May 20 2022 fuanan <fuanan3@h-partners.com> - 2.33.0-3
|
* Fri May 20 2022 fuanan <fuanan3@h-partners.com> - 2.33.0-3
|
||||||
- Type:CVE
|
- Type:CVE
|
||||||
- ID:CVE-2022-24765
|
- ID:CVE-2022-24765
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user