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

Side by Side Diff: chrome_frame/dll_redirector.cc

Issue 7866043: Prevent redirector from returning the current module in cases where it fails to look up the first... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years, 3 months 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/dll_redirector.h ('k') | chrome_frame/test/dll_redirector_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) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/dll_redirector.h" 5 #include "chrome_frame/dll_redirector.h"
6 6
7 #include <aclapi.h> 7 #include <aclapi.h>
8 #include <atlbase.h> 8 #include <atlbase.h>
9 #include <atlsecurity.h> 9 #include <atlsecurity.h>
10 #include <sddl.h> 10 #include <sddl.h>
(...skipping 24 matching lines...) Expand all
35 35
36 DllRedirector::DllRedirector(const char* shared_memory_name) 36 DllRedirector::DllRedirector(const char* shared_memory_name)
37 : shared_memory_name_(shared_memory_name), first_module_handle_(NULL) { 37 : shared_memory_name_(shared_memory_name), first_module_handle_(NULL) {
38 shared_memory_.reset(new base::SharedMemory(ASCIIToWide(shared_memory_name))); 38 shared_memory_.reset(new base::SharedMemory(ASCIIToWide(shared_memory_name)));
39 } 39 }
40 40
41 DllRedirector::~DllRedirector() { 41 DllRedirector::~DllRedirector() {
42 if (first_module_handle_) { 42 if (first_module_handle_) {
43 if (first_module_handle_ != reinterpret_cast<HMODULE>(&__ImageBase)) { 43 if (first_module_handle_ != reinterpret_cast<HMODULE>(&__ImageBase)) {
44 FreeLibrary(first_module_handle_); 44 FreeLibrary(first_module_handle_);
45 } else {
46 NOTREACHED() << "Error, DllRedirector attempting to free self.";
45 } 47 }
48
46 first_module_handle_ = NULL; 49 first_module_handle_ = NULL;
47 } 50 }
48 UnregisterAsFirstCFModule(); 51 UnregisterAsFirstCFModule();
49 } 52 }
50 53
51 // static 54 // static
52 DllRedirector* DllRedirector::GetInstance() { 55 DllRedirector* DllRedirector::GetInstance() {
53 return Singleton<DllRedirector>::get(); 56 return Singleton<DllRedirector>::get();
54 } 57 }
55 58
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
135 lock_acquired = shared_memory_->Lock(kSharedMemoryLockTimeoutMs, &sec_attr); 138 lock_acquired = shared_memory_->Lock(kSharedMemoryLockTimeoutMs, &sec_attr);
136 } else { 139 } else {
137 lock_acquired = shared_memory_->Lock(kSharedMemoryLockTimeoutMs, NULL); 140 lock_acquired = shared_memory_->Lock(kSharedMemoryLockTimeoutMs, NULL);
138 } 141 }
139 142
140 if (!lock_acquired) { 143 if (!lock_acquired) {
141 // We couldn't get the lock in a reasonable amount of time, so fall 144 // We couldn't get the lock in a reasonable amount of time, so fall
142 // back to loading our current version. We return true to indicate that the 145 // back to loading our current version. We return true to indicate that the
143 // caller should not attempt to delegate to an already loaded version. 146 // caller should not attempt to delegate to an already loaded version.
144 dll_version_.swap(our_version); 147 dll_version_.swap(our_version);
145 first_module_handle_ = reinterpret_cast<HMODULE>(&__ImageBase);
146 return true; 148 return true;
147 } 149 }
148 150
149 bool created_beacon = true; 151 bool created_beacon = true;
150 bool result = shared_memory_->CreateNamed(shared_memory_name_.c_str(), 152 bool result = shared_memory_->CreateNamed(shared_memory_name_.c_str(),
151 false, // open_existing 153 false, // open_existing
152 kSharedMemorySize); 154 kSharedMemorySize);
153 155
154 if (result) { 156 if (result) {
155 // We created the beacon, now we need to mutate the security attributes 157 // We created the beacon, now we need to mutate the security attributes
(...skipping 19 matching lines...) Expand all
175 if (result) { 177 if (result) {
176 // Either write our own version number or read it in if it was already 178 // Either write our own version number or read it in if it was already
177 // present in the shared memory section. 179 // present in the shared memory section.
178 if (created_beacon) { 180 if (created_beacon) {
179 dll_version_.swap(our_version); 181 dll_version_.swap(our_version);
180 182
181 lstrcpynA(reinterpret_cast<char*>(shared_memory_->memory()), 183 lstrcpynA(reinterpret_cast<char*>(shared_memory_->memory()),
182 dll_version_->GetString().c_str(), 184 dll_version_->GetString().c_str(),
183 std::min(kSharedMemorySize, 185 std::min(kSharedMemorySize,
184 dll_version_->GetString().length() + 1)); 186 dll_version_->GetString().length() + 1));
185
186 // Mark ourself as the first module in.
187 first_module_handle_ = reinterpret_cast<HMODULE>(&__ImageBase);
188 } else { 187 } else {
189 char buffer[kSharedMemorySize] = {0}; 188 char buffer[kSharedMemorySize] = {0};
190 memcpy(buffer, shared_memory_->memory(), kSharedMemorySize - 1); 189 memcpy(buffer, shared_memory_->memory(), kSharedMemorySize - 1);
191 dll_version_.reset(Version::GetVersionFromString(buffer)); 190 dll_version_.reset(Version::GetVersionFromString(buffer));
192 191
193 if (!dll_version_.get() || dll_version_->Equals(*our_version.get())) { 192 if (!dll_version_.get() || dll_version_->Equals(*our_version.get())) {
194 // If we either couldn't parse a valid version out of the shared 193 // If we either couldn't parse a valid version out of the shared
195 // memory or we did parse a version and it is the same as our own, 194 // memory or we did parse a version and it is the same as our own,
196 // then pretend we're first in to avoid trying to load any other DLLs. 195 // then pretend we're first in to avoid trying to load any other DLLs.
197 dll_version_.reset(our_version.release()); 196 dll_version_.reset(our_version.release());
198 first_module_handle_ = reinterpret_cast<HMODULE>(&__ImageBase);
199 created_beacon = true; 197 created_beacon = true;
200 } 198 }
201 } 199 }
202 } else { 200 } else {
203 NOTREACHED() << "Failed to map in version beacon."; 201 NOTREACHED() << "Failed to map in version beacon.";
204 } 202 }
205 } else { 203 } else {
206 NOTREACHED() << "Could not create file mapping for version beacon, gle: " 204 NOTREACHED() << "Could not create file mapping for version beacon, gle: "
207 << ::GetLastError(); 205 << ::GetLastError();
208 } 206 }
(...skipping 12 matching lines...) Expand all
221 // deleted. 219 // deleted.
222 shared_memory_->Close(); 220 shared_memory_->Close();
223 shared_memory_->Unlock(); 221 shared_memory_->Unlock();
224 } 222 }
225 } 223 }
226 } 224 }
227 225
228 LPFNGETCLASSOBJECT DllRedirector::GetDllGetClassObjectPtr() { 226 LPFNGETCLASSOBJECT DllRedirector::GetDllGetClassObjectPtr() {
229 HMODULE first_module_handle = GetFirstModule(); 227 HMODULE first_module_handle = GetFirstModule();
230 228
231 LPFNGETCLASSOBJECT proc_ptr = reinterpret_cast<LPFNGETCLASSOBJECT>( 229 LPFNGETCLASSOBJECT proc_ptr = NULL;
232 GetProcAddress(first_module_handle, "DllGetClassObject")); 230 if (first_module_handle) {
233 if (!proc_ptr) { 231 proc_ptr = reinterpret_cast<LPFNGETCLASSOBJECT>(
234 DPLOG(ERROR) << "DllRedirector: Could not get address of DllGetClassObject " 232 GetProcAddress(first_module_handle, "DllGetClassObject"));
235 "from first loaded module."; 233 DPLOG_IF(ERROR, !proc_ptr) << "DllRedirector: Could not get address of "
236 // Oh boink, the first module we loaded was somehow bogus, make ourselves 234 "DllGetClassObject from first loaded module.";
237 // the first module again.
238 first_module_handle = reinterpret_cast<HMODULE>(&__ImageBase);
239 } 235 }
236
240 return proc_ptr; 237 return proc_ptr;
241 } 238 }
242 239
243 Version* DllRedirector::GetCurrentModuleVersion() { 240 Version* DllRedirector::GetCurrentModuleVersion() {
244 scoped_ptr<FileVersionInfo> file_version_info( 241 scoped_ptr<FileVersionInfo> file_version_info(
245 FileVersionInfo::CreateFileVersionInfoForCurrentModule()); 242 FileVersionInfo::CreateFileVersionInfoForCurrentModule());
246 DCHECK(file_version_info.get()); 243 DCHECK(file_version_info.get());
247 244
248 Version* current_version = NULL; 245 Version* current_version = NULL;
249 if (file_version_info.get()) { 246 if (file_version_info.get()) {
250 current_version = Version::GetVersionFromString( 247 current_version = Version::GetVersionFromString(
251 WideToASCII(file_version_info->file_version())); 248 WideToASCII(file_version_info->file_version()));
252 DCHECK(current_version); 249 DCHECK(current_version);
253 } 250 }
254 251
255 return current_version; 252 return current_version;
256 } 253 }
257 254
258 HMODULE DllRedirector::GetFirstModule() { 255 HMODULE DllRedirector::GetFirstModule() {
259 DCHECK(dll_version_.get()) 256 DCHECK(dll_version_.get())
260 << "Error: Did you call RegisterAsFirstCFModule() first?"; 257 << "Error: Did you call RegisterAsFirstCFModule() first?";
261 258
262 if (first_module_handle_ == NULL) { 259 if (first_module_handle_ == NULL) {
263 first_module_handle_ = LoadVersionedModule(dll_version_.get()); 260 first_module_handle_ = LoadVersionedModule(dll_version_.get());
264 if (!first_module_handle_) { 261 }
265 first_module_handle_ = reinterpret_cast<HMODULE>(&__ImageBase); 262
266 } 263 if (first_module_handle_ == reinterpret_cast<HMODULE>(&__ImageBase)) {
264 NOTREACHED() << "Should not be loading own version.";
265 first_module_handle_ = NULL;
267 } 266 }
268 267
269 return first_module_handle_; 268 return first_module_handle_;
270 } 269 }
271 270
272 HMODULE DllRedirector::LoadVersionedModule(Version* version) { 271 HMODULE DllRedirector::LoadVersionedModule(Version* version) {
273 DCHECK(version); 272 DCHECK(version);
274 273
275 FilePath module_path; 274 FilePath module_path;
276 PathService::Get(base::FILE_MODULE, &module_path); 275 PathService::Get(base::FILE_MODULE, &module_path);
277 DCHECK(!module_path.empty()); 276 DCHECK(!module_path.empty());
278 277
279 // For a module located in 278 // For a module located in
280 // Foo\XXXXXXXXX\<module>.dll, load 279 // Foo\XXXXXXXXX\<module>.dll, load
281 // Foo\<version>\<module>.dll: 280 // Foo\<version>\<module>.dll:
282 FilePath module_name = module_path.BaseName(); 281 FilePath module_name = module_path.BaseName();
283 module_path = module_path.DirName() 282 module_path = module_path.DirName()
284 .DirName() 283 .DirName()
285 .Append(ASCIIToWide(version->GetString())) 284 .Append(ASCIIToWide(version->GetString()))
286 .Append(module_name); 285 .Append(module_name);
287 286
288 HMODULE hmodule = LoadLibrary(module_path.value().c_str()); 287 HMODULE hmodule = LoadLibrary(module_path.value().c_str());
289 if (hmodule == NULL) { 288 if (hmodule == NULL) {
290 DPLOG(ERROR) << "Could not load reported module version " 289 DPLOG(ERROR) << "Could not load reported module version "
291 << version->GetString(); 290 << version->GetString();
292 } 291 }
293 292
294 return hmodule; 293 return hmodule;
295 } 294 }
OLDNEW
« no previous file with comments | « chrome_frame/dll_redirector.h ('k') | chrome_frame/test/dll_redirector_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698