summaryrefslogtreecommitdiffstats
path: root/base/win
diff options
context:
space:
mode:
authorforshaw <forshaw@chromium.org>2015-09-16 14:31:30 -0700
committerCommit bot <commit-bot@chromium.org>2015-09-16 21:32:15 +0000
commit47161b3bd2e3291c3ee969efb21ab9ad74ca404b (patch)
treeb14e86a9b500d0ebb48d12f12be06c3ae4d66079 /base/win
parent7c05094e1588e251337e2d88841c882117cab3c8 (diff)
downloadchromium_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.cc44
-rw-r--r--base/win/win_util.h7
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