From 1d149ff59d6d4b400ad53eb5281c66a4d0297494 Mon Sep 17 00:00:00 2001 From: Zebediah Figura Date: Thu, 3 Sep 2020 21:02:52 -0500 Subject: [PATCH] Rebase against 314368e6c442f043ebfc22b70c1113e4e6232c04. --- ...0001-ntdll-Fix-holes-in-ELF-mappings.patch | 14 +- ...retrieving-DOS-attributes-in-fd_-get.patch | 145 ++----- ...storing-DOS-attributes-in-NtSetInfor.patch | 101 ++--- ...storing-DOS-attributes-in-NtCreateFi.patch | 92 ++--- ...ort-for-Mac-OS-X-style-extended-attr.patch | 75 ++-- ...ort-for-FreeBSD-style-extended-attri.patch | 75 +--- ...ep-after-failed-map-attempt-in-try_.patch} | 11 +- ...ree-ranges-view-block-size-on-64-bit.patch | 29 ++ ...om-up-allocation-order-for-64-bit-ar.patch | 58 --- ...rce-virtual-memory-allocation-order.patch} | 373 ++++++++++-------- ...tively-mapped-areas-from-free-areas-.patch | 256 ++++++++++++ ...y-exclude-natively-mapped-areas-from.patch | 66 ---- ...-support-for-junction-point-creation.patch | 166 +++----- ...andle-PAGE_WRITECOPY-protection.-try.patch | 18 +- ...f-a-WRITECOPY-page-has-been-modified.patch | 22 +- ...Fallback-to-copy-pages-for-WRITECOPY.patch | 14 +- patches/ntdll-WRITECOPY/definition | 2 +- patches/patchinstall.sh | 69 ++-- ...e-security-attributes-with-extended-.patch | 67 ++-- ...file-security-attributes-with-extend.patch | 47 ++- staging/upstream-commit | 2 +- 21 files changed, 874 insertions(+), 828 deletions(-) rename patches/ntdll-ForceBottomUpAlloc/{0004-ntdll-Increase-step-after-failed-map-attempt-in-try_.patch => 0001-ntdll-Increase-step-after-failed-map-attempt-in-try_.patch} (56%) create mode 100644 patches/ntdll-ForceBottomUpAlloc/0002-ntdll-Increase-free-ranges-view-block-size-on-64-bit.patch delete mode 100644 patches/ntdll-ForceBottomUpAlloc/0003-ntdll-Force-bottom-up-allocation-order-for-64-bit-ar.patch rename patches/ntdll-ForceBottomUpAlloc/{0005-ntdll-Use-free-area-list-for-virtual-memory-allocati.patch => 0003-ntdll-Force-virtual-memory-allocation-order.patch} (55%) create mode 100644 patches/ntdll-ForceBottomUpAlloc/0004-ntdll-Exclude-natively-mapped-areas-from-free-areas-.patch delete mode 100644 patches/ntdll-ForceBottomUpAlloc/0006-ntdll-Permanently-exclude-natively-mapped-areas-from.patch diff --git a/patches/ntdll-Builtin_Prot/0001-ntdll-Fix-holes-in-ELF-mappings.patch b/patches/ntdll-Builtin_Prot/0001-ntdll-Fix-holes-in-ELF-mappings.patch index b907b22c..54e512b5 100644 --- a/patches/ntdll-Builtin_Prot/0001-ntdll-Fix-holes-in-ELF-mappings.patch +++ b/patches/ntdll-Builtin_Prot/0001-ntdll-Fix-holes-in-ELF-mappings.patch @@ -1,4 +1,4 @@ -From 83309ce4174bf56eef86e516221290b8d88bdc27 Mon Sep 17 00:00:00 2001 +From 9e66f8a5f7579f0e7ef97ab4df66f91d8d8c0949 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20M=C3=BCller?= Date: Thu, 1 Jun 2017 06:04:53 +0200 Subject: [PATCH] ntdll: Fix holes in ELF mappings. (v2) @@ -10,10 +10,10 @@ Based on a patch by Andrew Wesie. 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c -index cdc8e1189b3..1f73e72a952 100644 +index 253d5e31e3d..c518a4f8141 100644 --- a/dlls/ntdll/unix/virtual.c +++ b/dlls/ntdll/unix/virtual.c -@@ -968,6 +968,16 @@ static inline BOOL is_write_watch_range( const void *addr, size_t size ) +@@ -1014,6 +1014,16 @@ static inline BOOL is_write_watch_range( const void *addr, size_t size ) } @@ -30,7 +30,7 @@ index cdc8e1189b3..1f73e72a952 100644 /*********************************************************************** * find_view_range * -@@ -2966,6 +2976,19 @@ NTSTATUS virtual_handle_fault( void *addr, DWORD err, void *stack ) +@@ -2985,6 +2995,19 @@ NTSTATUS virtual_handle_fault( void *addr, DWORD err, void *stack ) /* ignore fault if page is writable now */ if (get_unix_prot( get_page_vprot( page ) ) & PROT_WRITE) ret = STATUS_SUCCESS; } @@ -42,7 +42,7 @@ index cdc8e1189b3..1f73e72a952 100644 + mprotect_range( page, page_size, 0, 0 ); + if (!mincore( page, page_size, &vec ) && (vec & 1)) + ret = STATUS_SUCCESS; -+ else if (wine_anon_mmap( page, page_size, unix_prot, MAP_FIXED ) == page) ++ else if (anon_mmap_fixed( page, page_size, unix_prot, 0 ) == page) + ret = STATUS_SUCCESS; + else + set_page_vprot_bits( page, page_size, 0, VPROT_READ | VPROT_EXEC ); @@ -51,7 +51,7 @@ index cdc8e1189b3..1f73e72a952 100644 return ret; } diff --git a/dlls/psapi/tests/psapi_main.c b/dlls/psapi/tests/psapi_main.c -index eb52fc690cf..178f5605a23 100644 +index d85099455aa..be12af58311 100644 --- a/dlls/psapi/tests/psapi_main.c +++ b/dlls/psapi/tests/psapi_main.c @@ -195,6 +195,7 @@ todo_wine @@ -86,5 +86,5 @@ index eb52fc690cf..178f5605a23 100644 static BOOL check_with_margin(SIZE_T perf, SIZE_T sysperf, int margin) -- -2.27.0 +2.28.0 diff --git a/patches/ntdll-DOS_Attributes/0001-ntdll-Implement-retrieving-DOS-attributes-in-fd_-get.patch b/patches/ntdll-DOS_Attributes/0001-ntdll-Implement-retrieving-DOS-attributes-in-fd_-get.patch index d408a4b0..195a84d7 100644 --- a/patches/ntdll-DOS_Attributes/0001-ntdll-Implement-retrieving-DOS-attributes-in-fd_-get.patch +++ b/patches/ntdll-DOS_Attributes/0001-ntdll-Implement-retrieving-DOS-attributes-in-fd_-get.patch @@ -1,23 +1,19 @@ -From f96ab0203c4119942b9d8ccc27207cc73389b375 Mon Sep 17 00:00:00 2001 +From 80247bc4566977f67a1851f46facba226fbd93df Mon Sep 17 00:00:00 2001 From: "Erich E. Hoover" Date: Tue, 19 Aug 2014 22:10:49 -0600 Subject: [PATCH] ntdll: Implement retrieving DOS attributes in [fd_]get_file_info(). --- - configure.ac | 12 +++++++++++ - dlls/ntdll/unix/file.c | 22 ++++++++++++++++++- - include/wine/port.h | 9 ++++++++ - libs/port/Makefile.in | 3 ++- - libs/port/xattr.c | 49 ++++++++++++++++++++++++++++++++++++++++++ - 5 files changed, 93 insertions(+), 2 deletions(-) - create mode 100644 libs/port/xattr.c + configure.ac | 12 ++++++++++++ + dlls/ntdll/unix/file.c | 39 ++++++++++++++++++++++++++++++++++++++- + 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac -index 4829648c3a5..cff2d4b8288 100644 +index f60cd593549..cca97ee403b 100644 --- a/configure.ac +++ b/configure.ac -@@ -88,6 +88,7 @@ AC_ARG_WITH(usb, AS_HELP_STRING([--without-usb],[do not use the libusb lib +@@ -89,6 +89,7 @@ AC_ARG_WITH(usb, AS_HELP_STRING([--without-usb],[do not use the libusb lib AC_ARG_WITH(v4l2, AS_HELP_STRING([--without-v4l2],[do not use v4l2 (video capture)])) AC_ARG_WITH(vkd3d, AS_HELP_STRING([--without-vkd3d],[do not use vkd3d (Direct3D 12 support)])) AC_ARG_WITH(vulkan, AS_HELP_STRING([--without-vulkan],[do not use Vulkan])) @@ -25,7 +21,7 @@ index 4829648c3a5..cff2d4b8288 100644 AC_ARG_WITH(xcomposite,AS_HELP_STRING([--without-xcomposite],[do not use the Xcomposite extension]), [if test "x$withval" = "xno"; then ac_cv_header_X11_extensions_Xcomposite_h=no; fi]) AC_ARG_WITH(xcursor, AS_HELP_STRING([--without-xcursor],[do not use the Xcursor extension]), -@@ -697,6 +698,17 @@ AC_CHECK_HEADERS([libprocstat.h],,, +@@ -698,6 +699,17 @@ AC_CHECK_HEADERS([libprocstat.h],,, #include #endif]) @@ -44,10 +40,41 @@ index 4829648c3a5..cff2d4b8288 100644 AC_SUBST(DLLFLAGS,"-D_REENTRANT") diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c -index bf435f109f1..6ac9b18da57 100644 +index 03e92a5c59e..da8f65af7b3 100644 --- a/dlls/ntdll/unix/file.c +++ b/dlls/ntdll/unix/file.c -@@ -1448,6 +1448,22 @@ static BOOL append_entry( struct dir_data *data, const char *long_name, +@@ -105,6 +105,9 @@ + #ifdef HAVE_SYS_STATFS_H + #include + #endif ++#ifdef HAVE_ATTR_XATTR_H ++#include ++#endif + #include + #ifdef HAVE_UNISTD_H + # include +@@ -369,6 +372,20 @@ NTSTATUS errno_to_status( int err ) + } + } + ++#ifndef XATTR_USER_PREFIX ++#define XATTR_USER_PREFIX "user." ++#endif ++ ++static int xattr_get( const char *path, const char *name, void *value, size_t size ) ++{ ++#if defined(HAVE_ATTR_XATTR_H) ++ return getxattr( path, name, value, size ); ++#else ++ errno = ENOSYS; ++ return -1; ++#endif ++} ++ + /* get space from the current directory data buffer, allocating a new one if necessary */ + static void *get_dir_data_space( struct dir_data *data, unsigned int size ) + { +@@ -1448,6 +1465,22 @@ static BOOL append_entry( struct dir_data *data, const char *long_name, } @@ -70,7 +97,7 @@ index bf435f109f1..6ac9b18da57 100644 /* fetch the attributes of a file */ static inline ULONG get_file_attributes( const struct stat *st ) { -@@ -1491,7 +1507,8 @@ static int fd_get_file_info( int fd, unsigned int options, struct stat *st, ULON +@@ -1491,7 +1524,8 @@ static int fd_get_file_info( int fd, unsigned int options, struct stat *st, ULON static int get_file_info( const char *path, struct stat *st, ULONG *attr ) { char *parent_path; @@ -80,7 +107,7 @@ index bf435f109f1..6ac9b18da57 100644 *attr = 0; ret = lstat( path, st ); -@@ -1517,6 +1534,9 @@ static int get_file_info( const char *path, struct stat *st, ULONG *attr ) +@@ -1517,6 +1551,9 @@ static int get_file_info( const char *path, struct stat *st, ULONG *attr ) free( parent_path ); } *attr |= get_file_attributes( st ); @@ -90,92 +117,6 @@ index bf435f109f1..6ac9b18da57 100644 return ret; } -diff --git a/include/wine/port.h b/include/wine/port.h -index 928730a41d7..4670891ae77 100644 ---- a/include/wine/port.h -+++ b/include/wine/port.h -@@ -352,6 +352,15 @@ int usleep (unsigned int useconds); - - extern int mkstemps(char *template, int suffix_len); - -+/* Extended attribute functions */ -+ -+#ifndef XATTR_USER_PREFIX -+# define XATTR_USER_PREFIX "user." -+#endif -+ -+extern int xattr_fget( int filedes, const char *name, void *value, size_t size ); -+extern int xattr_get( const char *path, const char *name, void *value, size_t size ); -+ - #else /* NO_LIBWINE_PORT */ - - #define __WINE_NOT_PORTABLE(func) func##_is_not_portable func##_is_not_portable -diff --git a/libs/port/Makefile.in b/libs/port/Makefile.in -index 7bc67fa3fee..d1de285d527 100644 ---- a/libs/port/Makefile.in -+++ b/libs/port/Makefile.in -@@ -21,4 +21,5 @@ C_SRCS = \ - strnlen.c \ - symlink.c \ - usleep.c \ -- wctype.c -+ wctype.c \ -+ xattr.c -diff --git a/libs/port/xattr.c b/libs/port/xattr.c -new file mode 100644 -index 00000000000..88e900dac6d ---- /dev/null -+++ b/libs/port/xattr.c -@@ -0,0 +1,49 @@ -+/* -+ * extended attributes functions -+ * -+ * Copyright 2014 Erich E. Hoover -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA -+ */ -+ -+#include "config.h" -+#include "wine/port.h" -+ -+#if defined(HAVE_ATTR_XATTR_H) -+# include -+#endif -+ -+#include -+#include -+ -+int xattr_fget( int filedes, const char *name, void *value, size_t size ) -+{ -+#if defined(HAVE_ATTR_XATTR_H) -+ return fgetxattr( filedes, name, value, size ); -+#else -+ errno = ENOSYS; -+ return -1; -+#endif -+} -+ -+int xattr_get( const char *path, const char *name, void *value, size_t size ) -+{ -+#if defined(HAVE_ATTR_XATTR_H) -+ return getxattr( path, name, value, size ); -+#else -+ errno = ENOSYS; -+ return -1; -+#endif -+} -- -2.27.0 +2.28.0 diff --git a/patches/ntdll-DOS_Attributes/0003-ntdll-Implement-storing-DOS-attributes-in-NtSetInfor.patch b/patches/ntdll-DOS_Attributes/0003-ntdll-Implement-storing-DOS-attributes-in-NtSetInfor.patch index e1065674..577babdf 100644 --- a/patches/ntdll-DOS_Attributes/0003-ntdll-Implement-storing-DOS-attributes-in-NtSetInfor.patch +++ b/patches/ntdll-DOS_Attributes/0003-ntdll-Implement-storing-DOS-attributes-in-NtSetInfor.patch @@ -1,21 +1,19 @@ -From b099458217b2855bd8615b8c97bcc2462eb74b25 Mon Sep 17 00:00:00 2001 +From 6bbf7676b4b7887a54f47b43929b8f3f1d7e77ae Mon Sep 17 00:00:00 2001 From: "Erich E. Hoover" Date: Wed, 20 Aug 2014 00:08:52 -0600 Subject: [PATCH] ntdll: Implement storing DOS attributes in NtSetInformationFile. --- - dlls/ntdll/tests/file.c | 8 +++--- - dlls/ntdll/unix/file.c | 54 ++++++++++++++++++++++++++--------------- - include/wine/port.h | 2 ++ - libs/port/xattr.c | 20 +++++++++++++++ - 4 files changed, 60 insertions(+), 24 deletions(-) + dlls/ntdll/tests/file.c | 8 ++--- + dlls/ntdll/unix/file.c | 74 ++++++++++++++++++++++++++++++----------- + 2 files changed, 58 insertions(+), 24 deletions(-) diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c -index 184b7cdad59..37e5ac5d8a5 100644 +index 8b9ec4f624d..6d2c8d2fc94 100644 --- a/dlls/ntdll/tests/file.c +++ b/dlls/ntdll/tests/file.c -@@ -1364,7 +1364,7 @@ static void test_file_basic_information(void) +@@ -1389,7 +1389,7 @@ static void test_file_basic_information(void) memset(&fbi, 0, sizeof(fbi)); res = pNtQueryInformationFile(h, &io, &fbi, sizeof fbi, FileBasicInformation); ok ( res == STATUS_SUCCESS, "can't get attributes\n"); @@ -24,7 +22,7 @@ index 184b7cdad59..37e5ac5d8a5 100644 /* Then HIDDEN */ memset(&fbi, 0, sizeof(fbi)); -@@ -1377,7 +1377,7 @@ static void test_file_basic_information(void) +@@ -1402,7 +1402,7 @@ static void test_file_basic_information(void) memset(&fbi, 0, sizeof(fbi)); res = pNtQueryInformationFile(h, &io, &fbi, sizeof fbi, FileBasicInformation); ok ( res == STATUS_SUCCESS, "can't get attributes\n"); @@ -33,7 +31,7 @@ index 184b7cdad59..37e5ac5d8a5 100644 /* Check NORMAL last of all (to make sure we can clear attributes) */ memset(&fbi, 0, sizeof(fbi)); -@@ -1434,7 +1434,7 @@ static void test_file_all_information(void) +@@ -1459,7 +1459,7 @@ static void test_file_all_information(void) memset(&fai_buf.fai, 0, sizeof(fai_buf.fai)); res = pNtQueryInformationFile(h, &io, &fai_buf.fai, sizeof fai_buf, FileAllInformation); ok ( res == STATUS_SUCCESS, "can't get attributes, res %x\n", res); @@ -42,7 +40,7 @@ index 184b7cdad59..37e5ac5d8a5 100644 /* Then HIDDEN */ memset(&fai_buf.fai.BasicInformation, 0, sizeof(fai_buf.fai.BasicInformation)); -@@ -1447,7 +1447,7 @@ static void test_file_all_information(void) +@@ -1472,7 +1472,7 @@ static void test_file_all_information(void) memset(&fai_buf.fai, 0, sizeof(fai_buf.fai)); res = pNtQueryInformationFile(h, &io, &fai_buf.fai, sizeof fai_buf, FileAllInformation); ok ( res == STATUS_SUCCESS, "can't get attributes\n"); @@ -52,10 +50,37 @@ index 184b7cdad59..37e5ac5d8a5 100644 /* Check NORMAL last of all (to make sure we can clear attributes) */ memset(&fai_buf.fai.BasicInformation, 0, sizeof(fai_buf.fai.BasicInformation)); diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c -index 70a76ca81ee..924d06b2caa 100644 +index da8f65af7b3..0a326a7a1bd 100644 --- a/dlls/ntdll/unix/file.c +++ b/dlls/ntdll/unix/file.c -@@ -1497,6 +1497,39 @@ static int fd_get_file_info( int fd, unsigned int options, struct stat *st, ULON +@@ -376,6 +376,26 @@ NTSTATUS errno_to_status( int err ) + #define XATTR_USER_PREFIX "user." + #endif + ++static int xattr_fremove( int filedes, const char *name ) ++{ ++#if defined(HAVE_ATTR_XATTR_H) ++ return fremovexattr( filedes, name ); ++#else ++ errno = ENOSYS; ++ return -1; ++#endif ++} ++ ++static int xattr_fset( int filedes, const char *name, void *value, size_t size ) ++{ ++#if defined(HAVE_ATTR_XATTR_H) ++ return fsetxattr( filedes, name, value, size, 0 ); ++#else ++ errno = ENOSYS; ++ return -1; ++#endif ++} ++ + static int xattr_get( const char *path, const char *name, void *value, size_t size ) + { + #if defined(HAVE_ATTR_XATTR_H) +@@ -1520,6 +1540,39 @@ static int fd_get_file_info( int fd, unsigned int options, struct stat *st, ULON } @@ -95,7 +120,7 @@ index 70a76ca81ee..924d06b2caa 100644 /* get the stat info and file attributes for a file (by name) */ static int get_file_info( const char *path, struct stat *st, ULONG *attr ) { -@@ -4000,7 +4033,6 @@ NTSTATUS WINAPI NtSetInformationFile( HANDLE handle, IO_STATUS_BLOCK *io, +@@ -4139,7 +4192,6 @@ NTSTATUS WINAPI NtSetInformationFile( HANDLE handle, IO_STATUS_BLOCK *io, case FileBasicInformation: if (len >= sizeof(FILE_BASIC_INFORMATION)) { @@ -103,7 +128,7 @@ index 70a76ca81ee..924d06b2caa 100644 const FILE_BASIC_INFORMATION *info = ptr; LARGE_INTEGER mtime, atime; -@@ -4014,25 +4046,7 @@ NTSTATUS WINAPI NtSetInformationFile( HANDLE handle, IO_STATUS_BLOCK *io, +@@ -4153,25 +4205,7 @@ NTSTATUS WINAPI NtSetInformationFile( HANDLE handle, IO_STATUS_BLOCK *io, io->u.Status = set_file_times( fd, &mtime, &atime ); if (io->u.Status == STATUS_SUCCESS && info->FileAttributes) @@ -130,50 +155,6 @@ index 70a76ca81ee..924d06b2caa 100644 if (needs_close) close( fd ); } -diff --git a/include/wine/port.h b/include/wine/port.h -index 4670891ae77..e0249b4c59f 100644 ---- a/include/wine/port.h -+++ b/include/wine/port.h -@@ -359,6 +359,8 @@ extern int mkstemps(char *template, int suffix_len); - #endif - - extern int xattr_fget( int filedes, const char *name, void *value, size_t size ); -+extern int xattr_fremove( int filedes, const char *name ); -+extern int xattr_fset( int filedes, const char *name, void *value, size_t size ); - extern int xattr_get( const char *path, const char *name, void *value, size_t size ); - - #else /* NO_LIBWINE_PORT */ -diff --git a/libs/port/xattr.c b/libs/port/xattr.c -index 88e900dac6d..6918c9956cc 100644 ---- a/libs/port/xattr.c -+++ b/libs/port/xattr.c -@@ -38,6 +38,26 @@ int xattr_fget( int filedes, const char *name, void *value, size_t size ) - #endif - } - -+int xattr_fremove( int filedes, const char *name ) -+{ -+#if defined(HAVE_ATTR_XATTR_H) -+ return fremovexattr( filedes, name ); -+#else -+ errno = ENOSYS; -+ return -1; -+#endif -+} -+ -+int xattr_fset( int filedes, const char *name, void *value, size_t size ) -+{ -+#if defined(HAVE_ATTR_XATTR_H) -+ return fsetxattr( filedes, name, value, size, 0 ); -+#else -+ errno = ENOSYS; -+ return -1; -+#endif -+} -+ - int xattr_get( const char *path, const char *name, void *value, size_t size ) - { - #if defined(HAVE_ATTR_XATTR_H) -- -2.27.0 +2.28.0 diff --git a/patches/ntdll-DOS_Attributes/0004-ntdll-Implement-storing-DOS-attributes-in-NtCreateFi.patch b/patches/ntdll-DOS_Attributes/0004-ntdll-Implement-storing-DOS-attributes-in-NtCreateFi.patch index 3807891d..a5da6caa 100644 --- a/patches/ntdll-DOS_Attributes/0004-ntdll-Implement-storing-DOS-attributes-in-NtCreateFi.patch +++ b/patches/ntdll-DOS_Attributes/0004-ntdll-Implement-storing-DOS-attributes-in-NtCreateFi.patch @@ -1,17 +1,15 @@ -From 29333aaab5e4d2b62741a8321382b24f1630eb70 Mon Sep 17 00:00:00 2001 +From 92aeb076183fd7311b5fa05b33af0304d897361d Mon Sep 17 00:00:00 2001 From: "Erich E. Hoover" Date: Wed, 20 Aug 2014 15:28:00 -0600 Subject: [PATCH] ntdll: Implement storing DOS attributes in NtCreateFile. --- - dlls/ntdll/tests/directory.c | 24 +++++++++++------------- - dlls/ntdll/unix/file.c | 31 ++++++++++++++++++++++++++----- - include/wine/port.h | 2 ++ - libs/port/xattr.c | 20 ++++++++++++++++++++ - 4 files changed, 59 insertions(+), 18 deletions(-) + dlls/ntdll/tests/directory.c | 24 ++++++++--------- + dlls/ntdll/unix/file.c | 51 ++++++++++++++++++++++++++++++++---- + 2 files changed, 57 insertions(+), 18 deletions(-) diff --git a/dlls/ntdll/tests/directory.c b/dlls/ntdll/tests/directory.c -index 248ed99ab20..e0f4debc624 100644 +index d21a2e64f8e..dc4f09729ac 100644 --- a/dlls/ntdll/tests/directory.c +++ b/dlls/ntdll/tests/directory.c @@ -55,7 +55,6 @@ static NTSTATUS (WINAPI *pRtlWow64EnableFsRedirectionEx)( ULONG disable, ULONG * @@ -60,10 +58,37 @@ index 248ed99ab20..e0f4debc624 100644 } testfiles[i].nfound++; diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c -index 7ab1c130bf2..7c737edd22c 100644 +index 0a326a7a1bd..a72d95f8378 100644 --- a/dlls/ntdll/unix/file.c +++ b/dlls/ntdll/unix/file.c -@@ -3549,6 +3549,20 @@ void CDECL set_show_dot_files( BOOL enable ) +@@ -406,6 +406,26 @@ static int xattr_get( const char *path, const char *name, void *value, size_t si + #endif + } + ++static int xattr_remove( const char *path, const char *name ) ++{ ++#if defined(HAVE_ATTR_XATTR_H) ++ return removexattr( path, name ); ++#else ++ errno = ENOSYS; ++ return -1; ++#endif ++} ++ ++static int xattr_set( const char *path, const char *name, void *value, size_t size ) ++{ ++#if defined(HAVE_ATTR_XATTR_H) ++ return setxattr( path, name, value, size, 0 ); ++#else ++ errno = ENOSYS; ++ return -1; ++#endif ++} ++ + /* get space from the current directory data buffer, allocating a new one if necessary */ + static void *get_dir_data_space( struct dir_data *data, unsigned int size ) + { +@@ -3582,6 +3602,20 @@ void CDECL set_show_dot_files( BOOL enable ) show_dot_files = enable; } @@ -84,7 +109,7 @@ index 7ab1c130bf2..7c737edd22c 100644 /****************************************************************************** * open_unix_file -@@ -3636,13 +3650,14 @@ NTSTATUS WINAPI NtCreateFile( HANDLE *handle, ACCESS_MASK access, OBJECT_ATTRIBU +@@ -3669,13 +3703,14 @@ NTSTATUS WINAPI NtCreateFile( HANDLE *handle, ACCESS_MASK access, OBJECT_ATTRIBU io->u.Status = STATUS_SUCCESS; } @@ -104,7 +129,7 @@ index 7ab1c130bf2..7c737edd22c 100644 if (io->u.Status == STATUS_SUCCESS) { -@@ -3664,6 +3679,11 @@ NTSTATUS WINAPI NtCreateFile( HANDLE *handle, ACCESS_MASK access, OBJECT_ATTRIBU +@@ -3697,6 +3732,11 @@ NTSTATUS WINAPI NtCreateFile( HANDLE *handle, ACCESS_MASK access, OBJECT_ATTRIBU io->Information = FILE_OVERWRITTEN; break; } @@ -116,7 +141,7 @@ index 7ab1c130bf2..7c737edd22c 100644 } else if (io->u.Status == STATUS_TOO_MANY_OPENED_FILES) { -@@ -3671,6 +3691,7 @@ NTSTATUS WINAPI NtCreateFile( HANDLE *handle, ACCESS_MASK access, OBJECT_ATTRIBU +@@ -3704,6 +3744,7 @@ NTSTATUS WINAPI NtCreateFile( HANDLE *handle, ACCESS_MASK access, OBJECT_ATTRIBU if (!once++) ERR_(winediag)( "Too many open files, ulimit -n probably needs to be increased\n" ); } @@ -124,47 +149,6 @@ index 7ab1c130bf2..7c737edd22c 100644 return io->u.Status; } -diff --git a/include/wine/port.h b/include/wine/port.h -index e0249b4c59f..930efeeea1f 100644 ---- a/include/wine/port.h -+++ b/include/wine/port.h -@@ -362,6 +362,8 @@ extern int xattr_fget( int filedes, const char *name, void *value, size_t size ) - extern int xattr_fremove( int filedes, const char *name ); - extern int xattr_fset( int filedes, const char *name, void *value, size_t size ); - extern int xattr_get( const char *path, const char *name, void *value, size_t size ); -+extern int xattr_remove( const char *path, const char *name ); -+extern int xattr_set( const char *path, const char *name, void *value, size_t size ); - - #else /* NO_LIBWINE_PORT */ - -diff --git a/libs/port/xattr.c b/libs/port/xattr.c -index 6918c9956cc..683e7a615e2 100644 ---- a/libs/port/xattr.c -+++ b/libs/port/xattr.c -@@ -67,3 +67,23 @@ int xattr_get( const char *path, const char *name, void *value, size_t size ) - return -1; - #endif - } -+ -+int xattr_remove( const char *path, const char *name ) -+{ -+#if defined(HAVE_ATTR_XATTR_H) -+ return removexattr( path, name ); -+#else -+ errno = ENOSYS; -+ return -1; -+#endif -+} -+ -+int xattr_set( const char *path, const char *name, void *value, size_t size ) -+{ -+#if defined(HAVE_ATTR_XATTR_H) -+ return setxattr( path, name, value, size, 0 ); -+#else -+ errno = ENOSYS; -+ return -1; -+#endif -+} -- -2.27.0 +2.28.0 diff --git a/patches/ntdll-DOS_Attributes/0005-libport-Add-support-for-Mac-OS-X-style-extended-attr.patch b/patches/ntdll-DOS_Attributes/0005-libport-Add-support-for-Mac-OS-X-style-extended-attr.patch index 90562cd4..9acd3fca 100644 --- a/patches/ntdll-DOS_Attributes/0005-libport-Add-support-for-Mac-OS-X-style-extended-attr.patch +++ b/patches/ntdll-DOS_Attributes/0005-libport-Add-support-for-Mac-OS-X-style-extended-attr.patch @@ -1,18 +1,18 @@ -From f083b503de5dd5ae1805e633e191532a10896eab Mon Sep 17 00:00:00 2001 +From 65442c83060ee1980900cc5fe38978ef8c29eba4 Mon Sep 17 00:00:00 2001 From: "Erich E. Hoover" Date: Mon, 6 Oct 2014 14:21:11 -0600 -Subject: libport: Add support for Mac OS X style extended attributes. +Subject: [PATCH] libport: Add support for Mac OS X style extended attributes. --- - configure.ac | 3 +++ - libs/port/xattr.c | 27 +++++++++++++++++++++------ - 2 files changed, 24 insertions(+), 6 deletions(-) + configure.ac | 3 +++ + dlls/ntdll/unix/file.c | 23 ++++++++++++++++++----- + 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/configure.ac b/configure.ac -index 3c91af3..68dca0a 100644 +index cca97ee403b..5e33bfacf91 100644 --- a/configure.ac +++ b/configure.ac -@@ -671,6 +671,9 @@ AC_CHECK_HEADERS([libprocstat.h],,, +@@ -702,6 +702,9 @@ AC_CHECK_HEADERS([libprocstat.h],,, if test "x$with_xattr" != "xno" then AC_CHECK_HEADERS(attr/xattr.h, [HAVE_XATTR=1]) @@ -22,35 +22,24 @@ index 3c91af3..68dca0a 100644 fi if test "x$with_xattr" = "xyes" then -diff --git a/libs/port/xattr.c b/libs/port/xattr.c -index 683e7a6..efc65c5 100644 ---- a/libs/port/xattr.c -+++ b/libs/port/xattr.c -@@ -22,7 +22,10 @@ - #include "wine/port.h" - - #if defined(HAVE_ATTR_XATTR_H) -+# undef XATTR_ADDITIONAL_OPTIONS - # include -+#elif defined(HAVE_SYS_XATTR_H) -+# include +diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c +index a72d95f8378..5e0ac914e1c 100644 +--- a/dlls/ntdll/unix/file.c ++++ b/dlls/ntdll/unix/file.c +@@ -106,7 +106,10 @@ + #include #endif + #ifdef HAVE_ATTR_XATTR_H ++#undef XATTR_ADDITIONAL_OPTIONS + #include ++#elif defined(HAVE_SYS_XATTR_H) ++#include + #endif + #include + #ifdef HAVE_UNISTD_H +@@ -378,7 +381,9 @@ NTSTATUS errno_to_status( int err ) - #include -@@ -30,7 +33,9 @@ - - int xattr_fget( int filedes, const char *name, void *value, size_t size ) - { --#if defined(HAVE_ATTR_XATTR_H) -+#if defined(XATTR_ADDITIONAL_OPTIONS) -+ return fgetxattr( filedes, name, value, size, 0, 0 ); -+#elif defined(HAVE_SYS_XATTR_H) || defined(HAVE_ATTR_XATTR_H) - return fgetxattr( filedes, name, value, size ); - #else - errno = ENOSYS; -@@ -40,7 +45,9 @@ int xattr_fget( int filedes, const char *name, void *value, size_t size ) - - int xattr_fremove( int filedes, const char *name ) + static int xattr_fremove( int filedes, const char *name ) { -#if defined(HAVE_ATTR_XATTR_H) +#if defined(XATTR_ADDITIONAL_OPTIONS) @@ -59,9 +48,9 @@ index 683e7a6..efc65c5 100644 return fremovexattr( filedes, name ); #else errno = ENOSYS; -@@ -50,7 +57,9 @@ int xattr_fremove( int filedes, const char *name ) +@@ -388,7 +393,9 @@ static int xattr_fremove( int filedes, const char *name ) - int xattr_fset( int filedes, const char *name, void *value, size_t size ) + static int xattr_fset( int filedes, const char *name, void *value, size_t size ) { -#if defined(HAVE_ATTR_XATTR_H) +#if defined(XATTR_ADDITIONAL_OPTIONS) @@ -70,9 +59,9 @@ index 683e7a6..efc65c5 100644 return fsetxattr( filedes, name, value, size, 0 ); #else errno = ENOSYS; -@@ -60,7 +69,9 @@ int xattr_fset( int filedes, const char *name, void *value, size_t size ) +@@ -398,7 +405,9 @@ static int xattr_fset( int filedes, const char *name, void *value, size_t size ) - int xattr_get( const char *path, const char *name, void *value, size_t size ) + static int xattr_get( const char *path, const char *name, void *value, size_t size ) { -#if defined(HAVE_ATTR_XATTR_H) +#if defined(XATTR_ADDITIONAL_OPTIONS) @@ -81,9 +70,9 @@ index 683e7a6..efc65c5 100644 return getxattr( path, name, value, size ); #else errno = ENOSYS; -@@ -70,7 +81,9 @@ int xattr_get( const char *path, const char *name, void *value, size_t size ) +@@ -408,7 +417,9 @@ static int xattr_get( const char *path, const char *name, void *value, size_t si - int xattr_remove( const char *path, const char *name ) + static int xattr_remove( const char *path, const char *name ) { -#if defined(HAVE_ATTR_XATTR_H) +#if defined(XATTR_ADDITIONAL_OPTIONS) @@ -92,9 +81,9 @@ index 683e7a6..efc65c5 100644 return removexattr( path, name ); #else errno = ENOSYS; -@@ -80,7 +93,9 @@ int xattr_remove( const char *path, const char *name ) +@@ -418,7 +429,9 @@ static int xattr_remove( const char *path, const char *name ) - int xattr_set( const char *path, const char *name, void *value, size_t size ) + static int xattr_set( const char *path, const char *name, void *value, size_t size ) { -#if defined(HAVE_ATTR_XATTR_H) +#if defined(XATTR_ADDITIONAL_OPTIONS) @@ -104,5 +93,5 @@ index 683e7a6..efc65c5 100644 #else errno = ENOSYS; -- -1.9.1 +2.28.0 diff --git a/patches/ntdll-DOS_Attributes/0006-libport-Add-support-for-FreeBSD-style-extended-attri.patch b/patches/ntdll-DOS_Attributes/0006-libport-Add-support-for-FreeBSD-style-extended-attri.patch index 98e669d0..d175436a 100644 --- a/patches/ntdll-DOS_Attributes/0006-libport-Add-support-for-FreeBSD-style-extended-attri.patch +++ b/patches/ntdll-DOS_Attributes/0006-libport-Add-support-for-FreeBSD-style-extended-attri.patch @@ -1,18 +1,18 @@ -From 64708643d4dc9454faaccd720ab9b8a53b5aecf9 Mon Sep 17 00:00:00 2001 +From f4caa19ffcac13201c0c9bd45d3d93d44cb24980 Mon Sep 17 00:00:00 2001 From: "Erich E. Hoover" Date: Mon, 6 Oct 2014 14:26:24 -0600 -Subject: libport: Add support for FreeBSD style extended attributes. +Subject: [PATCH] libport: Add support for FreeBSD style extended attributes. --- - configure.ac | 2 +- - libs/port/xattr.c | 41 +++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 42 insertions(+), 1 deletion(-) + configure.ac | 2 +- + dlls/ntdll/unix/file.c | 18 ++++++++++++++++++ + 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac -index 68dca0a..3b0da05 100644 +index 5e33bfacf91..aef00416461 100644 --- a/configure.ac +++ b/configure.ac -@@ -670,7 +670,7 @@ AC_CHECK_HEADERS([libprocstat.h],,, +@@ -701,7 +701,7 @@ AC_CHECK_HEADERS([libprocstat.h],,, if test "x$with_xattr" != "xno" then @@ -21,52 +21,11 @@ index 68dca0a..3b0da05 100644 AC_CHECK_HEADERS(sys/xattr.h, [HAVE_XATTR=1] [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[getxattr("", "", "", 0, 0, 0);]])], [AC_DEFINE(XATTR_ADDITIONAL_OPTIONS, 1, [Define if xattr functions take additional arguments (Mac OS X)])])]) -diff --git a/libs/port/xattr.c b/libs/port/xattr.c -index efc65c5..92a717e 100644 ---- a/libs/port/xattr.c -+++ b/libs/port/xattr.c -@@ -26,17 +26,40 @@ - # include - #elif defined(HAVE_SYS_XATTR_H) - # include -+#elif defined(HAVE_SYS_EXTATTR_H) -+# undef XATTR_ADDITIONAL_OPTIONS -+# include - #endif - - #include - #include - -+#ifndef XATTR_USER_PREFIX_LEN -+# define XATTR_USER_PREFIX_LEN (sizeof(XATTR_USER_PREFIX) - 1) -+#endif -+ -+#ifdef HAVE_SYS_EXTATTR_H -+static inline int xattr_valid_namespace( const char *name ) -+{ -+ if (strncmp( XATTR_USER_PREFIX, name, XATTR_USER_PREFIX_LEN ) != 0) -+ { -+ errno = EPERM; -+ return 0; -+ } -+ return 1; -+} -+#endif -+ - int xattr_fget( int filedes, const char *name, void *value, size_t size ) - { - #if defined(XATTR_ADDITIONAL_OPTIONS) - return fgetxattr( filedes, name, value, size, 0, 0 ); - #elif defined(HAVE_SYS_XATTR_H) || defined(HAVE_ATTR_XATTR_H) - return fgetxattr( filedes, name, value, size ); -+#elif defined(HAVE_SYS_EXTATTR_H) -+ if (!xattr_valid_namespace( name )) return -1; -+ return extattr_get_fd( filedes, EXTATTR_NAMESPACE_USER, &name[XATTR_USER_PREFIX_LEN], -+ value, size ); - #else - errno = ENOSYS; - return -1; -@@ -49,6 +72,9 @@ int xattr_fremove( int filedes, const char *name ) +diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c +index 5e0ac914e1c..c4d5f9c9028 100644 +--- a/dlls/ntdll/unix/file.c ++++ b/dlls/ntdll/unix/file.c +@@ -385,6 +385,9 @@ static int xattr_fremove( int filedes, const char *name ) return fremovexattr( filedes, name, 0 ); #elif defined(HAVE_SYS_XATTR_H) || defined(HAVE_ATTR_XATTR_H) return fremovexattr( filedes, name ); @@ -76,7 +35,7 @@ index efc65c5..92a717e 100644 #else errno = ENOSYS; return -1; -@@ -61,6 +87,10 @@ int xattr_fset( int filedes, const char *name, void *value, size_t size ) +@@ -397,6 +400,10 @@ static int xattr_fset( int filedes, const char *name, void *value, size_t size ) return fsetxattr( filedes, name, value, size, 0, 0 ); #elif defined(HAVE_SYS_XATTR_H) || defined(HAVE_ATTR_XATTR_H) return fsetxattr( filedes, name, value, size, 0 ); @@ -87,7 +46,7 @@ index efc65c5..92a717e 100644 #else errno = ENOSYS; return -1; -@@ -73,6 +103,10 @@ int xattr_get( const char *path, const char *name, void *value, size_t size ) +@@ -409,6 +416,10 @@ static int xattr_get( const char *path, const char *name, void *value, size_t si return getxattr( path, name, value, size, 0, 0 ); #elif defined(HAVE_SYS_XATTR_H) || defined(HAVE_ATTR_XATTR_H) return getxattr( path, name, value, size ); @@ -98,7 +57,7 @@ index efc65c5..92a717e 100644 #else errno = ENOSYS; return -1; -@@ -85,6 +119,9 @@ int xattr_remove( const char *path, const char *name ) +@@ -421,6 +432,9 @@ static int xattr_remove( const char *path, const char *name ) return removexattr( path, name, 0 ); #elif defined(HAVE_SYS_XATTR_H) || defined(HAVE_ATTR_XATTR_H) return removexattr( path, name ); @@ -108,7 +67,7 @@ index efc65c5..92a717e 100644 #else errno = ENOSYS; return -1; -@@ -97,6 +134,10 @@ int xattr_set( const char *path, const char *name, void *value, size_t size ) +@@ -433,6 +447,10 @@ static int xattr_set( const char *path, const char *name, void *value, size_t si return setxattr( path, name, value, size, 0, 0 ); #elif defined(HAVE_SYS_XATTR_H) || defined(HAVE_ATTR_XATTR_H) return setxattr( path, name, value, size, 0 ); @@ -120,5 +79,5 @@ index efc65c5..92a717e 100644 errno = ENOSYS; return -1; -- -1.9.1 +2.28.0 diff --git a/patches/ntdll-ForceBottomUpAlloc/0004-ntdll-Increase-step-after-failed-map-attempt-in-try_.patch b/patches/ntdll-ForceBottomUpAlloc/0001-ntdll-Increase-step-after-failed-map-attempt-in-try_.patch similarity index 56% rename from patches/ntdll-ForceBottomUpAlloc/0004-ntdll-Increase-step-after-failed-map-attempt-in-try_.patch rename to patches/ntdll-ForceBottomUpAlloc/0001-ntdll-Increase-step-after-failed-map-attempt-in-try_.patch index 241ebebf..8abaf03e 100644 --- a/patches/ntdll-ForceBottomUpAlloc/0004-ntdll-Increase-step-after-failed-map-attempt-in-try_.patch +++ b/patches/ntdll-ForceBottomUpAlloc/0001-ntdll-Increase-step-after-failed-map-attempt-in-try_.patch @@ -1,18 +1,19 @@ -From 0e03dab87634938bf9b6462a3e7dce1def1289c9 Mon Sep 17 00:00:00 2001 -From: Paul Gofman +From ff02cbe4aea411563e0a9d22ed832acc2747d5b7 Mon Sep 17 00:00:00 2001 +From: Paul Gofman Date: Tue, 14 Jan 2020 21:39:23 +0300 -Subject: [PATCH] ntdll: Increase step after failed map attempt in +Subject: [PATCH 1/4] ntdll: Increase step after failed map attempt in try_map_free_area(). +Signed-off-by: Paul Gofman --- dlls/ntdll/unix/virtual.c | 1 + 1 file changed, 1 insertion(+) diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c -index 4b8942b1b53b..f4dba39cb160 100644 +index b469e9df4a1..52915e07323 100644 --- a/dlls/ntdll/unix/virtual.c +++ b/dlls/ntdll/unix/virtual.c -@@ -1083,6 +1083,7 @@ static void* try_map_free_area( void *base, void *end, ptrdiff_t step, +@@ -1080,6 +1080,7 @@ static void* try_map_free_area( void *base, void *end, ptrdiff_t step, step == 0) break; start = (char *)start + step; diff --git a/patches/ntdll-ForceBottomUpAlloc/0002-ntdll-Increase-free-ranges-view-block-size-on-64-bit.patch b/patches/ntdll-ForceBottomUpAlloc/0002-ntdll-Increase-free-ranges-view-block-size-on-64-bit.patch new file mode 100644 index 00000000..326980d2 --- /dev/null +++ b/patches/ntdll-ForceBottomUpAlloc/0002-ntdll-Increase-free-ranges-view-block-size-on-64-bit.patch @@ -0,0 +1,29 @@ +From 01730a2261a59a2826a652360b69dd3c74917fa6 Mon Sep 17 00:00:00 2001 +From: Paul Gofman +Date: Thu, 23 Jul 2020 18:40:39 +0300 +Subject: [PATCH] ntdll: Increase free ranges view block size on 64 bit. + +Signed-off-by: Paul Gofman +--- + dlls/ntdll/unix/virtual.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c +index f7eab895f58..54ad53ea088 100644 +--- a/dlls/ntdll/unix/virtual.c ++++ b/dlls/ntdll/unix/virtual.c +@@ -183,7 +183,11 @@ static BYTE *pages_vprot; + #endif + + static struct file_view *view_block_start, *view_block_end, *next_free_view; ++#ifdef _WIN64 ++static const size_t view_block_size = 0x200000; ++#else + static const size_t view_block_size = 0x100000; ++#endif + static void *preload_reserve_start; + static void *preload_reserve_end; + static BOOL force_exec_prot; /* whether to force PROT_EXEC on all PROT_READ mmaps */ +-- +2.28.0 + diff --git a/patches/ntdll-ForceBottomUpAlloc/0003-ntdll-Force-bottom-up-allocation-order-for-64-bit-ar.patch b/patches/ntdll-ForceBottomUpAlloc/0003-ntdll-Force-bottom-up-allocation-order-for-64-bit-ar.patch deleted file mode 100644 index 2fbdf31b..00000000 --- a/patches/ntdll-ForceBottomUpAlloc/0003-ntdll-Force-bottom-up-allocation-order-for-64-bit-ar.patch +++ /dev/null @@ -1,58 +0,0 @@ -From c9f4923096e5c6dcb1591355e3cdab63167448d4 Mon Sep 17 00:00:00 2001 -From: Paul Gofman -Date: Mon, 25 Nov 2019 12:19:20 +0300 -Subject: [PATCH] ntdll: Force bottom up allocation order for 64 bit arch - unless top down is requested. - -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=48175 -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=46568 ---- - dlls/ntdll/unix/virtual.c | 12 ++++++++++-- - 1 file changed, 10 insertions(+), 2 deletions(-) - -diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c -index 3907b0db70a9..4b8942b1b53b 100644 ---- a/dlls/ntdll/unix/virtual.c -+++ b/dlls/ntdll/unix/virtual.c -@@ -1775,13 +1775,19 @@ static NTSTATUS map_view( struct file_view **view_ret, void *base, size_t size, - } - else - { -- size_t view_size = size + granularity_mask + 1; - struct alloc_area alloc; -+ size_t view_size; - - alloc.size = size; - alloc.top_down = top_down; - alloc.limit = (void*)(get_zero_bits_64_mask( zero_bits_64 ) & (UINT_PTR)user_space_limit); - -+ if (is_win64 && !top_down) -+ { -+ /* Ditch 0x7ffffe000000 - 0x7fffffff0000 reserved area. */ -+ alloc.limit = min(alloc.limit, (void *)0x7ffffe000000); -+ } -+ - if (mmap_enum_reserved_areas( alloc_reserved_area_callback, &alloc, top_down )) - { - ptr = alloc.result; -@@ -1791,7 +1797,7 @@ static NTSTATUS map_view( struct file_view **view_ret, void *base, size_t size, - goto done; - } - -- if (zero_bits_64) -+ if (is_win64 || zero_bits_64) - { - if (!(ptr = map_free_area( address_space_start, alloc.limit, size, - top_down, get_unix_prot(vprot) ))) -@@ -1800,6 +1806,8 @@ static NTSTATUS map_view( struct file_view **view_ret, void *base, size_t size, - goto done; - } - -+ view_size = size + granularity_mask + 1; -+ - for (;;) - { - if ((ptr = wine_anon_mmap( NULL, view_size, get_unix_prot(vprot), 0 )) == (void *)-1) --- -2.26.2 - diff --git a/patches/ntdll-ForceBottomUpAlloc/0005-ntdll-Use-free-area-list-for-virtual-memory-allocati.patch b/patches/ntdll-ForceBottomUpAlloc/0003-ntdll-Force-virtual-memory-allocation-order.patch similarity index 55% rename from patches/ntdll-ForceBottomUpAlloc/0005-ntdll-Use-free-area-list-for-virtual-memory-allocati.patch rename to patches/ntdll-ForceBottomUpAlloc/0003-ntdll-Force-virtual-memory-allocation-order.patch index e2a00566..55309fee 100644 --- a/patches/ntdll-ForceBottomUpAlloc/0005-ntdll-Use-free-area-list-for-virtual-memory-allocati.patch +++ b/patches/ntdll-ForceBottomUpAlloc/0003-ntdll-Force-virtual-memory-allocation-order.patch @@ -1,76 +1,26 @@ -From c8bf6f3b7bd054d712463725ddd891b87801bf27 Mon Sep 17 00:00:00 2001 +From 1823294e18c99c17f3085486f12dcd2c6f8555b6 Mon Sep 17 00:00:00 2001 From: Paul Gofman -Date: Tue, 14 Jan 2020 21:42:21 +0300 -Subject: [PATCH] ntdll: Use free area list for virtual memory allocation. +Date: Mon, 25 Nov 2019 12:19:20 +0300 +Subject: [PATCH 3/4] ntdll: Force virtual memory allocation order. +Windows allocates virtual memory strictly bottom up or +top down depending on the requested flags. Modern Linux +VM allocator always allocates memory top down. Some +applications break if the allocated memory addresses +are from higher memory than they expect. + +Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=48175 +Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=46568 +Signed-off-by: Paul Gofman --- - dlls/ntdll/unix/virtual.c | 342 +++++++++++++++++++++++++------------- - 1 file changed, 230 insertions(+), 112 deletions(-) + dlls/ntdll/unix/virtual.c | 417 ++++++++++++++++++-------------------- + 1 file changed, 201 insertions(+), 216 deletions(-) diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c -index 2164c08f756..0939893d7c1 100644 +index 924dff973ce..e7dfc516538 100644 --- a/dlls/ntdll/unix/virtual.c +++ b/dlls/ntdll/unix/virtual.c -@@ -185,7 +185,11 @@ static BYTE *pages_vprot; - #endif - - static struct file_view *view_block_start, *view_block_end, *next_free_view; -+#ifdef _WIN64 -+static const size_t view_block_size = 0x200000; -+#else - static const size_t view_block_size = 0x100000; -+#endif - static void *preload_reserve_start; - static void *preload_reserve_end; - static BOOL force_exec_prot; /* whether to force PROT_EXEC on all PROT_READ mmaps */ -@@ -527,13 +531,13 @@ static struct range_entry *free_ranges_lower_bound( void *addr ) - * - * Updates the free_ranges after a new view has been created. - */ --static void free_ranges_insert_view( struct file_view *view ) -+static void free_ranges_remove_range( void *view_base, void *view_end, void *view_base_unaligned ) - { -- void *view_base = ROUND_ADDR( view->base, granularity_mask ); -- void *view_end = ROUND_ADDR( (char *)view->base + view->size + granularity_mask, granularity_mask ); - struct range_entry *range = free_ranges_lower_bound( view_base ); - struct range_entry *next = range + 1; - -+ TRACE("view %p-%p (%p).\n", view_base, view_end, view_base_unaligned); -+ - /* free_ranges initial value is such that the view is either inside range or before another one. */ - assert( range != free_ranges_end ); - assert( range->end > view_base || next != free_ranges_end ); -@@ -544,7 +548,7 @@ static void free_ranges_insert_view( struct file_view *view ) - (range->end == view_base && next->base >= view_end)) - { - /* on Win64, assert that it's correctly aligned so we're not going to be in trouble later */ -- assert( (!is_win64 && !is_wow64) || view->base == view_base ); -+ assert( (!is_win64 && !is_wow64) || view_base_unaligned == view_base ); - WARN( "range %p - %p is already mapped\n", view_base, view_end ); - return; - } -@@ -584,6 +588,12 @@ static void free_ranges_insert_view( struct file_view *view ) - } - } - -+static void free_ranges_insert_view( struct file_view *view ) -+{ -+ free_ranges_remove_range(ROUND_ADDR(view->base, granularity_mask), -+ ROUND_ADDR((char *)view->base + view->size + granularity_mask, granularity_mask), -+ view->base); -+} - - /*********************************************************************** - * free_ranges_remove_view -@@ -614,6 +624,7 @@ static void free_ranges_remove_view( struct file_view *view ) - return; - } - #endif -+ TRACE("view %p-%p.\n", view_base, view_end); - - /* free_ranges initial value is such that the view is either inside range or before another one. */ - assert( range != free_ranges_end ); -@@ -960,44 +971,6 @@ static struct file_view *find_view_range( const void *addr, size_t size ) +@@ -1020,44 +1020,6 @@ static struct file_view *find_view_range( const void *addr, size_t size ) } @@ -115,7 +65,7 @@ index 2164c08f756..0939893d7c1 100644 /*********************************************************************** * try_map_free_area * -@@ -1036,65 +1009,11 @@ static void* try_map_free_area( void *base, void *end, ptrdiff_t step, +@@ -1090,110 +1052,6 @@ static void* try_map_free_area( void *base, void *end, ptrdiff_t step, return NULL; } @@ -172,16 +122,61 @@ index 2164c08f756..0939893d7c1 100644 -} - - - /*********************************************************************** - * find_reserved_free_area - * - * Find a free area between views inside the specified range. - * virtual_mutex must be held by caller. +-/*********************************************************************** +- * find_reserved_free_area +- * +- * Find a free area between views inside the specified range. +- * virtual_mutex must be held by caller. - * The range must be inside the preloader reserved range. - */ - static void *find_reserved_free_area( void *base, void *end, size_t size, int top_down ) - { -@@ -1308,8 +1227,7 @@ static void delete_view( struct file_view *view ) /* [in] View */ +- */ +-static void *find_reserved_free_area( void *base, void *end, size_t size, int top_down ) +-{ +- struct range_entry *range; +- void *start; +- +- base = ROUND_ADDR( (char *)base + granularity_mask, granularity_mask ); +- end = (char *)ROUND_ADDR( (char *)end - size, granularity_mask ) + size; +- +- if (top_down) +- { +- start = (char *)end - size; +- range = free_ranges_lower_bound( start ); +- assert(range != free_ranges_end && range->end >= start); +- +- if ((char *)range->end - (char *)start < size) start = ROUND_ADDR( (char *)range->end - size, granularity_mask ); +- do +- { +- if (start >= end || start < base || (char *)end - (char *)start < size) return NULL; +- if (start < range->end && start >= range->base && (char *)range->end - (char *)start >= size) break; +- if (--range < free_ranges) return NULL; +- start = ROUND_ADDR( (char *)range->end - size, granularity_mask ); +- } +- while (1); +- } +- else +- { +- start = base; +- range = free_ranges_lower_bound( start ); +- assert(range != free_ranges_end && range->end >= start); +- +- if (start < range->base) start = ROUND_ADDR( (char *)range->base + granularity_mask, granularity_mask ); +- do +- { +- if (start >= end || start < base || (char *)end - (char *)start < size) return NULL; +- if (start < range->end && start >= range->base && (char *)range->end - (char *)start >= size) break; +- if (++range == free_ranges_end) return NULL; +- start = ROUND_ADDR( (char *)range->base + granularity_mask, granularity_mask ); +- } +- while (1); +- } +- return start; +-} +- +- + /*********************************************************************** + * add_reserved_area + * +@@ -1351,8 +1209,7 @@ static void delete_view( struct file_view *view ) /* [in] View */ { if (!(view->protect & VPROT_SYSTEM)) unmap_area( view->base, view->size ); set_page_vprot( view->base, view->size, 0 ); @@ -191,7 +186,7 @@ index 2164c08f756..0939893d7c1 100644 wine_rb_remove( &views_tree, &view->entry ); *(struct file_view **)view = next_free_view; next_free_view = view; -@@ -1357,8 +1275,7 @@ static NTSTATUS create_view( struct file_view **view_ret, void *base, size_t siz +@@ -1400,8 +1257,7 @@ static NTSTATUS create_view( struct file_view **view_ret, void *base, size_t siz set_page_vprot( base, size, vprot ); wine_rb_put( &views_tree, view->base, &view->entry ); @@ -201,36 +196,47 @@ index 2164c08f756..0939893d7c1 100644 *view_ret = view; -@@ -1590,6 +1507,7 @@ struct alloc_area - int top_down; - void *limit; - void *result; -+ int unix_prot; - }; - - /*********************************************************************** -@@ -1631,6 +1549,210 @@ static int CDECL alloc_reserved_area_callback( void *start, SIZE_T size, void *a - return 0; +@@ -1646,54 +1502,219 @@ static inline void *unmap_extra_space( void *ptr, size_t total_size, size_t want + return ptr; } -+struct area_alloc_reserved -+{ +- + struct alloc_area + { + char *map_area_start, *map_area_end, *result; -+ size_t size; + size_t size; +- int top_down; +- void *limit; +- void *result; + ptrdiff_t step; + int unix_prot; + BOOL top_down; -+}; -+ + }; + +-/*********************************************************************** +- * alloc_reserved_area_callback +- * +- * Try to map some space inside a reserved area. Callback for mmap_enum_reserved_areas. +- */ +-static int CDECL alloc_reserved_area_callback( void *start, SIZE_T size, void *arg ) +static int CDECL alloc_area_in_reserved_or_between_callback( void *start, SIZE_T size, void *arg ) -+{ -+ struct area_alloc_reserved *area = arg; -+ char *end = (char *)start + size; + { +- struct alloc_area *alloc = arg; +- void *end = (char *)start + size; +- +- if (start < address_space_start) start = address_space_start; +- if (is_beyond_limit( start, size, alloc->limit )) end = alloc->limit; +- if (start >= end) return 0; + char *intersect_start, *intersect_end; ++ char *end = (char *)start + size; ++ struct alloc_area *area = arg; + char *alloc_start; -+ + +- /* make sure we don't touch the preloader reserved range */ +- if (preload_reserve_end >= start) + if (area->top_down) -+ { + { +- if (preload_reserve_end >= end) + if (area->map_area_start >= end) + return 1; + @@ -246,16 +252,24 @@ index 2164c08f756..0939893d7c1 100644 + alloc_start = ROUND_ADDR( (char *)area->map_area_end - size, granularity_mask ); + + if (alloc_start >= intersect_end) -+ { + { +- if (preload_reserve_start <= start) return 0; /* no space in that area */ +- if (preload_reserve_start < end) end = preload_reserve_start; + if ((area->result = try_map_free_area( area->map_area_start, alloc_start + size, area->step, + alloc_start, area->size, area->unix_prot ))) + return 1; -+ } + } +- else if (preload_reserve_start <= start) start = preload_reserve_end; +- else + + alloc_start = ROUND_ADDR( intersect_end - area->size, granularity_mask ); + if (alloc_start >= intersect_start) -+ { -+ if ((area->result = wine_anon_mmap( alloc_start, area->size, area->unix_prot, MAP_FIXED )) != alloc_start) + { +- /* range is split in two by the preloader reservation, try first part */ +- if ((alloc->result = find_reserved_free_area( start, preload_reserve_start, alloc->size, +- alloc->top_down ))) ++ if ((area->result = anon_mmap_fixed( alloc_start, area->size, ++ area->unix_prot, 0 )) != alloc_start) + ERR("Could not map in reserved area, alloc_start %p, size %p.\n", + alloc_start, (void *)area->size); + return 1; @@ -283,12 +297,14 @@ index 2164c08f756..0939893d7c1 100644 + { + if ((area->result = try_map_free_area( area->map_area_start, intersect_start, area->step, + area->map_area_start, area->size, area->unix_prot ))) -+ return 1; -+ } + return 1; +- /* then fall through to try second part */ +- start = preload_reserve_end; + } + + if (intersect_end - intersect_start >= area->size) + { -+ if ((area->result = wine_anon_mmap( intersect_start, area->size, area->unix_prot, MAP_FIXED )) ++ if ((area->result = anon_mmap_fixed( intersect_start, area->size, area->unix_prot, 0 )) + != intersect_start) + ERR("Could not map in reserved area.\n"); + return 1; @@ -296,66 +312,69 @@ index 2164c08f756..0939893d7c1 100644 + area->map_area_start = intersect_end; + if (area->map_area_end - area->map_area_start < area->size) + return 1; -+ } -+ -+ return 0; -+} -+ -+static void *alloc_free_area_in_range(struct area_alloc_reserved *area, char *base, char *end, -+ size_t size, int top_down, int unix_prot) + } +- if ((alloc->result = find_reserved_free_area( start, end, alloc->size, alloc->top_down ))) +- return 1; + + return 0; + } + ++static void *alloc_free_area_in_range( struct alloc_area *area, char *base, char *end ) +{ + char *start; + + TRACE("range %p-%p.\n", base, end); + -+ if (base >= end) return NULL; ++ if (base >= end) ++ return NULL; + + area->map_area_start = base; + area->map_area_end = end; + -+ if (top_down) ++ if (area->top_down) + { -+ start = ROUND_ADDR( end - size, granularity_mask ); ++ start = ROUND_ADDR( end - area->size, granularity_mask ); + if (start >= end || start < base) + return NULL; + } + else + { + start = ROUND_ADDR( base + granularity_mask, granularity_mask ); -+ if (!start || start >= end || (char *)end - (char *)start < size) ++ if (!start || start >= end || (char *)end - (char *)start < area->size) + return NULL; + } + -+ mmap_enum_reserved_areas( alloc_area_in_reserved_or_between_callback, area, top_down ); ++ mmap_enum_reserved_areas( alloc_area_in_reserved_or_between_callback, area, area->top_down ); ++ + if (area->result) + return area->result; + -+ if (top_down) ++ if (area->top_down) + { -+ start = ROUND_ADDR( area->map_area_end - size, granularity_mask ); ++ start = ROUND_ADDR( area->map_area_end - area->size, granularity_mask ); + if (start >= area->map_area_end || start < area->map_area_start) + return NULL; + -+ return try_map_free_area( area->map_area_start, start + size, area->step, -+ start, size, unix_prot ); ++ return try_map_free_area( area->map_area_start, start + area->size, area->step, ++ start, area->size, area->unix_prot ); + } + else + { + start = ROUND_ADDR( area->map_area_start + granularity_mask, granularity_mask ); + if (!start || start >= area->map_area_end -+ || area->map_area_end - start < size) ++ || area->map_area_end - start < area->size) + return NULL; + + return try_map_free_area( start, area->map_area_end, area->step, -+ start, size, unix_prot ); ++ start, area->size, area->unix_prot ); + } +} + -+static void *alloc_free_area(void *limit, size_t size, BOOL top_down, int unix_prot) ++static void *alloc_free_area( void *limit, size_t size, BOOL top_down, int unix_prot ) +{ + struct range_entry *range, *ranges_start, *ranges_end; + char *reserve_start, *reserve_end; -+ struct area_alloc_reserved area; ++ struct alloc_area area; + char *base, *end; + int ranges_inc; + @@ -374,14 +393,14 @@ index 2164c08f756..0939893d7c1 100644 + ranges_inc = 1; + } + -+ memset(&area, 0, sizeof(area)); ++ memset( &area, 0, sizeof(area) ); + area.step = top_down ? -(granularity_mask + 1) : (granularity_mask + 1); + area.size = size; + area.top_down = top_down; + area.unix_prot = unix_prot; + -+ reserve_start = ROUND_ADDR((char *)preload_reserve_start, granularity_mask); -+ reserve_end = ROUND_ADDR((char *)preload_reserve_end + granularity_mask, granularity_mask); ++ reserve_start = ROUND_ADDR( (char *)preload_reserve_start, granularity_mask ); ++ reserve_end = ROUND_ADDR( (char *)preload_reserve_end + granularity_mask, granularity_mask ); + + for (range = ranges_start; range != ranges_end; range += ranges_inc) + { @@ -390,28 +409,35 @@ index 2164c08f756..0939893d7c1 100644 + + TRACE("range %p-%p.\n", base, end); + -+ if (base < (char *)address_space_start) base = (char *)address_space_start; -+ if (end > (char *)ROUND_ADDR(limit, granularity_mask)) end = ROUND_ADDR(limit, granularity_mask); ++ if (base < (char *)address_space_start) ++ base = (char *)address_space_start; ++ if (end > (char *)ROUND_ADDR( limit, granularity_mask )) ++ end = ROUND_ADDR( limit, granularity_mask ); + + if (reserve_end >= base) + { + if (reserve_end >= end) + { -+ if (reserve_start <= base) continue; /* no space in that area */ -+ if (reserve_start < end) end = reserve_start; ++ if (reserve_start <= base) ++ continue; /* no space in that area */ ++ if (reserve_start < end) ++ end = reserve_start; ++ } ++ else if (reserve_start <= base) ++ { ++ base = reserve_end; + } -+ else if (reserve_start <= base) base = reserve_end; + else + { -+ /* range is split in two by the preloader reservation, try first part */ -+ if ((area.result = alloc_free_area_in_range(&area, base, reserve_start, size, top_down, unix_prot))) ++ /* range is split in two by the preloader reservation, try first part. */ ++ if ((area.result = alloc_free_area_in_range( &area, base, reserve_start ))) + return area.result; -+ /* then fall through to try second part */ ++ /* then fall through to try second part. */ + base = reserve_end; + } + } + -+ if ((area.result = alloc_free_area_in_range(&area, base, end, size, top_down, unix_prot))) ++ if ((area.result = alloc_free_area_in_range( &area, base, end ))) + return area.result; + } + return NULL; @@ -420,30 +446,31 @@ index 2164c08f756..0939893d7c1 100644 /*********************************************************************** * map_fixed_area * -@@ -1716,11 +1838,15 @@ static NTSTATUS map_view( struct file_view **view_ret, void *base, size_t size, - alloc.size = size; - alloc.top_down = top_down; - alloc.limit = (void*)(get_zero_bits_64_mask( zero_bits_64 ) & (UINT_PTR)user_space_limit); -+ alloc.unix_prot = get_unix_prot( vprot ); - -- if (is_win64 && !top_down) -+ if (is_win64 || zero_bits_64) - { -- /* Ditch 0x7ffffe000000 - 0x7fffffff0000 reserved area. */ -- alloc.limit = min(alloc.limit, (void *)0x7ffffe000000); -+ if (!(ptr = alloc_free_area( alloc.limit, alloc.size, top_down, alloc.unix_prot))) -+ return STATUS_NO_MEMORY; -+ -+ TRACE( "got mem in free area %p-%p\n", ptr, (char *)ptr + size ); -+ goto done; - } - - if (mmap_enum_reserved_areas( alloc_reserved_area_callback, &alloc, top_down )) -@@ -1732,15 +1858,6 @@ static NTSTATUS map_view( struct file_view **view_ret, void *base, size_t size, - goto done; - } - -- if (is_win64 || zero_bits_64) +@@ -1765,48 +1786,11 @@ static NTSTATUS map_view( struct file_view **view_ret, void *base, size_t size, + if (status != STATUS_SUCCESS) return status; + ptr = base; + } +- else ++ else if (!(ptr = alloc_free_area( (void*)(get_zero_bits_64_mask( zero_bits_64 ) ++ & (UINT_PTR)user_space_limit), size, top_down, get_unix_prot( vprot ) ))) + { +- size_t view_size = size + granularity_mask + 1; +- struct alloc_area alloc; +- +- alloc.size = size; +- alloc.top_down = top_down; +- alloc.limit = (void*)(get_zero_bits_64_mask( zero_bits_64 ) & (UINT_PTR)user_space_limit); +- +- if (mmap_enum_reserved_areas( alloc_reserved_area_callback, &alloc, top_down )) +- { +- ptr = alloc.result; +- TRACE( "got mem in reserved area %p-%p\n", ptr, (char *)ptr + size ); +- if (anon_mmap_fixed( ptr, size, get_unix_prot(vprot), 0 ) != ptr) +- return STATUS_INVALID_PARAMETER; +- goto done; +- } +- +- if (zero_bits_64) - { - if (!(ptr = map_free_area( address_space_start, alloc.limit, size, - top_down, get_unix_prot(vprot) ))) @@ -452,10 +479,26 @@ index 2164c08f756..0939893d7c1 100644 - goto done; - } - - view_size = size + granularity_mask + 1; - - for (;;) -@@ -2393,6 +2510,7 @@ void virtual_init(void) +- for (;;) +- { +- if ((ptr = anon_mmap_alloc( view_size, get_unix_prot(vprot) )) == MAP_FAILED) +- { +- if (errno == ENOMEM) return STATUS_NO_MEMORY; +- return STATUS_INVALID_PARAMETER; +- } +- TRACE( "got mem with anon mmap %p-%p\n", ptr, (char *)ptr + size ); +- /* if we got something beyond the user limit, unmap it and retry */ +- if (is_beyond_limit( ptr, view_size, user_space_limit )) add_reserved_area( ptr, view_size ); +- else break; +- } +- ptr = unmap_extra_space( ptr, view_size, size ); ++ return STATUS_NO_MEMORY; + } +-done: + status = create_view( view_ret, ptr, size, vprot ); + if (status != STATUS_SUCCESS) unmap_area( ptr, size ); + return status; +@@ -2453,6 +2437,7 @@ void virtual_init(void) if (preload_reserve_start) address_space_start = min( address_space_start, preload_reserve_start ); } @@ -464,5 +507,5 @@ index 2164c08f756..0939893d7c1 100644 /* try to find space in a reserved area for the views and pages protection table */ -- -2.27.0 +2.26.2 diff --git a/patches/ntdll-ForceBottomUpAlloc/0004-ntdll-Exclude-natively-mapped-areas-from-free-areas-.patch b/patches/ntdll-ForceBottomUpAlloc/0004-ntdll-Exclude-natively-mapped-areas-from-free-areas-.patch new file mode 100644 index 00000000..3a6882ef --- /dev/null +++ b/patches/ntdll-ForceBottomUpAlloc/0004-ntdll-Exclude-natively-mapped-areas-from-free-areas-.patch @@ -0,0 +1,256 @@ +From 479dfa05cc83b7ae8ab0f40862e74efedd98df48 Mon Sep 17 00:00:00 2001 +From: Paul Gofman +Date: Tue, 2 Jun 2020 21:06:33 +0300 +Subject: [PATCH 4/4] ntdll: Exclude natively mapped areas from free areas + list. + +Signed-off-by: Paul Gofman +--- + dlls/ntdll/unix/virtual.c | 130 ++++++++++++++++++++++++++++++-------- + 1 file changed, 103 insertions(+), 27 deletions(-) + +diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c +index e7dfc516538..dad12b5a9f2 100644 +--- a/dlls/ntdll/unix/virtual.c ++++ b/dlls/ntdll/unix/virtual.c +@@ -103,6 +103,7 @@ struct file_view + #define VPROT_WRITEWATCH 0x40 + /* per-mapping protection flags */ + #define VPROT_SYSTEM 0x0200 /* system view (underlying mmap not under our control) */ ++#define VPROT_NATIVE 0x0400 + + /* Conversion from VPROT_* to Win32 flags */ + static const BYTE VIRTUAL_Win32Flags[16] = +@@ -877,7 +878,9 @@ static void dump_view( struct file_view *view ) + BYTE prot = get_page_vprot( addr ); + + TRACE( "View: %p - %p", addr, addr + view->size - 1 ); +- if (view->protect & VPROT_SYSTEM) ++ if (view->protect & VPROT_NATIVE) ++ TRACE(" (native)\n"); ++ else if (view->protect & VPROT_SYSTEM) + TRACE( " (builtin image)\n" ); + else if (view->protect & SEC_IMAGE) + TRACE( " (image)\n" ); +@@ -1019,6 +1022,16 @@ static struct file_view *find_view_range( const void *addr, size_t size ) + return NULL; + } + ++struct alloc_area ++{ ++ char *map_area_start, *map_area_end, *result; ++ size_t size; ++ ptrdiff_t step; ++ int unix_prot; ++ BOOL top_down; ++ char *native_mapped; ++ size_t native_mapped_size; ++}; + + /*********************************************************************** + * try_map_free_area +@@ -1026,21 +1039,27 @@ static struct file_view *find_view_range( const void *addr, size_t size ) + * Try mmaping some expected free memory region, eventually stepping and + * retrying inside it, and return where it actually succeeded, or NULL. + */ +-static void* try_map_free_area( void *base, void *end, ptrdiff_t step, +- void *start, size_t size, int unix_prot ) ++static void* try_map_free_area( struct alloc_area *area, void *base, void *end, void *start ) + { ++ ptrdiff_t step = area->step; + void *ptr; + +- while (start && base <= start && (char*)start + size <= (char*)end) ++ while (start && base <= start && (char*)start + area->size <= (char*)end) + { +- if ((ptr = anon_mmap_tryfixed( start, size, unix_prot, 0 )) != MAP_FAILED) return start; ++ if ((ptr = anon_mmap_tryfixed( start, area->size, area->unix_prot, 0 )) != MAP_FAILED) return start; + TRACE( "Found free area is already mapped, start %p.\n", start ); + if (errno != EEXIST) + { + ERR( "mmap() error %s, range %p-%p, unix_prot %#x.\n", +- strerror(errno), start, (char *)start + size, unix_prot ); ++ strerror(errno), start, (char *)start + area->size, area->unix_prot ); + return NULL; + } ++ if (!area->native_mapped && step) ++ { ++ area->native_mapped = start; ++ area->native_mapped_size = step > 0 ? step : -step; ++ area->native_mapped_size = min(area->native_mapped_size, (char *)end - (char *)start); ++ } + if ((step > 0 && (char *)end - (char *)start < step) || + (step < 0 && (char *)start - (char *)base < -step) || + step == 0) +@@ -1502,15 +1521,6 @@ static inline void *unmap_extra_space( void *ptr, size_t total_size, size_t want + return ptr; + } + +-struct alloc_area +-{ +- char *map_area_start, *map_area_end, *result; +- size_t size; +- ptrdiff_t step; +- int unix_prot; +- BOOL top_down; +-}; +- + static int CDECL alloc_area_in_reserved_or_between_callback( void *start, SIZE_T size, void *arg ) + { + char *intersect_start, *intersect_end; +@@ -1536,8 +1546,8 @@ static int CDECL alloc_area_in_reserved_or_between_callback( void *start, SIZE_T + + if (alloc_start >= intersect_end) + { +- if ((area->result = try_map_free_area( area->map_area_start, alloc_start + size, area->step, +- alloc_start, area->size, area->unix_prot ))) ++ if ((area->result = try_map_free_area( area, area->map_area_start, ++ alloc_start + size, alloc_start ))) + return 1; + } + +@@ -1571,8 +1581,8 @@ static int CDECL alloc_area_in_reserved_or_between_callback( void *start, SIZE_T + + if (intersect_start - area->map_area_start >= area->size) + { +- if ((area->result = try_map_free_area( area->map_area_start, intersect_start, area->step, +- area->map_area_start, area->size, area->unix_prot ))) ++ if ((area->result = try_map_free_area( area, area->map_area_start, ++ intersect_start, area->map_area_start ))) + return 1; + } + +@@ -1627,8 +1637,7 @@ static void *alloc_free_area_in_range( struct alloc_area *area, char *base, char + if (start >= area->map_area_end || start < area->map_area_start) + return NULL; + +- return try_map_free_area( area->map_area_start, start + area->size, area->step, +- start, area->size, area->unix_prot ); ++ return try_map_free_area( area, area->map_area_start, start + area->size, start ); + } + else + { +@@ -1637,8 +1646,7 @@ static void *alloc_free_area_in_range( struct alloc_area *area, char *base, char + || area->map_area_end - start < area->size) + return NULL; + +- return try_map_free_area( start, area->map_area_end, area->step, +- start, area->size, area->unix_prot ); ++ return try_map_free_area( area, start, area->map_area_end, start ); + } + } + +@@ -1648,6 +1656,7 @@ static void *alloc_free_area( void *limit, size_t size, BOOL top_down, int unix_ + char *reserve_start, *reserve_end; + struct alloc_area area; + char *base, *end; ++ NTSTATUS status; + int ranges_inc; + + TRACE("limit %p, size %p, top_down %#x.\n", limit, (void *)size, top_down); +@@ -1703,16 +1712,67 @@ static void *alloc_free_area( void *limit, size_t size, BOOL top_down, int unix_ + { + /* range is split in two by the preloader reservation, try first part. */ + if ((area.result = alloc_free_area_in_range( &area, base, reserve_start ))) +- return area.result; ++ break; + /* then fall through to try second part. */ + base = reserve_end; + } + } + + if ((area.result = alloc_free_area_in_range( &area, base, end ))) +- return area.result; ++ break; + } +- return NULL; ++ ++ if (area.native_mapped) ++ { ++ char *native_mapped_start, *native_mapped_end; ++ ++ TRACE("Excluding %p - %p from free list.\n", ++ area.native_mapped, (char *)area.native_mapped + area.native_mapped_size ); ++ ++ native_mapped_start = ROUND_ADDR(area.native_mapped, granularity_mask); ++ native_mapped_end = ROUND_ADDR((char *)area.native_mapped + area.native_mapped_size + granularity_mask, ++ granularity_mask); ++ ++ if (area.result >= native_mapped_end || area.result + size < native_mapped_start) ++ /* In case of top down allocation try_map_free_area() result area can overlap the ++ * area previously marked as native if the latter was unmapped behind our back. */ ++ { ++ struct file_view *prev, *next; ++ ++ prev = find_view_range( native_mapped_start - 1, native_mapped_end - native_mapped_start + 2 ); ++ if (prev && (char *)prev->base >= native_mapped_end) ++ { ++ next = prev; ++ prev = WINE_RB_ENTRY_VALUE( wine_rb_prev( &next->entry ), struct file_view, entry ); ++ } ++ else if (prev) ++ { ++ next = WINE_RB_ENTRY_VALUE( wine_rb_next( &prev->entry ), struct file_view, entry ); ++ } ++ else ++ { ++ next = NULL; ++ } ++ ++ if (prev && prev->protect & VPROT_NATIVE && (char *)prev->base + prev->size >= native_mapped_start) ++ { ++ assert( (char *)prev->base + prev->size == native_mapped_start ); ++ native_mapped_start = prev->base; ++ delete_view( prev ); ++ } ++ if (next && next->protect & VPROT_NATIVE && native_mapped_end >= (char *)next->base) ++ { ++ assert( native_mapped_end == (char *)next->base ); ++ native_mapped_end = (char *)next->base + next->size; ++ delete_view( next ); ++ } ++ if ((status = create_view( &next, native_mapped_start, native_mapped_end - native_mapped_start, ++ VPROT_SYSTEM | VPROT_NATIVE ))) ++ ERR("Could not cretae view for natively mapped area, status %#x.\n", status); ++ } ++ } ++ ++ return area.result; + } + + /*********************************************************************** +@@ -1766,6 +1826,17 @@ static NTSTATUS map_fixed_area( void *base, size_t size, unsigned int vprot ) + return STATUS_SUCCESS; + } + ++static void clear_native_views(void) ++{ ++ struct file_view *view, *next_view; ++ ++ WINE_RB_FOR_EACH_ENTRY_DESTRUCTOR( view, next_view, &views_tree, struct file_view, entry ) ++ { ++ if (view->protect & VPROT_NATIVE) ++ delete_view( view ); ++ } ++} ++ + /*********************************************************************** + * map_view + * +@@ -1789,7 +1860,12 @@ static NTSTATUS map_view( struct file_view **view_ret, void *base, size_t size, + else if (!(ptr = alloc_free_area( (void*)(get_zero_bits_64_mask( zero_bits_64 ) + & (UINT_PTR)user_space_limit), size, top_down, get_unix_prot( vprot ) ))) + { +- return STATUS_NO_MEMORY; ++ WARN("Allocation failed, clearing native views.\n"); ++ ++ clear_native_views(); ++ if (!(ptr = alloc_free_area( (void*)(get_zero_bits_64_mask( zero_bits_64 ) ++ & (UINT_PTR)user_space_limit), size, top_down, get_unix_prot( vprot ) ))) ++ return STATUS_NO_MEMORY; + } + status = create_view( view_ret, ptr, size, vprot ); + if (status != STATUS_SUCCESS) unmap_area( ptr, size ); +-- +2.26.2 + diff --git a/patches/ntdll-ForceBottomUpAlloc/0006-ntdll-Permanently-exclude-natively-mapped-areas-from.patch b/patches/ntdll-ForceBottomUpAlloc/0006-ntdll-Permanently-exclude-natively-mapped-areas-from.patch deleted file mode 100644 index d173bb9e..00000000 --- a/patches/ntdll-ForceBottomUpAlloc/0006-ntdll-Permanently-exclude-natively-mapped-areas-from.patch +++ /dev/null @@ -1,66 +0,0 @@ -From eda2aae6a4845e3b0f5e4edb805fb4add4316f17 Mon Sep 17 00:00:00 2001 -From: Paul Gofman -Date: Tue, 2 Jun 2020 21:06:33 +0300 -Subject: [PATCH] ntdll: Permanently exclude natively mapped areas from free - areas list. - ---- - dlls/ntdll/unix/virtual.c | 25 +++++++++++++++++++++++++ - 1 file changed, 25 insertions(+) - -diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c -index 667401aaa93..c49c60166c2 100644 ---- a/dlls/ntdll/unix/virtual.c -+++ b/dlls/ntdll/unix/virtual.c -@@ -124,6 +124,9 @@ static const BYTE VIRTUAL_Win32Flags[16] = - static struct wine_rb_tree views_tree; - static pthread_mutex_t virtual_mutex; - -+static void *last_already_mapped; -+static size_t last_already_mapped_size; -+ - static const BOOL is_win64 = (sizeof(void *) > sizeof(int)); - static const UINT page_shift = 12; - static const UINT_PTR page_mask = 0xfff; -@@ -997,6 +1000,13 @@ static void* try_map_free_area( void *base, void *end, ptrdiff_t step, - if (ptr != (void *)-1) - munmap( ptr, size ); - -+ if (!last_already_mapped && step) -+ { -+ last_already_mapped = start; -+ last_already_mapped_size = step > 0 ? step : -step; -+ last_already_mapped_size = min(last_already_mapped_size, (char *)end - (char *)start); -+ } -+ - if ((step > 0 && (char *)end - (char *)start < step) || - (step < 0 && (char *)start - (char *)base < -step) || - step == 0) -@@ -1841,9 +1851,24 @@ static NTSTATUS map_view( struct file_view **view_ret, void *base, size_t size, - - if (is_win64 || zero_bits_64) - { -+ last_already_mapped = NULL; -+ - if (!(ptr = alloc_free_area( alloc.limit, alloc.size, top_down, alloc.unix_prot))) - return STATUS_NO_MEMORY; - -+ if (last_already_mapped) -+ { -+ void *last_mapped_start, *last_mapped_end; -+ -+ TRACE("Permanently excluding %p - %p from free list.\n", -+ last_already_mapped, (char *)last_already_mapped + last_already_mapped_size - 1); -+ last_mapped_start = ROUND_ADDR(last_already_mapped, granularity_mask); -+ last_mapped_end = ROUND_ADDR((char *)last_already_mapped + last_already_mapped_size + granularity_mask, -+ granularity_mask); -+ if (ptr > last_mapped_end || (char *)ptr + size < (char *)last_mapped_start) -+ free_ranges_remove_range(last_mapped_start, last_mapped_end, last_already_mapped); -+ } -+ - TRACE( "got mem in free area %p-%p\n", ptr, (char *)ptr + size ); - goto done; - } --- -2.27.0 - diff --git a/patches/ntdll-Junction_Points/0001-ntdll-Add-support-for-junction-point-creation.patch b/patches/ntdll-Junction_Points/0001-ntdll-Add-support-for-junction-point-creation.patch index 6239c1b1..1e7c2cac 100644 --- a/patches/ntdll-Junction_Points/0001-ntdll-Add-support-for-junction-point-creation.patch +++ b/patches/ntdll-Junction_Points/0001-ntdll-Add-support-for-junction-point-creation.patch @@ -1,4 +1,4 @@ -From cafaad67d4b5ed7985930e2a13e55d400cbbbbc9 Mon Sep 17 00:00:00 2001 +From 6e22c1cc4c615e07ac3570e152d15f22aab9eead Mon Sep 17 00:00:00 2001 From: "Erich E. Hoover" Date: Thu, 16 Jan 2014 20:56:49 -0700 Subject: [PATCH] ntdll: Add support for junction point creation. @@ -6,22 +6,18 @@ Subject: [PATCH] ntdll: Add support for junction point creation. Signed-off-by: Erich E. Hoover --- configure.ac | 2 + - dlls/ntdll/tests/file.c | 101 +++++++++++++++++++++++++++++++ - dlls/ntdll/unix/file.c | 129 ++++++++++++++++++++++++++++++++++++++++ + dlls/ntdll/tests/file.c | 101 ++++++++++++++++++++++++++ + dlls/ntdll/unix/file.c | 155 ++++++++++++++++++++++++++++++++++++++++ include/Makefile.in | 1 + - include/ntifs.h | 42 +++++++++++++ - include/wine/port.h | 9 +++ - libs/port/Makefile.in | 1 + - libs/port/renameat2.c | 55 +++++++++++++++++ - 8 files changed, 340 insertions(+) + include/ntifs.h | 42 +++++++++++ + 5 files changed, 301 insertions(+) create mode 100644 include/ntifs.h - create mode 100644 libs/port/renameat2.c diff --git a/configure.ac b/configure.ac -index d85f4dee7c..1bc2b5cbe2 100644 +index aef00416461..15c0b7e4c26 100644 --- a/configure.ac +++ b/configure.ac -@@ -2214,6 +2214,8 @@ AC_CHECK_FUNCS(\ +@@ -2230,6 +2230,8 @@ AC_CHECK_FUNCS(\ pwrite \ readdir \ readlink \ @@ -31,7 +27,7 @@ index d85f4dee7c..1bc2b5cbe2 100644 select \ setproctitle \ diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c -index 1bb71e711a..84fea2b869 100644 +index 1492797b0c9..10bdef5d810 100644 --- a/dlls/ntdll/tests/file.c +++ b/dlls/ntdll/tests/file.c @@ -38,6 +38,7 @@ @@ -42,7 +38,7 @@ index 1bb71e711a..84fea2b869 100644 #ifndef IO_COMPLETION_ALL_ACCESS #define IO_COMPLETION_ALL_ACCESS 0x001F0003 -@@ -5143,6 +5144,105 @@ static void test_mailslot_name(void) +@@ -5141,6 +5142,105 @@ static void test_mailslot_name(void) CloseHandle( device ); } @@ -148,7 +144,7 @@ index 1bb71e711a..84fea2b869 100644 START_TEST(file) { HMODULE hkernel32 = GetModuleHandleA("kernel32.dll"); -@@ -5215,5 +5315,6 @@ START_TEST(file) +@@ -5213,5 +5313,6 @@ START_TEST(file) test_ioctl(); test_query_ea(); test_flush_buffers_file(); @@ -156,7 +152,7 @@ index 1bb71e711a..84fea2b869 100644 test_mailslot_name(); } diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c -index 7667bd6398..211ebc89df 100644 +index 290e18e54c5..c2243975e4b 100644 --- a/dlls/ntdll/unix/file.c +++ b/dlls/ntdll/unix/file.c @@ -36,6 +36,7 @@ @@ -167,7 +163,7 @@ index 7667bd6398..211ebc89df 100644 #include #ifdef HAVE_MNTENT_H #include -@@ -126,6 +127,7 @@ +@@ -132,6 +133,7 @@ #include "wine/list.h" #include "wine/debug.h" #include "unix_private.h" @@ -175,7 +171,40 @@ index 7667bd6398..211ebc89df 100644 WINE_DEFAULT_DEBUG_CHANNEL(file); WINE_DECLARE_DEBUG_CHANNEL(winediag); -@@ -5643,6 +5645,116 @@ static void ignore_server_ioctl_struct_holes( ULONG code, const void *in_buffer, +@@ -457,6 +459,32 @@ static int xattr_set( const char *path, const char *name, void *value, size_t si + #endif + } + ++#ifndef HAVE_RENAMEAT ++int renameat( int olddirfd, const char *oldpath, int newdirfd, const char *newpath ) ++{ ++ errno = ENOSYS; ++ return -1; ++} ++#endif ++ ++#ifndef HAVE_RENAMEAT2 ++int renameat2( int olddirfd, const char *oldpath, int newdirfd, const char *newpath, ++ unsigned int flags ) ++{ ++ if (flags == 0) ++ return renameat( olddirfd, oldpath, newdirfd, newpath ); ++#if defined(__NR_renameat2) ++ return syscall( __NR_renameat2, olddirfd, oldpath, newdirfd, newpath, flags ); ++#elif defined(RENAME_SWAP) ++ return renameatx_np(olddirfd, oldpath, newdirfd, newpath, ++ (flags & RENAME_EXCHANGE ? RENAME_SWAP : 0)); ++#else ++ errno = ENOSYS; ++ return -1; ++#endif ++} ++#endif /* HAVE_RENAMEAT2 */ ++ + /* get space from the current directory data buffer, allocating a new one if necessary */ + static void *get_dir_data_space( struct dir_data *data, unsigned int size ) + { +@@ -5731,6 +5759,116 @@ static void ignore_server_ioctl_struct_holes( ULONG code, const void *in_buffer, } @@ -292,7 +321,7 @@ index 7667bd6398..211ebc89df 100644 /****************************************************************************** * NtFsControlFile (NTDLL.@) */ -@@ -5725,6 +5837,23 @@ NTSTATUS WINAPI NtFsControlFile( HANDLE handle, HANDLE event, PIO_APC_ROUTINE ap +@@ -5813,6 +5951,23 @@ NTSTATUS WINAPI NtFsControlFile( HANDLE handle, HANDLE event, PIO_APC_ROUTINE ap break; } @@ -317,10 +346,10 @@ index 7667bd6398..211ebc89df 100644 TRACE("FSCTL_SET_SPARSE: Ignoring request\n"); io->Information = 0; diff --git a/include/Makefile.in b/include/Makefile.in -index 216adf0d7a..7dc16c230b 100644 +index 49b174ed319..2dbf84e6c36 100644 --- a/include/Makefile.in +++ b/include/Makefile.in -@@ -520,6 +520,7 @@ SOURCES = \ +@@ -523,6 +523,7 @@ SOURCES = \ ntddvdeo.h \ ntdef.h \ ntdsapi.h \ @@ -330,7 +359,7 @@ index 216adf0d7a..7dc16c230b 100644 ntsecapi.h \ diff --git a/include/ntifs.h b/include/ntifs.h new file mode 100644 -index 0000000000..21d42e1732 +index 00000000000..21d42e17325 --- /dev/null +++ b/include/ntifs.h @@ -0,0 +1,42 @@ @@ -376,99 +405,6 @@ index 0000000000..21d42e1732 +} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER; + +#endif /* __WINE_NTIFS_H */ -diff --git a/include/wine/port.h b/include/wine/port.h -index 930efeeea1..7d2c738870 100644 ---- a/include/wine/port.h -+++ b/include/wine/port.h -@@ -334,6 +334,15 @@ double rint(double x); - float rintf(float x); - #endif - -+#ifndef RENAME_EXCHANGE -+#define RENAME_EXCHANGE (1 << 1) -+#endif /* RENAME_EXCHANGE */ -+ -+#ifndef HAVE_RENAMEAT2 -+int renameat2( int olddirfd, const char *oldpath, int newdirfd, const char *newpath, -+ unsigned int flags ); -+#endif /* HAVE_RENAMEAT2 */ -+ - #ifndef HAVE_STATVFS - int statvfs( const char *path, struct statvfs *buf ); - #endif -diff --git a/libs/port/Makefile.in b/libs/port/Makefile.in -index d1de285d52..4b1ecab751 100644 ---- a/libs/port/Makefile.in -+++ b/libs/port/Makefile.in -@@ -14,6 +14,7 @@ C_SRCS = \ - pread.c \ - pwrite.c \ - readlink.c \ -+ renameat2.c \ - rint.c \ - spawn.c \ - statvfs.c \ -diff --git a/libs/port/renameat2.c b/libs/port/renameat2.c -new file mode 100644 -index 0000000000..f46f407ec7 ---- /dev/null -+++ b/libs/port/renameat2.c -@@ -0,0 +1,55 @@ -+/* -+ * renameat2 function -+ * -+ * Copyright 2015-2019 Erich E. Hoover -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA -+ */ -+ -+#include "config.h" -+#include "wine/port.h" -+ -+#ifdef HAVE_SYS_SYSCALL_H -+# include -+#endif -+ -+#include -+#include -+ -+#ifndef HAVE_RENAMEAT -+int renameat( int olddirfd, const char *oldpath, int newdirfd, const char *newpath ) -+{ -+ errno = ENOSYS; -+ return -1; -+} -+#endif -+ -+#ifndef HAVE_RENAMEAT2 -+int renameat2( int olddirfd, const char *oldpath, int newdirfd, const char *newpath, -+ unsigned int flags ) -+{ -+ if (flags == 0) -+ return renameat( olddirfd, oldpath, newdirfd, newpath ); -+#if defined(__NR_renameat2) -+ return syscall( __NR_renameat2, olddirfd, oldpath, newdirfd, newpath, flags ); -+#elif defined(RENAME_SWAP) -+ return renameatx_np(olddirfd, oldpath, newdirfd, newpath, -+ (flags & RENAME_EXCHANGE ? RENAME_SWAP : 0)); -+#else -+ errno = ENOSYS; -+ return -1; -+#endif -+} -+#endif /* HAVE_RENAMEAT2 */ -- -2.27.0 +2.28.0 diff --git a/patches/ntdll-WRITECOPY/0004-ntdll-Properly-handle-PAGE_WRITECOPY-protection.-try.patch b/patches/ntdll-WRITECOPY/0004-ntdll-Properly-handle-PAGE_WRITECOPY-protection.-try.patch index 0608a14d..6d7f481f 100644 --- a/patches/ntdll-WRITECOPY/0004-ntdll-Properly-handle-PAGE_WRITECOPY-protection.-try.patch +++ b/patches/ntdll-WRITECOPY/0004-ntdll-Properly-handle-PAGE_WRITECOPY-protection.-try.patch @@ -1,4 +1,4 @@ -From 683ec6017757a1f2cdd33feec608aad6a9022322 Mon Sep 17 00:00:00 2001 +From c8020cc027be026da2aef0ed866a59629d4e053e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20M=C3=BCller?= Date: Sat, 4 Oct 2014 03:22:09 +0200 Subject: [PATCH] ntdll: Properly handle PAGE_WRITECOPY protection. (try 5) @@ -9,11 +9,11 @@ For now, only enable it when a special environment variable is set. 1 file changed, 39 insertions(+), 7 deletions(-) diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c -index 54c6b732d0f..cd0e343c46b 100644 +index 563ed01deb5..79f6af38b00 100644 --- a/dlls/ntdll/unix/virtual.c +++ b/dlls/ntdll/unix/virtual.c -@@ -363,6 +363,21 @@ static int mmap_enum_reserved_areas( int (CDECL *enum_func)(void *base, SIZE_T s - return ret; +@@ -490,6 +490,21 @@ static void reserve_area( void *addr, void *end ) + #endif /* __APPLE__ */ } +/* This might look like a hack, but it actually isn't - the 'experimental' version @@ -32,9 +32,9 @@ index 54c6b732d0f..cd0e343c46b 100644 + return enabled; +} - static void reserve_area( void *addr, void *end ) + static void mmap_init( const struct preload_info *preload_info ) { -@@ -803,8 +818,19 @@ static int get_unix_prot( BYTE vprot ) +@@ -847,8 +862,19 @@ static int get_unix_prot( BYTE vprot ) { if (vprot & VPROT_READ) prot |= PROT_READ; if (vprot & VPROT_WRITE) prot |= PROT_WRITE | PROT_READ; @@ -55,7 +55,7 @@ index 54c6b732d0f..cd0e343c46b 100644 if (vprot & VPROT_WRITEWATCH) prot &= ~PROT_WRITE; } if (!prot) prot = PROT_NONE; -@@ -1550,7 +1576,7 @@ static void update_write_watches( void *base, size_t size, size_t accessed_size +@@ -1577,7 +1603,7 @@ static void update_write_watches( void *base, size_t size, size_t accessed_size { TRACE( "updating watch %p-%p-%p\n", base, (char *)base + accessed_size, (char *)base + size ); /* clear write watch flag on accessed pages */ @@ -64,7 +64,7 @@ index 54c6b732d0f..cd0e343c46b 100644 /* restore page protections on the entire range */ mprotect_range( base, size, 0, 0 ); } -@@ -2904,12 +2930,13 @@ NTSTATUS virtual_handle_fault( void *addr, DWORD err, void *stack ) +@@ -2919,12 +2945,13 @@ NTSTATUS virtual_handle_fault( void *addr, DWORD err, void *stack ) set_page_vprot_bits( page, page_size, 0, VPROT_WRITEWATCH ); mprotect_range( page, page_size, 0, 0 ); } @@ -82,7 +82,7 @@ index 54c6b732d0f..cd0e343c46b 100644 } pthread_mutex_unlock( &virtual_mutex ); return ret; -@@ -2986,11 +3013,16 @@ static NTSTATUS check_write_access( void *base, size_t size, BOOL *has_write_wat +@@ -3001,11 +3028,16 @@ static NTSTATUS check_write_access( void *base, size_t size, BOOL *has_write_wat { BYTE vprot = get_page_vprot( addr + i ); if (vprot & VPROT_WRITEWATCH) *has_write_watch = TRUE; diff --git a/patches/ntdll-WRITECOPY/0005-ntdll-Track-if-a-WRITECOPY-page-has-been-modified.patch b/patches/ntdll-WRITECOPY/0005-ntdll-Track-if-a-WRITECOPY-page-has-been-modified.patch index 0998f0c5..76685150 100644 --- a/patches/ntdll-WRITECOPY/0005-ntdll-Track-if-a-WRITECOPY-page-has-been-modified.patch +++ b/patches/ntdll-WRITECOPY/0005-ntdll-Track-if-a-WRITECOPY-page-has-been-modified.patch @@ -1,4 +1,4 @@ -From 065015c3bc777193f4d44ca7969995a9ec563ce2 Mon Sep 17 00:00:00 2001 +From 6af98b9092396f69ac66c4659581436d9c6c7183 Mon Sep 17 00:00:00 2001 From: Andrew Wesie Date: Fri, 24 Apr 2020 14:55:14 -0500 Subject: [PATCH] ntdll: Track if a WRITECOPY page has been modified. @@ -12,18 +12,18 @@ Signed-off-by: Andrew Wesie 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c -index f0ec65d12704..98c5aad578c6 100644 +index f3d7c24515f..045d10d92be 100644 --- a/dlls/ntdll/unix/virtual.c +++ b/dlls/ntdll/unix/virtual.c -@@ -97,6 +97,7 @@ struct file_view +@@ -101,6 +101,7 @@ struct file_view #define VPROT_GUARD 0x10 #define VPROT_COMMITTED 0x20 #define VPROT_WRITEWATCH 0x40 +#define VPROT_WRITTEN 0x80 /* per-mapping protection flags */ #define VPROT_SYSTEM 0x0200 /* system view (underlying mmap not under our control) */ - -@@ -820,7 +821,7 @@ static int get_unix_prot( BYTE vprot ) + #define VPROT_NATIVE 0x0400 +@@ -871,7 +872,7 @@ static int get_unix_prot( BYTE vprot ) #if defined(__i386__) if (vprot & VPROT_WRITECOPY) { @@ -32,7 +32,7 @@ index f0ec65d12704..98c5aad578c6 100644 prot = (prot & ~PROT_WRITE) | PROT_READ; else prot |= PROT_WRITE | PROT_READ; -@@ -1406,7 +1407,11 @@ static NTSTATUS create_view( struct file_view **view_ret, void *base, size_t siz +@@ -1315,7 +1316,11 @@ static NTSTATUS create_view( struct file_view **view_ret, void *base, size_t siz */ static DWORD get_win32_prot( BYTE vprot, unsigned int map_prot ) { @@ -45,7 +45,7 @@ index f0ec65d12704..98c5aad578c6 100644 if (vprot & VPROT_GUARD) ret |= PAGE_GUARD; if (map_prot & SEC_NOCACHE) ret |= PAGE_NOCACHE; return ret; -@@ -1517,7 +1522,7 @@ static BOOL set_vprot( struct file_view *view, void *base, size_t size, BYTE vpr +@@ -1426,7 +1431,7 @@ static BOOL set_vprot( struct file_view *view, void *base, size_t size, BYTE vpr if (view->protect & VPROT_WRITEWATCH) { /* each page may need different protections depending on write watch flag */ @@ -54,7 +54,7 @@ index f0ec65d12704..98c5aad578c6 100644 mprotect_range( base, size, 0, 0 ); return TRUE; } -@@ -1533,10 +1538,18 @@ static BOOL set_vprot( struct file_view *view, void *base, size_t size, BYTE vpr +@@ -1442,10 +1447,18 @@ static BOOL set_vprot( struct file_view *view, void *base, size_t size, BYTE vpr return TRUE; } @@ -74,7 +74,7 @@ index f0ec65d12704..98c5aad578c6 100644 return TRUE; } -@@ -2928,7 +2941,7 @@ NTSTATUS virtual_handle_fault( void *addr, DWORD err, void *stack ) +@@ -3013,7 +3026,7 @@ NTSTATUS virtual_handle_fault( void *addr, DWORD err, void *stack ) } if (vprot & VPROT_WRITECOPY) { @@ -83,7 +83,7 @@ index f0ec65d12704..98c5aad578c6 100644 mprotect_range( page, page_size, 0, 0 ); } /* ignore fault if page is writable now */ -@@ -3873,7 +3886,7 @@ static NTSTATUS get_basic_memory_info( HANDLE process, LPCVOID addr, +@@ -3955,7 +3968,7 @@ static NTSTATUS get_basic_memory_info( HANDLE process, LPCVOID addr, else if (view->protect & (SEC_FILE | SEC_RESERVE | SEC_COMMIT)) info->Type = MEM_MAPPED; else info->Type = MEM_PRIVATE; for (ptr = base; ptr < base + range_size; ptr += page_size) @@ -93,5 +93,5 @@ index f0ec65d12704..98c5aad578c6 100644 } server_leave_uninterrupted_section( &virtual_mutex, &sigset ); -- -2.20.1 +2.28.0 diff --git a/patches/ntdll-WRITECOPY/0008-ntdll-Fallback-to-copy-pages-for-WRITECOPY.patch b/patches/ntdll-WRITECOPY/0008-ntdll-Fallback-to-copy-pages-for-WRITECOPY.patch index 8bd52eed..f6a71373 100644 --- a/patches/ntdll-WRITECOPY/0008-ntdll-Fallback-to-copy-pages-for-WRITECOPY.patch +++ b/patches/ntdll-WRITECOPY/0008-ntdll-Fallback-to-copy-pages-for-WRITECOPY.patch @@ -1,4 +1,4 @@ -From 5749f2c2ddcf9dc0dc5d1257b4829bd6bdda4c7e Mon Sep 17 00:00:00 2001 +From 86b7f01ebe8d0cccd81a1d9913c9a42966ea7d3c Mon Sep 17 00:00:00 2001 From: Andrew Wesie Date: Tue, 28 Apr 2020 03:27:16 -0500 Subject: [PATCH] ntdll: Fallback to copy pages for WRITECOPY. @@ -16,10 +16,10 @@ Signed-off-by: Andrew Wesie 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c -index 8b3f93b70d41..c53b87076075 100644 +index 148da16f34d..1ca19a24003 100644 --- a/dlls/ntdll/unix/virtual.c +++ b/dlls/ntdll/unix/virtual.c -@@ -1538,8 +1538,9 @@ static BOOL set_vprot( struct file_view *view, void *base, size_t size, BYTE vpr +@@ -1447,8 +1447,9 @@ static BOOL set_vprot( struct file_view *view, void *base, size_t size, BYTE vpr return TRUE; } @@ -31,7 +31,7 @@ index 8b3f93b70d41..c53b87076075 100644 unix_prot |= PROT_WRITE; if (mprotect_exec( base, size, unix_prot )) /* FIXME: last error */ -@@ -2941,10 +2942,26 @@ NTSTATUS virtual_handle_fault( void *addr, DWORD err, void *stack ) +@@ -3026,10 +3027,26 @@ NTSTATUS virtual_handle_fault( void *addr, DWORD err, void *stack ) set_page_vprot_bits( page, page_size, 0, VPROT_WRITEWATCH ); mprotect_range( page, page_size, 0, 0 ); } @@ -50,16 +50,16 @@ index 8b3f93b70d41..c53b87076075 100644 + { + static BYTE *temp_page = NULL; + if (!temp_page) -+ temp_page = wine_anon_mmap( NULL, page_size, PROT_READ | PROT_WRITE, 0 ); ++ temp_page = anon_mmap_alloc( page_size, PROT_READ | PROT_WRITE ); + + /* original mapping is shared, replace with a private page */ + memcpy( temp_page, page, page_size ); -+ wine_anon_mmap( page, page_size, get_unix_prot( vprot | VPROT_WRITE | VPROT_WRITTEN ), MAP_FIXED ); ++ anon_mmap_fixed( page, page_size, get_unix_prot( vprot | VPROT_WRITE | VPROT_WRITTEN ), 0 ); + memcpy( page, temp_page, page_size ); + } } /* ignore fault if page is writable now */ if (get_unix_prot( get_page_vprot( page ) ) & PROT_WRITE) ret = STATUS_SUCCESS; -- -2.20.1 +2.28.0 diff --git a/patches/ntdll-WRITECOPY/definition b/patches/ntdll-WRITECOPY/definition index d5806b79..9f26ca0c 100644 --- a/patches/ntdll-WRITECOPY/definition +++ b/patches/ntdll-WRITECOPY/definition @@ -1,5 +1,5 @@ Fixes: [29384] Multiple applications expect correct handling of WRITECOPY memory protection (Voobly fails to launch Age of Empires II, MSYS2) - +Depends: ntdll-ForceBottomUpAlloc # Causes regressions? # https://bugs.wine-staging.com/show_bug.cgi?id=207 # https://bugs.wine-staging.com/show_bug.cgi?id=521 diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index ef5d4adb..b9e83750 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -52,7 +52,7 @@ usage() # Get the upstream commit sha upstream_commit() { - echo "87f41e6b408dd01055ff6a378b90d089d61ec370" + echo "314368e6c442f043ebfc22b70c1113e4e6232c04" } # Show version information @@ -1661,6 +1661,13 @@ if test "$enable_ntdll_Builtin_Prot" -eq 1; then enable_ntdll_WRITECOPY=1 fi +if test "$enable_ntdll_WRITECOPY" -eq 1; then + if test "$enable_ntdll_ForceBottomUpAlloc" -gt 1; then + abort "Patchset ntdll-ForceBottomUpAlloc disabled, but ntdll-WRITECOPY depends on that." + fi + enable_ntdll_ForceBottomUpAlloc=1 +fi + if test "$enable_ntdll_ApiSetMap" -eq 1; then if test "$enable_ntdll_FLS_Callbacks" -gt 1; then abort "Patchset ntdll-FLS_Callbacks disabled, but ntdll-ApiSetMap depends on that." @@ -3415,8 +3422,34 @@ if test "$enable_ntdll_ApiSetMap" -eq 1; then ) >> "$patchlist" fi +# Patchset ntdll-ForceBottomUpAlloc +# | +# | This patchset fixes the following Wine bugs: +# | * [#48175] AION (64 bit) - crashes in crysystem.dll.CryFree() due to high memory pointers allocated +# | * [#46568] 64-bit msxml6.dll from Microsoft Core XML Services 6.0 redist package fails to load (Wine doesn't respect +# | 44-bit user-mode VA limitation from Windows < 8.1) +# | +# | Modified files: +# | * dlls/ntdll/unix/virtual.c +# | +if test "$enable_ntdll_ForceBottomUpAlloc" -eq 1; then + patch_apply ntdll-ForceBottomUpAlloc/0001-ntdll-Increase-step-after-failed-map-attempt-in-try_.patch + patch_apply ntdll-ForceBottomUpAlloc/0002-ntdll-Increase-free-ranges-view-block-size-on-64-bit.patch + patch_apply ntdll-ForceBottomUpAlloc/0003-ntdll-Force-virtual-memory-allocation-order.patch + patch_apply ntdll-ForceBottomUpAlloc/0004-ntdll-Exclude-natively-mapped-areas-from-free-areas-.patch + ( + printf '%s\n' '+ { "Paul Gofman", "ntdll: Increase step after failed map attempt in try_map_free_area().", 1 },'; + printf '%s\n' '+ { "Paul Gofman", "ntdll: Increase free ranges view block size on 64 bit.", 1 },'; + printf '%s\n' '+ { "Paul Gofman", "ntdll: Force virtual memory allocation order.", 1 },'; + printf '%s\n' '+ { "Paul Gofman", "ntdll: Exclude natively mapped areas from free areas list.", 1 },'; + ) >> "$patchlist" +fi + # Patchset ntdll-WRITECOPY # | +# | This patchset has the following (direct or indirect) dependencies: +# | * ntdll-ForceBottomUpAlloc +# | # | This patchset fixes the following Wine bugs: # | * [#29384] Multiple applications expect correct handling of WRITECOPY memory protection (Voobly fails to launch Age of # | Empires II, MSYS2) @@ -3453,7 +3486,7 @@ fi # Patchset ntdll-Builtin_Prot # | # | This patchset has the following (direct or indirect) dependencies: -# | * ntdll-WRITECOPY +# | * ntdll-ForceBottomUpAlloc, ntdll-WRITECOPY # | # | This patchset fixes the following Wine bugs: # | * [#44650] Fix holes in ELF mappings @@ -3491,8 +3524,7 @@ fi # | * [#15679] cygwin symlinks not working in wine # | # | Modified files: -# | * configure.ac, dlls/ntdll/tests/directory.c, dlls/ntdll/tests/file.c, dlls/ntdll/unix/file.c, include/wine/port.h, -# | libs/port/Makefile.in, libs/port/xattr.c +# | * configure.ac, dlls/ntdll/tests/directory.c, dlls/ntdll/tests/file.c, dlls/ntdll/unix/file.c # | if test "$enable_ntdll_DOS_Attributes" -eq 1; then patch_apply ntdll-DOS_Attributes/0001-ntdll-Implement-retrieving-DOS-attributes-in-fd_-get.patch @@ -3567,29 +3599,6 @@ if test "$enable_ntdll_Fix_Alignment" -eq 1; then ) >> "$patchlist" fi -# Patchset ntdll-ForceBottomUpAlloc -# | -# | This patchset fixes the following Wine bugs: -# | * [#48175] AION (64 bit) - crashes in crysystem.dll.CryFree() due to high memory pointers allocated -# | * [#46568] 64-bit msxml6.dll from Microsoft Core XML Services 6.0 redist package fails to load (Wine doesn't respect -# | 44-bit user-mode VA limitation from Windows < 8.1) -# | -# | Modified files: -# | * dlls/ntdll/unix/virtual.c -# | -if test "$enable_ntdll_ForceBottomUpAlloc" -eq 1; then - patch_apply ntdll-ForceBottomUpAlloc/0003-ntdll-Force-bottom-up-allocation-order-for-64-bit-ar.patch - patch_apply ntdll-ForceBottomUpAlloc/0004-ntdll-Increase-step-after-failed-map-attempt-in-try_.patch - patch_apply ntdll-ForceBottomUpAlloc/0005-ntdll-Use-free-area-list-for-virtual-memory-allocati.patch - patch_apply ntdll-ForceBottomUpAlloc/0006-ntdll-Permanently-exclude-natively-mapped-areas-from.patch - ( - printf '%s\n' '+ { "Paul Gofman", "ntdll: Force bottom up allocation order for 64 bit arch unless top down is requested.", 1 },'; - printf '%s\n' '+ { "Paul Gofman", "ntdll: Increase step after failed map attempt in try_map_free_area().", 1 },'; - printf '%s\n' '+ { "Paul Gofman", "ntdll: Use free area list for virtual memory allocation.", 1 },'; - printf '%s\n' '+ { "Paul Gofman", "ntdll: Permanently exclude natively mapped areas from free areas list.", 1 },'; - ) >> "$patchlist" -fi - # Patchset ntdll-HashLinks # | # | Modified files: @@ -3677,8 +3686,7 @@ fi # | Modified files: # | * configure.ac, dlls/kernel32/tests/path.c, dlls/kernelbase/file.c, dlls/msvcp120/tests/msvcp120.c, # | dlls/msvcp140/tests/msvcp140.c, dlls/ntdll/tests/file.c, dlls/ntdll/unix/file.c, include/Makefile.in, include/ntifs.h, -# | include/wine/port.h, include/winternl.h, libs/port/Makefile.in, libs/port/renameat2.c, programs/cmd/builtins.c, -# | programs/cmd/directory.c, server/fd.c, server/protocol.def +# | include/winternl.h, programs/cmd/builtins.c, programs/cmd/directory.c, server/fd.c, server/protocol.def # | if test "$enable_ntdll_Junction_Points" -eq 1; then patch_apply ntdll-Junction_Points/0001-ntdll-Add-support-for-junction-point-creation.patch @@ -4420,8 +4428,7 @@ fi # | * [#33576] Support for stored file ACLs # | # | Modified files: -# | * dlls/advapi32/tests/security.c, include/wine/port.h, server/change.c, server/file.c, server/file.h, server/object.c, -# | server/object.h +# | * dlls/advapi32/tests/security.c, server/change.c, server/file.c, server/file.h, server/object.c, server/object.h # | if test "$enable_server_Stored_ACLs" -eq 1; then patch_apply server-Stored_ACLs/0001-server-Unify-the-storage-of-security-attributes-for-.patch diff --git a/patches/server-Stored_ACLs/0005-server-Store-file-security-attributes-with-extended-.patch b/patches/server-Stored_ACLs/0005-server-Store-file-security-attributes-with-extended-.patch index ab2fe924..8ef1abc3 100644 --- a/patches/server-Stored_ACLs/0005-server-Store-file-security-attributes-with-extended-.patch +++ b/patches/server-Stored_ACLs/0005-server-Store-file-security-attributes-with-extended-.patch @@ -1,30 +1,15 @@ -From f574af9e0d14b048ff0b410831f226cf764c5d05 Mon Sep 17 00:00:00 2001 +From a36fb419f7a4c4023507b985ed54387354596445 Mon Sep 17 00:00:00 2001 From: "Erich E. Hoover" Date: Mon, 30 Mar 2015 13:04:23 +0200 Subject: [PATCH] server: Store file security attributes with extended file attributes. (v8) --- - include/wine/port.h | 3 +++ - server/file.c | 34 ++++++++++++++++++++++++++++++++++ - 2 files changed, 37 insertions(+) + server/file.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 63 insertions(+) -diff --git a/include/wine/port.h b/include/wine/port.h -index 7d2c73887073..145f78bebdba 100644 ---- a/include/wine/port.h -+++ b/include/wine/port.h -@@ -366,6 +366,9 @@ extern int mkstemps(char *template, int suffix_len); - #ifndef XATTR_USER_PREFIX - # define XATTR_USER_PREFIX "user." - #endif -+#ifndef XATTR_SIZE_MAX -+# define XATTR_SIZE_MAX 65536 -+#endif - - extern int xattr_fget( int filedes, const char *name, void *value, size_t size ); - extern int xattr_fremove( int filedes, const char *name ); diff --git a/server/file.c b/server/file.c -index 9c94f9ba2bba..5e542b62e77e 100644 +index f0253115c5d..5df300a9a73 100644 --- a/server/file.c +++ b/server/file.c @@ -32,6 +32,7 @@ @@ -35,10 +20,30 @@ index 9c94f9ba2bba..5e542b62e77e 100644 #include #ifdef HAVE_UTIME_H #include -@@ -52,6 +53,14 @@ +@@ -39,6 +40,12 @@ + #ifdef HAVE_POLL_H + #include + #endif ++#ifdef HAVE_ATTR_XATTR_H ++#undef XATTR_ADDITIONAL_OPTIONS ++#include ++#elif defined(HAVE_SYS_XATTR_H) ++#include ++#endif + + #include "ntstatus.h" + #define WIN32_NO_STATUS +@@ -52,6 +59,21 @@ #include "process.h" #include "security.h" ++#ifndef XATTR_USER_PREFIX ++#define XATTR_USER_PREFIX "user." ++#endif ++#ifndef XATTR_SIZE_MAX ++#define XATTR_SIZE_MAX 65536 ++#endif ++ +/* We intentionally do not match the Samba 4 extended attribute for NT security descriptors (SDs): + * 1) Samba stores this information using an internal data structure (we use a flat NT SD). + * 2) Samba uses the attribute "security.NTACL". This attribute is within a namespace that only @@ -50,10 +55,26 @@ index 9c94f9ba2bba..5e542b62e77e 100644 struct file { struct object obj; /* object header */ -@@ -204,6 +213,28 @@ int is_file_executable( const char *name ) +@@ -203,6 +225,44 @@ int is_file_executable( const char *name ) return len >= 4 && (!strcasecmp( name + len - 4, ".exe") || !strcasecmp( name + len - 4, ".com" )); } ++static int xattr_fset( int filedes, const char *name, void *value, size_t size ) ++{ ++#if defined(XATTR_ADDITIONAL_OPTIONS) ++ return fsetxattr( filedes, name, value, size, 0, 0 ); ++#elif defined(HAVE_SYS_XATTR_H) || defined(HAVE_ATTR_XATTR_H) ++ return fsetxattr( filedes, name, value, size, 0 ); ++#elif defined(HAVE_SYS_EXTATTR_H) ++ if (!xattr_valid_namespace( name )) return -1; ++ return extattr_set_fd( filedes, EXTATTR_NAMESPACE_USER, &name[XATTR_USER_PREFIX_LEN], ++ value, size ); ++#else ++ errno = ENOSYS; ++ return -1; ++#endif ++} ++ +static void set_xattr_sd( int fd, const struct security_descriptor *sd ) +{ + char buffer[XATTR_SIZE_MAX]; @@ -79,7 +100,7 @@ index 9c94f9ba2bba..5e542b62e77e 100644 static struct object *create_file( struct fd *root, const char *nameptr, data_size_t len, unsigned int access, unsigned int sharing, int create, unsigned int options, unsigned int attrs, -@@ -623,6 +654,9 @@ int set_file_sd( struct object *obj, struct fd *fd, mode_t *mode, uid_t *uid, +@@ -622,6 +682,9 @@ int set_file_sd( struct object *obj, struct fd *fd, mode_t *mode, uid_t *uid, *mode = (*mode & S_IFMT) | new_mode; } @@ -90,5 +111,5 @@ index 9c94f9ba2bba..5e542b62e77e 100644 obj->sd = new_sd; return 1; -- -2.26.2 +2.28.0 diff --git a/patches/server-Stored_ACLs/0007-server-Retrieve-file-security-attributes-with-extend.patch b/patches/server-Stored_ACLs/0007-server-Retrieve-file-security-attributes-with-extend.patch index 5aedd2d6..51a4ebe2 100644 --- a/patches/server-Stored_ACLs/0007-server-Retrieve-file-security-attributes-with-extend.patch +++ b/patches/server-Stored_ACLs/0007-server-Retrieve-file-security-attributes-with-extend.patch @@ -1,19 +1,19 @@ -From 025a3715592c3f4fe8a3300422e6387f82f38792 Mon Sep 17 00:00:00 2001 +From f6264626e3a00195c740cd339043d48372005f17 Mon Sep 17 00:00:00 2001 From: "Erich E. Hoover" Date: Fri, 18 Apr 2014 14:01:35 -0600 Subject: [PATCH] server: Retrieve file security attributes with extended file attributes. (try 7) --- - dlls/advapi32/tests/security.c | 19 +++++++++---------- - server/file.c | 30 +++++++++++++++++++++++++++--- - 2 files changed, 36 insertions(+), 13 deletions(-) + dlls/advapi32/tests/security.c | 19 +++++++------- + server/file.c | 46 +++++++++++++++++++++++++++++++--- + 2 files changed, 52 insertions(+), 13 deletions(-) diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c -index a27cd41cde81..6968c9a3d2ac 100644 +index b79ea481e64..849a6b0b032 100644 --- a/dlls/advapi32/tests/security.c +++ b/dlls/advapi32/tests/security.c -@@ -3639,7 +3639,7 @@ static void test_CreateDirectoryA(void) +@@ -3648,7 +3648,7 @@ static void test_CreateDirectoryA(void) } ok(!error, "GetNamedSecurityInfo failed with error %d\n", error); test_inherited_dacl(pDacl, admin_sid, user_sid, OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE, @@ -22,7 +22,7 @@ index a27cd41cde81..6968c9a3d2ac 100644 LocalFree(pSD); /* Test inheritance of ACLs in CreateFile without security descriptor */ -@@ -4093,21 +4093,20 @@ static void test_GetNamedSecurityInfoA(void) +@@ -4102,21 +4102,20 @@ static void test_GetNamedSecurityInfoA(void) bret = GetAce(pDacl, 0, (VOID **)&ace); ok(bret, "Failed to get Current User ACE.\n"); bret = EqualSid(&ace->SidStart, user_sid); @@ -50,7 +50,7 @@ index a27cd41cde81..6968c9a3d2ac 100644 ok(((ACE_HEADER *)ace)->AceFlags == 0, "Administators Group ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags); ok(ace->Mask == 0x1f01ff || broken(ace->Mask == GENERIC_ALL) /* win2k */, -@@ -4134,8 +4133,8 @@ static void test_GetNamedSecurityInfoA(void) +@@ -4143,8 +4142,8 @@ static void test_GetNamedSecurityInfoA(void) { bret = GetAce(pDacl, 0, (VOID **)&ace); ok(bret, "Failed to get ACE.\n"); @@ -62,10 +62,33 @@ index a27cd41cde81..6968c9a3d2ac 100644 LocalFree(pSD); diff --git a/server/file.c b/server/file.c -index 818bd42af76a..53d59d3e8e2a 100644 +index a659b1c7872..19d04e050ed 100644 --- a/server/file.c +++ b/server/file.c -@@ -495,6 +495,29 @@ static void convert_generic_sd( struct security_descriptor *sd ) +@@ -225,6 +225,22 @@ int is_file_executable( const char *name ) + return len >= 4 && (!strcasecmp( name + len - 4, ".exe") || !strcasecmp( name + len - 4, ".com" )); + } + ++static int xattr_fget( int filedes, const char *name, void *value, size_t size ) ++{ ++#if defined(XATTR_ADDITIONAL_OPTIONS) ++ return fgetxattr( filedes, name, value, size, 0, 0 ); ++#elif defined(HAVE_SYS_XATTR_H) || defined(HAVE_ATTR_XATTR_H) ++ return fgetxattr( filedes, name, value, size ); ++#elif defined(HAVE_SYS_EXTATTR_H) ++ if (!xattr_valid_namespace( name )) return -1; ++ return extattr_get_fd( filedes, EXTATTR_NAMESPACE_USER, &name[XATTR_USER_PREFIX_LEN], ++ value, size ); ++#else ++ errno = ENOSYS; ++ return -1; ++#endif ++} ++ + static int xattr_fset( int filedes, const char *name, void *value, size_t size ) + { + #if defined(XATTR_ADDITIONAL_OPTIONS) +@@ -523,6 +539,29 @@ static void convert_generic_sd( struct security_descriptor *sd ) } } @@ -95,7 +118,7 @@ index 818bd42af76a..53d59d3e8e2a 100644 struct security_descriptor *get_file_sd( struct object *obj, struct fd *fd, mode_t *mode, uid_t *uid ) { -@@ -510,9 +533,10 @@ struct security_descriptor *get_file_sd( struct object *obj, struct fd *fd, mode +@@ -538,9 +577,10 @@ struct security_descriptor *get_file_sd( struct object *obj, struct fd *fd, mode (st.st_uid == *uid)) return obj->sd; @@ -110,5 +133,5 @@ index 818bd42af76a..53d59d3e8e2a 100644 *mode = st.st_mode; -- -2.26.2 +2.28.0 diff --git a/staging/upstream-commit b/staging/upstream-commit index 97253671..c0c4da10 100644 --- a/staging/upstream-commit +++ b/staging/upstream-commit @@ -1 +1 @@ -87f41e6b408dd01055ff6a378b90d089d61ec370 +314368e6c442f043ebfc22b70c1113e4e6232c04