Rebase against 44cb0afb2571984bda8ca1fa084a50c1fc04ac71.

This commit is contained in:
Sebastian Lackner
2017-09-25 13:15:02 +02:00
parent 48ffaa6b21
commit 094f2d8d0c
14 changed files with 302 additions and 495 deletions

View File

@@ -1,4 +1,4 @@
From f087db7a31a96e78b9d078b3de2dec90264efe6e Mon Sep 17 00:00:00 2001
From a370fb90c05a5077a9285c1235767cf1b1b6fa5f Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Sat, 4 Oct 2014 02:35:44 +0200
Subject: ntdll: Trigger write watches before passing userdata pointer to
@@ -6,14 +6,14 @@ Subject: ntdll: Trigger write watches before passing userdata pointer to
---
dlls/advapi32/tests/security.c | 1 -
dlls/ntdll/server.c | 8 ++++++++
2 files changed, 8 insertions(+), 1 deletion(-)
dlls/ntdll/server.c | 9 +++++++++
2 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c
index 698a9aa..e825bf9 100644
index 41219087421..5f5c59ed100 100644
--- a/dlls/advapi32/tests/security.c
+++ b/dlls/advapi32/tests/security.c
@@ -1499,7 +1499,6 @@ todo_wine
@@ -1494,7 +1494,6 @@ todo_wine
"failed with ERROR_INSUFFICIENT_BUFFER, instead of %d\n", err);
todo_wine
ok(PrivSetLen == sizeof(PRIVILEGE_SET), "PrivSetLen returns %d\n", PrivSetLen);
@@ -22,10 +22,14 @@ index 698a9aa..e825bf9 100644
"Access and/or AccessStatus were changed!\n");
diff --git a/dlls/ntdll/server.c b/dlls/ntdll/server.c
index 356d631..de9c186 100644
index 1e84fbf418e..f7aca1b07b0 100644
--- a/dlls/ntdll/server.c
+++ b/dlls/ntdll/server.c
@@ -305,6 +305,14 @@ unsigned int wine_server_call( void *req_ptr )
@@ -314,9 +314,18 @@ unsigned int server_call_unlocked( void *req_ptr )
*/
unsigned int wine_server_call( void *req_ptr )
{
+ struct __server_request_info * const req = req_ptr;
sigset_t old_set;
unsigned int ret;
@@ -38,8 +42,8 @@ index 356d631..de9c186 100644
+ }
+
pthread_sigmask( SIG_BLOCK, &server_block_set, &old_set );
ret = send_request( req );
if (!ret) ret = wait_reply( req );
ret = server_call_unlocked( req_ptr );
pthread_sigmask( SIG_SETMASK, &old_set, NULL );
--
2.7.1
2.14.1

View File

@@ -1,18 +1,18 @@
From c43f021985b9bd0d2ac1ba0e8145b8eddb665506 Mon Sep 17 00:00:00 2001
From edfa0038f4b084b05f2bb61ad741385c9ced2bd0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Sat, 4 Oct 2014 03:22:09 +0200
Subject: ntdll: Properly handle PAGE_WRITECOPY protection. (try 5)
For now, only enable it when a special environment variable is set.
---
dlls/ntdll/virtual.c | 51 ++++++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 44 insertions(+), 7 deletions(-)
dlls/ntdll/virtual.c | 46 +++++++++++++++++++++++++++++++++++++++-------
1 file changed, 39 insertions(+), 7 deletions(-)
diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c
index cb3b9aad385..7365c3ad487 100644
index 0b813d3b0e9..977b4c1811f 100644
--- a/dlls/ntdll/virtual.c
+++ b/dlls/ntdll/virtual.c
@@ -264,6 +264,21 @@ static const char *VIRTUAL_GetProtStr( BYTE prot )
@@ -293,6 +293,21 @@ static const char *VIRTUAL_GetProtStr( BYTE prot )
return buffer;
}
@@ -34,7 +34,7 @@ index cb3b9aad385..7365c3ad487 100644
/***********************************************************************
* VIRTUAL_GetUnixProt
@@ -277,8 +292,19 @@ static int VIRTUAL_GetUnixProt( BYTE vprot )
@@ -306,8 +321,19 @@ static int VIRTUAL_GetUnixProt( BYTE vprot )
{
if (vprot & VPROT_READ) prot |= PROT_READ;
if (vprot & VPROT_WRITE) prot |= PROT_WRITE | PROT_READ;
@@ -55,57 +55,51 @@ index cb3b9aad385..7365c3ad487 100644
if (vprot & VPROT_WRITEWATCH) prot &= ~PROT_WRITE;
}
if (!prot) prot = PROT_NONE;
@@ -1721,13 +1747,18 @@ NTSTATUS virtual_handle_fault( LPCVOID addr, DWORD err, BOOL on_signal_stack )
@@ -932,7 +958,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 */
- set_page_vprot_bits( base, accessed_size, 0, VPROT_WRITEWATCH );
+ set_page_vprot_bits( base, accessed_size, VPROT_WRITE, VPROT_WRITEWATCH | VPROT_WRITECOPY );
/* restore page protections on the entire range */
mprotect_range( base, size, 0, 0 );
}
@@ -1803,12 +1829,13 @@ NTSTATUS virtual_handle_fault( LPCVOID addr, DWORD err, BOOL on_signal_stack )
set_page_vprot_bits( page, page_size, 0, VPROT_WRITEWATCH );
mprotect_range( page, page_size, 0, 0 );
}
- /* ignore fault if page is writable now */
- if (VIRTUAL_GetUnixProt( get_page_vprot( page )) & PROT_WRITE)
+ if (vprot & VPROT_WRITECOPY)
{
- if ((vprot & VPROT_WRITEWATCH) || is_write_watch_range( page, page_size ))
- ret = STATUS_SUCCESS;
+ set_page_vprot_bits( page, page_size, VPROT_WRITE, VPROT_WRITECOPY );
+ mprotect_range( page, page_size, 0, 0 );
}
+ /* ignore fault if page is writable now */
+ if (VIRTUAL_GetUnixProt( get_page_vprot( page )) & PROT_WRITE) ret = STATUS_SUCCESS;
}
else if (!err && page == user_shared_data_external)
{
void *page = ROUND_ADDR( addr, page_mask );
BYTE vprot = get_page_vprot( page );
- if ((err & EXCEPTION_WRITE_FAULT) && (view->protect & VPROT_WRITEWATCH))
+ if (err & EXCEPTION_WRITE_FAULT)
{
- if (vprot & VPROT_WRITEWATCH)
+ if ((view->protect & VPROT_WRITEWATCH) && (vprot & VPROT_WRITEWATCH))
{
set_page_vprot_bits( page, page_size, 0, VPROT_WRITEWATCH );
mprotect_range( view, page, page_size, 0, 0 );
}
+ if (vprot & VPROT_WRITECOPY)
+ {
+ set_page_vprot_bits( page, page_size, VPROT_WRITE, VPROT_WRITECOPY );
+ mprotect_range( view, page, page_size, 0, 0 );
+ }
/* ignore fault if page is writable now */
if (VIRTUAL_GetUnixProt( get_page_vprot( page )) & PROT_WRITE) ret = STATUS_SUCCESS;
}
@@ -1918,6 +1949,7 @@ NTSTATUS CDECL wine_uninterrupted_write_memory( void *addr, const void *buffer,
struct file_view *view;
sigset_t sigset;
NTSTATUS ret = STATUS_ACCESS_VIOLATION;
+ BOOL writecopy = FALSE;
@@ -1846,11 +1873,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;
+ if (vprot & VPROT_WRITECOPY)
+ {
+ vprot = (vprot & ~VPROT_WRITECOPY) | VPROT_WRITE;
+ *has_write_watch = TRUE;
+ }
if (!(VIRTUAL_GetUnixProt( vprot & ~VPROT_WRITEWATCH ) & PROT_WRITE))
return STATUS_INVALID_USER_BUFFER;
}
if (*has_write_watch)
- mprotect_range( addr, size, 0, VPROT_WRITEWATCH ); /* temporarily enable write access */
+ mprotect_range( addr, size, VPROT_WRITE, VPROT_WRITEWATCH | VPROT_WRITECOPY ); /* temporarily enable write access */
return STATUS_SUCCESS;
}
if (!size) return STATUS_SUCCESS;
@@ -1929,12 +1961,17 @@ NTSTATUS CDECL wine_uninterrupted_write_memory( void *addr, const void *buffer,
for (i = 0; i < total; i += page_size)
{
- int prot = VIRTUAL_GetUnixProt( get_page_vprot( page + i ) & ~VPROT_WRITEWATCH );
- if (!(prot & PROT_WRITE)) goto done;
+ BYTE vprot = get_page_vprot( page + i ) & ~VPROT_WRITEWATCH;
+ if (vprot & VPROT_WRITECOPY)
+ {
+ vprot = (vprot & ~VPROT_WRITECOPY) | VPROT_WRITE;
+ writecopy = TRUE;
+ }
+ if (!(VIRTUAL_GetUnixProt( vprot ) & PROT_WRITE)) goto done;
}
- if (view->protect & VPROT_WRITEWATCH) /* enable write access by clearing write watches */
+ if ((view->protect & VPROT_WRITEWATCH) || writecopy) /* enable write access by clearing write watches */
{
- set_page_vprot_bits( addr, size, 0, VPROT_WRITEWATCH );
+ set_page_vprot_bits( addr, size, VPROT_WRITE, VPROT_WRITECOPY | VPROT_WRITEWATCH );
mprotect_range( view, addr, size, 0, 0 );
}
if (buffer) memcpy( addr, buffer, size );
--
2.14.1

View File

@@ -1,6 +1,6 @@
Fixes: [29384] Voobly expects correct handling of WRITECOPY memory protection
FIxes: [35561] MSYS2 expects correct handling of WRITECOPY memory protection
Depends: ws2_32-WriteWatches
Depends: ntdll-User_Shared_Data
# Causes regressions?
# https://bugs.wine-staging.com/show_bug.cgi?id=207