Added patch to block interruption of system APC in server_select.

This commit is contained in:
Sebastian Lackner 2015-10-21 18:56:08 +02:00
parent 91f812ed1b
commit 7cf357b20c
5 changed files with 131 additions and 1 deletions

View File

@ -34,8 +34,9 @@ Wine. All those differences are also documented on the
Included bug fixes and improvements
-----------------------------------
**Bug fixes and features included in the next upcoming release [3]:**
**Bug fixes and features included in the next upcoming release [4]:**
* Do not allow interruption of system APC in server_select ([Wine Bug #14697](https://bugs.winehq.org/show_bug.cgi?id=14697))
* Implement stub for ProcessQuotaLimits info class
* Release capture before sending WM_COMMAND ([Wine Bug #39296](https://bugs.winehq.org/show_bug.cgi?id=39296))
* Use wrapper function for consolidation callback during unwinding. ([Wine Bug #39449](https://bugs.winehq.org/show_bug.cgi?id=39449))

1
debian/changelog vendored
View File

@ -3,6 +3,7 @@ wine-staging (1.7.54) UNRELEASED; urgency=low
unwinding.
* Added patch to implement stub for ProcessQuotaLimits info class.
* Added patch to release capture before sending WM_COMMAND.
* Added patch to block interruption of system APC in server_select.
* Removed patch to implement kernel32.GetPhysicallyInstalledSystemMemory
(accepted upstream).
* Partially removed patches for ws2_32 TransmitFile (accepted upstream).

View File

@ -0,0 +1,122 @@
From db7522d47373208237a1b8806c72d06a21b3bb66 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Wed, 21 Oct 2015 18:53:58 +0200
Subject: ntdll: Block signals while executing system APCs.
---
dlls/ntdll/server.c | 46 +++++++++++++++++++++++++++++++++++++++-------
1 file changed, 39 insertions(+), 7 deletions(-)
diff --git a/dlls/ntdll/server.c b/dlls/ntdll/server.c
index 7d8d1e9..d46d023 100644
--- a/dlls/ntdll/server.c
+++ b/dlls/ntdll/server.c
@@ -371,13 +371,30 @@ static int wait_select_reply( void *cookie )
/***********************************************************************
+ * is_system_apc
+ *
+ * Checks if an APC call is a system APC.
+ */
+static BOOL is_system_apc( const apc_call_t *call )
+{
+ switch (call->type)
+ {
+ case APC_USER:
+ case APC_TIMER:
+ return FALSE;
+ default:
+ return TRUE;
+ }
+}
+
+
+/***********************************************************************
* invoke_apc
*
* Invoke a single APC. Return TRUE if a user APC has been run.
*/
-static BOOL invoke_apc( const apc_call_t *call, apc_result_t *result )
+static void invoke_apc( const apc_call_t *call, apc_result_t *result )
{
- BOOL user_apc = FALSE;
SIZE_T size;
void *addr;
@@ -391,7 +408,6 @@ static BOOL invoke_apc( const apc_call_t *call, apc_result_t *result )
{
void (WINAPI *func)(ULONG_PTR,ULONG_PTR,ULONG_PTR) = wine_server_get_ptr( call->user.func );
func( call->user.args[0], call->user.args[1], call->user.args[2] );
- user_apc = TRUE;
break;
}
case APC_TIMER:
@@ -399,7 +415,6 @@ static BOOL invoke_apc( const apc_call_t *call, apc_result_t *result )
void (WINAPI *func)(void*, unsigned int, unsigned int) = wine_server_get_ptr( call->timer.func );
func( wine_server_get_ptr( call->timer.arg ),
(DWORD)call->timer.time, (DWORD)(call->timer.time >> 32) );
- user_apc = TRUE;
break;
}
case APC_ASYNC_IO:
@@ -574,7 +589,6 @@ static BOOL invoke_apc( const apc_call_t *call, apc_result_t *result )
server_protocol_error( "get_apc_request: bad type %d\n", call->type );
break;
}
- return user_apc;
}
@@ -590,10 +604,12 @@ unsigned int server_select( const select_op_t *select_op, data_size_t size, UINT
obj_handle_t apc_handle = 0;
apc_call_t call;
apc_result_t result;
+ sigset_t old_set;
timeout_t abs_timeout = timeout ? timeout->QuadPart : TIMEOUT_INFINITE;
memset( &result, 0, sizeof(result) );
+ pthread_sigmask( SIG_BLOCK, &server_block_set, &old_set );
for (;;)
{
SERVER_START_REQ( select )
@@ -610,10 +626,25 @@ unsigned int server_select( const select_op_t *select_op, data_size_t size, UINT
call = reply->call;
}
SERVER_END_REQ;
- if (ret == STATUS_PENDING) ret = wait_select_reply( &cookie );
+ if (ret == STATUS_PENDING)
+ {
+ pthread_sigmask( SIG_SETMASK, &old_set, NULL );
+ ret = wait_select_reply( &cookie );
+ pthread_sigmask( SIG_BLOCK, &server_block_set, &old_set );
+ }
if (ret != STATUS_USER_APC) break;
- if (invoke_apc( &call, &result ))
+
+ if (is_system_apc( &call ))
{
+ /* execute system APC without releasing the lock */
+ invoke_apc( &call, &result );
+ }
+ else
+ {
+ pthread_sigmask( SIG_SETMASK, &old_set, NULL );
+ invoke_apc( &call, &result );
+ pthread_sigmask( SIG_BLOCK, &server_block_set, &old_set );
+
/* if we ran a user apc, we have to check once more if
* additional apcs are queued, but we don't want to wait */
abs_timeout = 0;
@@ -625,6 +656,7 @@ unsigned int server_select( const select_op_t *select_op, data_size_t size, UINT
if (size >= sizeof(select_op->signal_and_wait) && select_op->op == SELECT_SIGNAL_AND_WAIT)
size = offsetof( select_op_t, signal_and_wait.signal );
}
+ pthread_sigmask( SIG_SETMASK, &old_set, NULL );
if (ret == STATUS_TIMEOUT && user_apc) ret = STATUS_USER_APC;
--
2.6.1

View File

@ -1 +1,2 @@
Fixes: Do not check if object was signaled after user APC in server_select
Fixes: [14697] Do not allow interruption of system APC in server_select

View File

@ -4384,15 +4384,20 @@ fi
# Patchset ntdll-Wait_User_APC
# |
# | This patchset fixes the following Wine bugs:
# | * [#14697] Do not allow interruption of system APC in server_select
# |
# | Modified files:
# | * dlls/kernel32/tests/sync.c, dlls/ntdll/server.c
# |
if test "$enable_ntdll_Wait_User_APC" -eq 1; then
patch_apply ntdll-Wait_User_APC/0001-kernel32-tests-Add-test-to-show-that-multiple-user-A.patch
patch_apply ntdll-Wait_User_APC/0002-ntdll-Do-not-check-if-object-was-signaled-after-user.patch
patch_apply ntdll-Wait_User_APC/0003-ntdll-Block-signals-while-executing-system-APCs.patch
(
echo '+ { "Sebastian Lackner", "kernel32/tests: Add test to show that multiple user APCs are processed at once.", 1 },';
echo '+ { "Sebastian Lackner", "ntdll: Do not check if object was signaled after user APC in server_select.", 1 },';
echo '+ { "Sebastian Lackner", "ntdll: Block signals while executing system APCs.", 1 },';
) >> "$patchlist"
fi