diff options
author | nsylvain@chromium.org <nsylvain@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-05-20 16:05:56 +0000 |
---|---|---|
committer | nsylvain@chromium.org <nsylvain@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-05-20 16:05:56 +0000 |
commit | ff608eb386a2662bbe076a2a59b21eb90bc34532 (patch) | |
tree | 63c82289115c4b64d6d444816aab4f895f43917c /sandbox/src/window.cc | |
parent | 1e3af029048d55a3b7c39100683121d71c8ea673 (diff) | |
download | chromium_src-ff608eb386a2662bbe076a2a59b21eb90bc34532.zip chromium_src-ff608eb386a2662bbe076a2a59b21eb90bc34532.tar.gz chromium_src-ff608eb386a2662bbe076a2a59b21eb90bc34532.tar.bz2 |
Add support for alternate window station.
TEST: Start chrome, make sure it loads pages, then user process explorer to make sure the WindowStation handle name is not the same as the browser process.
BUG:10996
Review URL: http://codereview.chromium.org/113190
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@16483 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'sandbox/src/window.cc')
-rw-r--r-- | sandbox/src/window.cc | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/sandbox/src/window.cc b/sandbox/src/window.cc new file mode 100644 index 0000000..cd6022c --- /dev/null +++ b/sandbox/src/window.cc @@ -0,0 +1,142 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "sandbox/src/window.h" + +#include <aclapi.h> + +#include "base/logging.h" +#include "base/scoped_ptr.h" + +namespace { + +// Gets the security attributes of a window object referenced by |handle|. The +// lpSecurityDescriptor member of the SECURITY_ATTRIBUTES parameter returned +// must be freed using LocalFree by the caller. +bool GetSecurityAttributes(HANDLE handle, SECURITY_ATTRIBUTES* attributes) { + attributes->bInheritHandle = FALSE; + attributes->nLength = sizeof(SECURITY_ATTRIBUTES); + + PACL dacl = NULL; + DWORD result = ::GetSecurityInfo(handle, SE_WINDOW_OBJECT, + DACL_SECURITY_INFORMATION, NULL, NULL, &dacl, + NULL, &attributes->lpSecurityDescriptor); + if (ERROR_SUCCESS == result) + return true; + + return false; +} + +} + +namespace sandbox { + +ResultCode CreateAltWindowStation(HWINSTA* winsta) { + // Get the security attributes from the current window station; we will + // use this as the base security attributes for the new window station. + SECURITY_ATTRIBUTES attributes = {0}; + if (!GetSecurityAttributes(::GetProcessWindowStation(), &attributes)) { + return SBOX_ERROR_CANNOT_CREATE_WINSTATION; + } + + // Create the window station using NULL for the name to ask the os to + // generate it. + // TODO(nsylvain): don't ask for WINSTA_ALL_ACCESS if we don't need to. + *winsta = ::CreateWindowStationW(NULL, 0, WINSTA_ALL_ACCESS, &attributes); + LocalFree(attributes.lpSecurityDescriptor); + + if (*winsta) + return SBOX_ALL_OK; + + return SBOX_ERROR_CANNOT_CREATE_WINSTATION; +} + +ResultCode CreateAltDesktop(HWINSTA winsta, HDESK* desktop) { + std::wstring desktop_name = L"sbox_alternate_desktop_"; + + // Append the current PID to the desktop name. + wchar_t buffer[16]; + _snwprintf_s(buffer, sizeof(buffer) / sizeof(wchar_t), L"0x%X", + ::GetCurrentProcessId()); + desktop_name += buffer; + + // Get the security attributes from the current desktop, we will use this as + // the base security attributes for the new desktop. + SECURITY_ATTRIBUTES attributes = {0}; + if (!GetSecurityAttributes(GetThreadDesktop(GetCurrentThreadId()), + &attributes)) { + return SBOX_ERROR_CANNOT_CREATE_DESKTOP; + } + + // Back up the current window station, in case we need to switch it. + HWINSTA current_winsta = ::GetProcessWindowStation(); + + if (winsta) { + // We need to switch to the alternate window station before creating the + // desktop. + if (!::SetProcessWindowStation(winsta)) { + ::LocalFree(attributes.lpSecurityDescriptor); + return SBOX_ERROR_CANNOT_CREATE_DESKTOP; + } + } + + // Create the destkop. + // TODO(nsylvain): don't ask for GENERIC_ALL if we don't need to. + *desktop = ::CreateDesktop(desktop_name.c_str(), NULL, NULL, 0, GENERIC_ALL, + &attributes); + ::LocalFree(attributes.lpSecurityDescriptor); + + if (winsta) { + // Revert to the right window station. + if (!::SetProcessWindowStation(current_winsta)) { + return SBOX_ERROR_FAILED_TO_SWITCH_BACK_WINSTATION; + } + } + + if (*desktop) + return SBOX_ALL_OK; + + return SBOX_ERROR_CANNOT_CREATE_DESKTOP; +} + +std::wstring GetWindowObjectName(HANDLE handle) { + // Get the size of the name. + DWORD size = 0; + ::GetUserObjectInformation(handle, UOI_NAME, NULL, 0, &size); + + if (!size) { + NOTREACHED(); + return std::wstring(); + } + + // Create the buffer that will hold the name. + scoped_ptr<wchar_t> name_buffer(new wchar_t[size]); + + // Query the name of the object. + if (!::GetUserObjectInformation(handle, UOI_NAME, name_buffer.get(), size, + &size)) { + NOTREACHED(); + return std::wstring(); + } + + return std::wstring(name_buffer.get()); +} + +std::wstring GetFullDesktopName(HWINSTA winsta, HDESK desktop) { + if (!desktop) { + NOTREACHED(); + return std::wstring(); + } + + std::wstring name; + if (winsta) { + name = GetWindowObjectName(winsta); + name += L'\\'; + } + + name += GetWindowObjectName(desktop); + return name; +} + +} // namespace sandbox |