security/sandbox/win/src/policy_target.cc

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/security/sandbox/win/src/policy_target.cc	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,127 @@
     1.4 +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
     1.5 +// Use of this source code is governed by a BSD-style license that can be
     1.6 +// found in the LICENSE file.
     1.7 +
     1.8 +#include "sandbox/win/src/policy_target.h"
     1.9 +
    1.10 +#include "sandbox/win/src/crosscall_client.h"
    1.11 +#include "sandbox/win/src/ipc_tags.h"
    1.12 +#include "sandbox/win/src/policy_engine_processor.h"
    1.13 +#include "sandbox/win/src/policy_low_level.h"
    1.14 +#include "sandbox/win/src/policy_params.h"
    1.15 +#include "sandbox/win/src/sandbox_factory.h"
    1.16 +#include "sandbox/win/src/sandbox_nt_util.h"
    1.17 +#include "sandbox/win/src/sharedmem_ipc_client.h"
    1.18 +#include "sandbox/win/src/target_services.h"
    1.19 +
    1.20 +namespace sandbox {
    1.21 +
    1.22 +// Handle for our private heap.
    1.23 +extern void* g_heap;
    1.24 +
    1.25 +// This is the list of all imported symbols from ntdll.dll.
    1.26 +SANDBOX_INTERCEPT NtExports g_nt;
    1.27 +
    1.28 +// Policy data.
    1.29 +extern void* volatile     g_shared_policy_memory;
    1.30 +SANDBOX_INTERCEPT size_t  g_shared_policy_size;
    1.31 +
    1.32 +bool QueryBroker(int ipc_id, CountedParameterSetBase* params) {
    1.33 +  DCHECK_NT(static_cast<size_t>(ipc_id) < kMaxServiceCount);
    1.34 +  DCHECK_NT(g_shared_policy_memory);
    1.35 +  DCHECK_NT(g_shared_policy_size > 0);
    1.36 +
    1.37 +  if (static_cast<size_t>(ipc_id) >= kMaxServiceCount)
    1.38 +    return false;
    1.39 +
    1.40 +  PolicyGlobal* global_policy =
    1.41 +      reinterpret_cast<PolicyGlobal*>(g_shared_policy_memory);
    1.42 +
    1.43 +  if (!global_policy->entry[ipc_id])
    1.44 +    return false;
    1.45 +
    1.46 +  PolicyBuffer* policy = reinterpret_cast<PolicyBuffer*>(
    1.47 +      reinterpret_cast<char*>(g_shared_policy_memory) +
    1.48 +      reinterpret_cast<size_t>(global_policy->entry[ipc_id]));
    1.49 +
    1.50 +  if ((reinterpret_cast<size_t>(global_policy->entry[ipc_id]) >
    1.51 +       global_policy->data_size) ||
    1.52 +      (g_shared_policy_size < global_policy->data_size)) {
    1.53 +    NOTREACHED_NT();
    1.54 +    return false;
    1.55 +  }
    1.56 +
    1.57 +  for (int i = 0; i < params->count; i++) {
    1.58 +    if (!params->parameters[i].IsValid()) {
    1.59 +      NOTREACHED_NT();
    1.60 +      return false;
    1.61 +    }
    1.62 +  }
    1.63 +
    1.64 +  PolicyProcessor processor(policy);
    1.65 +  PolicyResult result = processor.Evaluate(kShortEval, params->parameters,
    1.66 +                                           params->count);
    1.67 +  DCHECK_NT(POLICY_ERROR != result);
    1.68 +
    1.69 +  return POLICY_MATCH == result && ASK_BROKER == processor.GetAction();
    1.70 +}
    1.71 +
    1.72 +// -----------------------------------------------------------------------
    1.73 +
    1.74 +// Hooks NtSetInformationThread to block RevertToSelf from being
    1.75 +// called before the actual call to LowerToken.
    1.76 +NTSTATUS WINAPI TargetNtSetInformationThread(
    1.77 +    NtSetInformationThreadFunction orig_SetInformationThread, HANDLE thread,
    1.78 +    NT_THREAD_INFORMATION_CLASS thread_info_class, PVOID thread_information,
    1.79 +    ULONG thread_information_bytes) {
    1.80 +  do {
    1.81 +    if (SandboxFactory::GetTargetServices()->GetState()->RevertedToSelf())
    1.82 +      break;
    1.83 +    if (ThreadImpersonationToken != thread_info_class)
    1.84 +      break;
    1.85 +    if (!thread_information)
    1.86 +      break;
    1.87 +    HANDLE token;
    1.88 +    if (sizeof(token) > thread_information_bytes)
    1.89 +      break;
    1.90 +
    1.91 +    NTSTATUS ret = CopyData(&token, thread_information, sizeof(token));
    1.92 +    if (!NT_SUCCESS(ret) || NULL != token)
    1.93 +      break;
    1.94 +
    1.95 +    // This is a revert to self.
    1.96 +    return STATUS_SUCCESS;
    1.97 +  } while (false);
    1.98 +
    1.99 +  return orig_SetInformationThread(thread, thread_info_class,
   1.100 +                                   thread_information,
   1.101 +                                   thread_information_bytes);
   1.102 +}
   1.103 +
   1.104 +// Hooks NtOpenThreadToken to force the open_as_self parameter to be set to
   1.105 +// FALSE if we are still running with the impersonation token. open_as_self set
   1.106 +// to TRUE means that the token will be open using the process token instead of
   1.107 +// the impersonation token. This is bad because the process token does not have
   1.108 +// access to open the thread token.
   1.109 +NTSTATUS WINAPI TargetNtOpenThreadToken(
   1.110 +    NtOpenThreadTokenFunction orig_OpenThreadToken, HANDLE thread,
   1.111 +    ACCESS_MASK desired_access, BOOLEAN open_as_self, PHANDLE token) {
   1.112 +  if (!SandboxFactory::GetTargetServices()->GetState()->RevertedToSelf())
   1.113 +    open_as_self = FALSE;
   1.114 +
   1.115 +  return orig_OpenThreadToken(thread, desired_access, open_as_self, token);
   1.116 +}
   1.117 +
   1.118 +// See comment for TargetNtOpenThreadToken
   1.119 +NTSTATUS WINAPI TargetNtOpenThreadTokenEx(
   1.120 +    NtOpenThreadTokenExFunction orig_OpenThreadTokenEx, HANDLE thread,
   1.121 +    ACCESS_MASK desired_access, BOOLEAN open_as_self, ULONG handle_attributes,
   1.122 +    PHANDLE token) {
   1.123 +  if (!SandboxFactory::GetTargetServices()->GetState()->RevertedToSelf())
   1.124 +    open_as_self = FALSE;
   1.125 +
   1.126 +  return orig_OpenThreadTokenEx(thread, desired_access, open_as_self,
   1.127 +                                handle_attributes, token);
   1.128 +}
   1.129 +
   1.130 +}  // namespace sandbox

mercurial