Skip to content

Commit 93fbff0

Browse files
committed
Sync with 2.33.2
* maint-2.33: Git 2.33.2 Git 2.32.1 Git 2.31.2 GIT-VERSION-GEN: bump to v2.33.1 Git 2.30.3 setup_git_directory(): add an owner check for the top-level directory Add a function to determine whether a path is owned by the current user
2 parents e9d7761 + 87ed4fc commit 93fbff0

File tree

12 files changed

+264
-13
lines changed

12 files changed

+264
-13
lines changed

Documentation/RelNotes/2.30.3.txt

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
Git v2.30.2 Release Notes
2+
=========================
3+
4+
This release addresses the security issue CVE-2022-24765.
5+
6+
Fixes since v2.30.2
7+
-------------------
8+
9+
* Build fix on Windows.
10+
11+
* Fix `GIT_CEILING_DIRECTORIES` with Windows-style root directories.
12+
13+
* CVE-2022-24765:
14+
On multi-user machines, Git users might find themselves
15+
unexpectedly in a Git worktree, e.g. when another user created a
16+
repository in `C:\.git`, in a mounted network drive or in a
17+
scratch space. Merely having a Git-aware prompt that runs `git
18+
status` (or `git diff`) and navigating to a directory which is
19+
supposedly not a Git worktree, or opening such a directory in an
20+
editor or IDE such as VS Code or Atom, will potentially run
21+
commands defined by that other user.
22+
23+
Credit for finding this vulnerability goes to 俞晨东; The fix was
24+
authored by Johannes Schindelin.

Documentation/RelNotes/2.31.2.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
Git v2.31.2 Release Notes
2+
=========================
3+
4+
This release merges up the fixes that appear in v2.30.3 to address
5+
the security issue CVE-2022-24765; see the release notes for that
6+
version for details.

Documentation/RelNotes/2.32.1.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
Git v2.32.1 Release Notes
2+
=========================
3+
4+
This release merges up the fixes that appear in v2.30.3 and
5+
v2.31.2 to address the security issue CVE-2022-24765; see the
6+
release notes for these versions for details.

Documentation/RelNotes/2.33.2.txt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
Git v2.33.2 Release Notes
2+
=========================
3+
4+
This release merges up the fixes that appear in v2.30.3, v2.31.2
5+
and v2.32.1 to address the security issue CVE-2022-24765; see
6+
the release notes for these versions for details.
7+
8+
In addition, it contains the following fixes:
9+
10+
* Squelch over-eager warning message added during this cycle.
11+
12+
* A bug in "git rebase -r" has been fixed.
13+
14+
* One CI task based on Fedora image noticed a not-quite-kosher
15+
construct recently, which has been corrected.

Documentation/config.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -449,6 +449,8 @@ include::config/rerere.txt[]
449449

450450
include::config/reset.txt[]
451451

452+
include::config/safe.txt[]
453+
452454
include::config/sendemail.txt[]
453455

454456
include::config/sequencer.txt[]

Documentation/config/safe.txt

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
safe.directory::
2+
These config entries specify Git-tracked directories that are
3+
considered safe even if they are owned by someone other than the
4+
current user. By default, Git will refuse to even parse a Git
5+
config of a repository owned by someone else, let alone run its
6+
hooks, and this config setting allows users to specify exceptions,
7+
e.g. for intentionally shared repositories (see the `--shared`
8+
option in linkgit:git-init[1]).
9+
+
10+
This is a multi-valued setting, i.e. you can add more than one directory
11+
via `git config --add`. To reset the list of safe directories (e.g. to
12+
override any such directories specified in the system config), add a
13+
`safe.directory` entry with an empty value.
14+
+
15+
This config setting is only respected when specified in a system or global
16+
config, not when it is specified in a repository config or via the command
17+
line option `-c safe.directory=<path>`.
18+
+
19+
The value of this setting is interpolated, i.e. `~/<path>` expands to a
20+
path relative to the home directory and `%(prefix)/<path>` expands to a
21+
path relative to Git's (runtime) prefix.

compat/mingw.c

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include "../git-compat-util.h"
22
#include "win32.h"
3+
#include <aclapi.h>
34
#include <conio.h>
45
#include <wchar.h>
56
#include "../strbuf.h"
@@ -1083,6 +1084,7 @@ int pipe(int filedes[2])
10831084
return 0;
10841085
}
10851086

1087+
#ifndef __MINGW64__
10861088
struct tm *gmtime_r(const time_t *timep, struct tm *result)
10871089
{
10881090
if (gmtime_s(result, timep) == 0)
@@ -1096,6 +1098,7 @@ struct tm *localtime_r(const time_t *timep, struct tm *result)
10961098
return result;
10971099
return NULL;
10981100
}
1101+
#endif
10991102

11001103
char *mingw_getcwd(char *pointer, int len)
11011104
{
@@ -2622,6 +2625,92 @@ static void setup_windows_environment(void)
26222625
}
26232626
}
26242627

2628+
static PSID get_current_user_sid(void)
2629+
{
2630+
HANDLE token;
2631+
DWORD len = 0;
2632+
PSID result = NULL;
2633+
2634+
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token))
2635+
return NULL;
2636+
2637+
if (!GetTokenInformation(token, TokenUser, NULL, 0, &len)) {
2638+
TOKEN_USER *info = xmalloc((size_t)len);
2639+
if (GetTokenInformation(token, TokenUser, info, len, &len)) {
2640+
len = GetLengthSid(info->User.Sid);
2641+
result = xmalloc(len);
2642+
if (!CopySid(len, result, info->User.Sid)) {
2643+
error(_("failed to copy SID (%ld)"),
2644+
GetLastError());
2645+
FREE_AND_NULL(result);
2646+
}
2647+
}
2648+
FREE_AND_NULL(info);
2649+
}
2650+
CloseHandle(token);
2651+
2652+
return result;
2653+
}
2654+
2655+
int is_path_owned_by_current_sid(const char *path)
2656+
{
2657+
WCHAR wpath[MAX_PATH];
2658+
PSID sid = NULL;
2659+
PSECURITY_DESCRIPTOR descriptor = NULL;
2660+
DWORD err;
2661+
2662+
static wchar_t home[MAX_PATH];
2663+
2664+
int result = 0;
2665+
2666+
if (xutftowcs_path(wpath, path) < 0)
2667+
return 0;
2668+
2669+
/*
2670+
* On Windows, the home directory is owned by the administrator, but for
2671+
* all practical purposes, it belongs to the user. Do pretend that it is
2672+
* owned by the user.
2673+
*/
2674+
if (!*home) {
2675+
DWORD size = ARRAY_SIZE(home);
2676+
DWORD len = GetEnvironmentVariableW(L"HOME", home, size);
2677+
if (!len || len > size)
2678+
wcscpy(home, L"::N/A::");
2679+
}
2680+
if (!wcsicmp(wpath, home))
2681+
return 1;
2682+
2683+
/* Get the owner SID */
2684+
err = GetNamedSecurityInfoW(wpath, SE_FILE_OBJECT,
2685+
OWNER_SECURITY_INFORMATION |
2686+
DACL_SECURITY_INFORMATION,
2687+
&sid, NULL, NULL, NULL, &descriptor);
2688+
2689+
if (err != ERROR_SUCCESS)
2690+
error(_("failed to get owner for '%s' (%ld)"), path, err);
2691+
else if (sid && IsValidSid(sid)) {
2692+
/* Now, verify that the SID matches the current user's */
2693+
static PSID current_user_sid;
2694+
2695+
if (!current_user_sid)
2696+
current_user_sid = get_current_user_sid();
2697+
2698+
if (current_user_sid &&
2699+
IsValidSid(current_user_sid) &&
2700+
EqualSid(sid, current_user_sid))
2701+
result = 1;
2702+
}
2703+
2704+
/*
2705+
* We can release the security descriptor struct only now because `sid`
2706+
* actually points into this struct.
2707+
*/
2708+
if (descriptor)
2709+
LocalFree(descriptor);
2710+
2711+
return result;
2712+
}
2713+
26252714
int is_valid_win32_path(const char *path, int allow_literal_nul)
26262715
{
26272716
const char *p = path;

compat/mingw.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,13 @@ char *mingw_query_user_email(void);
453453
#include <inttypes.h>
454454
#endif
455455

456+
/**
457+
* Verifies that the specified path is owned by the user running the
458+
* current process.
459+
*/
460+
int is_path_owned_by_current_sid(const char *path);
461+
#define is_path_owned_by_current_user is_path_owned_by_current_sid
462+
456463
/**
457464
* Verifies that the given path is a valid one on Windows.
458465
*

git-compat-util.h

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,9 @@
127127
/* Approximation of the length of the decimal representation of this type. */
128128
#define decimal_length(x) ((int)(sizeof(x) * 2.56 + 0.5) + 1)
129129

130-
#if defined(__sun__)
130+
#ifdef __MINGW64__
131+
#define _POSIX_C_SOURCE 1
132+
#elif defined(__sun__)
131133
/*
132134
* On Solaris, when _XOPEN_EXTENDED is set, its header file
133135
* forces the programs to be XPG4v2, defeating any _XOPEN_SOURCE
@@ -398,6 +400,18 @@ static inline int git_offset_1st_component(const char *path)
398400
#define is_valid_path(path) 1
399401
#endif
400402

403+
#ifndef is_path_owned_by_current_user
404+
static inline int is_path_owned_by_current_uid(const char *path)
405+
{
406+
struct stat st;
407+
if (lstat(path, &st))
408+
return 0;
409+
return st.st_uid == geteuid();
410+
}
411+
412+
#define is_path_owned_by_current_user is_path_owned_by_current_uid
413+
#endif
414+
401415
#ifndef find_last_dir_sep
402416
static inline char *git_find_last_dir_sep(const char *path)
403417
{

path.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1225,11 +1225,15 @@ int longest_ancestor_length(const char *path, struct string_list *prefixes)
12251225
const char *ceil = prefixes->items[i].string;
12261226
int len = strlen(ceil);
12271227

1228-
if (len == 1 && ceil[0] == '/')
1229-
len = 0; /* root matches anything, with length 0 */
1230-
else if (!strncmp(path, ceil, len) && path[len] == '/')
1231-
; /* match of length len */
1232-
else
1228+
/*
1229+
* For root directories (`/`, `C:/`, `//server/share/`)
1230+
* adjust the length to exclude the trailing slash.
1231+
*/
1232+
if (len > 0 && ceil[len - 1] == '/')
1233+
len--;
1234+
1235+
if (strncmp(path, ceil, len) ||
1236+
path[len] != '/' || !path[len + 1])
12331237
continue; /* no match */
12341238

12351239
if (len > max_len)

0 commit comments

Comments
 (0)