mingw: rename and open fixes
cover mingw: rename and open fixes
The recent change of mingw_rename() to use POSIX semantics had quite a bit of fall-out, breaking in pre-Windows 11 setups that use ReFS, and in a different way on Windows Server 2016.
While at it, this patch series also upstreams two related patches that matured in Git for Windows for long enough already.
Johannes Schindelin (3):
mingw: drop Windows 7-specific work-around
mingw_rename: support ReFS on Windows 2022
mingw: support Windows Server 2016 again
Matthias Aßhauer (1):
mingw_open_existing: handle directories better
Documentation/config/core.adoc | 6 --- compat/mingw.c | 93 +++++++++------------------------- 2 files changed, 23 insertions(+), 76 deletions(-)
base-commit: 866e6a391f466baeeb98bc585845ea638322c04b
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1948%2Fdscho%2Fmingw-rename-and-open-fixes-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1948/dscho/mingw-rename-and-open-fixes-v1
Pull-Request: https://github.com/gitgitgadget/git/pull/1948
Signature · 1 line
gitgitgadget
PATCH 1/4 mingw_open_existing: handle directories better
From: =?UTF-8?q?Matthias=20A=C3=9Fhauer?= <[email protected]>
CreateFileW() requires FILE_FLAG_BACKUP_SEMANTICS to create a directory handle [1] and errors out with ERROR_ACCESS_DENIED without this flag. Fall back to accessing Directory handles this way.
[1] https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilew#directories
This fixes https://github.com/git-for-windows/git/issues/5068
--- compat/mingw.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-)
compat/mingw.c +16 -5
@@ -588,13 +588,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 );
Signature · 1 line
gitgitgadget
PATCH 2/4 mingw: drop Windows 7-specific work-around
In reply to Johannes Schindelin via GitGitGadgetFrom: 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. For full details, see
https://gitforwindows.org/requirements#windows-version.
Actually, on second thought: revert only the part that makes this handle inheritance restriction logic optional and that suggests to open a bug report if it fails, but keep the fall-back to try again without said
logic: There have been a few false positives over the past few years (where the warning was triggered e.g. because Defender was still accessing a file that Git wanted to overwrite), and the fall-back logic seems to have helped occasionally in such situations.
--- Documentation/config/core.adoc | 6 --- compat/mingw.c | 68 ++-------------------------------- 2 files changed, 4 insertions(+), 70 deletions(-)
Documentation/config/core.adoc +0 -6
@@ -696,12 +696,6 @@ core.unsetenvvars:: Defaults to `PERL5LIB` to account for the fact that Git for 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
compat/mingw.c +4 -64
108 lines not on this page · raw message
Signature · 1 line
gitgitgadget
Re: [PATCH 2/4] mingw: drop Windows 7-specific work-around
Quoted 10 lines · Johannes Schindelin via GitGitGadget
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.
compat/mingw.c static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen · line 1804
Quoted 5 lines
compat/mingw.c +2
-0+* On the off-chance that something with the file handle restriction +* went wrong, silently fall back to trying without it. */compat/mingw.c +1
-0+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?"
PATCH 3/4 mingw_rename: support ReFS on Windows 2022
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
ReFS is an alternative filesystem to NTFS. On Windows 2022, it seems not to support the rename operation using POSIX semantics that Git uses on Windows as of 391bceae4350 (compat/mingw: support POSIX semantics for atomic renames, 2024-10-27).
However, Windows 2022 reports ERROR_NOT_SUPPORTED in this instance. This is in contrast to ERROR_INVALID_PARAMETER (as previous Windows versions would report that do not support POSIX semantics in renames at all).
Let's handle both errors the same: by falling back to the best-effort option, namely to rename without POSIX semantics.
This fixes https://github.com/git-for-windows/git/issues/5427
--- compat/mingw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
compat/mingw.c +1 -1
@@ -2277,7 +2277,7 @@ repeat:* 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 ) { supports_file_rename_info_ex =0 ; goto repeat; }
Signature · 1 line
gitgitgadget
PATCH 4/4 mingw: support Windows Server 2016 again
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
It was reported to the Git for Windows project that a simple git init fails on Windows Server 2016:
D:\Dev\test> git init
error: could not write config file D:/Dev/test/.git/config: Function not implemented
fatal: could not set 'core.repositoryformatversion' to '0'
According to https://endoflife.date/windows-server, Windows Server 2016 is officially supported for another one-and-a-half years as of time of writing, so this is not good.
The culprit is the mingw_rename() changes that try to use POSIX semantics when available, but fail to fall back properly on Windows Server 2016.
This fixes https://github.com/git-for-windows/git/issues/5695.
--- compat/mingw.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
compat/mingw.c +3 -1
@@ -2277,7 +2277,9 @@ repeat:* current system doesn't support FileRenameInfoEx. Keep us * from using it in future calls and retry. */ -if (gle ==ERROR_INVALID_PARAMETER || gle ==ERROR_NOT_SUPPORTED ) { +if (gle ==ERROR_INVALID_PARAMETER || + gle ==ERROR_NOT_SUPPORTED || + gle ==ERROR_INVALID_FUNCTION ) { supports_file_rename_info_ex =0 ; goto repeat; }
Signature · 1 line
gitgitgadget
"Johannes Schindelin via GitGitGadget" <[email protected]>
Quoted 6 lines · writes:
The recent change of
mingw_rename()to use POSIX semantics had quite a bit of fall-out, breaking in pre-Windows 11 setups that use ReFS, and in a different way on Windows Server 2016.While at it, this patch series also upstreams two related patches that matured in Git for Windows for long enough already.
Thanks. What a great timing, just before the -rc0 preview release ;-)
Will apply directly to 'master'.
Quoted 17 lines
Johannes Schindelin (3):
mingw: drop Windows 7-specific work-around
mingw_rename: support ReFS on Windows 2022
mingw: support Windows Server 2016 againMatthias Aßhauer (1):
mingw_open_existing: handle directories betterDocumentation/config/core.adoc | 6 --- compat/mingw.c | 93 +++++++++------------------------- 2 files changed, 23 insertions(+), 76 deletions(-)base-commit:
866e6a391f466baeeb98bc585845ea638322c04b
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1948%2Fdscho%2Fmingw-rename-and-open-fixes-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1948/dscho/mingw-rename-and-open-fixes-v1
Pull-Request: https://github.com/gitgitgadget/git/pull/1948