[PATCH v2 1/4] server: Allow named pipes creation with device file as root directory.
Paul Gofman
pgofman at codeweavers.com
Thu Nov 12 05:35:27 CST 2020
Signed-off-by: Paul Gofman <pgofman at codeweavers.com>
---
v2:
- Do not require directrory parent in get_req_object_attributes().
dlls/ntdll/tests/pipe.c | 34 ++++++++++++++++++++++++++++++++--
server/named_pipe.c | 2 +-
server/object.h | 2 +-
server/request.c | 9 ++++++++-
server/symlink.c | 6 ++++++
5 files changed, 48 insertions(+), 5 deletions(-)
diff --git a/dlls/ntdll/tests/pipe.c b/dlls/ntdll/tests/pipe.c
index 9e8b623d75b..bfc8dc0b3be 100644
--- a/dlls/ntdll/tests/pipe.c
+++ b/dlls/ntdll/tests/pipe.c
@@ -65,6 +65,7 @@ typedef struct {
#endif
static NTSTATUS (WINAPI *pNtFsControlFile) (HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, PVOID apc_context, PIO_STATUS_BLOCK io, ULONG code, PVOID in_buffer, ULONG in_size, PVOID out_buffer, ULONG out_size);
+static NTSTATUS (WINAPI *pNtCreateDirectoryObject)(HANDLE *, ACCESS_MASK, OBJECT_ATTRIBUTES *);
static NTSTATUS (WINAPI *pNtCreateNamedPipeFile) (PHANDLE handle, ULONG access,
POBJECT_ATTRIBUTES attr, PIO_STATUS_BLOCK iosb,
ULONG sharing, ULONG dispo, ULONG options,
@@ -73,6 +74,7 @@ static NTSTATUS (WINAPI *pNtCreateNamedPipeFile) (PHANDLE handle, ULONG access,
ULONG inbound_quota, ULONG outbound_quota,
PLARGE_INTEGER timeout);
static NTSTATUS (WINAPI *pNtQueryInformationFile) (IN HANDLE FileHandle, OUT PIO_STATUS_BLOCK IoStatusBlock, OUT PVOID FileInformation, IN ULONG Length, IN FILE_INFORMATION_CLASS FileInformationClass);
+static NTSTATUS (WINAPI *pNtQueryObject)(HANDLE, OBJECT_INFORMATION_CLASS, void *, ULONG, ULONG *);
static NTSTATUS (WINAPI *pNtQueryVolumeInformationFile)(HANDLE handle, PIO_STATUS_BLOCK io, void *buffer, ULONG length, FS_INFORMATION_CLASS info_class);
static NTSTATUS (WINAPI *pNtSetInformationFile) (HANDLE handle, PIO_STATUS_BLOCK io, PVOID ptr, ULONG len, FILE_INFORMATION_CLASS class);
static NTSTATUS (WINAPI *pNtCancelIoFile) (HANDLE hFile, PIO_STATUS_BLOCK io_status);
@@ -94,8 +96,10 @@ static BOOL init_func_ptrs(void)
}
loadfunc(NtFsControlFile)
+ loadfunc(NtCreateDirectoryObject)
loadfunc(NtCreateNamedPipeFile)
loadfunc(NtQueryInformationFile)
+ loadfunc(NtQueryObject)
loadfunc(NtQueryVolumeInformationFile)
loadfunc(NtSetInformationFile)
loadfunc(NtCancelIoFile)
@@ -2405,14 +2409,20 @@ static void test_security_info(void)
static void test_empty_name(void)
{
HANDLE hdirectory, hpipe, hwrite, handle;
+ OBJECT_TYPE_INFORMATION *type_info;
+ OBJECT_NAME_INFORMATION *name_info;
OBJECT_ATTRIBUTES attr;
LARGE_INTEGER timeout;
UNICODE_STRING name;
IO_STATUS_BLOCK io;
DWORD data, length;
+ char buffer[1024];
NTSTATUS status;
BOOL ret;
+ type_info = (OBJECT_TYPE_INFORMATION *)buffer;
+ name_info = (OBJECT_NAME_INFORMATION *)buffer;
+
hpipe = hwrite = NULL;
attr.Length = sizeof(attr);
@@ -2438,13 +2448,17 @@ static void test_empty_name(void)
&io, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_CREATE, FILE_SYNCHRONOUS_IO_NONALERT,
0, 0, 0, 3, 4096, 4096, &timeout);
todo_wine ok(status == STATUS_OBJECT_NAME_INVALID, "Got unexpected status %#x.\n", status);
-
+ if (!status)
+ CloseHandle(hpipe);
CloseHandle(hdirectory);
pRtlInitUnicodeString(&name, L"\\Device\\NamedPipe\\");
attr.RootDirectory = 0;
attr.ObjectName = &name;
+ status = pNtCreateDirectoryObject(&hdirectory, GENERIC_READ | SYNCHRONIZE, &attr);
+ todo_wine ok(status == STATUS_OBJECT_TYPE_MISMATCH, "Got unexpected status %#x.\n", status);
+
status = NtCreateFile(&hdirectory, GENERIC_READ | SYNCHRONIZE, &attr, &io, NULL, 0,
FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, NULL, 0 );
ok(!status, "Got unexpected status %#x.\n", status);
@@ -2454,10 +2468,18 @@ static void test_empty_name(void)
name.MaximumLength = 0;
attr.RootDirectory = hdirectory;
+ hpipe = NULL;
status = pNtCreateNamedPipeFile(&hpipe, GENERIC_READ | SYNCHRONIZE, &attr,
&io, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_CREATE, FILE_SYNCHRONOUS_IO_NONALERT,
0, 0, 0, 3, 4096, 4096, &timeout);
- todo_wine ok(!status, "Got unexpected status %#x.\n", status);
+ ok(!status, "Got unexpected status %#x.\n", status);
+ type_info->TypeName.Buffer = NULL;
+ status = pNtQueryObject(hpipe, ObjectTypeInformation, type_info, sizeof(buffer), NULL);
+ ok(!status, "Got unexpected status %#x.\n", status);
+ ok(type_info->TypeName.Buffer && !wcscmp(type_info->TypeName.Buffer, L"File"),
+ "Got unexpected type %s.\n", debugstr_w(type_info->TypeName.Buffer));
+ status = pNtQueryObject(hpipe, ObjectNameInformation, name_info, sizeof(buffer), NULL);
+ todo_wine ok(status == STATUS_OBJECT_PATH_INVALID, "Got unexpected status %#x.\n", status);
status = pNtCreateNamedPipeFile(&handle, GENERIC_READ | SYNCHRONIZE, &attr,
&io, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT,
@@ -2469,6 +2491,14 @@ static void test_empty_name(void)
FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0 );
todo_wine ok(!status, "Got unexpected status %#x.\n", status);
+ type_info->TypeName.Buffer = NULL;
+ status = pNtQueryObject(hwrite, ObjectTypeInformation, type_info, sizeof(buffer), NULL);
+ todo_wine ok(!status, "Got unexpected status %#x.\n", status);
+ todo_wine ok(type_info->TypeName.Buffer && !wcscmp(type_info->TypeName.Buffer, L"File"),
+ "Got unexpected type %s.\n", debugstr_w(type_info->TypeName.Buffer));
+ status = pNtQueryObject(hwrite, ObjectNameInformation, name_info, sizeof(buffer), NULL);
+ todo_wine ok(status == STATUS_OBJECT_PATH_INVALID, "Got unexpected status %#x.\n", status);
+
attr.RootDirectory = hpipe;
status = NtCreateFile(&handle, GENERIC_READ | SYNCHRONIZE, &attr, &io, NULL, 0,
FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN,
diff --git a/server/named_pipe.c b/server/named_pipe.c
index 60bd059d93d..3a8cd2fb919 100644
--- a/server/named_pipe.c
+++ b/server/named_pipe.c
@@ -1371,7 +1371,7 @@ DECL_HANDLER(create_named_pipe)
set_error( STATUS_OBJECT_PATH_SYNTAX_BAD );
return;
}
- if (!(root = get_directory_obj( current->process, objattr->rootdir ))) return;
+ if (!(root = get_handle_obj( current->process, objattr->rootdir, 0, NULL ))) return;
}
pipe = create_named_object( root, &named_pipe_ops, &name, objattr->attributes | OBJ_OPENIF, NULL );
diff --git a/server/object.h b/server/object.h
index 394a4aac463..678e1b8a3fc 100644
--- a/server/object.h
+++ b/server/object.h
@@ -253,7 +253,7 @@ extern struct object *create_obj_symlink( struct object *root, const struct unic
extern struct object *create_symlink( struct object *root, const struct unicode_str *name,
unsigned int attr, const struct unicode_str *target,
const struct security_descriptor *sd );
-
+extern BOOL is_symlink_obj( struct object *obj );
/* global variables */
/* command-line options */
diff --git a/server/request.c b/server/request.c
index 97bf1a746d2..b1de1243c03 100644
--- a/server/request.c
+++ b/server/request.c
@@ -66,6 +66,7 @@
#include "process.h"
#include "thread.h"
#include "security.h"
+#include "handle.h"
#define WANT_REQUEST_HANDLERS
#include "request.h"
@@ -205,7 +206,13 @@ const struct object_attributes *get_req_object_attributes( const struct security
}
if (root && attr->rootdir && attr->name_len)
{
- if (!(*root = get_directory_obj( current->process, attr->rootdir ))) return NULL;
+ if (!(*root = get_handle_obj( current->process, attr->rootdir, 0, NULL ))) return NULL;
+ if (is_symlink_obj( *root ))
+ {
+ release_object( *root );
+ set_error( STATUS_OBJECT_TYPE_MISMATCH );
+ return NULL;
+ }
}
*sd = attr->sd_len ? (const struct security_descriptor *)(attr + 1) : NULL;
name->len = attr->name_len;
diff --git a/server/symlink.c b/server/symlink.c
index b620f2accb9..ce90c0ebcb3 100644
--- a/server/symlink.c
+++ b/server/symlink.c
@@ -182,6 +182,12 @@ struct object *create_obj_symlink( struct object *root, const struct unicode_str
}
+BOOL is_symlink_obj( struct object *obj )
+{
+ return obj->ops == &symlink_ops;
+}
+
+
/* create a symbolic link object */
DECL_HANDLER(create_symlink)
{
--
2.28.0
More information about the wine-devel
mailing list