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

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
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::GetLockSecurityAttributes(CSecurityAttributes* sec_attr) {
tommi (sloooow) - chröme 2010/11/15 19:33:30 change name to "BuildSecurityAttributesForLock" or
robertshield 2010/11/15 20:32:18 Done.
50 DCHECK(sec_attr);
51 int32 major_version, minor_version, fix_version;
52 base::SysInfo::OperatingSystemVersionNumbers(&major_version,
53 &minor_version,
54 &fix_version);
55 if (major_version < 6) {
56 // Don't bother with changing ACLs on pre-vista.
57 return false;
58 }
59
60 bool success = false;
61
62 // Fill out the rest of the security descriptor from the process token.
63 CAccessToken token;
64 if (token.GetProcessToken(TOKEN_QUERY)) {
65 CSecurityDesc security_desc;
66 if (security_desc.FromString(L"S:(ML;;NW;;;LW)")) {
tommi (sloooow) - chröme 2010/11/15 19:33:30 Add a comment that explains what the string means
robertshield 2010/11/15 20:32:18 Done.
67 CSid sid_owner;
68 if (token.GetOwner(&sid_owner)) {
69 security_desc.SetOwner(sid_owner);
70 } else {
71 NOTREACHED() << "Could not set owner.";
tommi (sloooow) - chröme 2010/11/15 19:33:30 set -> get
robertshield 2010/11/15 20:32:18 Done.
72 }
73 CSid sid_group;
74 if (token.GetPrimaryGroup(&sid_group)) {
75 security_desc.SetGroup(sid_group);
76 } else {
77 NOTREACHED() << "Could not set group.";
tommi (sloooow) - chröme 2010/11/15 19:33:30 set -> get
robertshield 2010/11/15 20:32:18 Done.
78 }
79 CDacl dacl;
80 if (token.GetDefaultDacl(&dacl)) {
81 // Add an access control entry mask for the current user.
82 // This is what grants this user access from lower integrity levels.
83 CSid sid_user;
84 if (token.GetUser(&sid_user)) {
85 success = dacl.AddAllowedAce(sid_user, MUTEX_ALL_ACCESS);
86 security_desc.SetDacl(dacl);
87 sec_attr->Set(security_desc);
88 }
89 }
90 }
91 }
92
93 return success;
94 }
95
96 bool DllRedirector::SetFileMappingToReadOnly(base::SharedMemoryHandle mapping) {
97 bool success = false;
98
99 CAccessToken token;
100 if (token.GetProcessToken(TOKEN_QUERY)) {
101 CSid sid_user;
102 if (token.GetUser(&sid_user)) {
103 CDacl dacl;
104 dacl.AddAllowedAce(sid_user, STANDARD_RIGHTS_READ | FILE_MAP_READ);
105 success = AtlSetDacl(mapping, SE_KERNEL_OBJECT, dacl);
106 }
107 }
108
109 return success;
110 }
111
112
44 bool DllRedirector::RegisterAsFirstCFModule() { 113 bool DllRedirector::RegisterAsFirstCFModule() {
45 DCHECK(first_module_handle_ == NULL); 114 DCHECK(first_module_handle_ == NULL);
46 115
47 // Build our own file version outside of the lock: 116 // Build our own file version outside of the lock:
48 scoped_ptr<Version> our_version(GetCurrentModuleVersion()); 117 scoped_ptr<Version> our_version(GetCurrentModuleVersion());
49 118
50 // We sadly can't use the autolock here since we want to have a timeout. 119 // 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 120 // Be careful not to return while holding the lock. Also, attempt to do as
52 // little as possible while under this lock. 121 // little as possible while under this lock.
53 bool lock_acquired = shared_memory_->Lock(kSharedMemoryLockTimeoutMs); 122
123 bool lock_acquired = false;
124 CSecurityAttributes sec_attr;
125 if (GetLockSecurityAttributes(&sec_attr)) {
126 lock_acquired = shared_memory_->Lock(kSharedMemoryLockTimeoutMs, &sec_attr);
127 } else {
128 lock_acquired = shared_memory_->Lock(kSharedMemoryLockTimeoutMs, NULL);
129 }
54 130
55 if (!lock_acquired) { 131 if (!lock_acquired) {
56 // We couldn't get the lock in a reasonable amount of time, so fall 132 // 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 133 // 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. 134 // caller should not attempt to delegate to an already loaded version.
59 dll_version_.swap(our_version); 135 dll_version_.swap(our_version);
60 first_module_handle_ = reinterpret_cast<HMODULE>(&__ImageBase); 136 first_module_handle_ = reinterpret_cast<HMODULE>(&__ImageBase);
61 return true; 137 return true;
62 } 138 }
63 139
64 bool created_beacon = true; 140 bool created_beacon = true;
65 bool result = shared_memory_->CreateNamed(shared_memory_name_.c_str(), 141 bool result = shared_memory_->CreateNamed(shared_memory_name_.c_str(),
66 false, // open_existing 142 false, // open_existing
67 kSharedMemorySize); 143 kSharedMemorySize);
68 144
69 if (!result) { 145 if (result) {
146 // We created the beacon, now we need to mutate the security attributes
147 // on the shared memory to allow read-only access and let low-integrity
148 // processes open it.
149 bool acls_set = SetFileMappingToReadOnly(shared_memory_->handle());
150 DCHECK(acls_set);
151 } else {
70 created_beacon = false; 152 created_beacon = false;
71 153
72 // We failed to create the shared memory segment, suggesting it may already 154 // We failed to create the shared memory segment, suggesting it may already
73 // exist: try to create it read-only. 155 // exist: try to create it read-only.
74 result = shared_memory_->Open(shared_memory_name_.c_str(), 156 result = shared_memory_->Open(shared_memory_name_.c_str(),
75 true /* read_only */); 157 true /* read_only */);
76 } 158 }
77 159
78 if (result) { 160 if (result) {
79 // Map in the whole thing. 161 // Map in the whole thing.
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 } 198 }
117 199
118 // Matching Unlock. 200 // Matching Unlock.
119 shared_memory_->Unlock(); 201 shared_memory_->Unlock();
120 202
121 return created_beacon; 203 return created_beacon;
122 } 204 }
123 205
124 void DllRedirector::UnregisterAsFirstCFModule() { 206 void DllRedirector::UnregisterAsFirstCFModule() {
125 if (base::SharedMemory::IsHandleValid(shared_memory_->handle())) { 207 if (base::SharedMemory::IsHandleValid(shared_memory_->handle())) {
126 bool lock_acquired = shared_memory_->Lock(kSharedMemoryLockTimeoutMs); 208 bool lock_acquired = shared_memory_->Lock(kSharedMemoryLockTimeoutMs, NULL);
127 if (lock_acquired) { 209 if (lock_acquired) {
128 // Free our handles. The last closed handle SHOULD result in it being 210 // Free our handles. The last closed handle SHOULD result in it being
129 // deleted. 211 // deleted.
130 shared_memory_->Close(); 212 shared_memory_->Close();
131 shared_memory_->Unlock(); 213 shared_memory_->Unlock();
132 } 214 }
133 } 215 }
134 } 216 }
135 217
136 LPFNGETCLASSOBJECT DllRedirector::GetDllGetClassObjectPtr() { 218 LPFNGETCLASSOBJECT DllRedirector::GetDllGetClassObjectPtr() {
137 HMODULE first_module_handle = GetFirstModule(); 219 HMODULE first_module_handle = GetFirstModule();
138 220
139 LPFNGETCLASSOBJECT proc_ptr = reinterpret_cast<LPFNGETCLASSOBJECT>( 221 LPFNGETCLASSOBJECT proc_ptr = reinterpret_cast<LPFNGETCLASSOBJECT>(
140 GetProcAddress(first_module_handle, "DllGetClassObject")); 222 GetProcAddress(first_module_handle, "DllGetClassObject"));
141 if (!proc_ptr) { 223 if (!proc_ptr) {
142 DLOG(ERROR) << "DllRedirector: Could get address of DllGetClassObject " 224 DPLOG(ERROR) << "DllRedirector: Could get address of DllGetClassObject "
143 "from first loaded module, GLE: " 225 "from first loaded module, GLE: ";
tommi (sloooow) - chröme 2010/11/15 19:33:30 remove ", GLE: "
robertshield 2010/11/15 20:32:18 Done.
144 << GetLastError();
145 // Oh boink, the first module we loaded was somehow bogus, make ourselves 226 // Oh boink, the first module we loaded was somehow bogus, make ourselves
146 // the first module again. 227 // the first module again.
147 first_module_handle = reinterpret_cast<HMODULE>(&__ImageBase); 228 first_module_handle = reinterpret_cast<HMODULE>(&__ImageBase);
148 } 229 }
149 return proc_ptr; 230 return proc_ptr;
150 } 231 }
151 232
152 Version* DllRedirector::GetCurrentModuleVersion() { 233 Version* DllRedirector::GetCurrentModuleVersion() {
153 scoped_ptr<FileVersionInfo> file_version_info( 234 scoped_ptr<FileVersionInfo> file_version_info(
154 FileVersionInfo::CreateFileVersionInfoForCurrentModule()); 235 FileVersionInfo::CreateFileVersionInfoForCurrentModule());
(...skipping 30 matching lines...) Expand all
185 PathService::Get(base::DIR_MODULE, &module_path); 266 PathService::Get(base::DIR_MODULE, &module_path);
186 DCHECK(!module_path.empty()); 267 DCHECK(!module_path.empty());
187 268
188 FilePath module_name = module_path.BaseName(); 269 FilePath module_name = module_path.BaseName();
189 module_path = module_path.DirName() 270 module_path = module_path.DirName()
190 .Append(ASCIIToWide(version->GetString())) 271 .Append(ASCIIToWide(version->GetString()))
191 .Append(module_name); 272 .Append(module_name);
192 273
193 HMODULE hmodule = LoadLibrary(module_path.value().c_str()); 274 HMODULE hmodule = LoadLibrary(module_path.value().c_str());
194 if (hmodule == NULL) { 275 if (hmodule == NULL) {
195 DLOG(ERROR) << "Could not load reported module version " 276 DPLOG(ERROR) << "Could not load reported module version "
196 << version->GetString(); 277 << version->GetString();
197 } 278 }
198 279
199 return hmodule; 280 return hmodule;
200 } 281 }
201 282
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698