Skip to content

Commit 413ac6f

Browse files
vdyeGit for Windows Build Agent
authored andcommitted
Merge branch 'safe.directory-and-windows'
These two patches made it into Git for Windows v2.35.2, but not into Git v2.35.2. Signed-off-by: Victoria Dye <[email protected]> Signed-off-by: Johannes Schindelin <[email protected]>
2 parents 8fa8eda + 2b57c11 commit 413ac6f

File tree

3 files changed

+72
-2
lines changed

3 files changed

+72
-2
lines changed

Documentation/config/safe.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,9 @@ which id the original user has.
4040
If that is not what you would prefer and want git to only trust
4141
repositories that are owned by root instead, then you can remove
4242
the `SUDO_UID` variable from root's environment before invoking git.
43+
+
44+
Due to the permission model on Windows where ACLs are used instead of
45+
Unix' simpler permission model, it can be a bit tricky to figure out why
46+
a directory is considered unsafe. To help with this, Git will provide
47+
more detailed information when the environment variable
48+
`GIT_TEST_DEBUG_UNSAFE_DIRECTORIES` is set to `true`.

compat/mingw.c

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include "../git-compat-util.h"
22
#include "win32.h"
33
#include <aclapi.h>
4+
#include <sddl.h>
45
#include <conio.h>
56
#include <wchar.h>
67
#include "../strbuf.h"
@@ -2986,6 +2987,22 @@ static PSID get_current_user_sid(void)
29862987
return result;
29872988
}
29882989

2990+
static int acls_supported(const char *path)
2991+
{
2992+
size_t offset = offset_1st_component(path);
2993+
WCHAR wroot[MAX_PATH];
2994+
DWORD file_system_flags;
2995+
2996+
if (offset &&
2997+
xutftowcs_path_ex(wroot, path, MAX_PATH, offset,
2998+
MAX_PATH, 0) > 0 &&
2999+
GetVolumeInformationW(wroot, NULL, 0, NULL, NULL,
3000+
&file_system_flags, NULL, 0))
3001+
return !!(file_system_flags & FILE_PERSISTENT_ACLS);
3002+
3003+
return 0;
3004+
}
3005+
29893006
int is_path_owned_by_current_sid(const char *path)
29903007
{
29913008
WCHAR wpath[MAX_PATH];
@@ -3025,6 +3042,7 @@ int is_path_owned_by_current_sid(const char *path)
30253042
else if (sid && IsValidSid(sid)) {
30263043
/* Now, verify that the SID matches the current user's */
30273044
static PSID current_user_sid;
3045+
BOOL is_member;
30283046

30293047
if (!current_user_sid)
30303048
current_user_sid = get_current_user_sid();
@@ -3033,6 +3051,42 @@ int is_path_owned_by_current_sid(const char *path)
30333051
IsValidSid(current_user_sid) &&
30343052
EqualSid(sid, current_user_sid))
30353053
result = 1;
3054+
else if (IsWellKnownSid(sid, WinBuiltinAdministratorsSid) &&
3055+
CheckTokenMembership(NULL, sid, &is_member) &&
3056+
is_member)
3057+
/*
3058+
* If owned by the Administrators group, and the
3059+
* current user is an administrator, we consider that
3060+
* okay, too.
3061+
*/
3062+
result = 1;
3063+
else if (IsWellKnownSid(sid, WinWorldSid) &&
3064+
git_env_bool("GIT_TEST_DEBUG_UNSAFE_DIRECTORIES", 0) &&
3065+
!acls_supported(path)) {
3066+
/*
3067+
* On FAT32 volumes, ownership is not actually recorded.
3068+
*/
3069+
warning("'%s' is on a file system that does not record ownership", path);
3070+
} else if (git_env_bool("GIT_TEST_DEBUG_UNSAFE_DIRECTORIES", 0)) {
3071+
LPSTR str1, str2, to_free1 = NULL, to_free2 = NULL;
3072+
3073+
if (ConvertSidToStringSidA(sid, &str1))
3074+
to_free1 = str1;
3075+
else
3076+
str1 = "(inconvertible)";
3077+
3078+
if (!current_user_sid)
3079+
str2 = "(none)";
3080+
else if (!IsValidSid(current_user_sid))
3081+
str2 = "(invalid)";
3082+
else if (ConvertSidToStringSidA(current_user_sid, &str2))
3083+
to_free2 = str2;
3084+
else
3085+
str2 = "(inconvertible)";
3086+
warning("'%s' is owned by:\n\t'%s'\nbut the current user is:\n\t'%s'", path, str1, str2);
3087+
LocalFree(to_free1);
3088+
LocalFree(to_free2);
3089+
}
30363090
}
30373091

30383092
/*

setup.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1433,13 +1433,23 @@ const char *setup_git_directory_gently(int *nongit_ok)
14331433
case GIT_DIR_INVALID_OWNERSHIP:
14341434
if (!nongit_ok) {
14351435
struct strbuf quoted = STRBUF_INIT;
1436+
struct strbuf hint = STRBUF_INIT;
1437+
1438+
#ifdef __MINGW32__
1439+
if (!git_env_bool("GIT_TEST_DEBUG_UNSAFE_DIRECTORIES", 0))
1440+
strbuf_addstr(&hint,
1441+
_("\n\nSet the environment variable "
1442+
"GIT_TEST_DEBUG_UNSAFE_DIRECTORIES=true "
1443+
"and run\n"
1444+
"again for more information."));
1445+
#endif
14361446

14371447
sq_quote_buf_pretty(&quoted, dir.buf);
14381448
die(_("detected dubious ownership in repository at '%s'\n"
14391449
"To add an exception for this directory, call:\n"
14401450
"\n"
1441-
"\tgit config --global --add safe.directory %s"),
1442-
dir.buf, quoted.buf);
1451+
"\tgit config --global --add safe.directory %s%s"),
1452+
dir.buf, quoted.buf, hint.buf);
14431453
}
14441454
*nongit_ok = 1;
14451455
break;

0 commit comments

Comments
 (0)