From: Rémi Bernon rbernon@codeweavers.com
--- server/event.c | 11 +++-------- server/mutex.c | 10 +++------- server/object.c | 3 +-- server/object.h | 5 +++-- server/semaphore.c | 11 +++-------- server/thread.c | 12 +++++++++++- 6 files changed, 24 insertions(+), 28 deletions(-)
diff --git a/server/event.c b/server/event.c index ad7c09acc99..579a43ab1fb 100644 --- a/server/event.c +++ b/server/event.c @@ -48,6 +48,7 @@ struct type_descr event_type = STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE, EVENT_ALL_ACCESS }, + EVENT_MODIFY_STATE, /* signal access */ };
struct event @@ -61,7 +62,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 +204,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..ec8644df6b3 100644 --- a/server/mutex.c +++ b/server/mutex.c @@ -48,6 +48,7 @@ struct type_descr mutex_type = STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE, MUTANT_ALL_ACCESS }, + SYNCHRONIZE, /* signal access */ };
struct mutex @@ -63,7 +64,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 +171,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 7cb2ccbd93f..e8076da21eb 100644 --- a/server/object.c +++ b/server/object.c @@ -628,9 +628,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 9211d2f9633..b2fd9887a41 100644 --- a/server/object.h +++ b/server/object.h @@ -56,6 +56,7 @@ struct type_descr struct unicode_str name; /* type name */ unsigned int valid_access; /* mask for valid access bits */ struct generic_map mapping; /* generic access mapping */ + unsigned int signal_access; /* mask for valid signal access */ unsigned int index; /* index in global array of types */ unsigned int obj_count; /* count of objects of this type */ unsigned int handle_count; /* count of handles of this type */ @@ -81,7 +82,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 +169,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..b8d27afe3b7 100644 --- a/server/semaphore.c +++ b/server/semaphore.c @@ -48,6 +48,7 @@ struct type_descr semaphore_type = STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE, SEMAPHORE_ALL_ACCESS }, + SEMAPHORE_MODIFY_STATE, /* signal access */ };
struct semaphore @@ -60,7 +61,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 +155,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 12b73d44353..acdb50d8c56 100644 --- a/server/thread.c +++ b/server/thread.c @@ -1176,6 +1176,14 @@ 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_access( struct object *obj, unsigned int access ) +{ + if (!obj->ops->type->signal_access) return STATUS_OBJECT_TYPE_MISMATCH; + if (!(access & obj->ops->type->signal_access)) return STATUS_ACCESS_DENIED; + return STATUS_SUCCESS; +} + /* try signaling an event flag, a semaphore or a mutex */ static int signal_object( obj_handle_t handle ) { @@ -1185,7 +1193,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_access( obj, access ))) set_error( status ); + else ret = obj->ops->signal( obj ); release_object( obj ); } return ret;