diff options
-rw-r--r-- | base/process_util.h | 6 | ||||
-rw-r--r-- | base/process_util_win.cc | 13 | ||||
-rw-r--r-- | base/win/windows_version.cc | 13 | ||||
-rw-r--r-- | base/win/windows_version.h | 8 | ||||
-rw-r--r-- | chrome/app/chrome_exe_main_gtk.cc | 28 | ||||
-rw-r--r-- | chrome/app/chrome_exe_main_win.cc | 16 | ||||
-rw-r--r-- | chrome/app/chrome_main.cc | 4 | ||||
-rw-r--r-- | chrome/app/chrome_main_posix.cc | 27 | ||||
-rw-r--r-- | chrome/app/chrome_main_win.cc | 30 | ||||
-rw-r--r-- | chrome/test/base/out_of_proc_test_runner.cc | 12 | ||||
-rw-r--r-- | sandbox/tests/integration_tests/integration_tests.cc | 4 | ||||
-rw-r--r-- | sandbox/tests/unit_tests/unit_tests.cc | 4 | ||||
-rw-r--r-- | sandbox/tests/validation_tests/unit_tests.cc | 4 | ||||
-rw-r--r-- | ui/base/resource/resource_bundle_win.cc | 1 |
14 files changed, 59 insertions, 111 deletions
diff --git a/base/process_util.h b/base/process_util.h index 2109401..66c63dd 100644 --- a/base/process_util.h +++ b/base/process_util.h @@ -697,15 +697,13 @@ BASE_EXPORT bool EnableLowFragmentationHeap(); // overflow. Has no effect if the OS doesn't provide the necessary facility. BASE_EXPORT void EnableTerminationOnHeapCorruption(); -#if !defined(OS_WIN) -// Turns on process termination if memory runs out. This is handled on Windows -// inside RegisterInvalidParamHandler(). +// Turns on process termination if memory runs out. BASE_EXPORT void EnableTerminationOnOutOfMemory(); + #if defined(OS_MACOSX) // Exposed for testing. BASE_EXPORT malloc_zone_t* GetPurgeableZone(); #endif // defined(OS_MACOSX) -#endif // !defined(OS_WIN) // Enables stack dump to console output on exception and signals. // When enabled, the process will quit immediately. This is meant to be used in diff --git a/base/process_util_win.cc b/base/process_util_win.cc index 8a2eafe..315a68f 100644 --- a/base/process_util_win.cc +++ b/base/process_util_win.cc @@ -94,6 +94,15 @@ void AttachToConsole() { std::ios::sync_with_stdio(); } +void OnNoMemory() { + // Kill the process. This is important for security, since WebKit doesn't + // NULL-check many memory allocations. If a malloc fails, returns NULL, and + // the buffer is then used, it provides a handy mapping of memory starting at + // address 0 for an attacker to utilize. + __debugbreak(); + _exit(1); +} + } // namespace ProcessId GetCurrentProcId() { @@ -822,6 +831,10 @@ void EnableTerminationOnHeapCorruption() { HeapSetInformation(NULL, HeapEnableTerminationOnCorruption, NULL, 0); } +void EnableTerminationOnOutOfMemory() { + std::set_new_handler(&OnNoMemory); +} + bool EnableInProcessStackDumping() { // Add stack dumping support on exception on windows. Similar to OS_POSIX // signal() handling in process_util_posix.cc. diff --git a/base/win/windows_version.cc b/base/win/windows_version.cc index 8dc2d93..5779074 100644 --- a/base/win/windows_version.cc +++ b/base/win/windows_version.cc @@ -13,7 +13,18 @@ namespace win { // static OSInfo* OSInfo::GetInstance() { - return Singleton<OSInfo>::get(); + // Note: we don't use the Singleton class because it depends on AtExitManager, + // and it's convenient for other modules to use this classs without it. This + // pattern is copied from gurl.cc. + static OSInfo* info; + if (!info) { + OSInfo* new_info = new OSInfo(); + if (InterlockedCompareExchangePointer( + reinterpret_cast<PVOID*>(&info), new_info, NULL)) { + delete new_info; + } + } + return info; } OSInfo::OSInfo() diff --git a/base/win/windows_version.h b/base/win/windows_version.h index 296e0da..920438b 100644 --- a/base/win/windows_version.h +++ b/base/win/windows_version.h @@ -7,7 +7,7 @@ #pragma once #include "base/base_export.h" -#include "base/memory/singleton.h" +#include "base/basictypes.h" typedef void* HANDLE; @@ -27,8 +27,9 @@ enum Version { VERSION_WIN7, }; -// A Singleton that can be used to query various pieces of information about the -// OS and process state. +// A singleton that can be used to query various pieces of information about the +// OS and process state. Note that this doesn't use the base Singleton class, so +// it can be used without an AtExitManager. class BASE_EXPORT OSInfo { public: struct VersionNumber { @@ -92,7 +93,6 @@ class BASE_EXPORT OSInfo { size_t allocation_granularity_; WOW64Status wow64_status_; - friend struct DefaultSingletonTraits<OSInfo>; DISALLOW_COPY_AND_ASSIGN(OSInfo); }; diff --git a/chrome/app/chrome_exe_main_gtk.cc b/chrome/app/chrome_exe_main_gtk.cc index 81775b5d..b902e08 100644 --- a/chrome/app/chrome_exe_main_gtk.cc +++ b/chrome/app/chrome_exe_main_gtk.cc @@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "base/process_util.h" #include "build/build_config.h" #include "chrome/browser/first_run/upgrade_util.h" @@ -10,39 +9,12 @@ // windows, this does nothing but load chrome.dll and invoke its entry point in // order to make it easy to update the app from GoogleUpdate. We don't need // that extra layer with on linux. -// -// TODO(tc): This is similar to chrome_exe_main_mac.cc. After it's -// more clear what needs to go here, we should evaluate whether or not -// to merge this file with chrome_exe_main_mac.cc. extern "C" { int ChromeMain(int argc, const char** argv); - -#if defined(OS_POSIX) && !defined(OS_MACOSX) && defined(USE_TCMALLOC) -int tc_set_new_mode(int mode); -#endif } int main(int argc, const char** argv) { - base::EnableTerminationOnHeapCorruption(); - base::EnableTerminationOnOutOfMemory(); - - // NOTE(willchan): One might ask why this call is done here rather than in - // process_util_linux.cc with the definition of - // EnableTerminationOnOutOfMemory(). That's because base shouldn't have a - // dependency on TCMalloc. Really, we ought to have our allocator shim code - // implement this EnableTerminationOnOutOfMemory() function. Whateverz. This - // works for now. -#if defined(OS_POSIX) && !defined(OS_MACOSX) && defined(USE_TCMALLOC) - // For tcmalloc, we need to tell it to behave like new. - tc_set_new_mode(1); -#endif - - // The exit manager is in charge of calling the dtors of singletons. - // Win has one here, but we assert with multiples from BrowserMain() if we - // keep it. - // base::AtExitManager exit_manager; - int return_code = ChromeMain(argc, argv); #if defined(OS_LINUX) && !defined(OS_CHROMEOS) diff --git a/chrome/app/chrome_exe_main_win.cc b/chrome/app/chrome_exe_main_win.cc index f1f54eb..ccb32fb 100644 --- a/chrome/app/chrome_exe_main_win.cc +++ b/chrome/app/chrome_exe_main_win.cc @@ -14,13 +14,7 @@ #include "sandbox/src/dep.h" #include "sandbox/src/sandbox_factory.h" - int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t*, int) { - base::EnableTerminationOnHeapCorruption(); - - // The exit manager is in charge of calling the dtors of singletons. - base::AtExitManager exit_manager; - bool exit_now = true; // We restarted because of a previous crash. Ask user if we should relaunch. if (ShowRestartDialogIfCrashed(&exit_now)) { @@ -28,9 +22,6 @@ int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t*, int) { return content::RESULT_CODE_NORMAL_EXIT; } - // Initialize the commandline singleton from the environment. - CommandLine::Init(0, NULL); - // Initialize the sandbox services. sandbox::SandboxInterfaceInfo sandbox_info = {0}; sandbox_info.broker_services = sandbox::SandboxFactory::GetBrokerServices(); @@ -41,6 +32,13 @@ int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t*, int) { // Enforces strong DEP support. Vista uses the NXCOMPAT flag in the exe. sandbox::SetCurrentProcessDEP(sandbox::DEP_ENABLED); } + + // The exit manager is in charge of calling the dtors of singletons. + base::AtExitManager exit_manager; + + // Initialize the commandline singleton from the environment. + CommandLine::Init(0, NULL); + // Load and launch the chrome dll. *Everything* happens inside. MainDllLoader* loader = MakeMainDllLoader(); int rc = loader->Launch(instance, &sandbox_info); diff --git a/chrome/app/chrome_main.cc b/chrome/app/chrome_main.cc index ae0b9af..afe6ad4 100644 --- a/chrome/app/chrome_main.cc +++ b/chrome/app/chrome_main.cc @@ -588,6 +588,10 @@ int ChromeMain(int argc, char** argv) { // There is no HINSTANCE on non-Windows. void* instance = NULL; #endif + + base::EnableTerminationOnHeapCorruption(); + base::EnableTerminationOnOutOfMemory(); + // LowLevelInit performs startup initialization before we // e.g. allocate any memory. It must be the first call on startup. chrome_main::LowLevelInit(instance); diff --git a/chrome/app/chrome_main_posix.cc b/chrome/app/chrome_main_posix.cc index f68a905..8a6262d 100644 --- a/chrome/app/chrome_main_posix.cc +++ b/chrome/app/chrome_main_posix.cc @@ -8,13 +8,18 @@ #include "base/global_descriptors_posix.h" #include "base/logging.h" -#include "base/process_util.h" #include "content/common/chrome_descriptors.h" #if defined(OS_MACOSX) #include "chrome/app/breakpad_mac.h" #endif +#if !defined(OS_MACOSX) && defined(USE_TCMALLOC) +extern "C" { +int tc_set_new_mode(int mode); +} +#endif + namespace { // Setup signal-handling state: resanitize most signals, ignore SIGPIPE. @@ -44,16 +49,16 @@ void SetupSignalHandlers() { namespace chrome_main { void LowLevelInit(void* instance) { -#if defined(OS_MACOSX) - // TODO(mark): Some of these things ought to be handled in - // chrome_exe_main_mac.cc. Under the current architecture, nothing - // in chrome_exe_main can rely directly on chrome_dll code on the - // Mac, though, so until some of this code is refactored to avoid - // such a dependency, it lives here. See also the TODO(mark) - // at InitCrashReporter() and DestructCrashReporter(). - base::EnableTerminationOnHeapCorruption(); - base::EnableTerminationOnOutOfMemory(); -#endif // OS_MACOSX + // NOTE(willchan): One might ask why this call is done here rather than in + // process_util_linux.cc with the definition of + // EnableTerminationOnOutOfMemory(). That's because base shouldn't have a + // dependency on TCMalloc. Really, we ought to have our allocator shim code + // implement this EnableTerminationOnOutOfMemory() function. Whateverz. This + // works for now. +#if !defined(OS_MACOSX) && defined(USE_TCMALLOC) + // For tcmalloc, we need to tell it to behave like new. + tc_set_new_mode(1); +#endif // Set C library locale to make sure CommandLine can parse argument values // in correct encoding. diff --git a/chrome/app/chrome_main_win.cc b/chrome/app/chrome_main_win.cc index bf1e98c..3caff3a 100644 --- a/chrome/app/chrome_main_win.cc +++ b/chrome/app/chrome_main_win.cc @@ -20,10 +20,6 @@ #include "chrome/common/chrome_switches.h" #include "policy/policy_constants.h" -#if defined(USE_TCMALLOC) -#include "third_party/tcmalloc/chromium/src/google/malloc_extension.h" -#endif - namespace { CAppModule _Module; @@ -43,37 +39,11 @@ void PureCall() { _exit(1); } -#pragma warning(push) -// Disables warning 4748 which is: "/GS can not protect parameters and local -// variables from local buffer overrun because optimizations are disabled in -// function." GetStats() will not overflow the passed-in buffer and this -// function never returns. -#pragma warning(disable : 4748) -void OnNoMemory() { -#if defined(USE_TCMALLOC) - // Try to get some information on the stack to make the crash easier to - // diagnose from a minidump, being very careful not to do anything that might - // try to heap allocate. - char buf[32*1024]; - MallocExtension::instance()->GetStats(buf, sizeof(buf)); -#endif - // Kill the process. This is important for security, since WebKit doesn't - // NULL-check many memory allocations. If a malloc fails, returns NULL, and - // the buffer is then used, it provides a handy mapping of memory starting at - // address 0 for an attacker to utilize. - __debugbreak(); - _exit(1); -} -#pragma warning(pop) -#pragma optimize("", on) - // Register the invalid param handler and pure call handler to be able to // notify breakpad when it happens. void RegisterInvalidParamHandler() { _set_invalid_parameter_handler(InvalidParameter); _set_purecall_handler(PureCall); - // Gather allocation failure. - std::set_new_handler(&OnNoMemory); // Also enable the new handler for malloc() based failures. _set_new_mode(1); } diff --git a/chrome/test/base/out_of_proc_test_runner.cc b/chrome/test/base/out_of_proc_test_runner.cc index 942d883..0b865d2 100644 --- a/chrome/test/base/out_of_proc_test_runner.cc +++ b/chrome/test/base/out_of_proc_test_runner.cc @@ -579,18 +579,6 @@ int main(int argc, char** argv) { return ChromeTestSuite(argc, argv).Run(); } - // The exit manager is in charge of calling the dtors of singleton objects. - // On Windows, the call to ChromeMain() below will construct one for the - // chrome.dll module, but that global is not shared with this module, so if - // chrome.dll calls back out to this module and the called code uses a - // singleton, we'll need this. On other platforms, ChromeMain() isn't called - // at all below, so this is the lone exit manager for any code after this - // point. - // NOTE: We can't init this atop main() because ChromeTestSuite, as a subclass - // of TestSuite, creates one. So we wait until after the Run() call above to - // create the manager for the code path that _doesn't_ use ChromeTestSuite. - base::AtExitManager exit_manager; - #if defined(OS_WIN) if (command_line->HasSwitch(switches::kProcessType)) { // This is a child process, call ChromeMain. diff --git a/sandbox/tests/integration_tests/integration_tests.cc b/sandbox/tests/integration_tests/integration_tests.cc index 5330ae9..fcebd8d 100644 --- a/sandbox/tests/integration_tests/integration_tests.cc +++ b/sandbox/tests/integration_tests/integration_tests.cc @@ -2,14 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "base/at_exit.h" #include "testing/gtest/include/gtest/gtest.h" #include "sandbox/tests/common/controller.h" int wmain(int argc, wchar_t **argv) { - // The exit manager is in charge of calling the dtors of singleton objects. - base::AtExitManager exit_manager; - if (argc >= 2) { if (0 == _wcsicmp(argv[1], L"-child")) // This instance is a child, not the test. diff --git a/sandbox/tests/unit_tests/unit_tests.cc b/sandbox/tests/unit_tests/unit_tests.cc index 1614612..a9623db 100644 --- a/sandbox/tests/unit_tests/unit_tests.cc +++ b/sandbox/tests/unit_tests/unit_tests.cc @@ -2,13 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "base/at_exit.h" #include "testing/gtest/include/gtest/gtest.h" int wmain(int argc, wchar_t **argv) { - // The exit manager is in charge of calling the dtors of singleton objects. - base::AtExitManager exit_manager; - if (argc >= 2) { if (0 == _wcsicmp(argv[1], L"-child")) // This instance is a child, not the test. diff --git a/sandbox/tests/validation_tests/unit_tests.cc b/sandbox/tests/validation_tests/unit_tests.cc index c5bc5cd..490f7ec 100644 --- a/sandbox/tests/validation_tests/unit_tests.cc +++ b/sandbox/tests/validation_tests/unit_tests.cc @@ -2,14 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "base/at_exit.h" #include "testing/gtest/include/gtest/gtest.h" #include "sandbox/tests/common/controller.h" int wmain(int argc, wchar_t **argv) { - // The exit manager is in charge of calling the dtors of singleton objects. - base::AtExitManager exit_manager; - if (argc >= 2) { if (0 == _wcsicmp(argv[1], L"-child")) return sandbox::DispatchCall(argc, argv); diff --git a/ui/base/resource/resource_bundle_win.cc b/ui/base/resource/resource_bundle_win.cc index 5778db2..0b64b50 100644 --- a/ui/base/resource/resource_bundle_win.cc +++ b/ui/base/resource/resource_bundle_win.cc @@ -11,6 +11,7 @@ #include "base/path_service.h" #include "base/stl_util.h" #include "base/string_piece.h" +#include "base/synchronization/lock.h" #include "base/win/resource_util.h" #include "base/win/windows_version.h" #include "ui/base/resource/data_pack.h" |