| // Copyright 2022 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "sandbox/win/src/alternate_desktop.h" |
| |
| #include <windows.h> |
| |
| #include "base/win/win_util.h" |
| #include "sandbox/win/src/acl.h" |
| #include "sandbox/win/src/window.h" |
| |
| namespace sandbox { |
| |
| AlternateDesktop::~AlternateDesktop() { |
| if (desktop_) { |
| ::CloseDesktop(desktop_); |
| desktop_ = nullptr; |
| } |
| if (winstation_) { |
| ::CloseWindowStation(winstation_); |
| winstation_ = nullptr; |
| } |
| } |
| |
| // Updates the desktop token's integrity level to be no higher than |
| // `integrity_level`. |
| ResultCode AlternateDesktop::UpdateDesktopIntegrity( |
| IntegrityLevel integrity_level) { |
| // Integrity label enum is reversed (higher level is a lower value). |
| static_assert(INTEGRITY_LEVEL_SYSTEM < INTEGRITY_LEVEL_UNTRUSTED, |
| "Integrity level ordering reversed."); |
| DCHECK(integrity_level != INTEGRITY_LEVEL_LAST); |
| // Require that the desktop has been set. |
| if (!desktop_) |
| return SBOX_ERROR_CANNOT_CREATE_DESKTOP; |
| if (integrity_ < integrity_level) { |
| DWORD result = SetObjectIntegrityLabel( |
| desktop_, base::win::SecurityObjectType::kDesktop, 0, integrity_level); |
| if (ERROR_SUCCESS != result) |
| return SBOX_ERROR_CANNOT_SET_DESKTOP_INTEGRITY; |
| integrity_ = integrity_level; |
| } |
| return SBOX_ALL_OK; |
| } |
| |
| // Populate this object, creating a winstation if `alternate_winstation` is |
| // true. |
| ResultCode AlternateDesktop::Initialize(bool alternate_winstation) { |
| DCHECK(!desktop_ && !winstation_); |
| if (alternate_winstation) { |
| // Create the window station. |
| ResultCode result = CreateAltWindowStation(&winstation_); |
| if (SBOX_ALL_OK != result) |
| return result; |
| |
| // Verify that everything is fine. |
| if (!winstation_ || base::win::GetWindowObjectName(winstation_).empty()) { |
| return SBOX_ERROR_CANNOT_CREATE_DESKTOP; |
| } |
| } |
| ResultCode result = CreateAltDesktop(winstation_, &desktop_); |
| if (SBOX_ALL_OK != result) |
| return result; |
| |
| // Verify that everything is fine. |
| if (!desktop_ || base::win::GetWindowObjectName(desktop_).empty()) { |
| return SBOX_ERROR_CANNOT_CREATE_DESKTOP; |
| } |
| return SBOX_ALL_OK; |
| } |
| |
| std::wstring AlternateDesktop::GetDesktopName() { |
| if (!desktop_) |
| return std::wstring(); |
| return GetFullDesktopName(winstation_, desktop_); |
| } |
| |
| } // namespace sandbox |