Commit 37503be6 authored by Alexandre Julliard's avatar Alexandre Julliard

server: Fix checks for a valid directory in object attributes.

parent 6fe37f35
...@@ -177,12 +177,11 @@ DECL_HANDLER(create_completion) ...@@ -177,12 +177,11 @@ DECL_HANDLER(create_completion)
{ {
struct completion *completion; struct completion *completion;
struct unicode_str name; struct unicode_str name;
struct directory *root = NULL; struct directory *root;
const struct security_descriptor *sd; const struct security_descriptor *sd;
const struct object_attributes *objattr = get_req_object_attributes( &sd, &name ); const struct object_attributes *objattr = get_req_object_attributes( &sd, &name, &root );
if (!objattr) return; if (!objattr) return;
if (objattr->rootdir && !(root = get_directory_obj( current->process, objattr->rootdir, 0 ))) return;
if ((completion = create_completion( root, &name, objattr->attributes, req->concurrent, sd ))) if ((completion = create_completion( root, &name, objattr->attributes, req->concurrent, sd )))
{ {
......
...@@ -503,12 +503,11 @@ void init_directories(void) ...@@ -503,12 +503,11 @@ void init_directories(void)
DECL_HANDLER(create_directory) DECL_HANDLER(create_directory)
{ {
struct unicode_str name; struct unicode_str name;
struct directory *dir, *root = NULL; struct directory *dir, *root;
const struct security_descriptor *sd; const struct security_descriptor *sd;
const struct object_attributes *objattr = get_req_object_attributes( &sd, &name ); const struct object_attributes *objattr = get_req_object_attributes( &sd, &name, &root );
if (!objattr) return; if (!objattr) return;
if (objattr->rootdir && !(root = get_directory_obj( current->process, objattr->rootdir, 0 ))) return;
if ((dir = create_directory( root, &name, objattr->attributes, HASH_SIZE, sd ))) if ((dir = create_directory( root, &name, objattr->attributes, HASH_SIZE, sd )))
{ {
......
...@@ -280,15 +280,12 @@ DECL_HANDLER(create_event) ...@@ -280,15 +280,12 @@ DECL_HANDLER(create_event)
{ {
struct event *event; struct event *event;
struct unicode_str name; struct unicode_str name;
struct directory *root = NULL; struct directory *root;
const struct security_descriptor *sd; const struct security_descriptor *sd;
const struct object_attributes *objattr = get_req_object_attributes( &sd, &name ); const struct object_attributes *objattr = get_req_object_attributes( &sd, &name, &root );
if (!objattr) return; if (!objattr) return;
if (objattr->rootdir && !(root = get_directory_obj( current->process, objattr->rootdir, 0 )))
return;
if ((event = create_event( root, &name, objattr->attributes, if ((event = create_event( root, &name, objattr->attributes,
req->manual_reset, req->initial_state, sd ))) req->manual_reset, req->initial_state, sd )))
{ {
...@@ -354,14 +351,12 @@ DECL_HANDLER(create_keyed_event) ...@@ -354,14 +351,12 @@ DECL_HANDLER(create_keyed_event)
{ {
struct keyed_event *event; struct keyed_event *event;
struct unicode_str name; struct unicode_str name;
struct directory *root = NULL; struct directory *root;
const struct security_descriptor *sd; const struct security_descriptor *sd;
const struct object_attributes *objattr = get_req_object_attributes( &sd, &name ); const struct object_attributes *objattr = get_req_object_attributes( &sd, &name, &root );
if (!objattr) return; if (!objattr) return;
if (objattr->rootdir && !(root = get_directory_obj( current->process, objattr->rootdir, 0 ))) return;
if ((event = create_keyed_event( root, &name, objattr->attributes, sd ))) if ((event = create_keyed_event( root, &name, objattr->attributes, sd )))
{ {
if (get_error() == STATUS_OBJECT_NAME_EXISTS) if (get_error() == STATUS_OBJECT_NAME_EXISTS)
......
...@@ -688,7 +688,7 @@ DECL_HANDLER(create_file) ...@@ -688,7 +688,7 @@ DECL_HANDLER(create_file)
struct fd *root_fd = NULL; struct fd *root_fd = NULL;
struct unicode_str unicode_name; struct unicode_str unicode_name;
const struct security_descriptor *sd; const struct security_descriptor *sd;
const struct object_attributes *objattr = get_req_object_attributes( &sd, &unicode_name ); const struct object_attributes *objattr = get_req_object_attributes( &sd, &unicode_name, NULL );
const char *name; const char *name;
data_size_t name_len; data_size_t name_len;
......
...@@ -579,11 +579,17 @@ obj_handle_t open_object( struct process *process, obj_handle_t parent, unsigned ...@@ -579,11 +579,17 @@ obj_handle_t open_object( struct process *process, obj_handle_t parent, unsigned
struct directory *root = NULL; struct directory *root = NULL;
struct object *obj; struct object *obj;
if (parent && !(root = get_directory_obj( current->process, parent, 0 ))) return 0; if (name->len >= 65534)
{
set_error( STATUS_OBJECT_NAME_INVALID );
return 0;
}
if (parent && !(root = get_directory_obj( process, parent, 0 ))) return 0;
if ((obj = open_object_dir( root, name, attributes, ops ))) if ((obj = open_object_dir( root, name, attributes, ops )))
{ {
handle = alloc_handle( current->process, obj, access, attributes ); handle = alloc_handle( process, obj, access, attributes );
release_object( obj ); release_object( obj );
} }
if (root) release_object( root ); if (root) release_object( root );
......
...@@ -514,12 +514,21 @@ DECL_HANDLER(create_mailslot) ...@@ -514,12 +514,21 @@ DECL_HANDLER(create_mailslot)
{ {
struct mailslot *mailslot; struct mailslot *mailslot;
struct unicode_str name; struct unicode_str name;
struct directory *root = NULL; struct directory *root;
const struct security_descriptor *sd; const struct security_descriptor *sd;
const struct object_attributes *objattr = get_req_object_attributes( &sd, &name ); const struct object_attributes *objattr = get_req_object_attributes( &sd, &name, &root );
if (!objattr) return; if (!objattr) return;
if (objattr->rootdir && !(root = get_directory_obj( current->process, objattr->rootdir, 0 ))) return;
if (!name.len) /* mailslots need a root directory even without a name */
{
if (!objattr->rootdir)
{
set_error( STATUS_OBJECT_PATH_SYNTAX_BAD );
return;
}
else if (!(root = get_directory_obj( current->process, objattr->rootdir, 0 ))) return;
}
if ((mailslot = create_mailslot( root, &name, objattr->attributes, req->max_msgsize, if ((mailslot = create_mailslot( root, &name, objattr->attributes, req->max_msgsize,
req->read_timeout, sd ))) req->read_timeout, sd )))
......
...@@ -661,15 +661,12 @@ DECL_HANDLER(create_mapping) ...@@ -661,15 +661,12 @@ DECL_HANDLER(create_mapping)
{ {
struct object *obj; struct object *obj;
struct unicode_str name; struct unicode_str name;
struct directory *root = NULL; struct directory *root;
const struct security_descriptor *sd; const struct security_descriptor *sd;
const struct object_attributes *objattr = get_req_object_attributes( &sd, &name ); const struct object_attributes *objattr = get_req_object_attributes( &sd, &name, &root );
if (!objattr) return; if (!objattr) return;
if (objattr->rootdir && !(root = get_directory_obj( current->process, objattr->rootdir, 0 )))
return;
if ((obj = create_mapping( root, &name, objattr->attributes, if ((obj = create_mapping( root, &name, objattr->attributes,
req->size, req->protect, req->file_handle, sd ))) req->size, req->protect, req->file_handle, sd )))
{ {
......
...@@ -208,15 +208,12 @@ DECL_HANDLER(create_mutex) ...@@ -208,15 +208,12 @@ DECL_HANDLER(create_mutex)
{ {
struct mutex *mutex; struct mutex *mutex;
struct unicode_str name; struct unicode_str name;
struct directory *root = NULL; struct directory *root;
const struct security_descriptor *sd; const struct security_descriptor *sd;
const struct object_attributes *objattr = get_req_object_attributes( &sd, &name ); const struct object_attributes *objattr = get_req_object_attributes( &sd, &name, &root );
if (!objattr) return; if (!objattr) return;
if (objattr->rootdir && !(root = get_directory_obj( current->process, objattr->rootdir, 0 )))
return;
if ((mutex = create_mutex( root, &name, objattr->attributes, req->owned, sd ))) if ((mutex = create_mutex( root, &name, objattr->attributes, req->owned, sd )))
{ {
if (get_error() == STATUS_OBJECT_NAME_EXISTS) if (get_error() == STATUS_OBJECT_NAME_EXISTS)
......
...@@ -917,9 +917,9 @@ DECL_HANDLER(create_named_pipe) ...@@ -917,9 +917,9 @@ DECL_HANDLER(create_named_pipe)
struct named_pipe *pipe; struct named_pipe *pipe;
struct pipe_server *server; struct pipe_server *server;
struct unicode_str name; struct unicode_str name;
struct directory *root = NULL; struct directory *root;
const struct security_descriptor *sd; const struct security_descriptor *sd;
const struct object_attributes *objattr = get_req_object_attributes( &sd, &name ); const struct object_attributes *objattr = get_req_object_attributes( &sd, &name, &root );
if (!objattr) return; if (!objattr) return;
...@@ -930,8 +930,15 @@ DECL_HANDLER(create_named_pipe) ...@@ -930,8 +930,15 @@ DECL_HANDLER(create_named_pipe)
return; return;
} }
if (objattr->rootdir && !(root = get_directory_obj( current->process, objattr->rootdir, 0 ))) if (!name.len) /* pipes need a root directory even without a name */
return; {
if (!objattr->rootdir)
{
set_error( STATUS_OBJECT_PATH_SYNTAX_BAD );
return;
}
else if (!(root = get_directory_obj( current->process, objattr->rootdir, 0 ))) return;
}
pipe = create_named_pipe( root, &name, objattr->attributes | OBJ_OPENIF, sd ); pipe = create_named_pipe( root, &name, objattr->attributes | OBJ_OPENIF, sd );
......
...@@ -1538,14 +1538,12 @@ DECL_HANDLER(create_job) ...@@ -1538,14 +1538,12 @@ DECL_HANDLER(create_job)
{ {
struct job *job; struct job *job;
struct unicode_str name; struct unicode_str name;
struct directory *root = NULL; struct directory *root;
const struct security_descriptor *sd; const struct security_descriptor *sd;
const struct object_attributes *objattr = get_req_object_attributes( &sd, &name ); const struct object_attributes *objattr = get_req_object_attributes( &sd, &name, &root );
if (!objattr) return; if (!objattr) return;
if (objattr->rootdir && !(root = get_directory_obj( current->process, objattr->rootdir, 0 ))) return;
if ((job = create_job_object( root, &name, objattr->attributes, sd ))) if ((job = create_job_object( root, &name, objattr->attributes, sd )))
{ {
if (get_error() == STATUS_OBJECT_NAME_EXISTS) if (get_error() == STATUS_OBJECT_NAME_EXISTS)
......
...@@ -2026,7 +2026,7 @@ DECL_HANDLER(create_key) ...@@ -2026,7 +2026,7 @@ DECL_HANDLER(create_key)
struct unicode_str name, class; struct unicode_str name, class;
unsigned int access = req->access; unsigned int access = req->access;
const struct security_descriptor *sd; const struct security_descriptor *sd;
const struct object_attributes *objattr = get_req_object_attributes( &sd, &name ); const struct object_attributes *objattr = get_req_object_attributes( &sd, &name, NULL );
if (!objattr) return; if (!objattr) return;
...@@ -2183,7 +2183,7 @@ DECL_HANDLER(load_registry) ...@@ -2183,7 +2183,7 @@ DECL_HANDLER(load_registry)
struct key *key, *parent; struct key *key, *parent;
struct unicode_str name; struct unicode_str name;
const struct security_descriptor *sd; const struct security_descriptor *sd;
const struct object_attributes *objattr = get_req_object_attributes( &sd, &name ); const struct object_attributes *objattr = get_req_object_attributes( &sd, &name, NULL );
if (!objattr) return; if (!objattr) return;
......
...@@ -167,12 +167,15 @@ void *set_reply_data_size( data_size_t size ) ...@@ -167,12 +167,15 @@ void *set_reply_data_size( data_size_t size )
/* return object attributes from the current request */ /* return object attributes from the current request */
const struct object_attributes *get_req_object_attributes( const struct security_descriptor **sd, const struct object_attributes *get_req_object_attributes( const struct security_descriptor **sd,
struct unicode_str *name ) struct unicode_str *name,
struct directory **root )
{ {
static const struct object_attributes empty_attributes; static const struct object_attributes empty_attributes;
const struct object_attributes *attr = get_req_data(); const struct object_attributes *attr = get_req_data();
data_size_t size = get_req_data_size(); data_size_t size = get_req_data_size();
if (root) *root = NULL;
if (!size) if (!size)
{ {
*sd = NULL; *sd = NULL;
...@@ -196,6 +199,10 @@ const struct object_attributes *get_req_object_attributes( const struct security ...@@ -196,6 +199,10 @@ const struct object_attributes *get_req_object_attributes( const struct security
set_error( STATUS_OBJECT_NAME_INVALID ); set_error( STATUS_OBJECT_NAME_INVALID );
return NULL; return NULL;
} }
if (root && attr->rootdir && attr->name_len)
{
if (!(*root = get_directory_obj( current->process, attr->rootdir, 0 ))) return NULL;
}
*sd = attr->sd_len ? (const struct security_descriptor *)(attr + 1) : NULL; *sd = attr->sd_len ? (const struct security_descriptor *)(attr + 1) : NULL;
name->len = attr->name_len; name->len = attr->name_len;
name->str = (const WCHAR *)(attr + 1) + attr->sd_len / sizeof(WCHAR); name->str = (const WCHAR *)(attr + 1) + attr->sd_len / sizeof(WCHAR);
......
...@@ -47,7 +47,8 @@ extern void fatal_error( const char *err, ... ); ...@@ -47,7 +47,8 @@ extern void fatal_error( const char *err, ... );
extern const char *get_config_dir(void); extern const char *get_config_dir(void);
extern void *set_reply_data_size( data_size_t size ); extern void *set_reply_data_size( data_size_t size );
extern const struct object_attributes *get_req_object_attributes( const struct security_descriptor **sd, extern const struct object_attributes *get_req_object_attributes( const struct security_descriptor **sd,
struct unicode_str *name ); struct unicode_str *name,
struct directory **root );
extern const void *get_req_data_after_objattr( const struct object_attributes *attr, data_size_t *len ); extern const void *get_req_data_after_objattr( const struct object_attributes *attr, data_size_t *len );
extern int receive_fd( struct process *process ); extern int receive_fd( struct process *process );
extern int send_client_fd( struct process *process, int fd, obj_handle_t handle ); extern int send_client_fd( struct process *process, int fd, obj_handle_t handle );
......
...@@ -176,15 +176,12 @@ DECL_HANDLER(create_semaphore) ...@@ -176,15 +176,12 @@ DECL_HANDLER(create_semaphore)
{ {
struct semaphore *sem; struct semaphore *sem;
struct unicode_str name; struct unicode_str name;
struct directory *root = NULL; struct directory *root;
const struct security_descriptor *sd; const struct security_descriptor *sd;
const struct object_attributes *objattr = get_req_object_attributes( &sd, &name ); const struct object_attributes *objattr = get_req_object_attributes( &sd, &name, &root );
if (!objattr) return; if (!objattr) return;
if (objattr->rootdir && !(root = get_directory_obj( current->process, objattr->rootdir, 0 )))
return;
if ((sem = create_semaphore( root, &name, objattr->attributes, req->initial, req->max, sd ))) if ((sem = create_semaphore( root, &name, objattr->attributes, req->initial, req->max, sd )))
{ {
if (get_error() == STATUS_OBJECT_NAME_EXISTS) if (get_error() == STATUS_OBJECT_NAME_EXISTS)
......
...@@ -166,17 +166,15 @@ DECL_HANDLER(create_symlink) ...@@ -166,17 +166,15 @@ DECL_HANDLER(create_symlink)
{ {
struct symlink *symlink; struct symlink *symlink;
struct unicode_str name, target; struct unicode_str name, target;
struct directory *root = NULL; struct directory *root;
const struct security_descriptor *sd; const struct security_descriptor *sd;
const struct object_attributes *objattr = get_req_object_attributes( &sd, &name ); const struct object_attributes *objattr = get_req_object_attributes( &sd, &name, &root );
if (!objattr) return; if (!objattr) return;
target.str = get_req_data_after_objattr( objattr, &target.len ); target.str = get_req_data_after_objattr( objattr, &target.len );
target.len = (target.len / sizeof(WCHAR)) * sizeof(WCHAR); target.len = (target.len / sizeof(WCHAR)) * sizeof(WCHAR);
if (objattr->rootdir && !(root = get_directory_obj( current->process, objattr->rootdir, 0 ))) return;
if ((symlink = create_symlink( root, &name, objattr->attributes, &target, sd ))) if ((symlink = create_symlink( root, &name, objattr->attributes, &target, sd )))
{ {
reply->handle = alloc_handle( current->process, symlink, req->access, objattr->attributes ); reply->handle = alloc_handle( current->process, symlink, req->access, objattr->attributes );
......
...@@ -232,12 +232,11 @@ DECL_HANDLER(create_timer) ...@@ -232,12 +232,11 @@ DECL_HANDLER(create_timer)
{ {
struct timer *timer; struct timer *timer;
struct unicode_str name; struct unicode_str name;
struct directory *root = NULL; struct directory *root;
const struct security_descriptor *sd; const struct security_descriptor *sd;
const struct object_attributes *objattr = get_req_object_attributes( &sd, &name ); const struct object_attributes *objattr = get_req_object_attributes( &sd, &name, &root );
if (!objattr) return; if (!objattr) return;
if (objattr->rootdir && !(root = get_directory_obj( current->process, objattr->rootdir, 0 ))) return;
if ((timer = create_timer( root, &name, objattr->attributes, req->manual, sd ))) if ((timer = create_timer( root, &name, objattr->attributes, req->manual, sd )))
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment