security/sandbox/win/src/process_thread_policy.cc

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
     2 // Use of this source code is governed by a BSD-style license that can be
     3 // found in the LICENSE file.
     5 #include "sandbox/win/src/process_thread_policy.h"
     7 #include <string>
     9 #include "base/memory/scoped_ptr.h"
    10 #include "sandbox/win/src/ipc_tags.h"
    11 #include "sandbox/win/src/nt_internals.h"
    12 #include "sandbox/win/src/policy_engine_opcodes.h"
    13 #include "sandbox/win/src/policy_params.h"
    14 #include "sandbox/win/src/sandbox_types.h"
    15 #include "sandbox/win/src/win_utils.h"
    17 namespace {
    19 // These are the only safe rights that can be given to a sandboxed
    20 // process for the process created by the broker. All others are potential
    21 // vectors of privilege elevation.
    22 const DWORD kProcessRights = SYNCHRONIZE |
    23                              PROCESS_QUERY_INFORMATION |
    24                              PROCESS_QUERY_LIMITED_INFORMATION |
    25                              PROCESS_TERMINATE |
    26                              PROCESS_SUSPEND_RESUME;
    28 const DWORD kThreadRights = SYNCHRONIZE |
    29                             THREAD_TERMINATE |
    30                             THREAD_SUSPEND_RESUME |
    31                             THREAD_QUERY_INFORMATION |
    32                             THREAD_QUERY_LIMITED_INFORMATION |
    33                             THREAD_SET_LIMITED_INFORMATION;
    35 // Creates a child process and duplicates the handles to 'target_process'. The
    36 // remaining parameters are the same as CreateProcess().
    37 BOOL CreateProcessExWHelper(HANDLE target_process, BOOL give_full_access,
    38                             LPCWSTR lpApplicationName, LPWSTR lpCommandLine,
    39                             LPSECURITY_ATTRIBUTES lpProcessAttributes,
    40                             LPSECURITY_ATTRIBUTES lpThreadAttributes,
    41                             BOOL bInheritHandles, DWORD dwCreationFlags,
    42                             LPVOID lpEnvironment, LPCWSTR lpCurrentDirectory,
    43                             LPSTARTUPINFOW lpStartupInfo,
    44                             LPPROCESS_INFORMATION lpProcessInformation) {
    45   if (!::CreateProcessW(lpApplicationName, lpCommandLine, lpProcessAttributes,
    46                         lpThreadAttributes, bInheritHandles, dwCreationFlags,
    47                         lpEnvironment, lpCurrentDirectory, lpStartupInfo,
    48                         lpProcessInformation)) {
    49     return FALSE;
    50   }
    52   DWORD process_access = kProcessRights;
    53   DWORD thread_access = kThreadRights;
    54   if (give_full_access) {
    55     process_access = PROCESS_ALL_ACCESS;
    56     thread_access = THREAD_ALL_ACCESS;
    57   }
    58   if (!::DuplicateHandle(::GetCurrentProcess(), lpProcessInformation->hProcess,
    59                          target_process, &lpProcessInformation->hProcess,
    60                          process_access, FALSE, DUPLICATE_CLOSE_SOURCE)) {
    61     ::CloseHandle(lpProcessInformation->hThread);
    62     return FALSE;
    63   }
    64   if (!::DuplicateHandle(::GetCurrentProcess(), lpProcessInformation->hThread,
    65                          target_process, &lpProcessInformation->hThread,
    66                          thread_access, FALSE, DUPLICATE_CLOSE_SOURCE)) {
    67     return FALSE;
    68   }
    69   return TRUE;
    70 }
    72 }
    74 namespace sandbox {
    76 bool ProcessPolicy::GenerateRules(const wchar_t* name,
    77                                   TargetPolicy::Semantics semantics,
    78                                   LowLevelPolicy* policy) {
    79   scoped_ptr<PolicyRule> process;
    80   switch (semantics) {
    81     case TargetPolicy::PROCESS_MIN_EXEC: {
    82       process.reset(new PolicyRule(GIVE_READONLY));
    83       break;
    84     };
    85     case TargetPolicy::PROCESS_ALL_EXEC: {
    86       process.reset(new PolicyRule(GIVE_ALLACCESS));
    87       break;
    88     };
    89     default: {
    90       return false;
    91     };
    92   }
    94   if (!process->AddStringMatch(IF, NameBased::NAME, name, CASE_INSENSITIVE)) {
    95     return false;
    96   }
    97   if (!policy->AddRule(IPC_CREATEPROCESSW_TAG, process.get())) {
    98     return false;
    99   }
   100   return true;
   101 }
   103 NTSTATUS ProcessPolicy::OpenThreadAction(const ClientInfo& client_info,
   104                                          uint32 desired_access,
   105                                          uint32 thread_id,
   106                                          HANDLE* handle) {
   107   *handle = NULL;
   109   NtOpenThreadFunction NtOpenThread = NULL;
   110   ResolveNTFunctionPtr("NtOpenThread", &NtOpenThread);
   112   OBJECT_ATTRIBUTES attributes = {0};
   113   attributes.Length = sizeof(attributes);
   114   CLIENT_ID client_id = {0};
   115   client_id.UniqueProcess = reinterpret_cast<PVOID>(
   116                                 static_cast<ULONG_PTR>(client_info.process_id));
   117   client_id.UniqueThread =
   118       reinterpret_cast<PVOID>(static_cast<ULONG_PTR>(thread_id));
   120   HANDLE local_handle;
   121   NTSTATUS status = NtOpenThread(&local_handle, desired_access, &attributes,
   122                                  &client_id);
   123   if (NT_SUCCESS(status)) {
   124     if (!::DuplicateHandle(::GetCurrentProcess(), local_handle,
   125                            client_info.process, handle, 0, FALSE,
   126                            DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) {
   127       ::CloseHandle(local_handle);
   128       return STATUS_ACCESS_DENIED;
   129     }
   130   }
   132   return status;
   133 }
   135 NTSTATUS ProcessPolicy::OpenProcessAction(const ClientInfo& client_info,
   136                                           uint32 desired_access,
   137                                           uint32 process_id,
   138                                           HANDLE* handle) {
   139   *handle = NULL;
   141   NtOpenProcessFunction NtOpenProcess = NULL;
   142   ResolveNTFunctionPtr("NtOpenProcess", &NtOpenProcess);
   144   if (client_info.process_id != process_id)
   145     return STATUS_ACCESS_DENIED;
   147   OBJECT_ATTRIBUTES attributes = {0};
   148   attributes.Length = sizeof(attributes);
   149   CLIENT_ID client_id = {0};
   150   client_id.UniqueProcess = reinterpret_cast<PVOID>(
   151                                 static_cast<ULONG_PTR>(client_info.process_id));
   152   HANDLE local_handle;
   153   NTSTATUS status = NtOpenProcess(&local_handle, desired_access, &attributes,
   154                                   &client_id);
   155   if (NT_SUCCESS(status)) {
   156     if (!::DuplicateHandle(::GetCurrentProcess(), local_handle,
   157                            client_info.process, handle, 0, FALSE,
   158                            DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) {
   159       ::CloseHandle(local_handle);
   160       return STATUS_ACCESS_DENIED;
   161     }
   162   }
   164   return status;
   165 }
   167 NTSTATUS ProcessPolicy::OpenProcessTokenAction(const ClientInfo& client_info,
   168                                                HANDLE process,
   169                                                uint32 desired_access,
   170                                                HANDLE* handle) {
   171   *handle = NULL;
   172   NtOpenProcessTokenFunction NtOpenProcessToken = NULL;
   173   ResolveNTFunctionPtr("NtOpenProcessToken", &NtOpenProcessToken);
   175   if (CURRENT_PROCESS != process)
   176     return STATUS_ACCESS_DENIED;
   178   HANDLE local_handle;
   179   NTSTATUS status = NtOpenProcessToken(client_info.process, desired_access,
   180                                        &local_handle);
   181   if (NT_SUCCESS(status)) {
   182     if (!::DuplicateHandle(::GetCurrentProcess(), local_handle,
   183                            client_info.process, handle, 0, FALSE,
   184                            DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) {
   185       ::CloseHandle(local_handle);
   186       return STATUS_ACCESS_DENIED;
   187     }
   188   }
   189   return status;
   190 }
   192 NTSTATUS ProcessPolicy::OpenProcessTokenExAction(const ClientInfo& client_info,
   193                                                  HANDLE process,
   194                                                  uint32 desired_access,
   195                                                  uint32 attributes,
   196                                                  HANDLE* handle) {
   197   *handle = NULL;
   198   NtOpenProcessTokenExFunction NtOpenProcessTokenEx = NULL;
   199   ResolveNTFunctionPtr("NtOpenProcessTokenEx", &NtOpenProcessTokenEx);
   201   if (CURRENT_PROCESS != process)
   202     return STATUS_ACCESS_DENIED;
   204   HANDLE local_handle;
   205   NTSTATUS status = NtOpenProcessTokenEx(client_info.process, desired_access,
   206                                          attributes, &local_handle);
   207   if (NT_SUCCESS(status)) {
   208     if (!::DuplicateHandle(::GetCurrentProcess(), local_handle,
   209                            client_info.process, handle, 0, FALSE,
   210                            DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) {
   211       ::CloseHandle(local_handle);
   212       return STATUS_ACCESS_DENIED;
   213     }
   214   }
   215   return status;
   216 }
   218 DWORD ProcessPolicy::CreateProcessWAction(EvalResult eval_result,
   219                                           const ClientInfo& client_info,
   220                                           const std::wstring &app_name,
   221                                           const std::wstring &command_line,
   222                                           PROCESS_INFORMATION* process_info) {
   223   // The only action supported is ASK_BROKER which means create the process.
   224   if (GIVE_ALLACCESS != eval_result && GIVE_READONLY != eval_result) {
   225     return ERROR_ACCESS_DENIED;
   226   }
   228   STARTUPINFO startup_info = {0};
   229   startup_info.cb = sizeof(startup_info);
   230   scoped_ptr_malloc<wchar_t> cmd_line(_wcsdup(command_line.c_str()));
   232   BOOL should_give_full_access = (GIVE_ALLACCESS == eval_result);
   233   if (!CreateProcessExWHelper(client_info.process, should_give_full_access,
   234                               app_name.c_str(), cmd_line.get(), NULL, NULL,
   235                               FALSE, 0, NULL, NULL, &startup_info,
   236                               process_info)) {
   237     return ERROR_ACCESS_DENIED;
   238   }
   239   return ERROR_SUCCESS;
   240 }
   242 }  // namespace sandbox

mercurial