Looks like we haven't updated `MSYS2-packages`' `msys2-runtime-3.4` directory in quite a while. This roll-up integrates: - https://github.com/msys2/msys2-runtime/pull/192 - https://github.com/msys2/msys2-runtime/pull/205 - https://github.com/msys2/msys2-runtime/pull/209 - https://github.com/msys2/msys2-runtime/pull/210 - https://github.com/msys2/msys2-runtime/pull/220 Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
279 lines
11 KiB
Diff
279 lines
11 KiB
Diff
From 40793722b8ea98fcdf63533e10ebd28e84b7ffaa Mon Sep 17 00:00:00 2001
|
|
From: Corinna Vinschen <corinna@vinschen.de>
|
|
Date: Fri, 8 Mar 2024 20:57:06 +0100
|
|
Subject: [PATCH 52/N] Cygwin: try to avoid recalling offline files
|
|
|
|
Chances are high that Cygwin recalls offline files from remote
|
|
storage, even if the file is only accessed during stat(2) or
|
|
readdir(3).
|
|
|
|
To avoid this
|
|
- make sure Cygwin is placeholder-aware,
|
|
- open files in path_conv handling, as well as in stat(2)/readdir(3)
|
|
scenarios with FILE_OPEN_NO_RECALL, and
|
|
- during symlink checking or testing for executablility, don't even
|
|
try to open the file if one of the OFFLINE attributes is set.
|
|
|
|
Reported-by: Marcin Wisnicki <mwisnicki@gmail.com>
|
|
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
|
|
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
|
|
---
|
|
winsup/cygwin/autoload.cc | 1 +
|
|
winsup/cygwin/dcrt0.cc | 3 +++
|
|
winsup/cygwin/fhandler/disk_file.cc | 20 ++++++++++++++------
|
|
winsup/cygwin/local_includes/ntdll.h | 8 ++++++++
|
|
winsup/cygwin/local_includes/path.h | 16 +++++++++++++++-
|
|
winsup/cygwin/local_includes/winlean.h | 8 ++++++++
|
|
winsup/cygwin/path.cc | 17 +++++++++++++----
|
|
7 files changed, 62 insertions(+), 11 deletions(-)
|
|
|
|
diff --git a/winsup/cygwin/autoload.cc b/winsup/cygwin/autoload.cc
|
|
index cdf6e75..c579bef 100644
|
|
--- a/winsup/cygwin/autoload.cc
|
|
+++ b/winsup/cygwin/autoload.cc
|
|
@@ -477,6 +477,7 @@ LoadDLLfuncEx (SetThreadDescription, 8, KernelBase, 1)
|
|
LoadDLLfunc (VirtualAlloc2, 28, KernelBase)
|
|
|
|
LoadDLLfunc (NtMapViewOfSectionEx, 36, ntdll)
|
|
+LoadDLLfuncEx (RtlSetProcessPlaceholderCompatibilityMode, 4, ntdll, 1)
|
|
|
|
LoadDLLfunc (ldap_bind_s, 0, wldap32)
|
|
LoadDLLfunc (ldap_count_entries, 0, wldap32)
|
|
diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc
|
|
index d7a1b1a..a5b82b0 100644
|
|
--- a/winsup/cygwin/dcrt0.cc
|
|
+++ b/winsup/cygwin/dcrt0.cc
|
|
@@ -821,6 +821,9 @@ dll_crt0_1 (void *)
|
|
if (dynamically_loaded)
|
|
sigproc_init ();
|
|
|
|
+ /* Call this before accessing any files. */
|
|
+ RtlSetProcessPlaceholderCompatibilityMode (PHCM_EXPOSE_PLACEHOLDERS);
|
|
+
|
|
check_sanity_and_sync (user_data);
|
|
|
|
/* Initialize malloc and then call user_shared_initialize since it relies
|
|
diff --git a/winsup/cygwin/fhandler/disk_file.cc b/winsup/cygwin/fhandler/disk_file.cc
|
|
index 8528f7f..87c14df 100644
|
|
--- a/winsup/cygwin/fhandler/disk_file.cc
|
|
+++ b/winsup/cygwin/fhandler/disk_file.cc
|
|
@@ -175,7 +175,9 @@ readdir_check_reparse_point (POBJECT_ATTRIBUTES attr, bool remote)
|
|
bool ret = false;
|
|
|
|
status = NtOpenFile (&reph, READ_CONTROL, attr, &io, FILE_SHARE_VALID_FLAGS,
|
|
- FILE_OPEN_FOR_BACKUP_INTENT | FILE_OPEN_REPARSE_POINT);
|
|
+ FILE_OPEN_NO_RECALL
|
|
+ | FILE_OPEN_FOR_BACKUP_INTENT
|
|
+ | FILE_OPEN_REPARSE_POINT);
|
|
if (NT_SUCCESS (status))
|
|
{
|
|
PREPARSE_DATA_BUFFER rp = (PREPARSE_DATA_BUFFER) tp.c_get ();
|
|
@@ -326,6 +328,7 @@ fhandler_base::fstat_by_name (struct stat *buf)
|
|
status = NtOpenFile (&dir, SYNCHRONIZE | FILE_LIST_DIRECTORY,
|
|
&attr, &io, FILE_SHARE_VALID_FLAGS,
|
|
FILE_SYNCHRONOUS_IO_NONALERT
|
|
+ | FILE_OPEN_NO_RECALL
|
|
| FILE_OPEN_FOR_BACKUP_INTENT
|
|
| FILE_DIRECTORY_FILE);
|
|
if (!NT_SUCCESS (status))
|
|
@@ -609,7 +612,8 @@ fhandler_disk_file::fstatvfs (struct statvfs *sfs)
|
|
opened = NT_SUCCESS (NtOpenFile (&fh, READ_CONTROL,
|
|
pc.get_object_attr (attr, sec_none_nih),
|
|
&io, FILE_SHARE_VALID_FLAGS,
|
|
- FILE_OPEN_FOR_BACKUP_INTENT));
|
|
+ FILE_OPEN_NO_RECALL
|
|
+ | FILE_OPEN_FOR_BACKUP_INTENT));
|
|
if (!opened)
|
|
{
|
|
/* Can't open file. Try again with parent dir. */
|
|
@@ -618,7 +622,8 @@ fhandler_disk_file::fstatvfs (struct statvfs *sfs)
|
|
attr.ObjectName = &dirname;
|
|
opened = NT_SUCCESS (NtOpenFile (&fh, READ_CONTROL, &attr, &io,
|
|
FILE_SHARE_VALID_FLAGS,
|
|
- FILE_OPEN_FOR_BACKUP_INTENT));
|
|
+ FILE_OPEN_NO_RECALL
|
|
+ | FILE_OPEN_FOR_BACKUP_INTENT));
|
|
if (!opened)
|
|
goto out;
|
|
}
|
|
@@ -2054,7 +2059,8 @@ readdir_get_ino (const char *path, bool dot_dot)
|
|
|| NT_SUCCESS (NtOpenFile (&hdl, READ_CONTROL,
|
|
pc.get_object_attr (attr, sec_none_nih),
|
|
&io, FILE_SHARE_VALID_FLAGS,
|
|
- FILE_OPEN_FOR_BACKUP_INTENT
|
|
+ FILE_OPEN_NO_RECALL
|
|
+ | FILE_OPEN_FOR_BACKUP_INTENT
|
|
| (pc.is_known_reparse_point ()
|
|
? FILE_OPEN_REPARSE_POINT : 0)))
|
|
)
|
|
@@ -2103,8 +2109,9 @@ fhandler_disk_file::readdir_helper (DIR *dir, dirent *de, DWORD w32_err,
|
|
Mountpoints and unknown or unhandled reparse points will be treated
|
|
as normal file/directory/unknown. In all cases, returning the INO of
|
|
the reparse point (not of the target) matches behavior of posix systems.
|
|
+ Unless the file is OFFLINE. *.
|
|
*/
|
|
- if (attr & FILE_ATTRIBUTE_REPARSE_POINT)
|
|
+ if ((attr & FILE_ATTRIBUTE_REPARSE_POINT) && !isoffline (attr))
|
|
{
|
|
OBJECT_ATTRIBUTES oattr;
|
|
|
|
@@ -2345,7 +2352,8 @@ go_ahead:
|
|
&nfs_aol_ffei, sizeof nfs_aol_ffei)
|
|
: NtOpenFile (&hdl, READ_CONTROL, &attr, &io,
|
|
FILE_SHARE_VALID_FLAGS,
|
|
- FILE_OPEN_FOR_BACKUP_INTENT
|
|
+ FILE_OPEN_NO_RECALL
|
|
+ | FILE_OPEN_FOR_BACKUP_INTENT
|
|
| FILE_OPEN_REPARSE_POINT);
|
|
if (NT_SUCCESS (f_status))
|
|
{
|
|
diff --git a/winsup/cygwin/local_includes/ntdll.h b/winsup/cygwin/local_includes/ntdll.h
|
|
index a4e8b88..aa1f3b9 100644
|
|
--- a/winsup/cygwin/local_includes/ntdll.h
|
|
+++ b/winsup/cygwin/local_includes/ntdll.h
|
|
@@ -159,6 +159,13 @@ extern GUID __cygwin_socket_guid;
|
|
#define FILE_VC_QUOTAS_REBUILDING 0x00000200
|
|
#define FILE_VC_VALID_MASK 0x000003ff
|
|
|
|
+#define PHCM_APPLICATION_DEFAULT 0
|
|
+#define PHCM_DISGUISE_PLACEHOLDER 1
|
|
+#define PHCM_EXPOSE_PLACEHOLDERS 2
|
|
+#define PHCM_MAX 2
|
|
+#define PHCM_ERROR_INVALID_PARAMETER -1
|
|
+#define PHCM_ERROR_NO_TEB -2
|
|
+
|
|
/* IOCTL code to impersonate client of named pipe. */
|
|
|
|
#define FSCTL_PIPE_DISCONNECT CTL_CODE(FILE_DEVICE_NAMED_PIPE, 1, \
|
|
@@ -1605,6 +1612,7 @@ extern "C"
|
|
BOOLEAN);
|
|
NTSTATUS RtlSetGroupSecurityDescriptor (PSECURITY_DESCRIPTOR, PSID, BOOLEAN);
|
|
NTSTATUS RtlSetOwnerSecurityDescriptor (PSECURITY_DESCRIPTOR, PSID, BOOLEAN);
|
|
+ CHAR RtlSetProcessPlaceholderCompatibilityMode (CHAR);
|
|
PUCHAR RtlSubAuthorityCountSid (PSID);
|
|
PULONG RtlSubAuthoritySid (PSID, ULONG);
|
|
ULONG RtlUnicodeStringToAnsiSize (PUNICODE_STRING);
|
|
diff --git a/winsup/cygwin/local_includes/path.h b/winsup/cygwin/local_includes/path.h
|
|
index 74f831e..8c97c42 100644
|
|
--- a/winsup/cygwin/local_includes/path.h
|
|
+++ b/winsup/cygwin/local_includes/path.h
|
|
@@ -23,6 +23,14 @@ has_attribute (DWORD attributes, DWORD attribs_to_test)
|
|
&& (attributes & attribs_to_test);
|
|
}
|
|
|
|
+extern inline bool
|
|
+isoffline (DWORD attributes)
|
|
+{
|
|
+ return has_attribute (attributes, FILE_ATTRIBUTE_OFFLINE
|
|
+ | FILE_ATTRIBUTE_RECALL_ON_OPEN
|
|
+ | FILE_ATTRIBUTE_RECALL_ON_DATA_ACCESS);
|
|
+}
|
|
+
|
|
enum executable_states
|
|
{
|
|
is_executable,
|
|
@@ -230,6 +238,12 @@ class path_conv
|
|
bool exists () const {return fileattr != INVALID_FILE_ATTRIBUTES;}
|
|
bool has_attribute (DWORD x) const {return exists () && (fileattr & x);}
|
|
int isdir () const {return has_attribute (FILE_ATTRIBUTE_DIRECTORY);}
|
|
+ bool isoffline () const
|
|
+ {
|
|
+ return has_attribute (FILE_ATTRIBUTE_OFFLINE
|
|
+ | FILE_ATTRIBUTE_RECALL_ON_OPEN
|
|
+ | FILE_ATTRIBUTE_RECALL_ON_DATA_ACCESS);
|
|
+ }
|
|
executable_states exec_state ()
|
|
{
|
|
extern int _check_for_executable;
|
|
@@ -237,7 +251,7 @@ class path_conv
|
|
return is_executable;
|
|
if (mount_flags & MOUNT_NOTEXEC)
|
|
return not_executable;
|
|
- if (!_check_for_executable)
|
|
+ if (isoffline () || !_check_for_executable)
|
|
return dont_care_if_executable;
|
|
return dont_know_if_executable;
|
|
}
|
|
diff --git a/winsup/cygwin/local_includes/winlean.h b/winsup/cygwin/local_includes/winlean.h
|
|
index 9b30b65..d4b4038 100644
|
|
--- a/winsup/cygwin/local_includes/winlean.h
|
|
+++ b/winsup/cygwin/local_includes/winlean.h
|
|
@@ -74,6 +74,14 @@ details. */
|
|
#undef CRITICAL
|
|
#endif
|
|
|
|
+/* Filesystem flags not yet supported by Mingw-w64 headers. */
|
|
+#ifndef FILE_ATTRIBUTE_RECALL_ON_OPEN
|
|
+#define FILE_ATTRIBUTE_RECALL_ON_OPEN 0x00040000
|
|
+#endif
|
|
+#ifndef FILE_ATTRIBUTE_RECALL_ON_DATA_ACCESS
|
|
+#define FILE_ATTRIBUTE_RECALL_ON_DATA_ACCESS 0x00400000
|
|
+#endif
|
|
+
|
|
/* So-called "Microsoft Account" SIDs (S-1-11-...) have a netbios domain name
|
|
"MicrosoftAccounts". The new "Application Container SIDs" (S-1-15-...)
|
|
have a netbios domain name "APPLICATION PACKAGE AUTHORITY"
|
|
diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc
|
|
index af88ecf..e61d370 100644
|
|
--- a/winsup/cygwin/path.cc
|
|
+++ b/winsup/cygwin/path.cc
|
|
@@ -577,6 +577,7 @@ getfileattr (const char *path, bool caseinsensitive) /* path has to be always ab
|
|
status = NtOpenFile (&dir, SYNCHRONIZE | FILE_LIST_DIRECTORY,
|
|
&attr, &io, FILE_SHARE_VALID_FLAGS,
|
|
FILE_SYNCHRONOUS_IO_NONALERT
|
|
+ | FILE_OPEN_NO_RECALL
|
|
| FILE_OPEN_FOR_BACKUP_INTENT
|
|
| FILE_DIRECTORY_FILE);
|
|
if (NT_SUCCESS (status))
|
|
@@ -3353,7 +3354,8 @@ restart:
|
|
}
|
|
status = NtOpenFile (&h, READ_CONTROL | FILE_READ_ATTRIBUTES,
|
|
&attr, &io, FILE_SHARE_VALID_FLAGS,
|
|
- FILE_OPEN_REPARSE_POINT
|
|
+ FILE_OPEN_NO_RECALL
|
|
+ | FILE_OPEN_REPARSE_POINT
|
|
| FILE_OPEN_FOR_BACKUP_INTENT);
|
|
debug_printf ("%y = NtOpenFile (no-EAs %S)", status, &upath);
|
|
}
|
|
@@ -3481,6 +3483,7 @@ restart:
|
|
status = NtOpenFile (&dir, SYNCHRONIZE | FILE_LIST_DIRECTORY,
|
|
&dattr, &io, FILE_SHARE_VALID_FLAGS,
|
|
FILE_SYNCHRONOUS_IO_NONALERT
|
|
+ | FILE_OPEN_NO_RECALL
|
|
| FILE_OPEN_FOR_BACKUP_INTENT
|
|
| FILE_DIRECTORY_FILE);
|
|
if (!NT_SUCCESS (status))
|
|
@@ -3570,7 +3573,11 @@ restart:
|
|
directory using a relative path, symlink evaluation goes totally
|
|
awry. We never want a virtual drive evaluated as symlink. */
|
|
if (upath.Length <= 14)
|
|
- goto file_not_symlink;
|
|
+ goto file_not_symlink;
|
|
+
|
|
+ /* Offline files, even if reparse points, are not symlinks. */
|
|
+ if (isoffline (fileattr))
|
|
+ goto file_not_symlink;
|
|
|
|
/* Reparse points are potentially symlinks. This check must be
|
|
performed before checking the SYSTEM attribute for sysfile
|
|
@@ -3616,7 +3623,8 @@ restart:
|
|
|
|
status = NtOpenFile (&sym_h, SYNCHRONIZE | GENERIC_READ, &attr, &io,
|
|
FILE_SHARE_VALID_FLAGS,
|
|
- FILE_OPEN_FOR_BACKUP_INTENT
|
|
+ FILE_OPEN_NO_RECALL
|
|
+ | FILE_OPEN_FOR_BACKUP_INTENT
|
|
| FILE_SYNCHRONOUS_IO_NONALERT);
|
|
if (!NT_SUCCESS (status))
|
|
res = 0;
|
|
@@ -3660,7 +3668,8 @@ restart:
|
|
|
|
status = NtOpenFile (&sym_h, SYNCHRONIZE | GENERIC_READ, &attr, &io,
|
|
FILE_SHARE_VALID_FLAGS,
|
|
- FILE_OPEN_FOR_BACKUP_INTENT
|
|
+ FILE_OPEN_NO_RECALL
|
|
+ | FILE_OPEN_FOR_BACKUP_INTENT
|
|
| FILE_SYNCHRONOUS_IO_NONALERT);
|
|
|
|
if (!NT_SUCCESS (status))
|