From: Rémi Bernon rbernon@codeweavers.com
--- server/event.c | 10 ++-------- server/mutex.c | 9 ++------- server/object.c | 3 +-- server/object.h | 4 ++-- server/semaphore.c | 10 ++-------- server/thread.c | 25 ++++++++++++++++++++++++- 6 files changed, 33 insertions(+), 28 deletions(-)
diff --git a/server/event.c b/server/event.c index ad7c09acc99..894ebdf3ae3 100644 --- a/server/event.c +++ b/server/event.c @@ -61,7 +61,7 @@ struct event static void event_dump( struct object *obj, int verbose ); static int event_signaled( struct object *obj, struct wait_queue_entry *entry ); static void event_satisfied( struct object *obj, struct wait_queue_entry *entry ); -static int event_signal( struct object *obj, unsigned int access); +static int event_signal( struct object *obj ); static struct list *event_get_kernel_obj_list( struct object *obj );
static const struct object_ops event_ops = @@ -203,16 +203,10 @@ static void event_satisfied( struct object *obj, struct wait_queue_entry *entry if (!event->manual_reset) event->signaled = 0; }
-static int event_signal( struct object *obj, unsigned int access ) +static int event_signal( struct object *obj ) { struct event *event = (struct event *)obj; assert( obj->ops == &event_ops ); - - if (!(access & EVENT_MODIFY_STATE)) - { - set_error( STATUS_ACCESS_DENIED ); - return 0; - } set_event( event ); return 1; } diff --git a/server/mutex.c b/server/mutex.c index af0efe72132..8dbbc466397 100644 --- a/server/mutex.c +++ b/server/mutex.c @@ -63,7 +63,7 @@ static void mutex_dump( struct object *obj, int verbose ); static int mutex_signaled( struct object *obj, struct wait_queue_entry *entry ); static void mutex_satisfied( struct object *obj, struct wait_queue_entry *entry ); static void mutex_destroy( struct object *obj ); -static int mutex_signal( struct object *obj, unsigned int access ); +static int mutex_signal( struct object *obj );
static const struct object_ops mutex_ops = { @@ -170,16 +170,11 @@ static void mutex_satisfied( struct object *obj, struct wait_queue_entry *entry mutex->abandoned = 0; }
-static int mutex_signal( struct object *obj, unsigned int access ) +static int mutex_signal( struct object *obj ) { struct mutex *mutex = (struct mutex *)obj; assert( obj->ops == &mutex_ops );
- if (!(access & SYNCHRONIZE)) - { - set_error( STATUS_ACCESS_DENIED ); - return 0; - } if (!mutex->count || (mutex->owner != current)) { set_error( STATUS_MUTANT_NOT_OWNED ); diff --git a/server/object.c b/server/object.c index cd368ef724a..8d8dcd6485e 100644 --- a/server/object.c +++ b/server/object.c @@ -627,9 +627,8 @@ void no_satisfied( struct object *obj, struct wait_queue_entry *entry ) { }
-int no_signal( struct object *obj, unsigned int access ) +int no_signal( struct object *obj ) { - set_error( STATUS_OBJECT_TYPE_MISMATCH ); return 0; }
diff --git a/server/object.h b/server/object.h index 1058f9bfb0a..da858d61196 100644 --- a/server/object.h +++ b/server/object.h @@ -81,7 +81,7 @@ struct object_ops /* wait satisfied */ void (*satisfied)(struct object *,struct wait_queue_entry *); /* signal an object */ - int (*signal)(struct object *, unsigned int); + int (*signal)(struct object *); /* return an fd object that can be used to read/write from the object */ struct fd *(*get_fd)(struct object *); /* map access rights to the specific rights for this object */ @@ -168,7 +168,7 @@ extern struct object *find_object( const struct namespace *namespace, const stru extern struct object *find_object_index( const struct namespace *namespace, unsigned int index ); extern int no_add_queue( struct object *obj, struct wait_queue_entry *entry ); extern void no_satisfied( struct object *obj, struct wait_queue_entry *entry ); -extern int no_signal( struct object *obj, unsigned int access ); +extern int no_signal( struct object *obj ); extern struct fd *no_get_fd( struct object *obj ); extern unsigned int default_map_access( struct object *obj, unsigned int access ); extern struct security_descriptor *default_get_sd( struct object *obj ); diff --git a/server/semaphore.c b/server/semaphore.c index 53b42a886df..727597f6c44 100644 --- a/server/semaphore.c +++ b/server/semaphore.c @@ -60,7 +60,7 @@ struct semaphore static void semaphore_dump( struct object *obj, int verbose ); static int semaphore_signaled( struct object *obj, struct wait_queue_entry *entry ); static void semaphore_satisfied( struct object *obj, struct wait_queue_entry *entry ); -static int semaphore_signal( struct object *obj, unsigned int access ); +static int semaphore_signal( struct object *obj );
static const struct object_ops semaphore_ops = { @@ -154,16 +154,10 @@ static void semaphore_satisfied( struct object *obj, struct wait_queue_entry *en sem->count--; }
-static int semaphore_signal( struct object *obj, unsigned int access ) +static int semaphore_signal( struct object *obj ) { struct semaphore *sem = (struct semaphore *)obj; assert( obj->ops == &semaphore_ops ); - - if (!(access & SEMAPHORE_MODIFY_STATE)) - { - set_error( STATUS_ACCESS_DENIED ); - return 0; - } return release_semaphore( sem, 1, NULL ); }
diff --git a/server/thread.c b/server/thread.c index ffc016bfa56..63c0fdb905b 100644 --- a/server/thread.c +++ b/server/thread.c @@ -1184,6 +1184,27 @@ static void thread_timeout( void *ptr ) wake_thread( thread ); }
+/* check if an event flag, a semaphore or a mutex can be signaled */ +static unsigned int check_signal_object( struct object *obj, unsigned int access ) +{ + if (obj->ops->type == &event_type) + { + if (access & EVENT_MODIFY_STATE) return STATUS_SUCCESS; + return STATUS_ACCESS_DENIED; + } + if (obj->ops->type == &semaphore_type) + { + if (access & SEMAPHORE_MODIFY_STATE) return STATUS_SUCCESS; + return STATUS_ACCESS_DENIED; + } + if (obj->ops->type == &mutex_type) + { + if (access & SYNCHRONIZE) return STATUS_SUCCESS; + return STATUS_ACCESS_DENIED; + } + return STATUS_OBJECT_TYPE_MISMATCH; +} + /* try signaling an event flag, a semaphore or a mutex */ static int signal_object( obj_handle_t handle ) { @@ -1193,7 +1214,9 @@ static int signal_object( obj_handle_t handle ) obj = get_handle_obj( current->process, handle, 0, NULL ); if (obj) { - ret = obj->ops->signal( obj, get_handle_access( current->process, handle )); + unsigned int status, access = get_handle_access( current->process, handle ); + if ((status = check_signal_object( obj, access ))) set_error( status ); + else ret = obj->ops->signal( obj ); release_object( obj ); } return ret;