Skip to content

Commit

Permalink
msys2-runtime-3.4: sync with the msys2-runtime-3.4.10 branch
Browse files Browse the repository at this point in the history
Looks like we haven't updated `MSYS2-packages`' `msys2-runtime-3.4`
directory in quite a while. This roll-up integrates:

- msys2/msys2-runtime#205
- msys2/msys2-runtime#209
- msys2/msys2-runtime#210
- msys2/msys2-runtime#192

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
  • Loading branch information
dscho committed Jul 8, 2024
1 parent 36d576f commit e9f2945
Show file tree
Hide file tree
Showing 12 changed files with 1,008 additions and 5 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,278 @@
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))
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
From 6f45a7c693dc4b723c24d4f28f038d551d492243 Mon Sep 17 00:00:00 2001
From: Corinna Vinschen <corinna@vinschen.de>
Date: Fri, 8 Mar 2024 21:30:57 +0100
Subject: [PATCH 53/N] Cygwin: get/set security descriptors using
FILE_OPEN_NO_RECALL

Add FILE_OPEN_NO_RECALL to NtOpenFile calls trying to fetch
or write file security descriptors so as not to recall them
from offline storage inadvertently.

Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
winsup/cygwin/sec/base.cc | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/winsup/cygwin/sec/base.cc b/winsup/cygwin/sec/base.cc
index 8b04b40..0fc8699 100644
--- a/winsup/cygwin/sec/base.cc
+++ b/winsup/cygwin/sec/base.cc
@@ -65,7 +65,8 @@ get_file_sd (HANDLE fh, path_conv &pc, security_descriptor &sd,
fh ? pc.init_reopen_attr (attr, fh)
: 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);
if (!NT_SUCCESS (status))
@@ -129,7 +130,8 @@ get_file_sd (HANDLE fh, path_conv &pc, security_descriptor &sd,
NULL, NULL);
status = NtOpenFile (&fh, 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 (status))
{
@@ -234,7 +236,8 @@ set_file_sd (HANDLE fh, path_conv &pc, security_descriptor &sd, bool is_chown)
: 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);
if (!NT_SUCCESS (status))
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
From 260676cde0b49d30209387181a2371dd35ee364c Mon Sep 17 00:00:00 2001
From: Corinna Vinschen <corinna@vinschen.de>
Date: Thu, 4 Apr 2024 17:36:01 +0200
Subject: [PATCH 54/N] Cygwin: FILE_OPEN_NO_RECALL is incompatible with
FILE_DIRECTORY_FILE

If FILE_DIRECTORY_FILE is given, FILE_OPEN_NO_RECALL is not allowed,
otherwise NtCreateFile returns STATUS_INVALID_PARAMETER.

Drop FILE_OPEN_NO_RECALL where FILE_DIRECTORY_FILE is specified.

Fixes: f6b56abec186 ("Cygwin: try to avoid recalling offline files")
Reported-by: Bruce Jerrick <bmj001@gmail.com>
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
---
winsup/cygwin/fhandler/disk_file.cc | 1 -
winsup/cygwin/path.cc | 2 --
2 files changed, 3 deletions(-)

diff --git a/winsup/cygwin/fhandler/disk_file.cc b/winsup/cygwin/fhandler/disk_file.cc
index 87c14df..4df80dc 100644
--- a/winsup/cygwin/fhandler/disk_file.cc
+++ b/winsup/cygwin/fhandler/disk_file.cc
@@ -328,7 +328,6 @@ 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))
diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc
index e61d370..46d1b8c 100644
--- a/winsup/cygwin/path.cc
+++ b/winsup/cygwin/path.cc
@@ -577,7 +577,6 @@ 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))
@@ -3483,7 +3482,6 @@ 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))
Loading

0 comments on commit e9f2945

Please sign in to comment.