Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(39)

Side by Side Diff: chrome_frame/module_utils.cc

Issue 5012001: Chrome Frame: Add explicit object security attributes to the Chrome Frame ver... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 10 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome_frame/module_utils.h ('k') | chrome_frame/test/module_utils_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome_frame/module_utils.h" 5 #include "chrome_frame/module_utils.h"
6 6
7 #include <aclapi.h>
7 #include <atlbase.h> 8 #include <atlbase.h>
9 #include <atlsecurity.h>
10 #include <sddl.h>
11
8 #include "base/file_path.h" 12 #include "base/file_path.h"
9 #include "base/file_version_info.h" 13 #include "base/file_version_info.h"
10 #include "base/logging.h" 14 #include "base/logging.h"
11 #include "base/path_service.h" 15 #include "base/path_service.h"
12 #include "base/shared_memory.h" 16 #include "base/shared_memory.h"
17 #include "base/sys_info.h"
13 #include "base/utf_string_conversions.h" 18 #include "base/utf_string_conversions.h"
14 #include "base/version.h" 19 #include "base/version.h"
20 #include "chrome_frame/utils.h"
15 21
16 const char kSharedMemoryName[] = "ChromeFrameVersionBeacon"; 22 const wchar_t kSharedMemoryName[] = L"ChromeFrameVersionBeacon_";
17 const uint32 kSharedMemorySize = 128; 23 const uint32 kSharedMemorySize = 128;
18 const uint32 kSharedMemoryLockTimeoutMs = 1000; 24 const uint32 kSharedMemoryLockTimeoutMs = 1000;
19 25
20 // static 26 // static
21 DllRedirector::DllRedirector() : first_module_handle_(NULL) { 27 DllRedirector::DllRedirector() : first_module_handle_(NULL) {
22 // TODO(robertshield): Correctly construct the profile name here. Also allow 28 // TODO(robertshield): Allow for overrides to be taken from the environment.
23 // for overrides to be taken from the environment. 29 std::wstring beacon_name(kSharedMemoryName);
24 shared_memory_.reset(new base::SharedMemory(ASCIIToWide(kSharedMemoryName))); 30 beacon_name += GetHostProcessName(false);
31 shared_memory_.reset(new base::SharedMemory(beacon_name));
25 } 32 }
26 33
27 DllRedirector::DllRedirector(const char* shared_memory_name) 34 DllRedirector::DllRedirector(const char* shared_memory_name)
28 : shared_memory_name_(shared_memory_name), first_module_handle_(NULL) { 35 : shared_memory_name_(shared_memory_name), first_module_handle_(NULL) {
29 // TODO(robertshield): Correctly construct the profile name here. Also allow
30 // for overrides to be taken from the environment.
31 shared_memory_.reset(new base::SharedMemory(ASCIIToWide(shared_memory_name))); 36 shared_memory_.reset(new base::SharedMemory(ASCIIToWide(shared_memory_name)));
32 } 37 }
33 38
34 DllRedirector::~DllRedirector() { 39 DllRedirector::~DllRedirector() {
35 if (first_module_handle_) { 40 if (first_module_handle_) {
36 if (first_module_handle_ != reinterpret_cast<HMODULE>(&__ImageBase)) { 41 if (first_module_handle_ != reinterpret_cast<HMODULE>(&__ImageBase)) {
37 FreeLibrary(first_module_handle_); 42 FreeLibrary(first_module_handle_);
38 } 43 }
39 first_module_handle_ = NULL; 44 first_module_handle_ = NULL;
40 } 45 }
41 UnregisterAsFirstCFModule(); 46 UnregisterAsFirstCFModule();
42 } 47 }
43 48
49 bool DllRedirector::BuildSecurityAttributesForLock(
50 CSecurityAttributes* sec_attr) {
51 DCHECK(sec_attr);
52 int32 major_version, minor_version, fix_version;
53 base::SysInfo::OperatingSystemVersionNumbers(&major_version,
54 &minor_version,
55 &fix_version);
56 if (major_version < 6) {
57 // Don't bother with changing ACLs on pre-vista.
58 return false;
59 }
60
61 bool success = false;
62
63 // Fill out the rest of the security descriptor from the process token.
64 CAccessToken token;
65 if (token.GetProcessToken(TOKEN_QUERY)) {
66 CSecurityDesc security_desc;
67 // Set the SACL from an SDDL string that allows access to low-integrity
68 // processes. See http://msdn.microsoft.com/en-us/library/bb625958.aspx.
69 if (security_desc.FromString(L"S:(ML;;NW;;;LW)")) {
70 CSid sid_owner;
71 if (token.GetOwner(&sid_owner)) {
72 security_desc.SetOwner(sid_owner);
73 } else {
74 NOTREACHED() << "Could not get owner.";
75 }
76 CSid sid_group;
77 if (token.GetPrimaryGroup(&sid_group)) {
78 security_desc.SetGroup(sid_group);
79 } else {
80 NOTREACHED() << "Could not get group.";
81 }
82 CDacl dacl;
83 if (token.GetDefaultDacl(&dacl)) {
84 // Add an access control entry mask for the current user.
85 // This is what grants this user access from lower integrity levels.
86 CSid sid_user;
87 if (token.GetUser(&sid_user)) {
88 success = dacl.AddAllowedAce(sid_user, MUTEX_ALL_ACCESS);
89 security_desc.SetDacl(dacl);
90 sec_attr->Set(security_desc);
91 }
92 }
93 }
94 }
95
96 return success;
97 }
98
99 bool DllRedirector::SetFileMappingToReadOnly(base::SharedMemoryHandle mapping) {
100 bool success = false;
101
102 CAccessToken token;
103 if (token.GetProcessToken(TOKEN_QUERY)) {
104 CSid sid_user;
105 if (token.GetUser(&sid_user)) {
106 CDacl dacl;
107 dacl.AddAllowedAce(sid_user, STANDARD_RIGHTS_READ | FILE_MAP_READ);
108 success = AtlSetDacl(mapping, SE_KERNEL_OBJECT, dacl);
109 }
110 }
111
112 return success;
113 }
114
115
44 bool DllRedirector::RegisterAsFirstCFModule() { 116 bool DllRedirector::RegisterAsFirstCFModule() {
45 DCHECK(first_module_handle_ == NULL); 117 DCHECK(first_module_handle_ == NULL);
46 118
47 // Build our own file version outside of the lock: 119 // Build our own file version outside of the lock:
48 scoped_ptr<Version> our_version(GetCurrentModuleVersion()); 120 scoped_ptr<Version> our_version(GetCurrentModuleVersion());
49 121
50 // We sadly can't use the autolock here since we want to have a timeout. 122 // We sadly can't use the autolock here since we want to have a timeout.
51 // Be careful not to return while holding the lock. Also, attempt to do as 123 // Be careful not to return while holding the lock. Also, attempt to do as
52 // little as possible while under this lock. 124 // little as possible while under this lock.
53 bool lock_acquired = shared_memory_->Lock(kSharedMemoryLockTimeoutMs); 125
126 bool lock_acquired = false;
127 CSecurityAttributes sec_attr;
128 if (BuildSecurityAttributesForLock(&sec_attr)) {
129 lock_acquired = shared_memory_->Lock(kSharedMemoryLockTimeoutMs, &sec_attr);
130 } else {
131 lock_acquired = shared_memory_->Lock(kSharedMemoryLockTimeoutMs, NULL);
132 }
54 133
55 if (!lock_acquired) { 134 if (!lock_acquired) {
56 // We couldn't get the lock in a reasonable amount of time, so fall 135 // We couldn't get the lock in a reasonable amount of time, so fall
57 // back to loading our current version. We return true to indicate that the 136 // back to loading our current version. We return true to indicate that the
58 // caller should not attempt to delegate to an already loaded version. 137 // caller should not attempt to delegate to an already loaded version.
59 dll_version_.swap(our_version); 138 dll_version_.swap(our_version);
60 first_module_handle_ = reinterpret_cast<HMODULE>(&__ImageBase); 139 first_module_handle_ = reinterpret_cast<HMODULE>(&__ImageBase);
61 return true; 140 return true;
62 } 141 }
63 142
64 bool created_beacon = true; 143 bool created_beacon = true;
65 bool result = shared_memory_->CreateNamed(shared_memory_name_.c_str(), 144 bool result = shared_memory_->CreateNamed(shared_memory_name_.c_str(),
66 false, // open_existing 145 false, // open_existing
67 kSharedMemorySize); 146 kSharedMemorySize);
68 147
69 if (!result) { 148 if (result) {
149 // We created the beacon, now we need to mutate the security attributes
150 // on the shared memory to allow read-only access and let low-integrity
151 // processes open it.
152 bool acls_set = SetFileMappingToReadOnly(shared_memory_->handle());
153 DCHECK(acls_set);
154 } else {
70 created_beacon = false; 155 created_beacon = false;
71 156
72 // We failed to create the shared memory segment, suggesting it may already 157 // We failed to create the shared memory segment, suggesting it may already
73 // exist: try to create it read-only. 158 // exist: try to create it read-only.
74 result = shared_memory_->Open(shared_memory_name_.c_str(), 159 result = shared_memory_->Open(shared_memory_name_.c_str(),
75 true /* read_only */); 160 true /* read_only */);
76 } 161 }
77 162
78 if (result) { 163 if (result) {
79 // Map in the whole thing. 164 // Map in the whole thing.
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 } 201 }
117 202
118 // Matching Unlock. 203 // Matching Unlock.
119 shared_memory_->Unlock(); 204 shared_memory_->Unlock();
120 205
121 return created_beacon; 206 return created_beacon;
122 } 207 }
123 208
124 void DllRedirector::UnregisterAsFirstCFModule() { 209 void DllRedirector::UnregisterAsFirstCFModule() {
125 if (base::SharedMemory::IsHandleValid(shared_memory_->handle())) { 210 if (base::SharedMemory::IsHandleValid(shared_memory_->handle())) {
126 bool lock_acquired = shared_memory_->Lock(kSharedMemoryLockTimeoutMs); 211 bool lock_acquired = shared_memory_->Lock(kSharedMemoryLockTimeoutMs, NULL);
127 if (lock_acquired) { 212 if (lock_acquired) {
128 // Free our handles. The last closed handle SHOULD result in it being 213 // Free our handles. The last closed handle SHOULD result in it being
129 // deleted. 214 // deleted.
130 shared_memory_->Close(); 215 shared_memory_->Close();
131 shared_memory_->Unlock(); 216 shared_memory_->Unlock();
132 } 217 }
133 } 218 }
134 } 219 }
135 220
136 LPFNGETCLASSOBJECT DllRedirector::GetDllGetClassObjectPtr() { 221 LPFNGETCLASSOBJECT DllRedirector::GetDllGetClassObjectPtr() {
137 HMODULE first_module_handle = GetFirstModule(); 222 HMODULE first_module_handle = GetFirstModule();
138 223
139 LPFNGETCLASSOBJECT proc_ptr = reinterpret_cast<LPFNGETCLASSOBJECT>( 224 LPFNGETCLASSOBJECT proc_ptr = reinterpret_cast<LPFNGETCLASSOBJECT>(
140 GetProcAddress(first_module_handle, "DllGetClassObject")); 225 GetProcAddress(first_module_handle, "DllGetClassObject"));
141 if (!proc_ptr) { 226 if (!proc_ptr) {
142 DLOG(ERROR) << "DllRedirector: Could get address of DllGetClassObject " 227 DPLOG(ERROR) << "DllRedirector: Could not get address of DllGetClassObject "
143 "from first loaded module, GLE: " 228 "from first loaded module.";
144 << GetLastError();
145 // Oh boink, the first module we loaded was somehow bogus, make ourselves 229 // Oh boink, the first module we loaded was somehow bogus, make ourselves
146 // the first module again. 230 // the first module again.
147 first_module_handle = reinterpret_cast<HMODULE>(&__ImageBase); 231 first_module_handle = reinterpret_cast<HMODULE>(&__ImageBase);
148 } 232 }
149 return proc_ptr; 233 return proc_ptr;
150 } 234 }
151 235
152 Version* DllRedirector::GetCurrentModuleVersion() { 236 Version* DllRedirector::GetCurrentModuleVersion() {
153 scoped_ptr<FileVersionInfo> file_version_info( 237 scoped_ptr<FileVersionInfo> file_version_info(
154 FileVersionInfo::CreateFileVersionInfoForCurrentModule()); 238 FileVersionInfo::CreateFileVersionInfoForCurrentModule());
(...skipping 30 matching lines...) Expand all
185 PathService::Get(base::DIR_MODULE, &module_path); 269 PathService::Get(base::DIR_MODULE, &module_path);
186 DCHECK(!module_path.empty()); 270 DCHECK(!module_path.empty());
187 271
188 FilePath module_name = module_path.BaseName(); 272 FilePath module_name = module_path.BaseName();
189 module_path = module_path.DirName() 273 module_path = module_path.DirName()
190 .Append(ASCIIToWide(version->GetString())) 274 .Append(ASCIIToWide(version->GetString()))
191 .Append(module_name); 275 .Append(module_name);
192 276
193 HMODULE hmodule = LoadLibrary(module_path.value().c_str()); 277 HMODULE hmodule = LoadLibrary(module_path.value().c_str());
194 if (hmodule == NULL) { 278 if (hmodule == NULL) {
195 DLOG(ERROR) << "Could not load reported module version " 279 DPLOG(ERROR) << "Could not load reported module version "
196 << version->GetString(); 280 << version->GetString();
197 } 281 }
198 282
199 return hmodule; 283 return hmodule;
200 } 284 }
201 285
OLDNEW
« no previous file with comments | « chrome_frame/module_utils.h ('k') | chrome_frame/test/module_utils_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698