diff options
author | forshaw <forshaw@chromium.org> | 2015-09-16 14:31:30 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-09-16 21:32:15 +0000 |
commit | 47161b3bd2e3291c3ee969efb21ab9ad74ca404b (patch) | |
tree | b14e86a9b500d0ebb48d12f12be06c3ae4d66079 /base/win | |
parent | 7c05094e1588e251337e2d88841c882117cab3c8 (diff) | |
download | chromium_src-47161b3bd2e3291c3ee969efb21ab9ad74ca404b.zip chromium_src-47161b3bd2e3291c3ee969efb21ab9ad74ca404b.tar.gz chromium_src-47161b3bd2e3291c3ee969efb21ab9ad74ca404b.tar.bz2 |
Added common check for USER32 and GDI32 API availability.
This CL adds a check function to base to allow code to check if the USER32
and GDI32 API calls are available. Windows 8 and above allow an application
to disable these API calls for security reasons and fallback when calling
the API isn't consistent (such as returning error codes instead of handles).
This can lead to undefined behaviour if code calls into these APIs while they
are disabled. This check can be used to guard calls to these APIs and fallback
if appropriate.
BUG=523278
Review URL: https://codereview.chromium.org/1351513002
Cr-Commit-Position: refs/heads/master@{#349237}
Diffstat (limited to 'base/win')
-rw-r--r-- | base/win/win_util.cc | 44 | ||||
-rw-r--r-- | base/win/win_util.h | 7 |
2 files changed, 51 insertions, 0 deletions
diff --git a/base/win/win_util.cc b/base/win/win_util.cc index 96d646a..98d451f 100644 --- a/base/win/win_util.cc +++ b/base/win/win_util.cc @@ -57,6 +57,44 @@ void __cdecl ForceCrashOnSigAbort(int) { *((volatile int*)0) = 0x1337; } +typedef decltype(GetProcessMitigationPolicy)* GetProcessMitigationPolicyType; + +class LazyIsUser32AndGdi32Available { + public: + LazyIsUser32AndGdi32Available() : value_(!IsWin32kSyscallsDisabled()) {} + + ~LazyIsUser32AndGdi32Available() {} + + bool value() { return value_; } + + private: + static bool IsWin32kSyscallsDisabled() { + // Can't disable win32k prior to windows 8. + if (base::win::GetVersion() < base::win::VERSION_WIN8) + return false; + + GetProcessMitigationPolicyType get_process_mitigation_policy_func = + reinterpret_cast<GetProcessMitigationPolicyType>(GetProcAddress( + GetModuleHandle(L"kernel32.dll"), "GetProcessMitigationPolicy")); + + if (!get_process_mitigation_policy_func) + return false; + + PROCESS_MITIGATION_SYSTEM_CALL_DISABLE_POLICY policy = {}; + if (get_process_mitigation_policy_func(GetCurrentProcess(), + ProcessSystemCallDisablePolicy, + &policy, sizeof(policy))) { + return policy.DisallowWin32kSystemCalls != 0; + } + + return false; + } + + const bool value_; + + DISALLOW_COPY_AND_ASSIGN(LazyIsUser32AndGdi32Available); +}; + const wchar_t kWindows8OSKRegPath[] = L"Software\\Classes\\CLSID\\{054AAE20-4BEA-4347-8A35-64A533254A9D}" L"\\LocalServer32"; @@ -537,5 +575,11 @@ bool MaybeHasSHA256Support() { return true; // New enough to have SHA-256 support. } +bool IsUser32AndGdi32Available() { + static base::LazyInstance<LazyIsUser32AndGdi32Available>::Leaky available = + LAZY_INSTANCE_INITIALIZER; + return available.Get().value(); +} + } // namespace win } // namespace base diff --git a/base/win/win_util.h b/base/win/win_util.h index 9f42e44..3c900ff 100644 --- a/base/win/win_util.h +++ b/base/win/win_util.h @@ -166,6 +166,13 @@ BASE_EXPORT void SetDomainStateForTesting(bool state); // run-time detection of this capability. BASE_EXPORT bool MaybeHasSHA256Support(); +// Returns true if the current process can make USER32 or GDI32 calls such as +// CreateWindow and CreateDC. Windows 8 and above allow the kernel component +// of these calls to be disabled which can cause undefined behaviour such as +// crashes. This function can be used to guard areas of code using these calls +// and provide a fallback path if necessary. +BASE_EXPORT bool IsUser32AndGdi32Available(); + } // namespace win } // namespace base |