1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/sandbox/win/src/app_container.cc Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,182 @@ 1.4 +// Copyright (c) 2012 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/app_container.h" 1.9 + 1.10 +#include <Sddl.h> 1.11 +#include <vector> 1.12 + 1.13 +#include "base/logging.h" 1.14 +#include "base/memory/scoped_ptr.h" 1.15 +#include "base/win/startup_information.h" 1.16 +#include "sandbox/win/src/internal_types.h" 1.17 + 1.18 +namespace { 1.19 + 1.20 +// Converts the passed in sid string to a PSID that must be relased with 1.21 +// LocalFree. 1.22 +PSID ConvertSid(const string16& sid) { 1.23 + PSID local_sid; 1.24 + if (!ConvertStringSidToSid(sid.c_str(), &local_sid)) 1.25 + return NULL; 1.26 + return local_sid; 1.27 +} 1.28 + 1.29 +template <typename T> 1.30 +T BindFunction(const char* name) { 1.31 + HMODULE module = GetModuleHandle(sandbox::kKerneldllName); 1.32 + void* function = GetProcAddress(module, name); 1.33 + if (!function) { 1.34 + module = GetModuleHandle(sandbox::kKernelBasedllName); 1.35 + function = GetProcAddress(module, name); 1.36 + } 1.37 + return reinterpret_cast<T>(function); 1.38 +} 1.39 + 1.40 +} // namespace 1.41 + 1.42 +namespace sandbox { 1.43 + 1.44 +AppContainerAttributes::AppContainerAttributes() { 1.45 + memset(&capabilities_, 0, sizeof(capabilities_)); 1.46 +} 1.47 + 1.48 +AppContainerAttributes::~AppContainerAttributes() { 1.49 + for (size_t i = 0; i < attributes_.size(); i++) 1.50 + LocalFree(attributes_[i].Sid); 1.51 + LocalFree(capabilities_.AppContainerSid); 1.52 +} 1.53 + 1.54 +ResultCode AppContainerAttributes::SetAppContainer( 1.55 + const string16& app_container_sid, 1.56 + const std::vector<string16>& capabilities) { 1.57 + DCHECK(!capabilities_.AppContainerSid); 1.58 + DCHECK(attributes_.empty()); 1.59 + capabilities_.AppContainerSid = ConvertSid(app_container_sid); 1.60 + if (!capabilities_.AppContainerSid) 1.61 + return SBOX_ERROR_INVALID_APP_CONTAINER; 1.62 + 1.63 + for (size_t i = 0; i < capabilities.size(); i++) { 1.64 + SID_AND_ATTRIBUTES sid_and_attributes; 1.65 + sid_and_attributes.Sid = ConvertSid(capabilities[i]); 1.66 + if (!sid_and_attributes.Sid) 1.67 + return SBOX_ERROR_INVALID_CAPABILITY; 1.68 + 1.69 + sid_and_attributes.Attributes = SE_GROUP_ENABLED; 1.70 + attributes_.push_back(sid_and_attributes); 1.71 + } 1.72 + 1.73 + if (capabilities.size()) { 1.74 + capabilities_.CapabilityCount = static_cast<DWORD>(capabilities.size()); 1.75 + capabilities_.Capabilities = &attributes_[0]; 1.76 + } 1.77 + return SBOX_ALL_OK; 1.78 +} 1.79 + 1.80 +ResultCode AppContainerAttributes::ShareForStartup( 1.81 + base::win::StartupInformation* startup_information) const { 1.82 + // The only thing we support so far is an AppContainer. 1.83 + if (!capabilities_.AppContainerSid) 1.84 + return SBOX_ERROR_INVALID_APP_CONTAINER; 1.85 + 1.86 + if (!startup_information->UpdateProcThreadAttribute( 1.87 + PROC_THREAD_ATTRIBUTE_SECURITY_CAPABILITIES, 1.88 + const_cast<SECURITY_CAPABILITIES*>(&capabilities_), 1.89 + sizeof(capabilities_))) { 1.90 + DPLOG(ERROR) << "Failed UpdateProcThreadAttribute"; 1.91 + return SBOX_ERROR_CANNOT_INIT_APPCONTAINER; 1.92 + } 1.93 + return SBOX_ALL_OK; 1.94 +} 1.95 + 1.96 +bool AppContainerAttributes::HasAppContainer() const { 1.97 + return (capabilities_.AppContainerSid != NULL); 1.98 +} 1.99 + 1.100 +ResultCode CreateAppContainer(const string16& sid, const string16& name) { 1.101 + PSID local_sid; 1.102 + if (!ConvertStringSidToSid(sid.c_str(), &local_sid)) 1.103 + return SBOX_ERROR_INVALID_APP_CONTAINER; 1.104 + 1.105 + typedef HRESULT (WINAPI* AppContainerRegisterSidPtr)(PSID sid, 1.106 + LPCWSTR moniker, 1.107 + LPCWSTR display_name); 1.108 + static AppContainerRegisterSidPtr AppContainerRegisterSid = NULL; 1.109 + 1.110 + if (!AppContainerRegisterSid) { 1.111 + AppContainerRegisterSid = 1.112 + BindFunction<AppContainerRegisterSidPtr>("AppContainerRegisterSid"); 1.113 + } 1.114 + 1.115 + ResultCode operation_result = SBOX_ERROR_GENERIC; 1.116 + if (AppContainerRegisterSid) { 1.117 + HRESULT rv = AppContainerRegisterSid(local_sid, name.c_str(), name.c_str()); 1.118 + if (SUCCEEDED(rv)) 1.119 + operation_result = SBOX_ALL_OK; 1.120 + else 1.121 + DLOG(ERROR) << "AppContainerRegisterSid error:" << std::hex << rv; 1.122 + } 1.123 + LocalFree(local_sid); 1.124 + return operation_result; 1.125 +} 1.126 + 1.127 +ResultCode DeleteAppContainer(const string16& sid) { 1.128 + PSID local_sid; 1.129 + if (!ConvertStringSidToSid(sid.c_str(), &local_sid)) 1.130 + return SBOX_ERROR_INVALID_APP_CONTAINER; 1.131 + 1.132 + typedef HRESULT (WINAPI* AppContainerUnregisterSidPtr)(PSID sid); 1.133 + static AppContainerUnregisterSidPtr AppContainerUnregisterSid = NULL; 1.134 + 1.135 + if (!AppContainerUnregisterSid) { 1.136 + AppContainerUnregisterSid = 1.137 + BindFunction<AppContainerUnregisterSidPtr>("AppContainerUnregisterSid"); 1.138 + } 1.139 + 1.140 + ResultCode operation_result = SBOX_ERROR_GENERIC; 1.141 + if (AppContainerUnregisterSid) { 1.142 + HRESULT rv = AppContainerUnregisterSid(local_sid); 1.143 + if (SUCCEEDED(rv)) 1.144 + operation_result = SBOX_ALL_OK; 1.145 + else 1.146 + DLOG(ERROR) << "AppContainerUnregisterSid error:" << std::hex << rv; 1.147 + } 1.148 + LocalFree(local_sid); 1.149 + return operation_result; 1.150 +} 1.151 + 1.152 +string16 LookupAppContainer(const string16& sid) { 1.153 + PSID local_sid; 1.154 + if (!ConvertStringSidToSid(sid.c_str(), &local_sid)) 1.155 + return string16(); 1.156 + 1.157 + typedef HRESULT (WINAPI* AppContainerLookupMonikerPtr)(PSID sid, 1.158 + LPWSTR* moniker); 1.159 + typedef BOOLEAN (WINAPI* AppContainerFreeMemoryPtr)(void* ptr); 1.160 + 1.161 + static AppContainerLookupMonikerPtr AppContainerLookupMoniker = NULL; 1.162 + static AppContainerFreeMemoryPtr AppContainerFreeMemory = NULL; 1.163 + 1.164 + if (!AppContainerLookupMoniker || !AppContainerFreeMemory) { 1.165 + AppContainerLookupMoniker = 1.166 + BindFunction<AppContainerLookupMonikerPtr>("AppContainerLookupMoniker"); 1.167 + AppContainerFreeMemory = 1.168 + BindFunction<AppContainerFreeMemoryPtr>("AppContainerFreeMemory"); 1.169 + } 1.170 + 1.171 + if (!AppContainerLookupMoniker || !AppContainerFreeMemory) 1.172 + return string16(); 1.173 + 1.174 + wchar_t* buffer = NULL; 1.175 + HRESULT rv = AppContainerLookupMoniker(local_sid, &buffer); 1.176 + if (FAILED(rv)) 1.177 + return string16(); 1.178 + 1.179 + string16 name(buffer); 1.180 + if (!AppContainerFreeMemory(buffer)) 1.181 + NOTREACHED(); 1.182 + return name; 1.183 +} 1.184 + 1.185 +} // namespace sandbox