mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-21 01:05:45 +00:00
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:
parent
6bd2ddcccd
commit
ef5af7b0b1
@ -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);
|
@ -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
|
@ -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,
|
@ -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) {
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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_)
|
||||
|
@ -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.
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
@ -1,4 +0,0 @@
|
||||
Chromium Commit Directory / File (relative to security/sandbox/)
|
||||
---------------------------------------- ------------------------------------------------
|
||||
b169b9a1cc402573843e8c952af14c4e43487e91 chromium
|
||||
611754aea9d1c0ba5c7980fa267fd005dc249b85 chromium/sandbox/win/src/policy_target.cc
|
Loading…
Reference in New Issue
Block a user