Bernhard Loos : server: Correctly implement permission checking for named pipes.

Alexandre Julliard julliard at winehq.org
Sat Oct 8 15:16:36 CDT 2011


Module: wine
Branch: master
Commit: 9034e694a36df25fadd654c29a13bdd1444bbd6a
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=9034e694a36df25fadd654c29a13bdd1444bbd6a

Author: Bernhard Loos <bernhardloos at googlemail.com>
Date:   Thu Sep 29 11:20:50 2011 +0200

server: Correctly implement permission checking for named pipes.

---

 dlls/ntdll/tests/pipe.c |   52 +++++++++++++++++++++++++++++++++++++++++++++++
 server/named_pipe.c     |   10 +++++++++
 2 files changed, 62 insertions(+), 0 deletions(-)

diff --git a/dlls/ntdll/tests/pipe.c b/dlls/ntdll/tests/pipe.c
index 26c38b0..e7c49b8 100644
--- a/dlls/ntdll/tests/pipe.c
+++ b/dlls/ntdll/tests/pipe.c
@@ -172,6 +172,55 @@ static void test_create_invalid(void)
     CloseHandle(handle);
 }
 
+static void test_create(void)
+{
+    HANDLE hserver;
+    NTSTATUS res;
+    int j, k;
+    FILE_PIPE_LOCAL_INFORMATION info;
+    IO_STATUS_BLOCK iosb;
+
+    static const DWORD access[] = { 0, GENERIC_READ, GENERIC_WRITE, GENERIC_READ | GENERIC_WRITE};
+    static const DWORD sharing[] = { FILE_SHARE_READ, FILE_SHARE_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE };
+
+    for (j = 0; j < sizeof(sharing) / sizeof(DWORD); j++) {
+        for (k = 0; k < sizeof(access) / sizeof(DWORD); k++) {
+            HANDLE hclient;
+            BOOL should_succeed = TRUE;
+
+            res  = create_pipe(&hserver, sharing[j], FILE_SYNCHRONOUS_IO_NONALERT);
+            if (res) {
+                ok(0, "NtCreateNamedPipeFile returned %x, sharing: %x\n", res, sharing[j]);
+                continue;
+            }
+
+            res = pNtQueryInformationFile(hserver, &iosb, &info, sizeof(info), (FILE_INFORMATION_CLASS)24);
+            ok(!res, "NtQueryInformationFile for server returned %x, sharing: %x\n", res, sharing[j]);
+
+            hclient = CreateFileW(testpipe, access[k], 0, 0, OPEN_EXISTING, 0, 0);
+            if (hclient != INVALID_HANDLE_VALUE) {
+                res = pNtQueryInformationFile(hclient, &iosb, &info, sizeof(info), (FILE_INFORMATION_CLASS)24);
+                ok(!res, "NtQueryInformationFile for client returned %x, access: %x, sharing: %x\n",
+                   res, access[k], sharing[j]);
+                CloseHandle(hclient);
+            }
+
+            if (access[k] & GENERIC_WRITE)
+                should_succeed &= !!(sharing[j] & FILE_SHARE_WRITE);
+            if (access[k] & GENERIC_READ)
+                should_succeed &= !!(sharing[j] & FILE_SHARE_READ);
+
+            if (should_succeed)
+                ok(hclient != INVALID_HANDLE_VALUE, "CreateFile failed for sharing %x, access: %x, GetLastError: %d\n",
+                   sharing[j], access[k], GetLastError());
+            else
+                ok(hclient == INVALID_HANDLE_VALUE, "CreateFile succeded for sharing %x, access: %x\n", sharing[j], access[k]);
+
+            CloseHandle(hserver);
+        }
+    }
+}
+
 static BOOL ioapc_called;
 static void CALLBACK ioapc(void *arg, PIO_STATUS_BLOCK io, ULONG reserved)
 {
@@ -419,6 +468,9 @@ START_TEST(pipe)
     trace("starting invalid create tests\n");
     test_create_invalid();
 
+    trace("starting create tests\n");
+    test_create();
+
     trace("starting overlapped tests\n");
     test_overlapped();
 
diff --git a/server/named_pipe.c b/server/named_pipe.c
index 750f3bc..d6c1383 100644
--- a/server/named_pipe.c
+++ b/server/named_pipe.c
@@ -804,6 +804,7 @@ static struct object *named_pipe_open_file( struct object *obj, unsigned int acc
     struct named_pipe *pipe = (struct named_pipe *)obj;
     struct pipe_server *server;
     struct pipe_client *client;
+    unsigned int pipe_sharing;
     int fds[2];
 
     if (!(server = find_available_server( pipe )))
@@ -812,6 +813,15 @@ static struct object *named_pipe_open_file( struct object *obj, unsigned int acc
         return NULL;
     }
 
+    pipe_sharing = server->pipe->sharing;
+    if (((access & GENERIC_READ) && !(pipe_sharing & FILE_SHARE_READ)) ||
+        ((access & GENERIC_WRITE) && !(pipe_sharing & FILE_SHARE_WRITE)))
+    {
+        set_error( STATUS_ACCESS_DENIED );
+        release_object( server );
+        return NULL;
+    }
+
     if ((client = create_pipe_client( options )))
     {
         if (!socketpair( PF_UNIX, SOCK_STREAM, 0, fds ))




More information about the wine-cvs mailing list