From c38eaa16e72bc3dd5fd067a697e111b4bb545360 Mon Sep 17 00:00:00 2001 From: forshaw Date: Thu, 21 May 2015 14:35:20 -0700 Subject: [PATCH] Add creation of AC object directory to fix issue with VS debugger. This patch adds creation of an app container specific object directory when creating the lowbox token. Without this object directory the VS debugger will fail to attach to the process. No attempt is made to set the directory's DACL to ensure it can be used by the sandboxed process, it's only to fix the issue with the debugger which will run at normal user privilege. BUG=488318 Review URL: https://codereview.chromium.org/1151513003 Cr-Commit-Position: refs/heads/master@{#330996} --- sandbox/win/src/nt_internals.h | 6 +++ sandbox/win/src/sandbox_policy_base.cc | 52 +++++++++++++++++++++++++- sandbox/win/src/sandbox_policy_base.h | 2 + 3 files changed, 59 insertions(+), 1 deletion(-) diff --git a/sandbox/win/src/nt_internals.h b/sandbox/win/src/nt_internals.h index 45511a1f98a16b..40b29c6beb3276 100644 --- a/sandbox/win/src/nt_internals.h +++ b/sandbox/win/src/nt_internals.h @@ -58,6 +58,7 @@ typedef PSTRING POEM_STRING; typedef CONST STRING* PCOEM_STRING; #define OBJ_CASE_INSENSITIVE 0x00000040L +#define OBJ_OPENIF 0x00000080L typedef struct _OBJECT_ATTRIBUTES { ULONG Length; @@ -635,6 +636,11 @@ typedef enum _EVENT_TYPE { SynchronizationEvent } EVENT_TYPE, *PEVENT_TYPE; +typedef NTSTATUS (WINAPI* NtCreateDirectoryObjectFunction) ( + PHANDLE DirectoryHandle, + ACCESS_MASK DesiredAccess, + POBJECT_ATTRIBUTES ObjectAttributes); + typedef NTSTATUS (WINAPI* NtOpenDirectoryObjectFunction) ( PHANDLE DirectoryHandle, ACCESS_MASK DesiredAccess, diff --git a/sandbox/win/src/sandbox_policy_base.cc b/sandbox/win/src/sandbox_policy_base.cc index 81b1e6a4af1aaf..07a7d095816d96 100644 --- a/sandbox/win/src/sandbox_policy_base.cc +++ b/sandbox/win/src/sandbox_policy_base.cc @@ -9,6 +9,7 @@ #include "base/basictypes.h" #include "base/callback.h" #include "base/logging.h" +#include "base/strings/stringprintf.h" #include "base/win/windows_version.h" #include "sandbox/win/src/app_container.h" #include "sandbox/win/src/filesystem_dispatcher.h" @@ -31,6 +32,7 @@ #include "sandbox/win/src/registry_policy.h" #include "sandbox/win/src/restricted_token_utils.h" #include "sandbox/win/src/sandbox_policy.h" +#include "sandbox/win/src/sandbox_utils.h" #include "sandbox/win/src/sync_dispatcher.h" #include "sandbox/win/src/sync_policy.h" #include "sandbox/win/src/target_process.h" @@ -67,6 +69,43 @@ bool IsInheritableHandle(HANDLE handle) { return handle_type == FILE_TYPE_DISK || handle_type == FILE_TYPE_PIPE; } +HANDLE CreateLowBoxObjectDirectory(PSID lowbox_sid) { + DWORD session_id = 0; + if (!::ProcessIdToSessionId(::GetCurrentProcessId(), &session_id)) + return NULL; + + LPWSTR sid_string = NULL; + if (!::ConvertSidToStringSid(lowbox_sid, &sid_string)) + return NULL; + + base::string16 directory_path = base::StringPrintf( + L"\\Sessions\\%d\\AppContainerNamedObjects\\%ls", + session_id, sid_string).c_str(); + ::LocalFree(sid_string); + + NtCreateDirectoryObjectFunction CreateObjectDirectory = NULL; + ResolveNTFunctionPtr("NtCreateDirectoryObject", &CreateObjectDirectory); + + OBJECT_ATTRIBUTES obj_attr; + UNICODE_STRING obj_name; + sandbox::InitObjectAttribs(directory_path, + OBJ_CASE_INSENSITIVE | OBJ_OPENIF, + NULL, + &obj_attr, + &obj_name, + NULL); + + HANDLE handle = NULL; + NTSTATUS status = CreateObjectDirectory(&handle, + DIRECTORY_ALL_ACCESS, + &obj_attr); + + if (!NT_SUCCESS(status)) + return NULL; + + return handle; +} + } namespace sandbox { @@ -559,9 +598,20 @@ ResultCode PolicyBase::MakeTokens(HANDLE* initial, HANDLE* lockdown) { OBJECT_ATTRIBUTES obj_attr; InitializeObjectAttributes(&obj_attr, NULL, 0, NULL, NULL); HANDLE token_lowbox = NULL; + + if (!lowbox_directory_.IsValid()) + lowbox_directory_.Set(CreateLowBoxObjectDirectory(lowbox_sid_)); + DCHECK(lowbox_directory_.IsValid()); + + // The order of handles isn't important in the CreateLowBoxToken call. + // The kernel will maintain a reference to the object directory handle. + HANDLE saved_handles[1] = {lowbox_directory_.Get()}; + DWORD saved_handles_count = lowbox_directory_.IsValid() ? 1 : 0; + NTSTATUS status = CreateLowBoxToken(&token_lowbox, *lockdown, TOKEN_ALL_ACCESS, &obj_attr, - lowbox_sid_, 0, NULL, 0, NULL); + lowbox_sid_, 0, NULL, + saved_handles_count, saved_handles); if (!NT_SUCCESS(status)) return SBOX_ERROR_GENERIC; diff --git a/sandbox/win/src/sandbox_policy_base.h b/sandbox/win/src/sandbox_policy_base.h index 136e3a4589e775..1de5cf8c368cd4 100644 --- a/sandbox/win/src/sandbox_policy_base.h +++ b/sandbox/win/src/sandbox_policy_base.h @@ -13,6 +13,7 @@ #include "base/basictypes.h" #include "base/compiler_specific.h" #include "base/strings/string16.h" +#include "base/win/scoped_handle.h" #include "sandbox/win/src/crosscall_server.h" #include "sandbox/win/src/handle_closer.h" #include "sandbox/win/src/ipc_tags.h" @@ -167,6 +168,7 @@ class PolicyBase : public Dispatcher, public TargetPolicy { std::vector capabilities_; scoped_ptr appcontainer_list_; PSID lowbox_sid_; + base::win::ScopedHandle lowbox_directory_; static HDESK alternate_desktop_handle_; static HWINSTA alternate_winstation_handle_;