Bug 1366701 Part 2: Roll-up patch to apply remaining mozilla changes to chromium sandbox. r=tabraldes,aklotz,jimm,bobowen

Patches re-applied from security/sandbox/chromium-shim/patches/after_update/.
See patch files for additional commit comments.
This commit is contained in:
Bob Owen 2014-11-29 17:12:18 +00:00
parent 6bd2ddcccd
commit ef5af7b0b1
21 changed files with 1696 additions and 77 deletions

View File

@ -0,0 +1,34 @@
# HG changeset patch
# User Bob Owen <bobowencode@gmail.com>
# Date 1482405067 0
# Thu Dec 22 11:11:07 2016 +0000
# Node ID 43d0efc18f586e1ed90b95c4a52235c4648e96a9
# Parent 266ef86795979f2ef9b6650d1bb35fb27d11ad86
Add KEY_WOW64_64Key and KEY_WOW64_32KEY to the Chromium sandbox allowed registry read flags. r=aklotz
Originally landed as changeset:
https://hg.mozilla.org/mozilla-central/rev/d24db55deb85
diff --git a/security/sandbox/chromium/sandbox/win/src/registry_policy.cc b/security/sandbox/chromium/sandbox/win/src/registry_policy.cc
--- a/security/sandbox/chromium/sandbox/win/src/registry_policy.cc
+++ b/security/sandbox/chromium/sandbox/win/src/registry_policy.cc
@@ -15,17 +15,18 @@
#include "sandbox/win/src/sandbox_types.h"
#include "sandbox/win/src/sandbox_utils.h"
#include "sandbox/win/src/win_utils.h"
namespace {
static const uint32_t kAllowedRegFlags =
KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS | KEY_NOTIFY | KEY_READ |
- GENERIC_READ | GENERIC_EXECUTE | READ_CONTROL;
+ GENERIC_READ | GENERIC_EXECUTE | READ_CONTROL | KEY_WOW64_64KEY |
+ KEY_WOW64_32KEY;
// Opens the key referenced by |obj_attributes| with |access| and
// checks what permission was given. Remove the WRITE flags and update
// |access| with the new value.
NTSTATUS TranslateMaximumAllowed(OBJECT_ATTRIBUTES* obj_attributes,
DWORD* access) {
NtOpenKeyFunction NtOpenKey = NULL;
ResolveNTFunctionPtr("NtOpenKey", &NtOpenKey);

View File

@ -0,0 +1,748 @@
# HG changeset patch
# User Bob Owen <bobowencode@gmail.com>
# Date 1417281138 0
# Sat Nov 29 17:12:18 2014 +0000
# Node ID 6f0003647b90c4196fa349813baaaaf425900bf5
# Parent 4cf17a52d84ad44e38c91c9f4106241f85f7bf9e
Re-apply - Logging changes to the Chromium interception code. r=tabraldes
Originally landed as changset:
https://hg.mozilla.org/mozilla-central/rev/0f763c186855
diff --git a/security/sandbox/chromium/sandbox/win/src/filesystem_interception.cc b/security/sandbox/chromium/sandbox/win/src/filesystem_interception.cc
--- a/security/sandbox/chromium/sandbox/win/src/filesystem_interception.cc
+++ b/security/sandbox/chromium/sandbox/win/src/filesystem_interception.cc
@@ -9,16 +9,17 @@
#include "sandbox/win/src/crosscall_client.h"
#include "sandbox/win/src/ipc_tags.h"
#include "sandbox/win/src/policy_params.h"
#include "sandbox/win/src/policy_target.h"
#include "sandbox/win/src/sandbox_factory.h"
#include "sandbox/win/src/sandbox_nt_util.h"
#include "sandbox/win/src/sharedmem_ipc_client.h"
#include "sandbox/win/src/target_services.h"
+#include "mozilla/sandboxing/sandboxLogging.h"
// This status occurs when trying to access a network share on the machine from
// which it is shared.
#define STATUS_NETWORK_OPEN_RESTRICTION ((NTSTATUS)0xC0000201L)
namespace sandbox {
NTSTATUS WINAPI TargetNtCreateFile(NtCreateFileFunction orig_CreateFile,
@@ -33,16 +34,20 @@ NTSTATUS WINAPI TargetNtCreateFile(NtCre
NTSTATUS status = orig_CreateFile(file, desired_access, object_attributes,
io_status, allocation_size,
file_attributes, sharing, disposition,
options, ea_buffer, ea_length);
if (STATUS_ACCESS_DENIED != status &&
STATUS_NETWORK_OPEN_RESTRICTION != status)
return status;
+ mozilla::sandboxing::LogBlocked("NtCreateFile",
+ object_attributes->ObjectName->Buffer,
+ object_attributes->ObjectName->Length);
+
// We don't trust that the IPC can work this early.
if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
return status;
wchar_t* name = NULL;
do {
if (!ValidParameter(file, sizeof(HANDLE), WRITE))
break;
@@ -90,16 +95,19 @@ NTSTATUS WINAPI TargetNtCreateFile(NtCre
__try {
*file = answer.handle;
io_status->Status = answer.nt_status;
io_status->Information = answer.extended[0].ulong_ptr;
} __except(EXCEPTION_EXECUTE_HANDLER) {
break;
}
+ mozilla::sandboxing::LogAllowed("NtCreateFile",
+ object_attributes->ObjectName->Buffer,
+ object_attributes->ObjectName->Length);
} while (false);
if (name)
operator delete(name, NT_ALLOC);
return status;
}
@@ -110,16 +118,20 @@ NTSTATUS WINAPI TargetNtOpenFile(NtOpenF
ULONG options) {
// Check if the process can open it first.
NTSTATUS status = orig_OpenFile(file, desired_access, object_attributes,
io_status, sharing, options);
if (STATUS_ACCESS_DENIED != status &&
STATUS_NETWORK_OPEN_RESTRICTION != status)
return status;
+ mozilla::sandboxing::LogBlocked("NtOpenFile",
+ object_attributes->ObjectName->Buffer,
+ object_attributes->ObjectName->Length);
+
// We don't trust that the IPC can work this early.
if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
return status;
wchar_t* name = NULL;
do {
if (!ValidParameter(file, sizeof(HANDLE), WRITE))
break;
@@ -165,16 +177,19 @@ NTSTATUS WINAPI TargetNtOpenFile(NtOpenF
__try {
*file = answer.handle;
io_status->Status = answer.nt_status;
io_status->Information = answer.extended[0].ulong_ptr;
} __except(EXCEPTION_EXECUTE_HANDLER) {
break;
}
+ mozilla::sandboxing::LogAllowed("NtOpenFile",
+ object_attributes->ObjectName->Buffer,
+ object_attributes->ObjectName->Length);
} while (false);
if (name)
operator delete(name, NT_ALLOC);
return status;
}
@@ -183,16 +198,20 @@ NTSTATUS WINAPI TargetNtQueryAttributesF
POBJECT_ATTRIBUTES object_attributes,
PFILE_BASIC_INFORMATION file_attributes) {
// Check if the process can query it first.
NTSTATUS status = orig_QueryAttributes(object_attributes, file_attributes);
if (STATUS_ACCESS_DENIED != status &&
STATUS_NETWORK_OPEN_RESTRICTION != status)
return status;
+ mozilla::sandboxing::LogBlocked("NtQueryAttributesFile",
+ object_attributes->ObjectName->Buffer,
+ object_attributes->ObjectName->Length);
+
// We don't trust that the IPC can work this early.
if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
return status;
wchar_t* name = NULL;
do {
if (!ValidParameter(file_attributes, sizeof(FILE_BASIC_INFORMATION), WRITE))
break;
@@ -223,16 +242,19 @@ NTSTATUS WINAPI TargetNtQueryAttributesF
ResultCode code = CrossCall(ipc, IPC_NTQUERYATTRIBUTESFILE_TAG, name,
attributes, file_info, &answer);
if (SBOX_ALL_OK != code)
break;
status = answer.nt_status;
+ mozilla::sandboxing::LogAllowed("NtQueryAttributesFile",
+ object_attributes->ObjectName->Buffer,
+ object_attributes->ObjectName->Length);
} while (false);
if (name)
operator delete(name, NT_ALLOC);
return status;
}
@@ -242,16 +264,20 @@ NTSTATUS WINAPI TargetNtQueryFullAttribu
PFILE_NETWORK_OPEN_INFORMATION file_attributes) {
// Check if the process can query it first.
NTSTATUS status = orig_QueryFullAttributes(object_attributes,
file_attributes);
if (STATUS_ACCESS_DENIED != status &&
STATUS_NETWORK_OPEN_RESTRICTION != status)
return status;
+ mozilla::sandboxing::LogBlocked("NtQueryFullAttributesFile",
+ object_attributes->ObjectName->Buffer,
+ object_attributes->ObjectName->Length);
+
// We don't trust that the IPC can work this early.
if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
return status;
wchar_t* name = NULL;
do {
if (!ValidParameter(file_attributes, sizeof(FILE_NETWORK_OPEN_INFORMATION),
WRITE))
@@ -282,16 +308,20 @@ NTSTATUS WINAPI TargetNtQueryFullAttribu
CrossCallReturn answer = {0};
ResultCode code = CrossCall(ipc, IPC_NTQUERYFULLATTRIBUTESFILE_TAG, name,
attributes, file_info, &answer);
if (SBOX_ALL_OK != code)
break;
status = answer.nt_status;
+
+ mozilla::sandboxing::LogAllowed("NtQueryFullAttributesFile",
+ object_attributes->ObjectName->Buffer,
+ object_attributes->ObjectName->Length);
} while (false);
if (name)
operator delete(name, NT_ALLOC);
return status;
}
@@ -300,16 +330,18 @@ NTSTATUS WINAPI TargetNtSetInformationFi
PIO_STATUS_BLOCK io_status, PVOID file_info, ULONG length,
FILE_INFORMATION_CLASS file_info_class) {
// Check if the process can open it first.
NTSTATUS status = orig_SetInformationFile(file, io_status, file_info, length,
file_info_class);
if (STATUS_ACCESS_DENIED != status)
return status;
+ mozilla::sandboxing::LogBlocked("NtSetInformationFile");
+
// We don't trust that the IPC can work this early.
if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
return status;
wchar_t* name = NULL;
do {
void* memory = GetGlobalIPCMemory();
if (NULL == memory)
@@ -361,16 +393,17 @@ NTSTATUS WINAPI TargetNtSetInformationFi
ResultCode code = CrossCall(ipc, IPC_NTSETINFO_RENAME_TAG, file,
io_status_buffer, file_info_buffer, length,
file_info_class, &answer);
if (SBOX_ALL_OK != code)
break;
status = answer.nt_status;
+ mozilla::sandboxing::LogAllowed("NtSetInformationFile");
} while (false);
if (name)
operator delete(name, NT_ALLOC);
return status;
}
diff --git a/security/sandbox/chromium/sandbox/win/src/handle_interception.cc b/security/sandbox/chromium/sandbox/win/src/handle_interception.cc
--- a/security/sandbox/chromium/sandbox/win/src/handle_interception.cc
+++ b/security/sandbox/chromium/sandbox/win/src/handle_interception.cc
@@ -5,16 +5,17 @@
#include "sandbox/win/src/handle_interception.h"
#include "sandbox/win/src/crosscall_client.h"
#include "sandbox/win/src/ipc_tags.h"
#include "sandbox/win/src/sandbox_factory.h"
#include "sandbox/win/src/sandbox_nt_util.h"
#include "sandbox/win/src/sharedmem_ipc_client.h"
#include "sandbox/win/src/target_services.h"
+#include "mozilla/sandboxing/sandboxLogging.h"
namespace sandbox {
ResultCode DuplicateHandleProxy(HANDLE source_handle,
DWORD target_process_id,
HANDLE* target_handle,
DWORD desired_access,
DWORD options) {
@@ -29,17 +30,19 @@ ResultCode DuplicateHandleProxy(HANDLE s
ResultCode code = CrossCall(ipc, IPC_DUPLICATEHANDLEPROXY_TAG,
source_handle, target_process_id,
desired_access, options, &answer);
if (SBOX_ALL_OK != code)
return code;
if (answer.win32_result) {
::SetLastError(answer.win32_result);
+ mozilla::sandboxing::LogBlocked("DuplicateHandle");
return SBOX_ERROR_GENERIC;
}
*target_handle = answer.handle;
+ mozilla::sandboxing::LogAllowed("DuplicateHandle");
return SBOX_ALL_OK;
}
} // namespace sandbox
diff --git a/security/sandbox/chromium/sandbox/win/src/named_pipe_interception.cc b/security/sandbox/chromium/sandbox/win/src/named_pipe_interception.cc
--- a/security/sandbox/chromium/sandbox/win/src/named_pipe_interception.cc
+++ b/security/sandbox/chromium/sandbox/win/src/named_pipe_interception.cc
@@ -7,31 +7,34 @@
#include "sandbox/win/src/crosscall_client.h"
#include "sandbox/win/src/ipc_tags.h"
#include "sandbox/win/src/policy_params.h"
#include "sandbox/win/src/policy_target.h"
#include "sandbox/win/src/sandbox_factory.h"
#include "sandbox/win/src/sandbox_nt_util.h"
#include "sandbox/win/src/sharedmem_ipc_client.h"
#include "sandbox/win/src/target_services.h"
+#include "mozilla/sandboxing/sandboxLogging.h"
namespace sandbox {
HANDLE WINAPI TargetCreateNamedPipeW(
CreateNamedPipeWFunction orig_CreateNamedPipeW, LPCWSTR pipe_name,
DWORD open_mode, DWORD pipe_mode, DWORD max_instance, DWORD out_buffer_size,
DWORD in_buffer_size, DWORD default_timeout,
LPSECURITY_ATTRIBUTES security_attributes) {
HANDLE pipe = orig_CreateNamedPipeW(pipe_name, open_mode, pipe_mode,
max_instance, out_buffer_size,
in_buffer_size, default_timeout,
security_attributes);
if (INVALID_HANDLE_VALUE != pipe)
return pipe;
+ mozilla::sandboxing::LogBlocked("CreateNamedPipeW", pipe_name);
+
// We don't trust that the IPC can work this early.
if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
return INVALID_HANDLE_VALUE;
DWORD original_error = ::GetLastError();
// We don't support specific Security Attributes.
if (security_attributes)
@@ -57,16 +60,17 @@ HANDLE WINAPI TargetCreateNamedPipeW(
if (SBOX_ALL_OK != code)
break;
::SetLastError(answer.win32_result);
if (ERROR_SUCCESS != answer.win32_result)
return INVALID_HANDLE_VALUE;
+ mozilla::sandboxing::LogAllowed("CreateNamedPipeW", pipe_name);
return answer.handle;
} while (false);
::SetLastError(original_error);
return INVALID_HANDLE_VALUE;
}
} // namespace sandbox
diff --git a/security/sandbox/chromium/sandbox/win/src/process_thread_interception.cc b/security/sandbox/chromium/sandbox/win/src/process_thread_interception.cc
--- a/security/sandbox/chromium/sandbox/win/src/process_thread_interception.cc
+++ b/security/sandbox/chromium/sandbox/win/src/process_thread_interception.cc
@@ -9,32 +9,34 @@
#include "sandbox/win/src/crosscall_client.h"
#include "sandbox/win/src/ipc_tags.h"
#include "sandbox/win/src/policy_params.h"
#include "sandbox/win/src/policy_target.h"
#include "sandbox/win/src/sandbox_factory.h"
#include "sandbox/win/src/sandbox_nt_util.h"
#include "sandbox/win/src/sharedmem_ipc_client.h"
#include "sandbox/win/src/target_services.h"
+#include "mozilla/sandboxing/sandboxLogging.h"
namespace sandbox {
SANDBOX_INTERCEPT NtExports g_nt;
// Hooks NtOpenThread and proxy the call to the broker if it's trying to
// open a thread in the same process.
NTSTATUS WINAPI TargetNtOpenThread(NtOpenThreadFunction orig_OpenThread,
PHANDLE thread, ACCESS_MASK desired_access,
POBJECT_ATTRIBUTES object_attributes,
PCLIENT_ID client_id) {
NTSTATUS status = orig_OpenThread(thread, desired_access, object_attributes,
client_id);
if (NT_SUCCESS(status))
return status;
+ mozilla::sandboxing::LogBlocked("NtOpenThread");
do {
if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
break;
if (!client_id)
break;
uint32_t thread_id = 0;
bool should_break = false;
@@ -90,16 +92,17 @@ NTSTATUS WINAPI TargetNtOpenThread(NtOpe
__try {
// Write the output parameters.
*thread = answer.handle;
} __except(EXCEPTION_EXECUTE_HANDLER) {
break;
}
+ mozilla::sandboxing::LogAllowed("NtOpenThread");
return answer.nt_status;
} while (false);
return status;
}
// Hooks NtOpenProcess and proxy the call to the broker if it's trying to
// open the current process.
@@ -174,16 +177,17 @@ NTSTATUS WINAPI TargetNtOpenProcess(NtOp
NTSTATUS WINAPI TargetNtOpenProcessToken(
NtOpenProcessTokenFunction orig_OpenProcessToken, HANDLE process,
ACCESS_MASK desired_access, PHANDLE token) {
NTSTATUS status = orig_OpenProcessToken(process, desired_access, token);
if (NT_SUCCESS(status))
return status;
+ mozilla::sandboxing::LogBlocked("NtOpenProcessToken");
do {
if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
break;
if (CURRENT_PROCESS != process)
break;
if (!ValidParameter(token, sizeof(HANDLE), WRITE))
@@ -205,30 +209,32 @@ NTSTATUS WINAPI TargetNtOpenProcessToken
__try {
// Write the output parameters.
*token = answer.handle;
} __except(EXCEPTION_EXECUTE_HANDLER) {
break;
}
+ mozilla::sandboxing::LogAllowed("NtOpenProcessToken");
return answer.nt_status;
} while (false);
return status;
}
NTSTATUS WINAPI TargetNtOpenProcessTokenEx(
NtOpenProcessTokenExFunction orig_OpenProcessTokenEx, HANDLE process,
ACCESS_MASK desired_access, ULONG handle_attributes, PHANDLE token) {
NTSTATUS status = orig_OpenProcessTokenEx(process, desired_access,
handle_attributes, token);
if (NT_SUCCESS(status))
return status;
+ mozilla::sandboxing::LogBlocked("NtOpenProcessTokenEx");
do {
if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
break;
if (CURRENT_PROCESS != process)
break;
if (!ValidParameter(token, sizeof(HANDLE), WRITE))
@@ -250,16 +256,17 @@ NTSTATUS WINAPI TargetNtOpenProcessToken
__try {
// Write the output parameters.
*token = answer.handle;
} __except(EXCEPTION_EXECUTE_HANDLER) {
break;
}
+ mozilla::sandboxing::LogAllowed("NtOpenProcessTokenEx");
return answer.nt_status;
} while (false);
return status;
}
BOOL WINAPI TargetCreateProcessW(CreateProcessWFunction orig_CreateProcessW,
LPCWSTR application_name, LPWSTR command_line,
@@ -272,16 +279,18 @@ BOOL WINAPI TargetCreateProcessW(CreateP
if (SandboxFactory::GetTargetServices()->GetState()->IsCsrssConnected() &&
orig_CreateProcessW(application_name, command_line, process_attributes,
thread_attributes, inherit_handles, flags,
environment, current_directory, startup_info,
process_information)) {
return TRUE;
}
+ mozilla::sandboxing::LogBlocked("CreateProcessW", application_name);
+
// We don't trust that the IPC can work this early.
if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
return FALSE;
// Don't call GetLastError before InitCalled() succeeds because kernel32 may
// not be mapped yet.
DWORD original_error = ::GetLastError();
@@ -312,16 +321,17 @@ BOOL WINAPI TargetCreateProcessW(CreateP
proc_info, &answer);
if (SBOX_ALL_OK != code)
break;
::SetLastError(answer.win32_result);
if (ERROR_SUCCESS != answer.win32_result)
return FALSE;
+ mozilla::sandboxing::LogAllowed("CreateProcessW", application_name);
return TRUE;
} while (false);
::SetLastError(original_error);
return FALSE;
}
BOOL WINAPI TargetCreateProcessA(CreateProcessAFunction orig_CreateProcessA,
@@ -335,16 +345,18 @@ BOOL WINAPI TargetCreateProcessA(CreateP
if (SandboxFactory::GetTargetServices()->GetState()->IsCsrssConnected() &&
orig_CreateProcessA(application_name, command_line, process_attributes,
thread_attributes, inherit_handles, flags,
environment, current_directory, startup_info,
process_information)) {
return TRUE;
}
+ mozilla::sandboxing::LogBlocked("CreateProcessA", application_name);
+
// We don't trust that the IPC can work this early.
if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
return FALSE;
// Don't call GetLastError before InitCalled() succeeds because kernel32 may
// not be mapped yet.
DWORD original_error = ::GetLastError();
@@ -409,16 +421,17 @@ BOOL WINAPI TargetCreateProcessA(CreateP
if (SBOX_ALL_OK != code)
break;
::SetLastError(answer.win32_result);
if (ERROR_SUCCESS != answer.win32_result)
return FALSE;
+ mozilla::sandboxing::LogAllowed("CreateProcessA", application_name);
return TRUE;
} while (false);
::SetLastError(original_error);
return FALSE;
}
HANDLE WINAPI TargetCreateThread(CreateThreadFunction orig_CreateThread,
diff --git a/security/sandbox/chromium/sandbox/win/src/registry_interception.cc b/security/sandbox/chromium/sandbox/win/src/registry_interception.cc
--- a/security/sandbox/chromium/sandbox/win/src/registry_interception.cc
+++ b/security/sandbox/chromium/sandbox/win/src/registry_interception.cc
@@ -9,31 +9,38 @@
#include "sandbox/win/src/crosscall_client.h"
#include "sandbox/win/src/ipc_tags.h"
#include "sandbox/win/src/policy_params.h"
#include "sandbox/win/src/policy_target.h"
#include "sandbox/win/src/sandbox_factory.h"
#include "sandbox/win/src/sandbox_nt_util.h"
#include "sandbox/win/src/sharedmem_ipc_client.h"
#include "sandbox/win/src/target_services.h"
+#include "mozilla/sandboxing/sandboxLogging.h"
namespace sandbox {
NTSTATUS WINAPI TargetNtCreateKey(NtCreateKeyFunction orig_CreateKey,
PHANDLE key, ACCESS_MASK desired_access,
POBJECT_ATTRIBUTES object_attributes,
ULONG title_index, PUNICODE_STRING class_name,
ULONG create_options, PULONG disposition) {
// Check if the process can create it first.
NTSTATUS status = orig_CreateKey(key, desired_access, object_attributes,
title_index, class_name, create_options,
disposition);
if (NT_SUCCESS(status))
return status;
+ if (STATUS_OBJECT_NAME_NOT_FOUND != status) {
+ mozilla::sandboxing::LogBlocked("NtCreateKey",
+ object_attributes->ObjectName->Buffer,
+ object_attributes->ObjectName->Length);
+ }
+
// We don't trust that the IPC can work this early.
if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
return status;
do {
if (!ValidParameter(key, sizeof(HANDLE), WRITE))
break;
@@ -109,16 +116,19 @@ NTSTATUS WINAPI TargetNtCreateKey(NtCrea
if (disposition)
*disposition = answer.extended[0].unsigned_int;
status = answer.nt_status;
} __except(EXCEPTION_EXECUTE_HANDLER) {
break;
}
+ mozilla::sandboxing::LogAllowed("NtCreateKey",
+ object_attributes->ObjectName->Buffer,
+ object_attributes->ObjectName->Length);
} while (false);
return status;
}
NTSTATUS WINAPI CommonNtOpenKey(NTSTATUS status, PHANDLE key,
ACCESS_MASK desired_access,
POBJECT_ATTRIBUTES object_attributes) {
@@ -185,29 +195,38 @@ NTSTATUS WINAPI CommonNtOpenKey(NTSTATUS
break;
__try {
*key = answer.handle;
status = answer.nt_status;
} __except(EXCEPTION_EXECUTE_HANDLER) {
break;
}
+ mozilla::sandboxing::LogAllowed("NtOpenKey[Ex]",
+ object_attributes->ObjectName->Buffer,
+ object_attributes->ObjectName->Length);
} while (false);
return status;
}
NTSTATUS WINAPI TargetNtOpenKey(NtOpenKeyFunction orig_OpenKey, PHANDLE key,
ACCESS_MASK desired_access,
POBJECT_ATTRIBUTES object_attributes) {
// Check if the process can open it first.
NTSTATUS status = orig_OpenKey(key, desired_access, object_attributes);
if (NT_SUCCESS(status))
return status;
+ if (STATUS_OBJECT_NAME_NOT_FOUND != status) {
+ mozilla::sandboxing::LogBlocked("NtOpenKey",
+ object_attributes->ObjectName->Buffer,
+ object_attributes->ObjectName->Length);
+ }
+
return CommonNtOpenKey(status, key, desired_access, object_attributes);
}
NTSTATUS WINAPI TargetNtOpenKeyEx(NtOpenKeyExFunction orig_OpenKeyEx,
PHANDLE key, ACCESS_MASK desired_access,
POBJECT_ATTRIBUTES object_attributes,
ULONG open_options) {
// Check if the process can open it first.
@@ -215,12 +234,18 @@ NTSTATUS WINAPI TargetNtOpenKeyEx(NtOpen
open_options);
// We do not support open_options at this time. The 2 current known values
// are REG_OPTION_CREATE_LINK, to open a symbolic link, and
// REG_OPTION_BACKUP_RESTORE to open the key with special privileges.
if (NT_SUCCESS(status) || open_options != 0)
return status;
+ if (STATUS_OBJECT_NAME_NOT_FOUND != status) {
+ mozilla::sandboxing::LogBlocked("NtOpenKeyEx",
+ object_attributes->ObjectName->Buffer,
+ object_attributes->ObjectName->Length);
+ }
+
return CommonNtOpenKey(status, key, desired_access, object_attributes);
}
} // namespace sandbox
diff --git a/security/sandbox/chromium/sandbox/win/src/sync_interception.cc b/security/sandbox/chromium/sandbox/win/src/sync_interception.cc
--- a/security/sandbox/chromium/sandbox/win/src/sync_interception.cc
+++ b/security/sandbox/chromium/sandbox/win/src/sync_interception.cc
@@ -9,16 +9,17 @@
#include "sandbox/win/src/crosscall_client.h"
#include "sandbox/win/src/ipc_tags.h"
#include "sandbox/win/src/policy_params.h"
#include "sandbox/win/src/policy_target.h"
#include "sandbox/win/src/sandbox_factory.h"
#include "sandbox/win/src/sandbox_nt_util.h"
#include "sandbox/win/src/sharedmem_ipc_client.h"
#include "sandbox/win/src/target_services.h"
+#include "mozilla/sandboxing/sandboxLogging.h"
namespace sandbox {
ResultCode ProxyCreateEvent(LPCWSTR name,
uint32_t initial_state,
EVENT_TYPE event_type,
void* ipc_memory,
CrossCallReturn* answer) {
@@ -59,16 +60,20 @@ NTSTATUS WINAPI TargetNtCreateEvent(NtCr
EVENT_TYPE event_type,
BOOLEAN initial_state) {
NTSTATUS status = orig_CreateEvent(event_handle, desired_access,
object_attributes, event_type,
initial_state);
if (status != STATUS_ACCESS_DENIED || !object_attributes)
return status;
+ mozilla::sandboxing::LogBlocked("NtCreatEvent",
+ object_attributes->ObjectName->Buffer,
+ object_attributes->ObjectName->Length);
+
// We don't trust that the IPC can work this early.
if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
return status;
do {
if (!ValidParameter(event_handle, sizeof(HANDLE), WRITE))
break;
@@ -98,30 +103,37 @@ NTSTATUS WINAPI TargetNtCreateEvent(NtCr
break;
}
__try {
*event_handle = answer.handle;
status = STATUS_SUCCESS;
} __except(EXCEPTION_EXECUTE_HANDLER) {
break;
}
+ mozilla::sandboxing::LogAllowed("NtCreateEvent",
+ object_attributes->ObjectName->Buffer,
+ object_attributes->ObjectName->Length);
} while (false);
return status;
}
NTSTATUS WINAPI TargetNtOpenEvent(NtOpenEventFunction orig_OpenEvent,
PHANDLE event_handle,
ACCESS_MASK desired_access,
POBJECT_ATTRIBUTES object_attributes) {
NTSTATUS status = orig_OpenEvent(event_handle, desired_access,
object_attributes);
if (status != STATUS_ACCESS_DENIED || !object_attributes)
return status;
+ mozilla::sandboxing::LogBlocked("NtOpenEvent",
+ object_attributes->ObjectName->Buffer,
+ object_attributes->ObjectName->Length);
+ //
// We don't trust that the IPC can work this early.
if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
return status;
do {
if (!ValidParameter(event_handle, sizeof(HANDLE), WRITE))
break;
@@ -150,14 +162,17 @@ NTSTATUS WINAPI TargetNtOpenEvent(NtOpen
break;
}
__try {
*event_handle = answer.handle;
status = STATUS_SUCCESS;
} __except(EXCEPTION_EXECUTE_HANDLER) {
break;
}
+ mozilla::sandboxing::LogAllowed("NtOpenEvent",
+ object_attributes->ObjectName->Buffer,
+ object_attributes->ObjectName->Length);
} while (false);
return status;
}
} // namespace sandbox

View File

@ -0,0 +1,158 @@
# HG changeset patch
# User David Parks <dparks@mozilla.com>
# Date 1488233752 28800
# Mon Feb 27 14:15:52 2017 -0800
# Node ID 58cf9c0f78b7b229b6b3ba70b64b9719b30b3d48
# Parent 139c07a8ef8157027b3054d77fe3b5ff2c119081
Permit sandboxed processes to access Flash temporary files. r=bobowen
Allows the creation/use of temp files when the user has already green-lit
the use of a file for write purposes in that folder.
Originally landed in changeset:
https://hg.mozilla.org/mozilla-central/rev/0f64b24c40c4
diff --git a/security/sandbox/chromium/sandbox/win/src/filesystem_dispatcher.cc b/security/sandbox/chromium/sandbox/win/src/filesystem_dispatcher.cc
--- a/security/sandbox/chromium/sandbox/win/src/filesystem_dispatcher.cc
+++ b/security/sandbox/chromium/sandbox/win/src/filesystem_dispatcher.cc
@@ -221,16 +221,25 @@ bool FilesystemDispatcher::NtQueryAttrib
params[FileName::BROKER] = ParamPickerMake(broker);
// To evaluate the policy we need to call back to the policy object. We
// are just middlemen in the operation since is the FileSystemPolicy which
// knows what to do.
EvalResult result = policy_base_->EvalPolicy(IPC_NTQUERYATTRIBUTESFILE_TAG,
params.GetBase());
+ // If the policies forbid access (any result other than ASK_BROKER),
+ // then check for user-granted access to file.
+ if (ASK_BROKER != result &&
+ mozilla::sandboxing::PermissionsService::GetInstance()->
+ UserGrantedFileAccess(ipc->client_info->process_id, filename,
+ 0, 0)) {
+ result = ASK_BROKER;
+ }
+
FILE_BASIC_INFORMATION* information =
reinterpret_cast<FILE_BASIC_INFORMATION*>(info->Buffer());
NTSTATUS nt_status;
if (!FileSystemPolicy::QueryAttributesFileAction(result, *ipc->client_info,
*name, attributes,
information, &nt_status)) {
ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
return true;
@@ -261,16 +270,25 @@ bool FilesystemDispatcher::NtQueryFullAt
params[FileName::BROKER] = ParamPickerMake(broker);
// To evaluate the policy we need to call back to the policy object. We
// are just middlemen in the operation since is the FileSystemPolicy which
// knows what to do.
EvalResult result = policy_base_->EvalPolicy(
IPC_NTQUERYFULLATTRIBUTESFILE_TAG, params.GetBase());
+ // If the policies forbid access (any result other than ASK_BROKER),
+ // then check for user-granted access to file.
+ if (ASK_BROKER != result &&
+ mozilla::sandboxing::PermissionsService::GetInstance()->
+ UserGrantedFileAccess(ipc->client_info->process_id, filename,
+ 0, 0)) {
+ result = ASK_BROKER;
+ }
+
FILE_NETWORK_OPEN_INFORMATION* information =
reinterpret_cast<FILE_NETWORK_OPEN_INFORMATION*>(info->Buffer());
NTSTATUS nt_status;
if (!FileSystemPolicy::QueryFullAttributesFileAction(result,
*ipc->client_info,
*name, attributes,
information,
&nt_status)) {
@@ -316,16 +334,26 @@ bool FilesystemDispatcher::NtSetInformat
params[FileName::BROKER] = ParamPickerMake(broker);
// To evaluate the policy we need to call back to the policy object. We
// are just middlemen in the operation since is the FileSystemPolicy which
// knows what to do.
EvalResult result = policy_base_->EvalPolicy(IPC_NTSETINFO_RENAME_TAG,
params.GetBase());
+ // If the policies forbid access (any result other than ASK_BROKER),
+ // then check for user-granted write access to file. We only permit
+ // the FileRenameInformation action.
+ if (ASK_BROKER != result && info_class == FileRenameInformation &&
+ mozilla::sandboxing::PermissionsService::GetInstance()->
+ UserGrantedFileAccess(ipc->client_info->process_id, filename,
+ FILE_WRITE_ATTRIBUTES, 0)) {
+ result = ASK_BROKER;
+ }
+
IO_STATUS_BLOCK* io_status =
reinterpret_cast<IO_STATUS_BLOCK*>(status->Buffer());
NTSTATUS nt_status;
if (!FileSystemPolicy::SetInformationFileAction(result, *ipc->client_info,
handle, rename_info, length,
info_class, io_status,
&nt_status)) {
ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
diff --git a/security/sandbox/chromium/sandbox/win/src/filesystem_interception.cc b/security/sandbox/chromium/sandbox/win/src/filesystem_interception.cc
--- a/security/sandbox/chromium/sandbox/win/src/filesystem_interception.cc
+++ b/security/sandbox/chromium/sandbox/win/src/filesystem_interception.cc
@@ -223,19 +223,16 @@ NTSTATUS WINAPI TargetNtQueryAttributesF
InOutCountedBuffer file_info(file_attributes,
sizeof(FILE_BASIC_INFORMATION));
uint32_t broker = FALSE;
CountedParameterSet<FileName> params;
params[FileName::NAME] = ParamPickerMake(name);
params[FileName::BROKER] = ParamPickerMake(broker);
- if (!QueryBroker(IPC_NTQUERYATTRIBUTESFILE_TAG, params.GetBase()))
- break;
-
SharedMemIPCClient ipc(memory);
CrossCallReturn answer = {0};
ResultCode code = CrossCall(ipc, IPC_NTQUERYATTRIBUTESFILE_TAG, name,
attributes, file_info, &answer);
if (SBOX_ALL_OK != code)
break;
@@ -290,19 +287,16 @@ NTSTATUS WINAPI TargetNtQueryFullAttribu
InOutCountedBuffer file_info(file_attributes,
sizeof(FILE_NETWORK_OPEN_INFORMATION));
uint32_t broker = FALSE;
CountedParameterSet<FileName> params;
params[FileName::NAME] = ParamPickerMake(name);
params[FileName::BROKER] = ParamPickerMake(broker);
- if (!QueryBroker(IPC_NTQUERYFULLATTRIBUTESFILE_TAG, params.GetBase()))
- break;
-
SharedMemIPCClient ipc(memory);
CrossCallReturn answer = {0};
ResultCode code = CrossCall(ipc, IPC_NTQUERYFULLATTRIBUTESFILE_TAG, name,
attributes, file_info, &answer);
if (SBOX_ALL_OK != code)
break;
@@ -369,19 +363,16 @@ NTSTATUS WINAPI TargetNtSetInformationFi
if (!NT_SUCCESS(ret) || !name)
break;
uint32_t broker = FALSE;
CountedParameterSet<FileName> params;
params[FileName::NAME] = ParamPickerMake(name);
params[FileName::BROKER] = ParamPickerMake(broker);
- if (!QueryBroker(IPC_NTSETINFO_RENAME_TAG, params.GetBase()))
- break;
-
InOutCountedBuffer io_status_buffer(io_status, sizeof(IO_STATUS_BLOCK));
// This is actually not an InOut buffer, only In, but using InOut facility
// really helps to simplify the code.
InOutCountedBuffer file_info_buffer(file_info, length);
SharedMemIPCClient ipc(memory);
CrossCallReturn answer = {0};
ResultCode code = CrossCall(ipc, IPC_NTSETINFO_RENAME_TAG, file,

View File

@ -0,0 +1,192 @@
# HG changeset patch
# User Bob Owen <bobowencode@gmail.com>
# Date 1454317140 0
# Mon Feb 01 08:59:00 2016 +0000
# Node ID 9870a92ea5f352ab5a841003a30ab52c8deb589e
# Parent d62b6a3a0c58528a8bf864bb5ab6bb9faada972b
Change to allow network drives in sandbox rules with non-file device fix. r=aklotz
Originally landed in changeset:
https://hg.mozilla.org/mozilla-central/rev/c70d06fa5302
diff --git a/security/sandbox/chromium/sandbox/win/src/win_utils.cc b/security/sandbox/chromium/sandbox/win/src/win_utils.cc
--- a/security/sandbox/chromium/sandbox/win/src/win_utils.cc
+++ b/security/sandbox/chromium/sandbox/win/src/win_utils.cc
@@ -190,63 +190,68 @@ bool ResolveRegistryName(base::string16
return false;
}
// |full_path| can have any of the following forms:
// \??\c:\some\foo\bar
// \Device\HarddiskVolume0\some\foo\bar
// \??\HarddiskVolume0\some\foo\bar
+// \??\UNC\SERVER\Share\some\foo\bar
DWORD IsReparsePoint(const base::string16& full_path) {
// Check if it's a pipe. We can't query the attributes of a pipe.
if (IsPipe(full_path))
return ERROR_NOT_A_REPARSE_POINT;
base::string16 path;
bool nt_path = IsNTPath(full_path, &path);
bool has_drive = StartsWithDriveLetter(path);
bool is_device_path = IsDevicePath(path, &path);
if (!has_drive && !is_device_path && !nt_path)
return ERROR_INVALID_NAME;
- bool added_implied_device = false;
if (!has_drive) {
- path = base::string16(kNTDotPrefix) + path;
- added_implied_device = true;
+ // Add Win32 device namespace prefix, required for some Windows APIs.
+ path.insert(0, kNTDotPrefix);
}
- base::string16::size_type last_pos = base::string16::npos;
- bool passed_once = false;
+ // Ensure that volume path matches start of path.
+ wchar_t vol_path[MAX_PATH];
+ if (!::GetVolumePathNameW(path.c_str(), vol_path, MAX_PATH)) {
+ // This will fail if this is a device that isn't volume related, which can't
+ // then be a reparse point.
+ return is_device_path ? ERROR_NOT_A_REPARSE_POINT : ERROR_INVALID_NAME;
+ }
+
+ // vol_path includes a trailing slash, so reduce size for path and loop check.
+ size_t vol_path_len = wcslen(vol_path) - 1;
+ if (!EqualPath(path, vol_path, vol_path_len)) {
+ return ERROR_INVALID_NAME;
+ }
do {
- path = path.substr(0, last_pos);
-
DWORD attributes = ::GetFileAttributes(path.c_str());
if (INVALID_FILE_ATTRIBUTES == attributes) {
DWORD error = ::GetLastError();
if (error != ERROR_FILE_NOT_FOUND &&
error != ERROR_PATH_NOT_FOUND &&
+ error != ERROR_INVALID_FUNCTION &&
error != ERROR_INVALID_NAME) {
// Unexpected error.
- if (passed_once && added_implied_device &&
- (path.rfind(L'\\') == kNTDotPrefixLen - 1)) {
- break;
- }
NOTREACHED_NT();
return error;
}
} else if (FILE_ATTRIBUTE_REPARSE_POINT & attributes) {
// This is a reparse point.
return ERROR_SUCCESS;
}
- passed_once = true;
- last_pos = path.rfind(L'\\');
- } while (last_pos > 2); // Skip root dir.
+ path.resize(path.rfind(L'\\'));
+ } while (path.size() > vol_path_len); // Skip root dir.
return ERROR_NOT_A_REPARSE_POINT;
}
// We get a |full_path| of the forms accepted by IsReparsePoint(), and the name
// we'll get from |handle| will be \device\harddiskvolume1\some\foo\bar.
bool SameObject(HANDLE handle, const wchar_t* full_path) {
// Check if it's a pipe.
@@ -256,63 +261,67 @@ bool SameObject(HANDLE handle, const wch
base::string16 actual_path;
if (!GetPathFromHandle(handle, &actual_path))
return false;
base::string16 path(full_path);
DCHECK_NT(!path.empty());
// This may end with a backslash.
- const wchar_t kBackslash = '\\';
- if (path.back() == kBackslash)
- path = path.substr(0, path.length() - 1);
+ if (path.back() == L'\\') {
+ path.pop_back();
+ }
- // Perfect match (case-insesitive check).
+ // Perfect match (case-insensitive check).
if (EqualPath(actual_path, path))
return true;
bool nt_path = IsNTPath(path, &path);
bool has_drive = StartsWithDriveLetter(path);
if (!has_drive && nt_path) {
base::string16 simple_actual_path;
- if (!IsDevicePath(actual_path, &simple_actual_path))
- return false;
-
- // Perfect match (case-insesitive check).
- return (EqualPath(simple_actual_path, path));
+ if (IsDevicePath(path, &path)) {
+ if (IsDevicePath(actual_path, &simple_actual_path)) {
+ // Perfect match (case-insensitive check).
+ return (EqualPath(simple_actual_path, path));
+ } else {
+ return false;
+ }
+ } else {
+ // Add Win32 device namespace for GetVolumePathName.
+ path.insert(0, kNTDotPrefix);
+ }
}
- if (!has_drive)
+ // Get the volume path in the same format as actual_path.
+ wchar_t vol_path[MAX_PATH];
+ if (!::GetVolumePathName(path.c_str(), vol_path, MAX_PATH)) {
return false;
-
- // We only need 3 chars, but let's alloc a buffer for four.
- wchar_t drive[4] = {0};
- wchar_t vol_name[MAX_PATH];
- memcpy(drive, &path[0], 2 * sizeof(*drive));
-
- // We'll get a double null terminated string.
- DWORD vol_length = ::QueryDosDeviceW(drive, vol_name, MAX_PATH);
- if (vol_length < 2 || vol_length == MAX_PATH)
+ }
+ size_t vol_path_len = wcslen(vol_path);
+ base::string16 nt_vol;
+ if (!GetNtPathFromWin32Path(vol_path, &nt_vol)) {
return false;
-
- // Ignore the nulls at the end.
- vol_length = static_cast<DWORD>(wcslen(vol_name));
+ }
// The two paths should be the same length.
- if (vol_length + path.size() - 2 != actual_path.size())
+ if (nt_vol.size() + path.size() - vol_path_len != actual_path.size()) {
return false;
+ }
- // Check up to the drive letter.
- if (!EqualPath(actual_path, vol_name, vol_length))
+ // Check the volume matches.
+ if (!EqualPath(actual_path, nt_vol.c_str(), nt_vol.size())) {
return false;
+ }
- // Check the path after the drive letter.
- if (!EqualPath(actual_path, vol_length, path, 2))
+ // Check the path after the volume matches.
+ if (!EqualPath(actual_path, nt_vol.size(), path, vol_path_len)) {
return false;
+ }
return true;
}
// Just make a best effort here. There are lots of corner cases that we're
// not expecting - and will fail to make long.
bool ConvertToLongPath(base::string16* native_path,
const base::string16* drive_letter) {

View File

@ -0,0 +1,170 @@
# HG changeset patch
# User Bob Owen <bobowencode@gmail.com>
# Date 1486465183 0
# Tue Feb 07 10:59:43 2017 +0000
# Node ID 69c8c415e87bd14843e26488e9cff30e39d69750
# Parent 945bec53811d358e3c668405bc1feb63e671782a
Change USER_NON_ADMIN access token level from whitelist to blacklist containing Admin SIDs. r=jimm
Originally landed in changeset:
https://hg.mozilla.org/mozilla-central/rev/0e6bf137521e
diff --git a/security/sandbox/chromium/sandbox/win/src/restricted_token.cc b/security/sandbox/chromium/sandbox/win/src/restricted_token.cc
--- a/security/sandbox/chromium/sandbox/win/src/restricted_token.cc
+++ b/security/sandbox/chromium/sandbox/win/src/restricted_token.cc
@@ -254,16 +254,50 @@ DWORD RestrictedToken::AddAllSidsForDeny
reinterpret_cast<SID*>(token_groups->Groups[i].Sid));
}
}
}
return ERROR_SUCCESS;
}
+DWORD RestrictedToken::AddDenyOnlySids(const std::vector<Sid>& deny_only_sids) {
+ DCHECK(init_);
+ if (!init_) {
+ return ERROR_NO_TOKEN;
+ }
+
+ DWORD error;
+ std::unique_ptr<BYTE[]> buffer =
+ GetTokenInfo(effective_token_, TokenGroups, &error);
+
+ if (!buffer) {
+ return error;
+ }
+
+ TOKEN_GROUPS* token_groups = reinterpret_cast<TOKEN_GROUPS*>(buffer.get());
+
+ // Build the list of the deny only group SIDs
+ for (unsigned int i = 0; i < token_groups->GroupCount ; ++i) {
+ if ((token_groups->Groups[i].Attributes & SE_GROUP_INTEGRITY) == 0 &&
+ (token_groups->Groups[i].Attributes & SE_GROUP_LOGON_ID) == 0) {
+ for (unsigned int j = 0; j < deny_only_sids.size(); ++j) {
+ if (::EqualSid(const_cast<SID*>(deny_only_sids[j].GetPSID()),
+ token_groups->Groups[i].Sid)) {
+ sids_for_deny_only_.push_back(
+ reinterpret_cast<SID*>(token_groups->Groups[i].Sid));
+ break;
+ }
+ }
+ }
+ }
+
+ return ERROR_SUCCESS;
+}
+
DWORD RestrictedToken::AddSidForDenyOnly(const Sid &sid) {
DCHECK(init_);
if (!init_)
return ERROR_NO_TOKEN;
sids_for_deny_only_.push_back(sid);
return ERROR_SUCCESS;
}
diff --git a/security/sandbox/chromium/sandbox/win/src/restricted_token.h b/security/sandbox/chromium/sandbox/win/src/restricted_token.h
--- a/security/sandbox/chromium/sandbox/win/src/restricted_token.h
+++ b/security/sandbox/chromium/sandbox/win/src/restricted_token.h
@@ -83,16 +83,27 @@ class RestrictedToken {
// std::vector<Sid> sid_exceptions;
// sid_exceptions.push_back(ATL::Sids::Users().GetPSID());
// sid_exceptions.push_back(ATL::Sids::World().GetPSID());
// restricted_token.AddAllSidsForDenyOnly(&sid_exceptions);
// Note: A Sid marked for Deny Only in a token cannot be used to grant
// access to any resource. It can only be used to deny access.
DWORD AddAllSidsForDenyOnly(std::vector<Sid> *exceptions);
+ // Lists all sids in the token and mark them as Deny Only if present in the
+ // deny_only_sids parameter.
+ //
+ // If the function succeeds, the return value is ERROR_SUCCESS. If the
+ // function fails, the return value is the win32 error code corresponding to
+ // the error.
+ //
+ // Note: A Sid marked for Deny Only in a token cannot be used to grant
+ // access to any resource. It can only be used to deny access.
+ DWORD AddDenyOnlySids(const std::vector<Sid>& deny_only_sids);
+
// Adds a user or group SID for Deny Only in the restricted token.
// Parameter: sid is the SID to add in the Deny Only list.
// The return value is always ERROR_SUCCESS.
//
// Sample Usage:
// restricted_token.AddSidForDenyOnly(ATL::Sids::Admins().GetPSID());
DWORD AddSidForDenyOnly(const Sid &sid);
diff --git a/security/sandbox/chromium/sandbox/win/src/restricted_token_utils.cc b/security/sandbox/chromium/sandbox/win/src/restricted_token_utils.cc
--- a/security/sandbox/chromium/sandbox/win/src/restricted_token_utils.cc
+++ b/security/sandbox/chromium/sandbox/win/src/restricted_token_utils.cc
@@ -26,16 +26,17 @@ DWORD CreateRestrictedToken(TokenLevel s
base::win::ScopedHandle* token) {
RestrictedToken restricted_token;
restricted_token.Init(NULL); // Initialized with the current process token
if (lockdown_default_dacl)
restricted_token.SetLockdownDefaultDacl();
std::vector<base::string16> privilege_exceptions;
std::vector<Sid> sid_exceptions;
+ std::vector<Sid> deny_only_sids;
bool deny_sids = true;
bool remove_privileges = true;
switch (security_level) {
case USER_UNPROTECTED: {
deny_sids = false;
remove_privileges = false;
@@ -50,20 +51,26 @@ DWORD CreateRestrictedToken(TokenLevel s
if (ERROR_SUCCESS != err_code) {
return err_code;
}
}
break;
}
case USER_NON_ADMIN: {
- sid_exceptions.push_back(WinBuiltinUsersSid);
- sid_exceptions.push_back(WinWorldSid);
- sid_exceptions.push_back(WinInteractiveSid);
- sid_exceptions.push_back(WinAuthenticatedUserSid);
+ deny_sids = false;
+ deny_only_sids.push_back(WinBuiltinAdministratorsSid);
+ deny_only_sids.push_back(WinAccountAdministratorSid);
+ deny_only_sids.push_back(WinAccountDomainAdminsSid);
+ deny_only_sids.push_back(WinAccountCertAdminsSid);
+ deny_only_sids.push_back(WinAccountSchemaAdminsSid);
+ deny_only_sids.push_back(WinAccountEnterpriseAdminsSid);
+ deny_only_sids.push_back(WinAccountPolicyAdminsSid);
+ deny_only_sids.push_back(WinBuiltinHyperVAdminsSid);
+ deny_only_sids.push_back(WinLocalAccountAndAdministratorSid);
privilege_exceptions.push_back(SE_CHANGE_NOTIFY_NAME);
break;
}
case USER_INTERACTIVE: {
sid_exceptions.push_back(WinBuiltinUsersSid);
sid_exceptions.push_back(WinWorldSid);
sid_exceptions.push_back(WinInteractiveSid);
sid_exceptions.push_back(WinAuthenticatedUserSid);
@@ -116,16 +123,21 @@ DWORD CreateRestrictedToken(TokenLevel s
}
}
DWORD err_code = ERROR_SUCCESS;
if (deny_sids) {
err_code = restricted_token.AddAllSidsForDenyOnly(&sid_exceptions);
if (ERROR_SUCCESS != err_code)
return err_code;
+ } else if (!deny_only_sids.empty()) {
+ err_code = restricted_token.AddDenyOnlySids(deny_only_sids);
+ if (ERROR_SUCCESS != err_code) {
+ return err_code;
+ }
}
if (remove_privileges) {
err_code = restricted_token.DeleteAllPrivileges(&privilege_exceptions);
if (ERROR_SUCCESS != err_code)
return err_code;
}

View File

@ -0,0 +1,132 @@
# HG changeset patch
# User David Parks <dparks@mozilla.com>
# Date 1484929677 28800
# Fri Jan 20 08:27:57 2017 -0800
# Node ID d6a40d4bae2bdce74539e2606d0ead89c091a089
# Parent b14dffc51edda918dbaadf2ece96d0ecdd9f6f25
Add mechanism to libsandbox_s to track names of files that have been given special sandbox access permissions (PermissionsService). r=bobowen
Hook this into the browser via the XREAppData. This patch contains only the changes to Chromium source code.
Originally landed in changeset:
https://hg.mozilla.org/mozilla-central/rev/6ecd19d25822
diff --git a/security/sandbox/chromium/sandbox/win/src/filesystem_dispatcher.cc b/security/sandbox/chromium/sandbox/win/src/filesystem_dispatcher.cc
--- a/security/sandbox/chromium/sandbox/win/src/filesystem_dispatcher.cc
+++ b/security/sandbox/chromium/sandbox/win/src/filesystem_dispatcher.cc
@@ -12,16 +12,18 @@
#include "sandbox/win/src/interception.h"
#include "sandbox/win/src/interceptors.h"
#include "sandbox/win/src/ipc_tags.h"
#include "sandbox/win/src/policy_broker.h"
#include "sandbox/win/src/policy_params.h"
#include "sandbox/win/src/sandbox.h"
#include "sandbox/win/src/sandbox_nt_util.h"
+#include "mozilla/sandboxing/permissionsService.h"
+
namespace sandbox {
FilesystemDispatcher::FilesystemDispatcher(PolicyBase* policy_base)
: policy_base_(policy_base) {
static const IPCCall create_params = {
{IPC_NTCREATEFILE_TAG,
{WCHAR_TYPE,
UINT32_TYPE,
@@ -110,16 +112,26 @@ bool FilesystemDispatcher::NtCreateFile(
params[OpenFile::OPTIONS] = ParamPickerMake(create_options);
params[OpenFile::BROKER] = ParamPickerMake(broker);
// To evaluate the policy we need to call back to the policy object. We
// are just middlemen in the operation since is the FileSystemPolicy which
// knows what to do.
EvalResult result = policy_base_->EvalPolicy(IPC_NTCREATEFILE_TAG,
params.GetBase());
+
+ // If the policies forbid access (any result other than ASK_BROKER),
+ // then check for user-granted access to file.
+ if (ASK_BROKER != result &&
+ mozilla::sandboxing::PermissionsService::GetInstance()->
+ UserGrantedFileAccess(ipc->client_info->process_id, filename,
+ desired_access, create_disposition)) {
+ result = ASK_BROKER;
+ }
+
HANDLE handle;
ULONG_PTR io_information = 0;
NTSTATUS nt_status;
if (!FileSystemPolicy::CreateFileAction(result, *ipc->client_info, *name,
attributes, desired_access,
file_attributes, share_access,
create_disposition, create_options,
&handle, &nt_status,
@@ -157,16 +169,26 @@ bool FilesystemDispatcher::NtOpenFile(IP
params[OpenFile::OPTIONS] = ParamPickerMake(open_options);
params[OpenFile::BROKER] = ParamPickerMake(broker);
// To evaluate the policy we need to call back to the policy object. We
// are just middlemen in the operation since is the FileSystemPolicy which
// knows what to do.
EvalResult result = policy_base_->EvalPolicy(IPC_NTOPENFILE_TAG,
params.GetBase());
+
+ // If the policies forbid access (any result other than ASK_BROKER),
+ // then check for user-granted access to file.
+ if (ASK_BROKER != result &&
+ mozilla::sandboxing::PermissionsService::GetInstance()->UserGrantedFileAccess(
+ ipc->client_info->process_id, filename,
+ desired_access, create_disposition)) {
+ result = ASK_BROKER;
+ }
+
HANDLE handle;
ULONG_PTR io_information = 0;
NTSTATUS nt_status;
if (!FileSystemPolicy::OpenFileAction(result, *ipc->client_info, *name,
attributes, desired_access,
share_access, open_options, &handle,
&nt_status, &io_information)) {
ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
diff --git a/security/sandbox/chromium/sandbox/win/src/filesystem_interception.cc b/security/sandbox/chromium/sandbox/win/src/filesystem_interception.cc
--- a/security/sandbox/chromium/sandbox/win/src/filesystem_interception.cc
+++ b/security/sandbox/chromium/sandbox/win/src/filesystem_interception.cc
@@ -70,19 +70,16 @@ NTSTATUS WINAPI TargetNtCreateFile(NtCre
uint32_t broker = FALSE;
CountedParameterSet<OpenFile> params;
params[OpenFile::NAME] = ParamPickerMake(name);
params[OpenFile::ACCESS] = ParamPickerMake(desired_access_uint32);
params[OpenFile::DISPOSITION] = ParamPickerMake(disposition_uint32);
params[OpenFile::OPTIONS] = ParamPickerMake(options_uint32);
params[OpenFile::BROKER] = ParamPickerMake(broker);
- if (!QueryBroker(IPC_NTCREATEFILE_TAG, params.GetBase()))
- break;
-
SharedMemIPCClient ipc(memory);
CrossCallReturn answer = {0};
// The following call must match in the parameters with
// FilesystemDispatcher::ProcessNtCreateFile.
ResultCode code = CrossCall(ipc, IPC_NTCREATEFILE_TAG, name, attributes,
desired_access_uint32, file_attributes, sharing,
disposition, options_uint32, &answer);
if (SBOX_ALL_OK != code)
@@ -154,19 +151,16 @@ NTSTATUS WINAPI TargetNtOpenFile(NtOpenF
uint32_t broker = FALSE;
CountedParameterSet<OpenFile> params;
params[OpenFile::NAME] = ParamPickerMake(name);
params[OpenFile::ACCESS] = ParamPickerMake(desired_access_uint32);
params[OpenFile::DISPOSITION] = ParamPickerMake(disposition_uint32);
params[OpenFile::OPTIONS] = ParamPickerMake(options_uint32);
params[OpenFile::BROKER] = ParamPickerMake(broker);
- if (!QueryBroker(IPC_NTOPENFILE_TAG, params.GetBase()))
- break;
-
SharedMemIPCClient ipc(memory);
CrossCallReturn answer = {0};
ResultCode code = CrossCall(ipc, IPC_NTOPENFILE_TAG, name, attributes,
desired_access_uint32, sharing, options_uint32,
&answer);
if (SBOX_ALL_OK != code)
break;

View File

@ -0,0 +1,6 @@
add_interception_logging.patch
allow_rules_for_network_drive_and_non_file_devices.patch
add_WOW64_flags_to_allowed_registry_read_flags.patch
change_USER_NON_ADMIN_to_blacklist.patch
consult_PermissionsService_for_file_access.patch
allow_flash_temporary_files.patch

View File

@ -17,6 +17,8 @@
#include "sandbox/win/src/sandbox.h"
#include "sandbox/win/src/sandbox_nt_util.h"
#include "mozilla/sandboxing/permissionsService.h"
namespace sandbox {
FilesystemDispatcher::FilesystemDispatcher(PolicyBase* policy_base)
@ -115,6 +117,16 @@ bool FilesystemDispatcher::NtCreateFile(IPCInfo* ipc,
// knows what to do.
EvalResult result = policy_base_->EvalPolicy(IPC_NTCREATEFILE_TAG,
params.GetBase());
// If the policies forbid access (any result other than ASK_BROKER),
// then check for user-granted access to file.
if (ASK_BROKER != result &&
mozilla::sandboxing::PermissionsService::GetInstance()->
UserGrantedFileAccess(ipc->client_info->process_id, filename,
desired_access, create_disposition)) {
result = ASK_BROKER;
}
HANDLE handle;
ULONG_PTR io_information = 0;
NTSTATUS nt_status;
@ -162,6 +174,16 @@ bool FilesystemDispatcher::NtOpenFile(IPCInfo* ipc,
// knows what to do.
EvalResult result = policy_base_->EvalPolicy(IPC_NTOPENFILE_TAG,
params.GetBase());
// If the policies forbid access (any result other than ASK_BROKER),
// then check for user-granted access to file.
if (ASK_BROKER != result &&
mozilla::sandboxing::PermissionsService::GetInstance()->UserGrantedFileAccess(
ipc->client_info->process_id, filename,
desired_access, create_disposition)) {
result = ASK_BROKER;
}
HANDLE handle;
ULONG_PTR io_information = 0;
NTSTATUS nt_status;
@ -204,6 +226,15 @@ bool FilesystemDispatcher::NtQueryAttributesFile(IPCInfo* ipc,
EvalResult result = policy_base_->EvalPolicy(IPC_NTQUERYATTRIBUTESFILE_TAG,
params.GetBase());
// If the policies forbid access (any result other than ASK_BROKER),
// then check for user-granted access to file.
if (ASK_BROKER != result &&
mozilla::sandboxing::PermissionsService::GetInstance()->
UserGrantedFileAccess(ipc->client_info->process_id, filename,
0, 0)) {
result = ASK_BROKER;
}
FILE_BASIC_INFORMATION* information =
reinterpret_cast<FILE_BASIC_INFORMATION*>(info->Buffer());
NTSTATUS nt_status;
@ -244,6 +275,15 @@ bool FilesystemDispatcher::NtQueryFullAttributesFile(IPCInfo* ipc,
EvalResult result = policy_base_->EvalPolicy(
IPC_NTQUERYFULLATTRIBUTESFILE_TAG, params.GetBase());
// If the policies forbid access (any result other than ASK_BROKER),
// then check for user-granted access to file.
if (ASK_BROKER != result &&
mozilla::sandboxing::PermissionsService::GetInstance()->
UserGrantedFileAccess(ipc->client_info->process_id, filename,
0, 0)) {
result = ASK_BROKER;
}
FILE_NETWORK_OPEN_INFORMATION* information =
reinterpret_cast<FILE_NETWORK_OPEN_INFORMATION*>(info->Buffer());
NTSTATUS nt_status;
@ -299,6 +339,16 @@ bool FilesystemDispatcher::NtSetInformationFile(IPCInfo* ipc,
EvalResult result = policy_base_->EvalPolicy(IPC_NTSETINFO_RENAME_TAG,
params.GetBase());
// If the policies forbid access (any result other than ASK_BROKER),
// then check for user-granted write access to file. We only permit
// the FileRenameInformation action.
if (ASK_BROKER != result && info_class == FileRenameInformation &&
mozilla::sandboxing::PermissionsService::GetInstance()->
UserGrantedFileAccess(ipc->client_info->process_id, filename,
FILE_WRITE_ATTRIBUTES, 0)) {
result = ASK_BROKER;
}
IO_STATUS_BLOCK* io_status =
reinterpret_cast<IO_STATUS_BLOCK*>(status->Buffer());
NTSTATUS nt_status;

View File

@ -14,6 +14,7 @@
#include "sandbox/win/src/sandbox_nt_util.h"
#include "sandbox/win/src/sharedmem_ipc_client.h"
#include "sandbox/win/src/target_services.h"
#include "mozilla/sandboxing/sandboxLogging.h"
// This status occurs when trying to access a network share on the machine from
// which it is shared.
@ -38,6 +39,10 @@ NTSTATUS WINAPI TargetNtCreateFile(NtCreateFileFunction orig_CreateFile,
STATUS_NETWORK_OPEN_RESTRICTION != status)
return status;
mozilla::sandboxing::LogBlocked("NtCreateFile",
object_attributes->ObjectName->Buffer,
object_attributes->ObjectName->Length);
// We don't trust that the IPC can work this early.
if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
return status;
@ -70,9 +75,6 @@ NTSTATUS WINAPI TargetNtCreateFile(NtCreateFileFunction orig_CreateFile,
params[OpenFile::OPTIONS] = ParamPickerMake(options_uint32);
params[OpenFile::BROKER] = ParamPickerMake(broker);
if (!QueryBroker(IPC_NTCREATEFILE_TAG, params.GetBase()))
break;
SharedMemIPCClient ipc(memory);
CrossCallReturn answer = {0};
// The following call must match in the parameters with
@ -95,6 +97,9 @@ NTSTATUS WINAPI TargetNtCreateFile(NtCreateFileFunction orig_CreateFile,
} __except(EXCEPTION_EXECUTE_HANDLER) {
break;
}
mozilla::sandboxing::LogAllowed("NtCreateFile",
object_attributes->ObjectName->Buffer,
object_attributes->ObjectName->Length);
} while (false);
if (name)
@ -115,6 +120,10 @@ NTSTATUS WINAPI TargetNtOpenFile(NtOpenFileFunction orig_OpenFile, PHANDLE file,
STATUS_NETWORK_OPEN_RESTRICTION != status)
return status;
mozilla::sandboxing::LogBlocked("NtOpenFile",
object_attributes->ObjectName->Buffer,
object_attributes->ObjectName->Length);
// We don't trust that the IPC can work this early.
if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
return status;
@ -147,9 +156,6 @@ NTSTATUS WINAPI TargetNtOpenFile(NtOpenFileFunction orig_OpenFile, PHANDLE file,
params[OpenFile::OPTIONS] = ParamPickerMake(options_uint32);
params[OpenFile::BROKER] = ParamPickerMake(broker);
if (!QueryBroker(IPC_NTOPENFILE_TAG, params.GetBase()))
break;
SharedMemIPCClient ipc(memory);
CrossCallReturn answer = {0};
ResultCode code = CrossCall(ipc, IPC_NTOPENFILE_TAG, name, attributes,
@ -170,6 +176,9 @@ NTSTATUS WINAPI TargetNtOpenFile(NtOpenFileFunction orig_OpenFile, PHANDLE file,
} __except(EXCEPTION_EXECUTE_HANDLER) {
break;
}
mozilla::sandboxing::LogAllowed("NtOpenFile",
object_attributes->ObjectName->Buffer,
object_attributes->ObjectName->Length);
} while (false);
if (name)
@ -188,6 +197,10 @@ NTSTATUS WINAPI TargetNtQueryAttributesFile(
STATUS_NETWORK_OPEN_RESTRICTION != status)
return status;
mozilla::sandboxing::LogBlocked("NtQueryAttributesFile",
object_attributes->ObjectName->Buffer,
object_attributes->ObjectName->Length);
// We don't trust that the IPC can work this early.
if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
return status;
@ -215,9 +228,6 @@ NTSTATUS WINAPI TargetNtQueryAttributesFile(
params[FileName::NAME] = ParamPickerMake(name);
params[FileName::BROKER] = ParamPickerMake(broker);
if (!QueryBroker(IPC_NTQUERYATTRIBUTESFILE_TAG, params.GetBase()))
break;
SharedMemIPCClient ipc(memory);
CrossCallReturn answer = {0};
ResultCode code = CrossCall(ipc, IPC_NTQUERYATTRIBUTESFILE_TAG, name,
@ -228,6 +238,9 @@ NTSTATUS WINAPI TargetNtQueryAttributesFile(
status = answer.nt_status;
mozilla::sandboxing::LogAllowed("NtQueryAttributesFile",
object_attributes->ObjectName->Buffer,
object_attributes->ObjectName->Length);
} while (false);
if (name)
@ -247,6 +260,10 @@ NTSTATUS WINAPI TargetNtQueryFullAttributesFile(
STATUS_NETWORK_OPEN_RESTRICTION != status)
return status;
mozilla::sandboxing::LogBlocked("NtQueryFullAttributesFile",
object_attributes->ObjectName->Buffer,
object_attributes->ObjectName->Length);
// We don't trust that the IPC can work this early.
if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
return status;
@ -275,9 +292,6 @@ NTSTATUS WINAPI TargetNtQueryFullAttributesFile(
params[FileName::NAME] = ParamPickerMake(name);
params[FileName::BROKER] = ParamPickerMake(broker);
if (!QueryBroker(IPC_NTQUERYFULLATTRIBUTESFILE_TAG, params.GetBase()))
break;
SharedMemIPCClient ipc(memory);
CrossCallReturn answer = {0};
ResultCode code = CrossCall(ipc, IPC_NTQUERYFULLATTRIBUTESFILE_TAG, name,
@ -287,6 +301,10 @@ NTSTATUS WINAPI TargetNtQueryFullAttributesFile(
break;
status = answer.nt_status;
mozilla::sandboxing::LogAllowed("NtQueryFullAttributesFile",
object_attributes->ObjectName->Buffer,
object_attributes->ObjectName->Length);
} while (false);
if (name)
@ -305,6 +323,8 @@ NTSTATUS WINAPI TargetNtSetInformationFile(
if (STATUS_ACCESS_DENIED != status)
return status;
mozilla::sandboxing::LogBlocked("NtSetInformationFile");
// We don't trust that the IPC can work this early.
if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
return status;
@ -348,9 +368,6 @@ NTSTATUS WINAPI TargetNtSetInformationFile(
params[FileName::NAME] = ParamPickerMake(name);
params[FileName::BROKER] = ParamPickerMake(broker);
if (!QueryBroker(IPC_NTSETINFO_RENAME_TAG, params.GetBase()))
break;
InOutCountedBuffer io_status_buffer(io_status, sizeof(IO_STATUS_BLOCK));
// This is actually not an InOut buffer, only In, but using InOut facility
// really helps to simplify the code.
@ -366,6 +383,7 @@ NTSTATUS WINAPI TargetNtSetInformationFile(
break;
status = answer.nt_status;
mozilla::sandboxing::LogAllowed("NtSetInformationFile");
} while (false);
if (name)

View File

@ -10,6 +10,7 @@
#include "sandbox/win/src/sandbox_nt_util.h"
#include "sandbox/win/src/sharedmem_ipc_client.h"
#include "sandbox/win/src/target_services.h"
#include "mozilla/sandboxing/sandboxLogging.h"
namespace sandbox {
@ -34,10 +35,12 @@ ResultCode DuplicateHandleProxy(HANDLE source_handle,
if (answer.win32_result) {
::SetLastError(answer.win32_result);
mozilla::sandboxing::LogBlocked("DuplicateHandle");
return SBOX_ERROR_GENERIC;
}
*target_handle = answer.handle;
mozilla::sandboxing::LogAllowed("DuplicateHandle");
return SBOX_ALL_OK;
}

View File

@ -12,6 +12,7 @@
#include "sandbox/win/src/sandbox_nt_util.h"
#include "sandbox/win/src/sharedmem_ipc_client.h"
#include "sandbox/win/src/target_services.h"
#include "mozilla/sandboxing/sandboxLogging.h"
namespace sandbox {
@ -27,6 +28,8 @@ HANDLE WINAPI TargetCreateNamedPipeW(
if (INVALID_HANDLE_VALUE != pipe)
return pipe;
mozilla::sandboxing::LogBlocked("CreateNamedPipeW", pipe_name);
// We don't trust that the IPC can work this early.
if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
return INVALID_HANDLE_VALUE;
@ -62,6 +65,7 @@ HANDLE WINAPI TargetCreateNamedPipeW(
if (ERROR_SUCCESS != answer.win32_result)
return INVALID_HANDLE_VALUE;
mozilla::sandboxing::LogAllowed("CreateNamedPipeW", pipe_name);
return answer.handle;
} while (false);

View File

@ -14,6 +14,7 @@
#include "sandbox/win/src/sandbox_nt_util.h"
#include "sandbox/win/src/sharedmem_ipc_client.h"
#include "sandbox/win/src/target_services.h"
#include "mozilla/sandboxing/sandboxLogging.h"
namespace sandbox {
@ -30,6 +31,7 @@ NTSTATUS WINAPI TargetNtOpenThread(NtOpenThreadFunction orig_OpenThread,
if (NT_SUCCESS(status))
return status;
mozilla::sandboxing::LogBlocked("NtOpenThread");
do {
if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
break;
@ -95,6 +97,7 @@ NTSTATUS WINAPI TargetNtOpenThread(NtOpenThreadFunction orig_OpenThread,
break;
}
mozilla::sandboxing::LogAllowed("NtOpenThread");
return answer.nt_status;
} while (false);
@ -179,6 +182,7 @@ NTSTATUS WINAPI TargetNtOpenProcessToken(
if (NT_SUCCESS(status))
return status;
mozilla::sandboxing::LogBlocked("NtOpenProcessToken");
do {
if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
break;
@ -210,6 +214,7 @@ NTSTATUS WINAPI TargetNtOpenProcessToken(
break;
}
mozilla::sandboxing::LogAllowed("NtOpenProcessToken");
return answer.nt_status;
} while (false);
@ -224,6 +229,7 @@ NTSTATUS WINAPI TargetNtOpenProcessTokenEx(
if (NT_SUCCESS(status))
return status;
mozilla::sandboxing::LogBlocked("NtOpenProcessTokenEx");
do {
if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
break;
@ -255,6 +261,7 @@ NTSTATUS WINAPI TargetNtOpenProcessTokenEx(
break;
}
mozilla::sandboxing::LogAllowed("NtOpenProcessTokenEx");
return answer.nt_status;
} while (false);
@ -277,6 +284,8 @@ BOOL WINAPI TargetCreateProcessW(CreateProcessWFunction orig_CreateProcessW,
return TRUE;
}
mozilla::sandboxing::LogBlocked("CreateProcessW", application_name);
// We don't trust that the IPC can work this early.
if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
return FALSE;
@ -317,6 +326,7 @@ BOOL WINAPI TargetCreateProcessW(CreateProcessWFunction orig_CreateProcessW,
if (ERROR_SUCCESS != answer.win32_result)
return FALSE;
mozilla::sandboxing::LogAllowed("CreateProcessW", application_name);
return TRUE;
} while (false);
@ -340,6 +350,8 @@ BOOL WINAPI TargetCreateProcessA(CreateProcessAFunction orig_CreateProcessA,
return TRUE;
}
mozilla::sandboxing::LogBlocked("CreateProcessA", application_name);
// We don't trust that the IPC can work this early.
if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
return FALSE;
@ -414,6 +426,7 @@ BOOL WINAPI TargetCreateProcessA(CreateProcessAFunction orig_CreateProcessA,
if (ERROR_SUCCESS != answer.win32_result)
return FALSE;
mozilla::sandboxing::LogAllowed("CreateProcessA", application_name);
return TRUE;
} while (false);

View File

@ -14,6 +14,7 @@
#include "sandbox/win/src/sandbox_nt_util.h"
#include "sandbox/win/src/sharedmem_ipc_client.h"
#include "sandbox/win/src/target_services.h"
#include "mozilla/sandboxing/sandboxLogging.h"
namespace sandbox {
@ -29,6 +30,12 @@ NTSTATUS WINAPI TargetNtCreateKey(NtCreateKeyFunction orig_CreateKey,
if (NT_SUCCESS(status))
return status;
if (STATUS_OBJECT_NAME_NOT_FOUND != status) {
mozilla::sandboxing::LogBlocked("NtCreateKey",
object_attributes->ObjectName->Buffer,
object_attributes->ObjectName->Length);
}
// We don't trust that the IPC can work this early.
if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
return status;
@ -114,6 +121,9 @@ NTSTATUS WINAPI TargetNtCreateKey(NtCreateKeyFunction orig_CreateKey,
} __except(EXCEPTION_EXECUTE_HANDLER) {
break;
}
mozilla::sandboxing::LogAllowed("NtCreateKey",
object_attributes->ObjectName->Buffer,
object_attributes->ObjectName->Length);
} while (false);
return status;
@ -190,6 +200,9 @@ NTSTATUS WINAPI CommonNtOpenKey(NTSTATUS status, PHANDLE key,
} __except(EXCEPTION_EXECUTE_HANDLER) {
break;
}
mozilla::sandboxing::LogAllowed("NtOpenKey[Ex]",
object_attributes->ObjectName->Buffer,
object_attributes->ObjectName->Length);
} while (false);
return status;
@ -203,6 +216,12 @@ NTSTATUS WINAPI TargetNtOpenKey(NtOpenKeyFunction orig_OpenKey, PHANDLE key,
if (NT_SUCCESS(status))
return status;
if (STATUS_OBJECT_NAME_NOT_FOUND != status) {
mozilla::sandboxing::LogBlocked("NtOpenKey",
object_attributes->ObjectName->Buffer,
object_attributes->ObjectName->Length);
}
return CommonNtOpenKey(status, key, desired_access, object_attributes);
}
@ -220,6 +239,12 @@ NTSTATUS WINAPI TargetNtOpenKeyEx(NtOpenKeyExFunction orig_OpenKeyEx,
if (NT_SUCCESS(status) || open_options != 0)
return status;
if (STATUS_OBJECT_NAME_NOT_FOUND != status) {
mozilla::sandboxing::LogBlocked("NtOpenKeyEx",
object_attributes->ObjectName->Buffer,
object_attributes->ObjectName->Length);
}
return CommonNtOpenKey(status, key, desired_access, object_attributes);
}

View File

@ -20,7 +20,8 @@ namespace {
static const uint32_t kAllowedRegFlags =
KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS | KEY_NOTIFY | KEY_READ |
GENERIC_READ | GENERIC_EXECUTE | READ_CONTROL;
GENERIC_READ | GENERIC_EXECUTE | READ_CONTROL | KEY_WOW64_64KEY |
KEY_WOW64_32KEY;
// Opens the key referenced by |obj_attributes| with |access| and
// checks what permission was given. Remove the WRITE flags and update

View File

@ -259,6 +259,40 @@ DWORD RestrictedToken::AddAllSidsForDenyOnly(std::vector<Sid> *exceptions) {
return ERROR_SUCCESS;
}
DWORD RestrictedToken::AddDenyOnlySids(const std::vector<Sid>& deny_only_sids) {
DCHECK(init_);
if (!init_) {
return ERROR_NO_TOKEN;
}
DWORD error;
std::unique_ptr<BYTE[]> buffer =
GetTokenInfo(effective_token_, TokenGroups, &error);
if (!buffer) {
return error;
}
TOKEN_GROUPS* token_groups = reinterpret_cast<TOKEN_GROUPS*>(buffer.get());
// Build the list of the deny only group SIDs
for (unsigned int i = 0; i < token_groups->GroupCount ; ++i) {
if ((token_groups->Groups[i].Attributes & SE_GROUP_INTEGRITY) == 0 &&
(token_groups->Groups[i].Attributes & SE_GROUP_LOGON_ID) == 0) {
for (unsigned int j = 0; j < deny_only_sids.size(); ++j) {
if (::EqualSid(const_cast<SID*>(deny_only_sids[j].GetPSID()),
token_groups->Groups[i].Sid)) {
sids_for_deny_only_.push_back(
reinterpret_cast<SID*>(token_groups->Groups[i].Sid));
break;
}
}
}
}
return ERROR_SUCCESS;
}
DWORD RestrictedToken::AddSidForDenyOnly(const Sid &sid) {
DCHECK(init_);
if (!init_)

View File

@ -88,6 +88,17 @@ class RestrictedToken {
// access to any resource. It can only be used to deny access.
DWORD AddAllSidsForDenyOnly(std::vector<Sid> *exceptions);
// Lists all sids in the token and mark them as Deny Only if present in the
// deny_only_sids parameter.
//
// If the function succeeds, the return value is ERROR_SUCCESS. If the
// function fails, the return value is the win32 error code corresponding to
// the error.
//
// Note: A Sid marked for Deny Only in a token cannot be used to grant
// access to any resource. It can only be used to deny access.
DWORD AddDenyOnlySids(const std::vector<Sid>& deny_only_sids);
// Adds a user or group SID for Deny Only in the restricted token.
// Parameter: sid is the SID to add in the Deny Only list.
// The return value is always ERROR_SUCCESS.

View File

@ -31,6 +31,7 @@ DWORD CreateRestrictedToken(TokenLevel security_level,
std::vector<base::string16> privilege_exceptions;
std::vector<Sid> sid_exceptions;
std::vector<Sid> deny_only_sids;
bool deny_sids = true;
bool remove_privileges = true;
@ -55,10 +56,16 @@ DWORD CreateRestrictedToken(TokenLevel security_level,
break;
}
case USER_NON_ADMIN: {
sid_exceptions.push_back(WinBuiltinUsersSid);
sid_exceptions.push_back(WinWorldSid);
sid_exceptions.push_back(WinInteractiveSid);
sid_exceptions.push_back(WinAuthenticatedUserSid);
deny_sids = false;
deny_only_sids.push_back(WinBuiltinAdministratorsSid);
deny_only_sids.push_back(WinAccountAdministratorSid);
deny_only_sids.push_back(WinAccountDomainAdminsSid);
deny_only_sids.push_back(WinAccountCertAdminsSid);
deny_only_sids.push_back(WinAccountSchemaAdminsSid);
deny_only_sids.push_back(WinAccountEnterpriseAdminsSid);
deny_only_sids.push_back(WinAccountPolicyAdminsSid);
deny_only_sids.push_back(WinBuiltinHyperVAdminsSid);
deny_only_sids.push_back(WinLocalAccountAndAdministratorSid);
privilege_exceptions.push_back(SE_CHANGE_NOTIFY_NAME);
break;
}
@ -121,6 +128,11 @@ DWORD CreateRestrictedToken(TokenLevel security_level,
err_code = restricted_token.AddAllSidsForDenyOnly(&sid_exceptions);
if (ERROR_SUCCESS != err_code)
return err_code;
} else if (!deny_only_sids.empty()) {
err_code = restricted_token.AddDenyOnlySids(deny_only_sids);
if (ERROR_SUCCESS != err_code) {
return err_code;
}
}
if (remove_privileges) {

View File

@ -14,6 +14,7 @@
#include "sandbox/win/src/sandbox_nt_util.h"
#include "sandbox/win/src/sharedmem_ipc_client.h"
#include "sandbox/win/src/target_services.h"
#include "mozilla/sandboxing/sandboxLogging.h"
namespace sandbox {
@ -64,6 +65,10 @@ NTSTATUS WINAPI TargetNtCreateEvent(NtCreateEventFunction orig_CreateEvent,
if (status != STATUS_ACCESS_DENIED || !object_attributes)
return status;
mozilla::sandboxing::LogBlocked("NtCreatEvent",
object_attributes->ObjectName->Buffer,
object_attributes->ObjectName->Length);
// We don't trust that the IPC can work this early.
if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
return status;
@ -103,6 +108,9 @@ NTSTATUS WINAPI TargetNtCreateEvent(NtCreateEventFunction orig_CreateEvent,
} __except(EXCEPTION_EXECUTE_HANDLER) {
break;
}
mozilla::sandboxing::LogAllowed("NtCreateEvent",
object_attributes->ObjectName->Buffer,
object_attributes->ObjectName->Length);
} while (false);
return status;
@ -117,6 +125,10 @@ NTSTATUS WINAPI TargetNtOpenEvent(NtOpenEventFunction orig_OpenEvent,
if (status != STATUS_ACCESS_DENIED || !object_attributes)
return status;
mozilla::sandboxing::LogBlocked("NtOpenEvent",
object_attributes->ObjectName->Buffer,
object_attributes->ObjectName->Length);
//
// We don't trust that the IPC can work this early.
if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
return status;
@ -155,6 +167,9 @@ NTSTATUS WINAPI TargetNtOpenEvent(NtOpenEventFunction orig_OpenEvent,
} __except(EXCEPTION_EXECUTE_HANDLER) {
break;
}
mozilla::sandboxing::LogAllowed("NtOpenEvent",
object_attributes->ObjectName->Buffer,
object_attributes->ObjectName->Length);
} while (false);
return status;

View File

@ -195,6 +195,7 @@ bool ResolveRegistryName(base::string16 name, base::string16* resolved_name) {
// \??\c:\some\foo\bar
// \Device\HarddiskVolume0\some\foo\bar
// \??\HarddiskVolume0\some\foo\bar
// \??\UNC\SERVER\Share\some\foo\bar
DWORD IsReparsePoint(const base::string16& full_path) {
// Check if it's a pipe. We can't query the attributes of a pipe.
if (IsPipe(full_path))
@ -208,29 +209,34 @@ DWORD IsReparsePoint(const base::string16& full_path) {
if (!has_drive && !is_device_path && !nt_path)
return ERROR_INVALID_NAME;
bool added_implied_device = false;
if (!has_drive) {
path = base::string16(kNTDotPrefix) + path;
added_implied_device = true;
// Add Win32 device namespace prefix, required for some Windows APIs.
path.insert(0, kNTDotPrefix);
}
base::string16::size_type last_pos = base::string16::npos;
bool passed_once = false;
// Ensure that volume path matches start of path.
wchar_t vol_path[MAX_PATH];
if (!::GetVolumePathNameW(path.c_str(), vol_path, MAX_PATH)) {
// This will fail if this is a device that isn't volume related, which can't
// then be a reparse point.
return is_device_path ? ERROR_NOT_A_REPARSE_POINT : ERROR_INVALID_NAME;
}
// vol_path includes a trailing slash, so reduce size for path and loop check.
size_t vol_path_len = wcslen(vol_path) - 1;
if (!EqualPath(path, vol_path, vol_path_len)) {
return ERROR_INVALID_NAME;
}
do {
path = path.substr(0, last_pos);
DWORD attributes = ::GetFileAttributes(path.c_str());
if (INVALID_FILE_ATTRIBUTES == attributes) {
DWORD error = ::GetLastError();
if (error != ERROR_FILE_NOT_FOUND &&
error != ERROR_PATH_NOT_FOUND &&
error != ERROR_INVALID_FUNCTION &&
error != ERROR_INVALID_NAME) {
// Unexpected error.
if (passed_once && added_implied_device &&
(path.rfind(L'\\') == kNTDotPrefixLen - 1)) {
break;
}
NOTREACHED_NT();
return error;
}
@ -239,9 +245,8 @@ DWORD IsReparsePoint(const base::string16& full_path) {
return ERROR_SUCCESS;
}
passed_once = true;
last_pos = path.rfind(L'\\');
} while (last_pos > 2); // Skip root dir.
path.resize(path.rfind(L'\\'));
} while (path.size() > vol_path_len); // Skip root dir.
return ERROR_NOT_A_REPARSE_POINT;
}
@ -261,11 +266,11 @@ bool SameObject(HANDLE handle, const wchar_t* full_path) {
DCHECK_NT(!path.empty());
// This may end with a backslash.
const wchar_t kBackslash = '\\';
if (path.back() == kBackslash)
path = path.substr(0, path.length() - 1);
if (path.back() == L'\\') {
path.pop_back();
}
// Perfect match (case-insesitive check).
// Perfect match (case-insensitive check).
if (EqualPath(actual_path, path))
return true;
@ -274,40 +279,44 @@ bool SameObject(HANDLE handle, const wchar_t* full_path) {
if (!has_drive && nt_path) {
base::string16 simple_actual_path;
if (!IsDevicePath(actual_path, &simple_actual_path))
return false;
// Perfect match (case-insesitive check).
return (EqualPath(simple_actual_path, path));
if (IsDevicePath(path, &path)) {
if (IsDevicePath(actual_path, &simple_actual_path)) {
// Perfect match (case-insensitive check).
return (EqualPath(simple_actual_path, path));
} else {
return false;
}
} else {
// Add Win32 device namespace for GetVolumePathName.
path.insert(0, kNTDotPrefix);
}
}
if (!has_drive)
// Get the volume path in the same format as actual_path.
wchar_t vol_path[MAX_PATH];
if (!::GetVolumePathName(path.c_str(), vol_path, MAX_PATH)) {
return false;
// We only need 3 chars, but let's alloc a buffer for four.
wchar_t drive[4] = {0};
wchar_t vol_name[MAX_PATH];
memcpy(drive, &path[0], 2 * sizeof(*drive));
// We'll get a double null terminated string.
DWORD vol_length = ::QueryDosDeviceW(drive, vol_name, MAX_PATH);
if (vol_length < 2 || vol_length == MAX_PATH)
}
size_t vol_path_len = wcslen(vol_path);
base::string16 nt_vol;
if (!GetNtPathFromWin32Path(vol_path, &nt_vol)) {
return false;
// Ignore the nulls at the end.
vol_length = static_cast<DWORD>(wcslen(vol_name));
}
// The two paths should be the same length.
if (vol_length + path.size() - 2 != actual_path.size())
if (nt_vol.size() + path.size() - vol_path_len != actual_path.size()) {
return false;
}
// Check up to the drive letter.
if (!EqualPath(actual_path, vol_name, vol_length))
// Check the volume matches.
if (!EqualPath(actual_path, nt_vol.c_str(), nt_vol.size())) {
return false;
}
// Check the path after the drive letter.
if (!EqualPath(actual_path, vol_length, path, 2))
// Check the path after the volume matches.
if (!EqualPath(actual_path, nt_vol.size(), path, vol_path_len)) {
return false;
}
return true;
}

View File

@ -1,12 +0,0 @@
Please add a link to the bugzilla bug and patch name that should be re-applied.
Also, please update any existing links to their actual mozilla-central changeset.
https://hg.mozilla.org/mozilla-central/rev/a05726163a79
https://hg.mozilla.org/mozilla-central/rev/e834e810a3fa
https://hg.mozilla.org/mozilla-central/rev/c70d06fa5302
https://hg.mozilla.org/mozilla-central/rev/d24db55deb85
https://hg.mozilla.org/mozilla-central/rev/0e6bf137521e
https://hg.mozilla.org/mozilla-central/rev/1755a454e2de
https://bugzilla.mozilla.org/show_bug.cgi?id=1385928 bug1385928.patch
https://chromium.googlesource.com/chromium/src/+/0cb5dadc2b1f84fbbd9c6f75056e38d05a5b07d3
https://chromium.googlesource.com/chromium/src/+/db4c64b63d6098294ed255e962700fd2d465575e

View File

@ -1,4 +0,0 @@
Chromium Commit Directory / File (relative to security/sandbox/)
---------------------------------------- ------------------------------------------------
b169b9a1cc402573843e8c952af14c4e43487e91 chromium
611754aea9d1c0ba5c7980fa267fd005dc249b85 chromium/sandbox/win/src/policy_target.cc