Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions Documentation/config/core.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -696,12 +696,6 @@ core.unsetenvvars::
Defaults to `PERL5LIB` to account for the fact that Git for
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the Git mailing list, Oswald Buddenhagen wrote (reply to this):

On Sun, Aug 03, 2025 at 09:25:16PM +0000, Johannes Schindelin via GitGitGadget wrote:
>From: Johannes Schindelin <[email protected]>
>
>In ac33519ddfa8 (mingw: restrict file handle inheritance only on Windows
>7 and later, 2019-11-22), I introduced code to safe-guard the
>defense-in-depth handling that restricts handles' inheritance so that it
>would work with Windows 7, too.
>
>Let's revert this patch: Git for Windows dropped supporting Windows 7 (and
>Windows 8) directly after Git for Windows v2.46.2.
>
it doesn't follow from this why it's apparently ok to remove this for even newer versions.

>+	 * On the off-chance that something with the file handle restriction
>+	 * went wrong, silently fall back to trying without it.
> 	 */
>+	if (!ret && stdhandles_count) {
>
the comment should really spell out what that off chance is, so one doesn't have to check the log.

it may also make sense to elaborate why just dropping the restrictions isn't a problem - my first thought is "huh, doesn't this open the door for security holes, at least theoretically?"

Windows insists on using its own Perl interpreter.

core.restrictinheritedhandles::
Windows-only: override whether spawned processes inherit only standard
file handles (`stdin`, `stdout` and `stderr`) or all handles. Can be
`auto`, `true` or `false`. Defaults to `auto`, which means `true` on
Windows 7 and later, and `false` on older Windows versions.

core.createObject::
You can set this to 'link', in which case a hardlink followed by
a delete of the source are used to make sure that object creation
Expand Down
93 changes: 23 additions & 70 deletions compat/mingw.c
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,6 @@ enum hide_dotfiles_type {
HIDE_DOTFILES_DOTGITONLY
};

static int core_restrict_inherited_handles = -1;
static enum hide_dotfiles_type hide_dotfiles = HIDE_DOTFILES_DOTGITONLY;
static char *unset_environment_variables;

Expand All @@ -268,15 +267,6 @@ int mingw_core_config(const char *var, const char *value,
return 0;
}

if (!strcmp(var, "core.restrictinheritedhandles")) {
if (value && !strcasecmp(value, "auto"))
core_restrict_inherited_handles = -1;
else
core_restrict_inherited_handles =
git_config_bool(var, value);
return 0;
}

return 0;
}

Expand Down Expand Up @@ -588,13 +578,24 @@ static int mingw_open_existing(const wchar_t *filename, int oflags, ...)
&security_attributes, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (handle == INVALID_HANDLE_VALUE) {
DWORD err = GetLastError();
if (err == ERROR_ACCESS_DENIED) {
DWORD attrs = GetFileAttributesW(filename);
if (attrs != INVALID_FILE_ATTRIBUTES && (attrs & FILE_ATTRIBUTE_DIRECTORY))
handle = CreateFileW(filename, access,
FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE,
&security_attributes, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL| FILE_FLAG_BACKUP_SEMANTICS, NULL);
}

/* See `mingw_open_append()` for why we have this conversion. */
if (err == ERROR_INVALID_PARAMETER)
err = ERROR_PATH_NOT_FOUND;
if (handle == INVALID_HANDLE_VALUE) {
err = GetLastError();

errno = err_win_to_posix(err);
return -1;
/* See `mingw_open_append()` for why we have this conversion. */
if (err == ERROR_INVALID_PARAMETER)
err = ERROR_PATH_NOT_FOUND;

errno = err_win_to_posix(err);
return -1;
}
}

fd = _open_osfhandle((intptr_t)handle, oflags | O_BINARY);
Expand Down Expand Up @@ -1656,7 +1657,6 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen
const char *dir,
int prepend_cmd, int fhin, int fhout, int fherr)
{
static int restrict_handle_inheritance = -1;
STARTUPINFOEXW si;
PROCESS_INFORMATION pi;
LPPROC_THREAD_ATTRIBUTE_LIST attr_list = NULL;
Expand All @@ -1676,16 +1676,6 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen
/* Make sure to override previous errors, if any */
errno = 0;

if (restrict_handle_inheritance < 0)
restrict_handle_inheritance = core_restrict_inherited_handles;
/*
* The following code to restrict which handles are inherited seems
* to work properly only on Windows 7 and later, so let's disable it
* on Windows Vista and 2008.
*/
if (restrict_handle_inheritance < 0)
restrict_handle_inheritance = GetVersion() >> 16 >= 7601;

do_unset_environment_variables();

/* Determine whether or not we are associated to a console */
Expand Down Expand Up @@ -1787,7 +1777,7 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen
wenvblk = make_environment_block(deltaenv);

memset(&pi, 0, sizeof(pi));
if (restrict_handle_inheritance && stdhandles_count &&
if (stdhandles_count &&
(InitializeProcThreadAttributeList(NULL, 1, 0, &size) ||
GetLastError() == ERROR_INSUFFICIENT_BUFFER) &&
(attr_list = (LPPROC_THREAD_ATTRIBUTE_LIST)
Expand All @@ -1808,52 +1798,13 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen
&si.StartupInfo, &pi);

/*
* On Windows 2008 R2, it seems that specifying certain types of handles
* (such as FILE_TYPE_CHAR or FILE_TYPE_PIPE) will always produce an
* error. Rather than playing finicky and fragile games, let's just try
* to detect this situation and simply try again without restricting any
* handle inheritance. This is still better than failing to create
* processes.
* On the off-chance that something with the file handle restriction
* went wrong, silently fall back to trying without it.
*/
if (!ret && restrict_handle_inheritance && stdhandles_count) {
if (!ret && stdhandles_count) {
DWORD err = GetLastError();
struct strbuf buf = STRBUF_INIT;

if (err != ERROR_NO_SYSTEM_RESOURCES &&
/*
* On Windows 7 and earlier, handles on pipes and character
* devices are inherited automatically, and cannot be
* specified in the thread handle list. Rather than trying
* to catch each and every corner case (and running the
* chance of *still* forgetting a few), let's just fall
* back to creating the process without trying to limit the
* handle inheritance.
*/
!(err == ERROR_INVALID_PARAMETER &&
GetVersion() >> 16 < 9200) &&
!getenv("SUPPRESS_HANDLE_INHERITANCE_WARNING")) {
DWORD fl = 0;
int i;

setenv("SUPPRESS_HANDLE_INHERITANCE_WARNING", "1", 1);

for (i = 0; i < stdhandles_count; i++) {
HANDLE h = stdhandles[i];
strbuf_addf(&buf, "handle #%d: %p (type %lx, "
"handle info (%d) %lx\n", i, h,
GetFileType(h),
GetHandleInformation(h, &fl),
fl);
}
strbuf_addstr(&buf, "\nThis is a bug; please report it "
"at\nhttps://github.com/git-for-windows/"
"git/issues/new\n\n"
"To suppress this warning, please set "
"the environment variable\n\n"
"\tSUPPRESS_HANDLE_INHERITANCE_WARNING=1"
"\n");
}
restrict_handle_inheritance = 0;
flags &= ~EXTENDED_STARTUPINFO_PRESENT;
ret = CreateProcessW(*wcmd ? wcmd : NULL, wargs, NULL, NULL,
TRUE, flags, wenvblk, dir ? wdir : NULL,
Expand Down Expand Up @@ -2326,7 +2277,9 @@ int mingw_rename(const char *pold, const char *pnew)
* current system doesn't support FileRenameInfoEx. Keep us
* from using it in future calls and retry.
*/
if (gle == ERROR_INVALID_PARAMETER) {
if (gle == ERROR_INVALID_PARAMETER ||
gle == ERROR_NOT_SUPPORTED ||
gle == ERROR_INVALID_FUNCTION) {
supports_file_rename_info_ex = 0;
goto repeat;
}
Expand Down
Loading