server: Add a helper function to validate and return object attributes.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2016-01-15 18:15:31 +09:00
parent 7350682aa6
commit 9504e2addf
11 changed files with 48 additions and 91 deletions

View File

@ -287,16 +287,10 @@ DECL_HANDLER(create_event)
struct event *event;
struct unicode_str name;
struct directory *root = NULL;
const struct object_attributes *objattr = get_req_data();
const struct security_descriptor *sd;
const struct object_attributes *objattr = get_req_object_attributes( &sd, &name );
reply->handle = 0;
if (!objattr_is_valid( objattr, get_req_data_size() ))
return;
sd = objattr->sd_len ? (const struct security_descriptor *)(objattr + 1) : NULL;
objattr_get_name( objattr, &name );
if (!objattr) return;
if (objattr->rootdir && !(root = get_directory_obj( current->process, objattr->rootdir, 0 )))
return;
@ -378,13 +372,10 @@ DECL_HANDLER(create_keyed_event)
struct keyed_event *event;
struct unicode_str name;
struct directory *root = NULL;
const struct object_attributes *objattr = get_req_data();
const struct security_descriptor *sd;
const struct object_attributes *objattr = get_req_object_attributes( &sd, &name );
if (!objattr_is_valid( objattr, get_req_data_size() )) return;
sd = objattr->sd_len ? (const struct security_descriptor *)(objattr + 1) : NULL;
objattr_get_name( objattr, &name );
if (!objattr) return;
if (objattr->rootdir && !(root = get_directory_obj( current->process, objattr->rootdir, 0 ))) return;

View File

@ -686,17 +686,16 @@ DECL_HANDLER(create_file)
{
struct object *file;
struct fd *root_fd = NULL;
const struct object_attributes *objattr = get_req_data();
struct unicode_str unicode_name;
const struct security_descriptor *sd;
const struct object_attributes *objattr = get_req_object_attributes( &sd, &unicode_name );
const char *name;
data_size_t name_len;
reply->handle = 0;
if (!objattr) return;
if (!objattr_is_valid( objattr, get_req_data_size() ))
return;
/* name is transferred in the unix codepage outside of the objattr structure */
if (objattr->name_len)
if (unicode_name.len)
{
set_error( STATUS_INVALID_PARAMETER );
return;
@ -712,8 +711,6 @@ DECL_HANDLER(create_file)
if (!root_fd) return;
}
sd = objattr->sd_len ? (const struct security_descriptor *)(objattr + 1) : NULL;
name = (const char *)get_req_data() + sizeof(*objattr) + objattr->sd_len;
name_len = get_req_data_size() - sizeof(*objattr) - objattr->sd_len;

View File

@ -664,16 +664,10 @@ DECL_HANDLER(create_mapping)
struct object *obj;
struct unicode_str name;
struct directory *root = NULL;
const struct object_attributes *objattr = get_req_data();
const struct security_descriptor *sd;
const struct object_attributes *objattr = get_req_object_attributes( &sd, &name );
reply->handle = 0;
if (!objattr_is_valid( objattr, get_req_data_size() ))
return;
sd = objattr->sd_len ? (const struct security_descriptor *)(objattr + 1) : NULL;
objattr_get_name( objattr, &name );
if (!objattr) return;
if (objattr->rootdir && !(root = get_directory_obj( current->process, objattr->rootdir, 0 )))
return;

View File

@ -211,16 +211,10 @@ DECL_HANDLER(create_mutex)
struct mutex *mutex;
struct unicode_str name;
struct directory *root = NULL;
const struct object_attributes *objattr = get_req_data();
const struct security_descriptor *sd;
const struct object_attributes *objattr = get_req_object_attributes( &sd, &name );
reply->handle = 0;
if (!objattr_is_valid( objattr, get_req_data_size() ))
return;
sd = objattr->sd_len ? (const struct security_descriptor *)(objattr + 1) : NULL;
objattr_get_name( objattr, &name );
if (!objattr) return;
if (objattr->rootdir && !(root = get_directory_obj( current->process, objattr->rootdir, 0 )))
return;

View File

@ -923,8 +923,10 @@ DECL_HANDLER(create_named_pipe)
struct pipe_server *server;
struct unicode_str name;
struct directory *root = NULL;
const struct object_attributes *objattr = get_req_data();
const struct security_descriptor *sd;
const struct object_attributes *objattr = get_req_object_attributes( &sd, &name );
if (!objattr) return;
if (!req->sharing || (req->sharing & ~(FILE_SHARE_READ | FILE_SHARE_WRITE)) ||
(!(req->flags & NAMED_PIPE_MESSAGE_STREAM_WRITE) && (req->flags & NAMED_PIPE_MESSAGE_STREAM_READ)))
@ -933,14 +935,6 @@ DECL_HANDLER(create_named_pipe)
return;
}
reply->handle = 0;
if (!objattr_is_valid( objattr, get_req_data_size() ))
return;
sd = objattr->sd_len ? (const struct security_descriptor *)(objattr + 1) : NULL;
objattr_get_name( objattr, &name );
if (objattr->rootdir && !(root = get_directory_obj( current->process, objattr->rootdir, 0 )))
return;

View File

@ -1539,13 +1539,10 @@ DECL_HANDLER(create_job)
struct job *job;
struct unicode_str name;
struct directory *root = NULL;
const struct object_attributes *objattr = get_req_data();
const struct security_descriptor *sd;
const struct object_attributes *objattr = get_req_object_attributes( &sd, &name );
if (!objattr_is_valid( objattr, get_req_data_size() )) return;
sd = objattr->sd_len ? (const struct security_descriptor *)(objattr + 1) : NULL;
objattr_get_name( objattr, &name );
if (!objattr) return;
if (objattr->rootdir && !(root = get_directory_obj( current->process, objattr->rootdir, 0 ))) return;

View File

@ -65,6 +65,8 @@
#include "file.h"
#include "process.h"
#include "thread.h"
#include "security.h"
#define WANT_REQUEST_HANDLERS
#include "request.h"
@ -163,6 +165,31 @@ void *set_reply_data_size( data_size_t size )
return current->reply_data;
}
/* return object attributes from the current request */
const struct object_attributes *get_req_object_attributes( const struct security_descriptor **sd,
struct unicode_str *name )
{
const struct object_attributes *attr = get_req_data();
data_size_t size = get_req_data_size();
if ((size < sizeof(*attr)) || (size - sizeof(*attr) < attr->sd_len) ||
(size - sizeof(*attr) - attr->sd_len < attr->name_len))
{
set_error( STATUS_ACCESS_VIOLATION );
return NULL;
}
if (attr->sd_len && !sd_is_valid( (const struct security_descriptor *)(attr + 1), attr->sd_len ))
{
set_error( STATUS_INVALID_SECURITY_DESCR );
return NULL;
}
*sd = attr->sd_len ? (const struct security_descriptor *)(attr + 1) : NULL;
name->len = (attr->name_len / sizeof(WCHAR)) * sizeof(WCHAR);
name->str = (const WCHAR *)(attr + 1) + attr->sd_len / sizeof(WCHAR);
return attr;
}
/* write the remaining part of the reply */
void write_reply( struct thread *thread )
{

View File

@ -46,6 +46,8 @@ extern void fatal_error( const char *err, ... );
extern const char *get_config_dir(void);
extern void *set_reply_data_size( data_size_t size );
extern const struct object_attributes *get_req_object_attributes( const struct security_descriptor **sd,
struct unicode_str *name );
extern int receive_fd( struct process *process );
extern int send_client_fd( struct process *process, int fd, obj_handle_t handle );
extern void read_request( struct thread *thread );

View File

@ -139,13 +139,4 @@ static inline const SID *sd_get_group( const struct security_descriptor *sd )
return NULL;
}
/* determines whether an object_attributes struct is valid in a buffer
* and calls set_error appropriately */
extern int objattr_is_valid( const struct object_attributes *objattr, data_size_t size );
static inline void objattr_get_name( const struct object_attributes *objattr, struct unicode_str *name )
{
name->len = ((objattr->name_len) / sizeof(WCHAR)) * sizeof(WCHAR);
name->str = (const WCHAR *)objattr + (sizeof(*objattr) + objattr->sd_len) / sizeof(WCHAR);
}
#endif /* __WINE_SERVER_SECURITY_H */

View File

@ -179,16 +179,10 @@ DECL_HANDLER(create_semaphore)
struct semaphore *sem;
struct unicode_str name;
struct directory *root = NULL;
const struct object_attributes *objattr = get_req_data();
const struct security_descriptor *sd;
const struct object_attributes *objattr = get_req_object_attributes( &sd, &name );
reply->handle = 0;
if (!objattr_is_valid( objattr, get_req_data_size() ))
return;
sd = objattr->sd_len ? (const struct security_descriptor *)(objattr + 1) : NULL;
objattr_get_name( objattr, &name );
if (!objattr) return;
if (objattr->rootdir && !(root = get_directory_obj( current->process, objattr->rootdir, 0 )))
return;

View File

@ -334,30 +334,6 @@ int sd_is_valid( const struct security_descriptor *sd, data_size_t size )
return TRUE;
}
/* determines whether an object_attributes struct is valid in a buffer
* and calls set_error appropriately */
int objattr_is_valid( const struct object_attributes *objattr, data_size_t size )
{
if ((size < sizeof(*objattr)) || (size - sizeof(*objattr) < objattr->sd_len) ||
(size - sizeof(*objattr) - objattr->sd_len < objattr->name_len))
{
set_error( STATUS_ACCESS_VIOLATION );
return FALSE;
}
if (objattr->sd_len)
{
const struct security_descriptor *sd = (const struct security_descriptor *)(objattr + 1);
if (!sd_is_valid( sd, objattr->sd_len ))
{
set_error( STATUS_INVALID_SECURITY_DESCR );
return FALSE;
}
}
return TRUE;
}
/* maps from generic rights to specific rights as given by a mapping */
static inline void map_generic_mask(unsigned int *mask, const GENERIC_MAPPING *mapping)
{