security/sandbox/win/src/window.cc

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
michael@0 2 // Use of this source code is governed by a BSD-style license that can be
michael@0 3 // found in the LICENSE file.
michael@0 4
michael@0 5 #include "sandbox/win/src/window.h"
michael@0 6
michael@0 7 #include <aclapi.h>
michael@0 8
michael@0 9 #include "base/logging.h"
michael@0 10 #include "base/memory/scoped_ptr.h"
michael@0 11
michael@0 12 namespace {
michael@0 13
michael@0 14 // Gets the security attributes of a window object referenced by |handle|. The
michael@0 15 // lpSecurityDescriptor member of the SECURITY_ATTRIBUTES parameter returned
michael@0 16 // must be freed using LocalFree by the caller.
michael@0 17 bool GetSecurityAttributes(HANDLE handle, SECURITY_ATTRIBUTES* attributes) {
michael@0 18 attributes->bInheritHandle = FALSE;
michael@0 19 attributes->nLength = sizeof(SECURITY_ATTRIBUTES);
michael@0 20
michael@0 21 PACL dacl = NULL;
michael@0 22 DWORD result = ::GetSecurityInfo(handle, SE_WINDOW_OBJECT,
michael@0 23 DACL_SECURITY_INFORMATION, NULL, NULL, &dacl,
michael@0 24 NULL, &attributes->lpSecurityDescriptor);
michael@0 25 if (ERROR_SUCCESS == result)
michael@0 26 return true;
michael@0 27
michael@0 28 return false;
michael@0 29 }
michael@0 30
michael@0 31 }
michael@0 32
michael@0 33 namespace sandbox {
michael@0 34
michael@0 35 ResultCode CreateAltWindowStation(HWINSTA* winsta) {
michael@0 36 // Get the security attributes from the current window station; we will
michael@0 37 // use this as the base security attributes for the new window station.
michael@0 38 SECURITY_ATTRIBUTES attributes = {0};
michael@0 39 if (!GetSecurityAttributes(::GetProcessWindowStation(), &attributes)) {
michael@0 40 return SBOX_ERROR_CANNOT_CREATE_WINSTATION;
michael@0 41 }
michael@0 42
michael@0 43 // Create the window station using NULL for the name to ask the os to
michael@0 44 // generate it.
michael@0 45 // TODO(nsylvain): don't ask for WINSTA_ALL_ACCESS if we don't need to.
michael@0 46 *winsta = ::CreateWindowStationW(NULL, 0, WINSTA_ALL_ACCESS, &attributes);
michael@0 47 LocalFree(attributes.lpSecurityDescriptor);
michael@0 48
michael@0 49 if (*winsta)
michael@0 50 return SBOX_ALL_OK;
michael@0 51
michael@0 52 return SBOX_ERROR_CANNOT_CREATE_WINSTATION;
michael@0 53 }
michael@0 54
michael@0 55 ResultCode CreateAltDesktop(HWINSTA winsta, HDESK* desktop) {
michael@0 56 std::wstring desktop_name = L"sbox_alternate_desktop_";
michael@0 57
michael@0 58 // Append the current PID to the desktop name.
michael@0 59 wchar_t buffer[16];
michael@0 60 _snwprintf_s(buffer, sizeof(buffer) / sizeof(wchar_t), L"0x%X",
michael@0 61 ::GetCurrentProcessId());
michael@0 62 desktop_name += buffer;
michael@0 63
michael@0 64 // Get the security attributes from the current desktop, we will use this as
michael@0 65 // the base security attributes for the new desktop.
michael@0 66 SECURITY_ATTRIBUTES attributes = {0};
michael@0 67 if (!GetSecurityAttributes(GetThreadDesktop(GetCurrentThreadId()),
michael@0 68 &attributes)) {
michael@0 69 return SBOX_ERROR_CANNOT_CREATE_DESKTOP;
michael@0 70 }
michael@0 71
michael@0 72 // Back up the current window station, in case we need to switch it.
michael@0 73 HWINSTA current_winsta = ::GetProcessWindowStation();
michael@0 74
michael@0 75 if (winsta) {
michael@0 76 // We need to switch to the alternate window station before creating the
michael@0 77 // desktop.
michael@0 78 if (!::SetProcessWindowStation(winsta)) {
michael@0 79 ::LocalFree(attributes.lpSecurityDescriptor);
michael@0 80 return SBOX_ERROR_CANNOT_CREATE_DESKTOP;
michael@0 81 }
michael@0 82 }
michael@0 83
michael@0 84 // Create the destkop.
michael@0 85 // TODO(nsylvain): don't ask for GENERIC_ALL if we don't need to.
michael@0 86 *desktop = ::CreateDesktop(desktop_name.c_str(), NULL, NULL, 0, GENERIC_ALL,
michael@0 87 &attributes);
michael@0 88 ::LocalFree(attributes.lpSecurityDescriptor);
michael@0 89
michael@0 90 if (winsta) {
michael@0 91 // Revert to the right window station.
michael@0 92 if (!::SetProcessWindowStation(current_winsta)) {
michael@0 93 return SBOX_ERROR_FAILED_TO_SWITCH_BACK_WINSTATION;
michael@0 94 }
michael@0 95 }
michael@0 96
michael@0 97 if (*desktop)
michael@0 98 return SBOX_ALL_OK;
michael@0 99
michael@0 100 return SBOX_ERROR_CANNOT_CREATE_DESKTOP;
michael@0 101 }
michael@0 102
michael@0 103 std::wstring GetWindowObjectName(HANDLE handle) {
michael@0 104 // Get the size of the name.
michael@0 105 DWORD size = 0;
michael@0 106 ::GetUserObjectInformation(handle, UOI_NAME, NULL, 0, &size);
michael@0 107
michael@0 108 if (!size) {
michael@0 109 NOTREACHED();
michael@0 110 return std::wstring();
michael@0 111 }
michael@0 112
michael@0 113 // Create the buffer that will hold the name.
michael@0 114 scoped_ptr<wchar_t[]> name_buffer(new wchar_t[size]);
michael@0 115
michael@0 116 // Query the name of the object.
michael@0 117 if (!::GetUserObjectInformation(handle, UOI_NAME, name_buffer.get(), size,
michael@0 118 &size)) {
michael@0 119 NOTREACHED();
michael@0 120 return std::wstring();
michael@0 121 }
michael@0 122
michael@0 123 return std::wstring(name_buffer.get());
michael@0 124 }
michael@0 125
michael@0 126 std::wstring GetFullDesktopName(HWINSTA winsta, HDESK desktop) {
michael@0 127 if (!desktop) {
michael@0 128 NOTREACHED();
michael@0 129 return std::wstring();
michael@0 130 }
michael@0 131
michael@0 132 std::wstring name;
michael@0 133 if (winsta) {
michael@0 134 name = GetWindowObjectName(winsta);
michael@0 135 name += L'\\';
michael@0 136 }
michael@0 137
michael@0 138 name += GetWindowObjectName(desktop);
michael@0 139 return name;
michael@0 140 }
michael@0 141
michael@0 142 } // namespace sandbox

mercurial