[5/6] server: implement passing a process security descriptor to CreateProcess

Joris van der Wel joris at jorisvanderwel.com
Sun Jul 6 13:19:20 CDT 2014


server: implement passing a process security descriptor to
 CreateProcess

---
 dlls/advapi32/tests/security.c |  3 ---
 dlls/kernel32/process.c        | 22 +++++++++++++++++++++-
 server/process.c               | 24 ++++++++++++++++++++++++
 3 files changed, 45 insertions(+), 4 deletions(-)
-------------- next part --------------
From 82cd10a7b63129a50b30c6e4a5c6f24e156b6cc5 Mon Sep 17 00:00:00 2001
From: Joris van der Wel <joris at jorisvanderwel.com>
Date: Sun, 6 Jul 2014 16:44:03 +0200
Subject: server: implement passing a process security descriptor to
 CreateProcess

---
 dlls/advapi32/tests/security.c |  3 ---
 dlls/kernel32/process.c        | 22 +++++++++++++++++++++-
 server/process.c               | 24 ++++++++++++++++++++++++
 3 files changed, 45 insertions(+), 4 deletions(-)

diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c
index 7ee1bd8..669472d 100644
--- a/dlls/advapi32/tests/security.c
+++ b/dlls/advapi32/tests/security.c
@@ -2695,7 +2695,6 @@ static void test_process_security_child(void)
     ret = DuplicateHandle( GetCurrentProcess(), handle, GetCurrentProcess(),
                            &handle1, PROCESS_ALL_ACCESS, TRUE, 0 );
     err = GetLastError();
-    todo_wine
     ok(!ret && err == ERROR_ACCESS_DENIED, "duplicating handle should have failed "
        "with STATUS_ACCESS_DENIED, instead of err:%d\n", err);
 
@@ -2703,10 +2702,8 @@ static void test_process_security_child(void)
 
     /* These two should fail - they are denied by ACL */
     handle = OpenProcess( PROCESS_VM_READ, FALSE, GetCurrentProcessId() );
-    todo_wine
     ok(handle == NULL, "OpenProcess(PROCESS_VM_READ) should have failed\n");
     handle = OpenProcess( PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId() );
-    todo_wine
     ok(handle == NULL, "OpenProcess(PROCESS_ALL_ACCESS) should have failed\n");
 
     /* Documented privilege elevation */
diff --git a/dlls/kernel32/process.c b/dlls/kernel32/process.c
index 082a6ea..e4db5be 100644
--- a/dlls/kernel32/process.c
+++ b/dlls/kernel32/process.c
@@ -1939,17 +1939,32 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW
     int socketfd[2], stdin_fd = -1, stdout_fd = -1;
     pid_t pid;
     int err, cpu;
+    struct security_descriptor *psd = NULL;
+    data_size_t psd_len = 0;
+
 
     if ((cpu = get_process_cpu( filename, binary_info )) == -1)
     {
         SetLastError( ERROR_BAD_EXE_FORMAT );
         return FALSE;
+    }    
+        
+    if (psa && (psa->nLength >= sizeof(*psa)) && psa->lpSecurityDescriptor)
+    {
+        status = wine_server_create_struct_sd( psa->lpSecurityDescriptor, &psd, &psd_len );
+        if (status != STATUS_SUCCESS)
+        {
+            WARN("Invalid process security descriptor with status %x\n", status);
+            SetLastError( RtlNtStatusToDosError(status) );
+            return FALSE;
+        }
     }
 
     /* create the socket for the new process */
 
     if (socketpair( PF_UNIX, SOCK_STREAM, 0, socketfd ) == -1)
     {
+        wine_server_free_struct_sd( psd );
         SetLastError( ERROR_TOO_MANY_OPEN_FILES );
         return FALSE;
     }
@@ -1989,6 +2004,7 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW
                          winedebug, binary_info, TRUE );
         }
         close( socketfd[0] );
+        wine_server_free_struct_sd( psd );
         SetLastError( RtlNtStatusToDosError( status ));
         return FALSE;
     }
@@ -2001,6 +2017,7 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW
         RtlReleasePebLock();
         close( socketfd[0] );
         close( socketfd[1] );
+        wine_server_free_struct_sd( psd );
         return FALSE;
     }
     if (!env) env = NtCurrentTeb()->Peb->ProcessParameters->Environment;
@@ -2034,11 +2051,12 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW
         req->thread_access   = THREAD_ALL_ACCESS;
         req->thread_attr     = (tsa && (tsa->nLength >= sizeof(*tsa)) && tsa->bInheritHandle) ? OBJ_INHERIT : 0;
         req->cpu             = cpu;
-        req->process_sd_size = 0;  
+        req->process_sd_size = psd_len;
         req->thread_sd_size  = 0;
         req->info_size       = startup_info_size;
         req->env_size        = (env_end - env) * sizeof(WCHAR);
         
+        wine_server_add_data( req, psd         , req->process_sd_size );
         wine_server_add_data( req, startup_info, req->info_size       );
         wine_server_add_data( req, env         , req->env_size        );
         
@@ -2053,6 +2071,8 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW
     }
     SERVER_END_REQ;
 
+    wine_server_free_struct_sd( psd );
+
     RtlReleasePebLock();
     if (status)
     {
diff --git a/server/process.c b/server/process.c
index 6c004f4..d1db87a 100644
--- a/server/process.c
+++ b/server/process.c
@@ -883,6 +883,7 @@ DECL_HANDLER(new_process)
     const startup_info_t *req_info;
     data_size_t req_info_size;
     const WCHAR *req_env;
+    const struct security_descriptor *req_psd = NULL;
 
     if (socket_fd == -1)
     {
@@ -907,6 +908,17 @@ DECL_HANDLER(new_process)
         return;
     }
     
+    if (req->process_sd_size)
+    {
+        req_psd = get_req_data();
+        
+        if (!sd_is_valid( req_psd, req->process_sd_size ))
+        {
+            set_error( STATUS_INVALID_SECURITY_DESCR );
+            return;
+        }
+    }
+    
     req_info = (const startup_info_t *)
                ((char*)get_req_data() + req->process_sd_size + req->thread_sd_size);
     
@@ -1013,6 +1025,18 @@ DECL_HANDLER(new_process)
     reply->phandle = alloc_handle( parent, process, req->process_access, req->process_attr );
     reply->thandle = alloc_handle( parent, thread, req->thread_access, req->thread_attr );
 
+    /* note: alloc_handle might fail with access denied 
+     * if the security descriptor is set before that call */
+    
+    if (req_psd)
+    {
+        default_set_sd( &process->obj,
+                        req_psd,
+                        OWNER_SECURITY_INFORMATION|
+                        GROUP_SECURITY_INFORMATION|
+                        DACL_SECURITY_INFORMATION|
+                        SACL_SECURITY_INFORMATION );
+    }
  done:
     release_object( info );
 }
-- 
1.8.1.msysgit.1



More information about the wine-patches mailing list