1 // Copyright (c) 2012 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/app_container.h"
10 #include "base/logging.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/win/startup_information.h"
13 #include "sandbox/win/src/internal_types.h"
17 // Converts the passed in sid string to a PSID that must be relased with
19 PSID
ConvertSid(const base::string16
& sid
) {
21 if (!ConvertStringSidToSid(sid
.c_str(), &local_sid
))
27 T
BindFunction(const char* name
) {
28 HMODULE module
= GetModuleHandle(sandbox::kKerneldllName
);
29 void* function
= GetProcAddress(module
, name
);
31 module
= GetModuleHandle(sandbox::kKernelBasedllName
);
32 function
= GetProcAddress(module
, name
);
34 return reinterpret_cast<T
>(function
);
41 AppContainerAttributes::AppContainerAttributes() {
42 memset(&capabilities_
, 0, sizeof(capabilities_
));
45 AppContainerAttributes::~AppContainerAttributes() {
46 for (size_t i
= 0; i
< attributes_
.size(); i
++)
47 LocalFree(attributes_
[i
].Sid
);
48 LocalFree(capabilities_
.AppContainerSid
);
51 ResultCode
AppContainerAttributes::SetAppContainer(
52 const base::string16
& app_container_sid
,
53 const std::vector
<base::string16
>& capabilities
) {
54 DCHECK(!capabilities_
.AppContainerSid
);
55 DCHECK(attributes_
.empty());
56 capabilities_
.AppContainerSid
= ConvertSid(app_container_sid
);
57 if (!capabilities_
.AppContainerSid
)
58 return SBOX_ERROR_INVALID_APP_CONTAINER
;
60 for (size_t i
= 0; i
< capabilities
.size(); i
++) {
61 SID_AND_ATTRIBUTES sid_and_attributes
;
62 sid_and_attributes
.Sid
= ConvertSid(capabilities
[i
]);
63 if (!sid_and_attributes
.Sid
)
64 return SBOX_ERROR_INVALID_CAPABILITY
;
66 sid_and_attributes
.Attributes
= SE_GROUP_ENABLED
;
67 attributes_
.push_back(sid_and_attributes
);
70 if (capabilities
.size()) {
71 capabilities_
.CapabilityCount
= static_cast<DWORD
>(capabilities
.size());
72 capabilities_
.Capabilities
= &attributes_
[0];
77 ResultCode
AppContainerAttributes::ShareForStartup(
78 base::win::StartupInformation
* startup_information
) const {
79 // The only thing we support so far is an AppContainer.
80 if (!capabilities_
.AppContainerSid
)
81 return SBOX_ERROR_INVALID_APP_CONTAINER
;
83 if (!startup_information
->UpdateProcThreadAttribute(
84 PROC_THREAD_ATTRIBUTE_SECURITY_CAPABILITIES
,
85 const_cast<SECURITY_CAPABILITIES
*>(&capabilities_
),
86 sizeof(capabilities_
))) {
87 DPLOG(ERROR
) << "Failed UpdateProcThreadAttribute";
88 return SBOX_ERROR_CANNOT_INIT_APPCONTAINER
;
93 bool AppContainerAttributes::HasAppContainer() const {
94 return (capabilities_
.AppContainerSid
!= NULL
);
97 ResultCode
CreateAppContainer(const base::string16
& sid
,
98 const base::string16
& name
) {
100 if (!ConvertStringSidToSid(sid
.c_str(), &local_sid
))
101 return SBOX_ERROR_INVALID_APP_CONTAINER
;
103 typedef HRESULT (WINAPI
* AppContainerRegisterSidPtr
)(PSID sid
,
105 LPCWSTR display_name
);
106 static AppContainerRegisterSidPtr AppContainerRegisterSid
= NULL
;
108 if (!AppContainerRegisterSid
) {
109 AppContainerRegisterSid
=
110 BindFunction
<AppContainerRegisterSidPtr
>("AppContainerRegisterSid");
113 ResultCode operation_result
= SBOX_ERROR_GENERIC
;
114 if (AppContainerRegisterSid
) {
115 HRESULT rv
= AppContainerRegisterSid(local_sid
, name
.c_str(), name
.c_str());
117 operation_result
= SBOX_ALL_OK
;
119 DLOG(ERROR
) << "AppContainerRegisterSid error:" << std::hex
<< rv
;
121 LocalFree(local_sid
);
122 return operation_result
;
125 ResultCode
DeleteAppContainer(const base::string16
& sid
) {
127 if (!ConvertStringSidToSid(sid
.c_str(), &local_sid
))
128 return SBOX_ERROR_INVALID_APP_CONTAINER
;
130 typedef HRESULT (WINAPI
* AppContainerUnregisterSidPtr
)(PSID sid
);
131 static AppContainerUnregisterSidPtr AppContainerUnregisterSid
= NULL
;
133 if (!AppContainerUnregisterSid
) {
134 AppContainerUnregisterSid
=
135 BindFunction
<AppContainerUnregisterSidPtr
>("AppContainerUnregisterSid");
138 ResultCode operation_result
= SBOX_ERROR_GENERIC
;
139 if (AppContainerUnregisterSid
) {
140 HRESULT rv
= AppContainerUnregisterSid(local_sid
);
142 operation_result
= SBOX_ALL_OK
;
144 DLOG(ERROR
) << "AppContainerUnregisterSid error:" << std::hex
<< rv
;
146 LocalFree(local_sid
);
147 return operation_result
;
150 base::string16
LookupAppContainer(const base::string16
& sid
) {
152 if (!ConvertStringSidToSid(sid
.c_str(), &local_sid
))
153 return base::string16();
155 typedef HRESULT (WINAPI
* AppContainerLookupMonikerPtr
)(PSID sid
,
157 typedef BOOLEAN (WINAPI
* AppContainerFreeMemoryPtr
)(void* ptr
);
159 static AppContainerLookupMonikerPtr AppContainerLookupMoniker
= NULL
;
160 static AppContainerFreeMemoryPtr AppContainerFreeMemory
= NULL
;
162 if (!AppContainerLookupMoniker
|| !AppContainerFreeMemory
) {
163 AppContainerLookupMoniker
=
164 BindFunction
<AppContainerLookupMonikerPtr
>("AppContainerLookupMoniker");
165 AppContainerFreeMemory
=
166 BindFunction
<AppContainerFreeMemoryPtr
>("AppContainerFreeMemory");
169 if (!AppContainerLookupMoniker
|| !AppContainerFreeMemory
)
170 return base::string16();
172 wchar_t* buffer
= NULL
;
173 HRESULT rv
= AppContainerLookupMoniker(local_sid
, &buffer
);
175 return base::string16();
177 base::string16
name(buffer
);
178 if (!AppContainerFreeMemory(buffer
))
183 } // namespace sandbox