From: Elizabeth Figura zfigura@codeweavers.com
--- dlls/ntdll/unix/sync.c | 15 ++++++++++++--- server/inproc_sync.c | 2 ++ server/protocol.def | 1 + 3 files changed, 15 insertions(+), 3 deletions(-)
diff --git a/dlls/ntdll/unix/sync.c b/dlls/ntdll/unix/sync.c index 4211b796042..7f603882074 100644 --- a/dlls/ntdll/unix/sync.c +++ b/dlls/ntdll/unix/sync.c @@ -310,6 +310,7 @@ static unsigned int validate_open_object_attributes( const OBJECT_ATTRIBUTES *at struct inproc_sync { int fd; + unsigned int access; unsigned int type : 2; };
@@ -318,7 +319,7 @@ static void release_inproc_sync( struct inproc_sync *sync ) close( sync->fd ); }
-static NTSTATUS get_inproc_sync( HANDLE handle, struct inproc_sync *sync ) +static NTSTATUS get_inproc_sync( HANDLE handle, ACCESS_MASK desired_access, struct inproc_sync *sync ) { sigset_t sigset; NTSTATUS ret; @@ -336,6 +337,7 @@ static NTSTATUS get_inproc_sync( HANDLE handle, struct inproc_sync *sync ) obj_handle_t fd_handle; sync->fd = wine_server_receive_fd( &fd_handle ); assert( wine_server_ptr_handle(fd_handle) == handle ); + sync->access = reply->access; sync->type = reply->type; } } @@ -343,7 +345,14 @@ static NTSTATUS get_inproc_sync( HANDLE handle, struct inproc_sync *sync )
server_leave_uninterrupted_section( &fd_cache_mutex, &sigset );
- return ret; + if (ret) return ret; + if ((sync->access & desired_access) != desired_access) + { + release_inproc_sync( sync ); + return STATUS_ACCESS_DENIED; + } + + return STATUS_SUCCESS; }
static NTSTATUS inproc_release_semaphore( HANDLE handle, ULONG count, ULONG *prev_count ) @@ -405,7 +414,7 @@ static NTSTATUS inproc_wait( DWORD count, const HANDLE *handles, BOOLEAN wait_an assert( count <= ARRAY_SIZE(syncs) ); for (int i = 0; i < count; ++i) { - if ((ret = get_inproc_sync( handles[i], stack + i ))) + if ((ret = get_inproc_sync( handles[i], SYNCHRONIZE, stack + i ))) { while (i--) release_inproc_sync( syncs[i] ); return ret; diff --git a/server/inproc_sync.c b/server/inproc_sync.c index 995e8b57c4e..90c5f17d5e6 100644 --- a/server/inproc_sync.c +++ b/server/inproc_sync.c @@ -181,6 +181,8 @@ DECL_HANDLER(get_inproc_sync_fd)
if (!(obj = get_handle_obj( current->process, req->handle, 0, NULL ))) return;
+ reply->access = get_handle_access( current->process, req->handle ); + if ((fd = get_inproc_sync_fd( obj, &reply->type )) < 0) set_error( STATUS_NOT_IMPLEMENTED ); else send_client_fd( current->process, fd, req->handle );
diff --git a/server/protocol.def b/server/protocol.def index bfc13d0bffe..ec6cde3e606 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -4130,4 +4130,5 @@ enum inproc_sync_type obj_handle_t handle; /* handle to the object */ @REPLY unsigned char type; /* inproc sync type */ + unsigned int access; /* handle access rights */ @END