server: Do not dereference symlinks specified as root directory.
Signed-off-by: Paul Gofman <pgofman@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
981d69ada6
commit
ae106feed2
|
@ -1082,7 +1082,7 @@ static void test_symboliclink(void)
|
|||
NTSTATUS status;
|
||||
UNICODE_STRING str, target;
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
HANDLE dir, link, h;
|
||||
HANDLE dir, link, h, h2;
|
||||
IO_STATUS_BLOCK iosb;
|
||||
|
||||
/* No name and/or no attributes */
|
||||
|
@ -1179,6 +1179,68 @@ static void test_symboliclink(void)
|
|||
pNtClose(h);
|
||||
pNtClose(link);
|
||||
pNtClose(dir);
|
||||
|
||||
InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
|
||||
RtlInitUnicodeString(&str, L"\\BaseNamedObjects\\om.c-test");
|
||||
status = pNtCreateDirectoryObject(&dir, DIRECTORY_QUERY, &attr);
|
||||
ok(status == STATUS_SUCCESS, "Got unexpected status %#x.\n", status);
|
||||
|
||||
RtlInitUnicodeString(&str, L"\\DosDevices\\test_link");
|
||||
RtlInitUnicodeString(&target, L"\\BaseNamedObjects");
|
||||
status = pNtCreateSymbolicLinkObject(&link, SYMBOLIC_LINK_QUERY, &attr, &target);
|
||||
ok(status == STATUS_SUCCESS && !!link, "Got unexpected status %#x.\n", status);
|
||||
|
||||
status = NtCreateFile(&h, GENERIC_READ | SYNCHRONIZE, &attr, &iosb, NULL, 0,
|
||||
FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, NULL, 0 );
|
||||
ok(status == STATUS_OBJECT_TYPE_MISMATCH, "Got unexpected status %#x.\n", status);
|
||||
|
||||
status = pNtOpenSymbolicLinkObject( &h, SYMBOLIC_LINK_QUERY, &attr );
|
||||
ok(status == STATUS_SUCCESS, "Got unexpected status %#x.\n", status);
|
||||
pNtClose(h);
|
||||
|
||||
InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
|
||||
RtlInitUnicodeString( &str, L"\\BaseNamedObjects\\om.c-test\\" );
|
||||
status = NtCreateFile(&h, GENERIC_READ | SYNCHRONIZE, &attr, &iosb, NULL, 0,
|
||||
FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, NULL, 0 );
|
||||
ok(status == STATUS_OBJECT_NAME_INVALID, "Got unexpected status %#x.\n", status);
|
||||
|
||||
InitializeObjectAttributes(&attr, &str, 0, link, NULL);
|
||||
RtlInitUnicodeString( &str, L"om.c-test\\test_object" );
|
||||
status = pNtCreateMutant( &h, GENERIC_ALL, &attr, FALSE );
|
||||
ok(status == STATUS_OBJECT_TYPE_MISMATCH, "Got unexpected status %#x.\n", status);
|
||||
|
||||
InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
|
||||
RtlInitUnicodeString( &str, L"\\DosDevices\\test_link\\om.c-test\\test_object" );
|
||||
status = pNtCreateMutant( &h, GENERIC_ALL, &attr, FALSE );
|
||||
ok(status == STATUS_SUCCESS, "Got unexpected status %#x.\n", status);
|
||||
status = pNtOpenMutant( &h2, GENERIC_ALL, &attr );
|
||||
ok(status == STATUS_SUCCESS, "Got unexpected status %#x.\n", status);
|
||||
pNtClose(h2);
|
||||
RtlInitUnicodeString( &str, L"\\BaseNamedObjects\\om.c-test\\test_object" );
|
||||
status = pNtCreateMutant( &h2, GENERIC_ALL, &attr, FALSE );
|
||||
ok(status == STATUS_OBJECT_NAME_COLLISION, "Got unexpected status %#x.\n", status);
|
||||
|
||||
InitializeObjectAttributes(&attr, &str, 0, link, NULL);
|
||||
RtlInitUnicodeString( &str, L"om.c-test\\test_object" );
|
||||
status = pNtOpenMutant( &h2, GENERIC_ALL, &attr );
|
||||
ok(status == STATUS_OBJECT_TYPE_MISMATCH, "Got unexpected status %#x.\n", status);
|
||||
|
||||
pNtClose(h);
|
||||
|
||||
status = pNtOpenMutant( &h, GENERIC_ALL, &attr );
|
||||
ok(status == STATUS_OBJECT_TYPE_MISMATCH, "Got unexpected status %#x.\n", status);
|
||||
|
||||
InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
|
||||
RtlInitUnicodeString( &str, L"test_object" );
|
||||
status = pNtCreateMutant( &h, GENERIC_ALL, &attr, FALSE );
|
||||
ok(status == STATUS_SUCCESS, "Got unexpected status %#x.\n", status);
|
||||
status = pNtOpenMutant( &h2, GENERIC_ALL, &attr );
|
||||
ok(status == STATUS_SUCCESS, "Got unexpected status %#x.\n", status);
|
||||
pNtClose(h);
|
||||
pNtClose(h2);
|
||||
|
||||
pNtClose(link);
|
||||
pNtClose(dir);
|
||||
}
|
||||
|
||||
#define test_file_info(a) _test_file_info(__LINE__,a)
|
||||
|
|
|
@ -69,7 +69,8 @@ static void console_input_dump( struct object *obj, int verbose );
|
|||
static void console_input_destroy( struct object *obj );
|
||||
static int console_input_signaled( struct object *obj, struct wait_queue_entry *entry );
|
||||
static struct fd *console_input_get_fd( struct object *obj );
|
||||
static struct object *console_input_lookup_name( struct object *obj, struct unicode_str *name, unsigned int attr );
|
||||
static struct object *console_input_lookup_name( struct object *obj, struct unicode_str *name,
|
||||
unsigned int attr, struct object *root );
|
||||
static struct object *console_input_open_file( struct object *obj, unsigned int access,
|
||||
unsigned int sharing, unsigned int options );
|
||||
|
||||
|
@ -143,7 +144,8 @@ static void console_server_dump( struct object *obj, int verbose );
|
|||
static void console_server_destroy( struct object *obj );
|
||||
static int console_server_signaled( struct object *obj, struct wait_queue_entry *entry );
|
||||
static struct fd *console_server_get_fd( struct object *obj );
|
||||
static struct object *console_server_lookup_name( struct object *obj, struct unicode_str *name, unsigned int attr );
|
||||
static struct object *console_server_lookup_name( struct object *obj, struct unicode_str *name,
|
||||
unsigned int attr, struct object *root );
|
||||
static struct object *console_server_open_file( struct object *obj, unsigned int access,
|
||||
unsigned int sharing, unsigned int options );
|
||||
|
||||
|
@ -259,7 +261,8 @@ static const struct fd_ops screen_buffer_fd_ops =
|
|||
|
||||
static struct object_type *console_device_get_type( struct object *obj );
|
||||
static void console_device_dump( struct object *obj, int verbose );
|
||||
static struct object *console_device_lookup_name( struct object *obj, struct unicode_str *name, unsigned int attr );
|
||||
static struct object *console_device_lookup_name( struct object *obj, struct unicode_str *name,
|
||||
unsigned int attr, struct object *root );
|
||||
static struct object *console_device_open_file( struct object *obj, unsigned int access,
|
||||
unsigned int sharing, unsigned int options );
|
||||
|
||||
|
@ -355,7 +358,8 @@ struct console_connection
|
|||
|
||||
static void console_connection_dump( struct object *obj, int verbose );
|
||||
static struct fd *console_connection_get_fd( struct object *obj );
|
||||
static struct object *console_connection_lookup_name( struct object *obj, struct unicode_str *name, unsigned int attr );
|
||||
static struct object *console_connection_lookup_name( struct object *obj, struct unicode_str *name,
|
||||
unsigned int attr, struct object *root );
|
||||
static struct object *console_connection_open_file( struct object *obj, unsigned int access,
|
||||
unsigned int sharing, unsigned int options );
|
||||
static int console_connection_close_handle( struct object *obj, struct process *process, obj_handle_t handle );
|
||||
|
@ -709,7 +713,8 @@ static struct object *create_console_connection( struct console_input *console )
|
|||
return &connection->obj;
|
||||
}
|
||||
|
||||
static struct object *console_input_lookup_name( struct object *obj, struct unicode_str *name, unsigned int attr )
|
||||
static struct object *console_input_lookup_name( struct object *obj, struct unicode_str *name,
|
||||
unsigned int attr, struct object *root )
|
||||
{
|
||||
struct console_input *console = (struct console_input *)obj;
|
||||
static const WCHAR connectionW[] = {'C','o','n','n','e','c','t','i','o','n'};
|
||||
|
@ -793,7 +798,8 @@ static void console_server_destroy( struct object *obj )
|
|||
if (server->fd) release_object( server->fd );
|
||||
}
|
||||
|
||||
static struct object *console_server_lookup_name( struct object *obj, struct unicode_str *name, unsigned int attr )
|
||||
static struct object *console_server_lookup_name( struct object *obj, struct unicode_str *name,
|
||||
unsigned int attr, struct object *root )
|
||||
{
|
||||
struct console_server *server = (struct console_server*)obj;
|
||||
static const WCHAR referenceW[] = {'R','e','f','e','r','e','n','c','e'};
|
||||
|
@ -1117,7 +1123,8 @@ static struct fd *console_connection_get_fd( struct object *obj )
|
|||
return (struct fd *)grab_object( connection->fd );
|
||||
}
|
||||
|
||||
static struct object *console_connection_lookup_name( struct object *obj, struct unicode_str *name, unsigned int attr )
|
||||
static struct object *console_connection_lookup_name( struct object *obj, struct unicode_str *name,
|
||||
unsigned int attr, struct object *root )
|
||||
{
|
||||
static const WCHAR referenceW[] = {'R','e','f','e','r','e','n','c','e'};
|
||||
|
||||
|
@ -1165,7 +1172,8 @@ static void console_device_dump( struct object *obj, int verbose )
|
|||
fputs( "Console device\n", stderr );
|
||||
}
|
||||
|
||||
static struct object *console_device_lookup_name( struct object *obj, struct unicode_str *name, unsigned int attr )
|
||||
static struct object *console_device_lookup_name( struct object *obj, struct unicode_str *name,
|
||||
unsigned int attr, struct object *root )
|
||||
{
|
||||
static const WCHAR connectionW[] = {'C','o','n','n','e','c','t','i','o','n'};
|
||||
static const WCHAR consoleW[] = {'C','o','n','s','o','l','e'};
|
||||
|
|
|
@ -83,7 +83,7 @@ struct directory
|
|||
static void directory_dump( struct object *obj, int verbose );
|
||||
static struct object_type *directory_get_type( struct object *obj );
|
||||
static struct object *directory_lookup_name( struct object *obj, struct unicode_str *name,
|
||||
unsigned int attr );
|
||||
unsigned int attr, struct object *root );
|
||||
static void directory_destroy( struct object *obj );
|
||||
|
||||
static const struct object_ops directory_ops =
|
||||
|
@ -139,7 +139,7 @@ static struct object_type *directory_get_type( struct object *obj )
|
|||
}
|
||||
|
||||
static struct object *directory_lookup_name( struct object *obj, struct unicode_str *name,
|
||||
unsigned int attr )
|
||||
unsigned int attr, struct object *root )
|
||||
{
|
||||
struct directory *dir = (struct directory *)obj;
|
||||
struct object *found;
|
||||
|
|
|
@ -68,7 +68,8 @@ static void file_dump( struct object *obj, int verbose );
|
|||
static struct fd *file_get_fd( struct object *obj );
|
||||
static struct security_descriptor *file_get_sd( struct object *obj );
|
||||
static int file_set_sd( struct object *obj, const struct security_descriptor *sd, unsigned int set_info );
|
||||
static struct object *file_lookup_name( struct object *obj, struct unicode_str *name, unsigned int attr );
|
||||
static struct object *file_lookup_name( struct object *obj, struct unicode_str *name,
|
||||
unsigned int attr, struct object *root );
|
||||
static struct object *file_open_file( struct object *obj, unsigned int access,
|
||||
unsigned int sharing, unsigned int options );
|
||||
static struct list *file_get_kernel_obj_list( struct object *obj );
|
||||
|
@ -603,7 +604,8 @@ static int file_set_sd( struct object *obj, const struct security_descriptor *sd
|
|||
return 1;
|
||||
}
|
||||
|
||||
static struct object *file_lookup_name( struct object *obj, struct unicode_str *name, unsigned int attr )
|
||||
static struct object *file_lookup_name( struct object *obj, struct unicode_str *name,
|
||||
unsigned int attr, struct object *root )
|
||||
{
|
||||
if (!name || !name->len) return NULL; /* open the file itself */
|
||||
|
||||
|
|
|
@ -186,7 +186,7 @@ struct mailslot_device_file
|
|||
static void mailslot_device_dump( struct object *obj, int verbose );
|
||||
static struct object_type *mailslot_device_get_type( struct object *obj );
|
||||
static struct object *mailslot_device_lookup_name( struct object *obj, struct unicode_str *name,
|
||||
unsigned int attr );
|
||||
unsigned int attr, struct object *root );
|
||||
static struct object *mailslot_device_open_file( struct object *obj, unsigned int access,
|
||||
unsigned int sharing, unsigned int options );
|
||||
static void mailslot_device_destroy( struct object *obj );
|
||||
|
@ -395,7 +395,7 @@ static struct object_type *mailslot_device_get_type( struct object *obj )
|
|||
}
|
||||
|
||||
static struct object *mailslot_device_lookup_name( struct object *obj, struct unicode_str *name,
|
||||
unsigned int attr )
|
||||
unsigned int attr, struct object *root )
|
||||
{
|
||||
struct mailslot_device *device = (struct mailslot_device*)obj;
|
||||
struct object *found;
|
||||
|
|
|
@ -239,7 +239,7 @@ static const struct fd_ops pipe_client_fd_ops =
|
|||
static void named_pipe_device_dump( struct object *obj, int verbose );
|
||||
static struct object_type *named_pipe_device_get_type( struct object *obj );
|
||||
static struct object *named_pipe_device_lookup_name( struct object *obj,
|
||||
struct unicode_str *name, unsigned int attr );
|
||||
struct unicode_str *name, unsigned int attr, struct object *root );
|
||||
static struct object *named_pipe_device_open_file( struct object *obj, unsigned int access,
|
||||
unsigned int sharing, unsigned int options );
|
||||
static void named_pipe_device_destroy( struct object *obj );
|
||||
|
@ -468,7 +468,7 @@ static struct object_type *named_pipe_device_get_type( struct object *obj )
|
|||
}
|
||||
|
||||
static struct object *named_pipe_device_lookup_name( struct object *obj, struct unicode_str *name,
|
||||
unsigned int attr )
|
||||
unsigned int attr, struct object *root )
|
||||
{
|
||||
struct named_pipe_device *device = (struct named_pipe_device*)obj;
|
||||
struct object *found;
|
||||
|
|
|
@ -241,14 +241,14 @@ struct object *lookup_named_object( struct object *root, const struct unicode_st
|
|||
/* skip leading backslash */
|
||||
name_tmp.str++;
|
||||
name_tmp.len -= sizeof(WCHAR);
|
||||
parent = get_root_directory();
|
||||
parent = root = get_root_directory();
|
||||
}
|
||||
|
||||
if (!name_tmp.len) ptr = NULL; /* special case for empty path */
|
||||
|
||||
clear_error();
|
||||
|
||||
while ((obj = parent->ops->lookup_name( parent, ptr, attr )))
|
||||
while ((obj = parent->ops->lookup_name( parent, ptr, attr, root )))
|
||||
{
|
||||
/* move to the next element */
|
||||
release_object ( parent );
|
||||
|
@ -670,7 +670,7 @@ WCHAR *no_get_full_name( struct object *obj, data_size_t *ret_len )
|
|||
}
|
||||
|
||||
struct object *no_lookup_name( struct object *obj, struct unicode_str *name,
|
||||
unsigned int attr )
|
||||
unsigned int attr, struct object *root )
|
||||
{
|
||||
if (!name) set_error( STATUS_OBJECT_TYPE_MISMATCH );
|
||||
return NULL;
|
||||
|
|
|
@ -83,7 +83,7 @@ struct object_ops
|
|||
/* get the object full name */
|
||||
WCHAR *(*get_full_name)(struct object *, data_size_t *);
|
||||
/* lookup a name if an object has a namespace */
|
||||
struct object *(*lookup_name)(struct object *, struct unicode_str *,unsigned int);
|
||||
struct object *(*lookup_name)(struct object *, struct unicode_str *,unsigned int,struct object *);
|
||||
/* link an object's name into a parent object */
|
||||
int (*link_name)(struct object *, struct object_name *, struct object *);
|
||||
/* unlink an object's name from its parent */
|
||||
|
@ -165,7 +165,8 @@ extern int default_set_sd( struct object *obj, const struct security_descriptor
|
|||
extern int set_sd_defaults_from_token( struct object *obj, const struct security_descriptor *sd,
|
||||
unsigned int set_info, struct token *token );
|
||||
extern WCHAR *no_get_full_name( struct object *obj, data_size_t *ret_len );
|
||||
extern struct object *no_lookup_name( struct object *obj, struct unicode_str *name, unsigned int attributes );
|
||||
extern struct object *no_lookup_name( struct object *obj, struct unicode_str *name,
|
||||
unsigned int attributes, struct object *root );
|
||||
extern int no_link_name( struct object *obj, struct object_name *name, struct object *parent );
|
||||
extern void default_unlink_name( struct object *obj, struct object_name *name );
|
||||
extern struct object *no_open_file( struct object *obj, unsigned int access, unsigned int sharing,
|
||||
|
|
|
@ -1735,7 +1735,8 @@ static void sock_release_ifchange( struct sock *sock )
|
|||
|
||||
static struct object_type *socket_device_get_type( struct object *obj );
|
||||
static void socket_device_dump( struct object *obj, int verbose );
|
||||
static struct object *socket_device_lookup_name( struct object *obj, struct unicode_str *name, unsigned int attr );
|
||||
static struct object *socket_device_lookup_name( struct object *obj, struct unicode_str *name,
|
||||
unsigned int attr, struct object *root );
|
||||
static struct object *socket_device_open_file( struct object *obj, unsigned int access,
|
||||
unsigned int sharing, unsigned int options );
|
||||
|
||||
|
@ -1775,7 +1776,8 @@ static void socket_device_dump( struct object *obj, int verbose )
|
|||
fputs( "Socket device\n", stderr );
|
||||
}
|
||||
|
||||
static struct object *socket_device_lookup_name( struct object *obj, struct unicode_str *name, unsigned int attr )
|
||||
static struct object *socket_device_lookup_name( struct object *obj, struct unicode_str *name,
|
||||
unsigned int attr, struct object *root )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@ static void symlink_dump( struct object *obj, int verbose );
|
|||
static struct object_type *symlink_get_type( struct object *obj );
|
||||
static unsigned int symlink_map_access( struct object *obj, unsigned int access );
|
||||
static struct object *symlink_lookup_name( struct object *obj, struct unicode_str *name,
|
||||
unsigned int attr );
|
||||
unsigned int attr, struct object *root );
|
||||
static void symlink_destroy( struct object *obj );
|
||||
|
||||
static const struct object_ops symlink_ops =
|
||||
|
@ -94,7 +94,7 @@ static struct object_type *symlink_get_type( struct object *obj )
|
|||
}
|
||||
|
||||
static struct object *symlink_lookup_name( struct object *obj, struct unicode_str *name,
|
||||
unsigned int attr )
|
||||
unsigned int attr, struct object *root )
|
||||
{
|
||||
struct symlink *symlink = (struct symlink *)obj;
|
||||
struct unicode_str target_str, name_left;
|
||||
|
@ -104,6 +104,7 @@ static struct object *symlink_lookup_name( struct object *obj, struct unicode_st
|
|||
|
||||
if (!name) return NULL;
|
||||
if (!name->len && (attr & OBJ_OPENLINK)) return NULL;
|
||||
if (obj == root) return NULL;
|
||||
|
||||
target_str.str = symlink->target;
|
||||
target_str.len = symlink->len;
|
||||
|
|
|
@ -46,7 +46,7 @@ static void winstation_dump( struct object *obj, int verbose );
|
|||
static struct object_type *winstation_get_type( struct object *obj );
|
||||
static int winstation_close_handle( struct object *obj, struct process *process, obj_handle_t handle );
|
||||
static struct object *winstation_lookup_name( struct object *obj, struct unicode_str *name,
|
||||
unsigned int attr );
|
||||
unsigned int attr, struct object *root );
|
||||
static void winstation_destroy( struct object *obj );
|
||||
static unsigned int winstation_map_access( struct object *obj, unsigned int access );
|
||||
static void desktop_dump( struct object *obj, int verbose );
|
||||
|
@ -155,7 +155,7 @@ static int winstation_close_handle( struct object *obj, struct process *process,
|
|||
}
|
||||
|
||||
static struct object *winstation_lookup_name( struct object *obj, struct unicode_str *name,
|
||||
unsigned int attr )
|
||||
unsigned int attr, struct object *root )
|
||||
{
|
||||
struct winstation *winstation = (struct winstation *)obj;
|
||||
struct object *found;
|
||||
|
|
Loading…
Reference in New Issue