summaryrefslogtreecommitdiffstats
path: root/security/sandbox/chromium-shim/patches/after_update
diff options
context:
space:
mode:
Diffstat (limited to 'security/sandbox/chromium-shim/patches/after_update')
-rw-r--r--security/sandbox/chromium-shim/patches/after_update/add_WOW64_flags_to_allowed_registry_read_flags.patch34
-rw-r--r--security/sandbox/chromium-shim/patches/after_update/add_interception_logging.patch810
-rw-r--r--security/sandbox/chromium-shim/patches/after_update/allow_ntpath_in_SignedPolicy_GenerateRules.patch82
-rw-r--r--security/sandbox/chromium-shim/patches/after_update/allow_rules_for_network_drive_and_non_file_devices.patch190
-rw-r--r--security/sandbox/chromium-shim/patches/after_update/arm64_set_LoaderThreads.patch99
-rw-r--r--security/sandbox/chromium-shim/patches/after_update/change_to_DCHECK_in_CloseHandleWrapper.patch38
-rw-r--r--security/sandbox/chromium-shim/patches/after_update/linux_32bit_arg_fixup.patch84
-rw-r--r--security/sandbox/chromium-shim/patches/after_update/move_shared_memory_duplication_after_initialization.patch94
-rw-r--r--security/sandbox/chromium-shim/patches/after_update/patch_order.txt8
9 files changed, 1439 insertions, 0 deletions
diff --git a/security/sandbox/chromium-shim/patches/after_update/add_WOW64_flags_to_allowed_registry_read_flags.patch b/security/sandbox/chromium-shim/patches/after_update/add_WOW64_flags_to_allowed_registry_read_flags.patch
new file mode 100644
index 0000000000..7eb643719e
--- /dev/null
+++ b/security/sandbox/chromium-shim/patches/after_update/add_WOW64_flags_to_allowed_registry_read_flags.patch
@@ -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 = nullptr;
+ ResolveNTFunctionPtr("NtOpenKey", &NtOpenKey);
diff --git a/security/sandbox/chromium-shim/patches/after_update/add_interception_logging.patch b/security/sandbox/chromium-shim/patches/after_update/add_interception_logging.patch
new file mode 100644
index 0000000000..344fd569d7
--- /dev/null
+++ b/security/sandbox/chromium-shim/patches/after_update/add_interception_logging.patch
@@ -0,0 +1,810 @@
+# HG changeset patch
+# User Bob Owen <bobowencode@gmail.com>
+# Date 1417281138 0
+# Sat Nov 29 17:12:18 2014 +0000
+# Node ID 4ea2e332affe4b74bd37fbf2fee8da0b1c94e115
+# Parent 5eec91873c96c2cbfc856ba86335fa068c89d6ce
+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
+@@ -10,16 +10,17 @@
+ #include "sandbox/win/src/filesystem_policy.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,
+@@ -37,16 +38,20 @@ NTSTATUS WINAPI TargetNtCreateFile(NtCre
+ // Check if the process can open it first.
+ 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;
+
+ do {
+ if (!ValidParameter(file, sizeof(HANDLE), WRITE))
+ break;
+ if (!ValidParameter(io_status, sizeof(IO_STATUS_BLOCK), WRITE))
+@@ -96,16 +101,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);
+
+ return status;
+ }
+
+ NTSTATUS WINAPI TargetNtOpenFile(NtOpenFileFunction orig_OpenFile,
+ PHANDLE file,
+ ACCESS_MASK desired_access,
+@@ -115,16 +123,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;
+
+ do {
+ if (!ValidParameter(file, sizeof(HANDLE), WRITE))
+ break;
+ if (!ValidParameter(io_status, sizeof(IO_STATUS_BLOCK), WRITE))
+@@ -171,31 +183,38 @@ 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);
+
+ return status;
+ }
+
+ NTSTATUS WINAPI
+ TargetNtQueryAttributesFile(NtQueryAttributesFileFunction orig_QueryAttributes,
+ 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;
+
+ do {
+ if (!ValidParameter(file_attributes, sizeof(FILE_BASIC_INFORMATION), WRITE))
+ break;
+
+@@ -227,32 +246,39 @@ TargetNtQueryAttributesFile(NtQueryAttri
+ ResultCode code = CrossCall(ipc, IpcTag::NTQUERYATTRIBUTESFILE, name.get(),
+ 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);
+
+ return status;
+ }
+
+ NTSTATUS WINAPI TargetNtQueryFullAttributesFile(
+ NtQueryFullAttributesFileFunction orig_QueryFullAttributes,
+ POBJECT_ATTRIBUTES object_attributes,
+ 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;
+
+ do {
+ if (!ValidParameter(file_attributes, sizeof(FILE_NETWORK_OPEN_INFORMATION),
+ WRITE))
+ break;
+@@ -284,16 +310,20 @@ NTSTATUS WINAPI TargetNtQueryFullAttribu
+ CrossCallReturn answer = {0};
+ ResultCode code = CrossCall(ipc, IpcTag::NTQUERYFULLATTRIBUTESFILE,
+ name.get(), 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);
+
+ return status;
+ }
+
+ NTSTATUS WINAPI
+ TargetNtSetInformationFile(NtSetInformationFileFunction orig_SetInformationFile,
+ HANDLE file,
+@@ -302,16 +332,18 @@ TargetNtSetInformationFile(NtSetInformat
+ 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;
+
+ do {
+ void* memory = GetGlobalIPCMemory();
+ if (!memory)
+ break;
+@@ -366,14 +398,15 @@ TargetNtSetInformationFile(NtSetInformat
+ ResultCode code =
+ CrossCall(ipc, IpcTag::NTSETINFO_RENAME, 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);
+
+ return status;
+ }
+
+ } // namespace sandbox
+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, IpcTag::DUPLICATEHANDLEPROXY,
+ 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,16 +7,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 {
+
+ HANDLE WINAPI
+ TargetCreateNamedPipeW(CreateNamedPipeWFunction orig_CreateNamedPipeW,
+ LPCWSTR pipe_name,
+ DWORD open_mode,
+ DWORD pipe_mode,
+@@ -26,16 +27,18 @@ TargetCreateNamedPipeW(CreateNamedPipeWF
+ 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)
+@@ -61,16 +64,17 @@ TargetCreateNamedPipeW(CreateNamedPipeWF
+ 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
+@@ -10,16 +10,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 {
+
+ 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,
+@@ -27,16 +28,17 @@ NTSTATUS WINAPI TargetNtOpenThread(NtOpe
+ 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;
+@@ -91,16 +93,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.
+@@ -176,16 +179,17 @@ 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))
+@@ -207,16 +211,17 @@ TargetNtOpenProcessToken(NtOpenProcessTo
+
+ __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,
+@@ -224,16 +229,17 @@ TargetNtOpenProcessTokenEx(NtOpenProcess
+ 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))
+@@ -255,16 +261,17 @@ TargetNtOpenProcessTokenEx(NtOpenProcess
+
+ __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,
+@@ -280,16 +287,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();
+
+@@ -320,16 +329,17 @@ BOOL WINAPI TargetCreateProcessW(CreateP
+ cur_dir, current_directory, 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,
+@@ -346,16 +356,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();
+
+@@ -420,16 +432,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,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 {
+
+ NTSTATUS WINAPI TargetNtCreateKey(NtCreateKeyFunction orig_CreateKey,
+ PHANDLE key,
+ ACCESS_MASK desired_access,
+ POBJECT_ATTRIBUTES object_attributes,
+ ULONG title_index,
+@@ -27,16 +28,22 @@ NTSTATUS WINAPI TargetNtCreateKey(NtCrea
+ 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;
+
+@@ -114,16 +121,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,
+@@ -193,30 +203,39 @@ 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) {
+@@ -225,12 +244,18 @@ NTSTATUS WINAPI TargetNtOpenKeyEx(NtOpen
+ orig_OpenKeyEx(key, desired_access, object_attributes, 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/signed_interception.cc b/security/sandbox/chromium/sandbox/win/src/signed_interception.cc
+--- a/security/sandbox/chromium/sandbox/win/src/signed_interception.cc
++++ b/security/sandbox/chromium/sandbox/win/src/signed_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 {
+
+ NTSTATUS WINAPI
+ TargetNtCreateSection(NtCreateSectionFunction orig_CreateSection,
+ PHANDLE section_handle,
+ ACCESS_MASK desired_access,
+ POBJECT_ATTRIBUTES object_attributes,
+@@ -37,16 +38,18 @@ TargetNtCreateSection(NtCreateSectionFun
+ break;
+ if (maximum_size)
+ break;
+ if (section_page_protection != PAGE_EXECUTE)
+ break;
+ if (allocation_attributes != SEC_IMAGE)
+ break;
+
++ mozilla::sandboxing::LogBlocked("NtCreateSection");
++
+ // IPC must be fully started.
+ void* memory = GetGlobalIPCMemory();
+ if (!memory)
+ break;
+
+ std::unique_ptr<wchar_t, NtAllocDeleter> path;
+
+ if (!NtGetPathFromHandle(file_handle, &path))
+@@ -73,16 +76,17 @@ TargetNtCreateSection(NtCreateSectionFun
+ if (code != SBOX_ALL_OK)
+ break;
+
+ if (!NT_SUCCESS(answer.nt_status))
+ break;
+
+ __try {
+ *section_handle = answer.handle;
++ mozilla::sandboxing::LogAllowed("NtCreateSection");
+ return answer.nt_status;
+ } __except (EXCEPTION_EXECUTE_HANDLER) {
+ break;
+ }
+ } while (false);
+
+ // Fall back to the original API in all failure cases.
+ return orig_CreateSection(section_handle, desired_access, object_attributes,
+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;
+
+@@ -97,30 +102,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;
+
+@@ -149,14 +161,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
diff --git a/security/sandbox/chromium-shim/patches/after_update/allow_ntpath_in_SignedPolicy_GenerateRules.patch b/security/sandbox/chromium-shim/patches/after_update/allow_ntpath_in_SignedPolicy_GenerateRules.patch
new file mode 100644
index 0000000000..8e6a951467
--- /dev/null
+++ b/security/sandbox/chromium-shim/patches/after_update/allow_ntpath_in_SignedPolicy_GenerateRules.patch
@@ -0,0 +1,82 @@
+# HG changeset patch
+# User Toshihito Kikuchi <tkikuchi@mozilla.com>
+# Date 1605814807 28800
+# Thu Nov 19 11:40:07 2020 -0800
+# Node ID 29b049665db1f28ffdfce319ad48912d4a024e23
+# Parent 94435953fb89c1fe147c6b76a9ecb61f59625d30
+Bug 1620114 - Allow an NT path string to be passed to SignedPolicy::GenerateRules. r=bobowen
+so that our SandboxBroker can add a policy rule with an NT path directly.
+
+diff --git a/security/sandbox/chromium/sandbox/win/src/signed_policy.cc b/security/sandbox/chromium/sandbox/win/src/signed_policy.cc
+--- a/security/sandbox/chromium/sandbox/win/src/signed_policy.cc
++++ b/security/sandbox/chromium/sandbox/win/src/signed_policy.cc
+@@ -7,39 +7,63 @@
+ #include <stdint.h>
+
+ #include <string>
+
+ #include "sandbox/win/src/ipc_tags.h"
+ #include "sandbox/win/src/policy_engine_opcodes.h"
+ #include "sandbox/win/src/policy_params.h"
+ #include "sandbox/win/src/sandbox_policy.h"
++#include "sandbox/win/src/sandbox_utils.h"
+ #include "sandbox/win/src/win_utils.h"
+
++namespace {
++
++bool IsValidNtPath(const base::FilePath& name) {
++ UNICODE_STRING uni_name;
++ OBJECT_ATTRIBUTES obj_attr;
++ sandbox::InitObjectAttribs(name.value(), OBJ_CASE_INSENSITIVE, nullptr,
++ &obj_attr, &uni_name, nullptr);
++
++ NtQueryAttributesFileFunction NtQueryAttributesFile = nullptr;
++ ResolveNTFunctionPtr("NtQueryAttributesFile", &NtQueryAttributesFile);
++ FILE_BASIC_INFORMATION file_info;
++ return NtQueryAttributesFile &&
++ NT_SUCCESS(NtQueryAttributesFile(&obj_attr, &file_info));
++}
++
++} // namespace
++
+ namespace sandbox {
+
+ bool SignedPolicy::GenerateRules(const wchar_t* name,
+ TargetPolicy::Semantics semantics,
+ LowLevelPolicy* policy) {
+ // Only support one semantic.
+ if (TargetPolicy::SIGNED_ALLOW_LOAD != semantics) {
+ return false;
+ }
+
+ base::FilePath file_path(name);
++ base::FilePath nt_filename;
+ std::wstring nt_path_name;
+- if (!GetNtPathFromWin32Path(file_path.DirName().value().c_str(),
+- &nt_path_name))
++ if (GetNtPathFromWin32Path(file_path.DirName().value().c_str(),
++ &nt_path_name)) {
++ base::FilePath nt_path(nt_path_name);
++ nt_filename = nt_path.Append(file_path.BaseName());
++ } else if (IsValidNtPath(file_path)) {
++ nt_filename = std::move(file_path);
++ } else {
+ return false;
+- base::FilePath nt_path(nt_path_name);
+- std::wstring nt_filename = nt_path.Append(file_path.BaseName()).value();
++ }
++
+ // Create a rule to ASK_BROKER if name matches.
+ PolicyRule signed_policy(ASK_BROKER);
+- if (!signed_policy.AddStringMatch(IF, NameBased::NAME, nt_filename.c_str(),
+- CASE_INSENSITIVE)) {
++ if (!signed_policy.AddStringMatch(
++ IF, NameBased::NAME, nt_filename.value().c_str(), CASE_INSENSITIVE)) {
+ return false;
+ }
+ if (!policy->AddRule(IpcTag::NTCREATESECTION, &signed_policy)) {
+ return false;
+ }
+
+ return true;
+ }
diff --git a/security/sandbox/chromium-shim/patches/after_update/allow_rules_for_network_drive_and_non_file_devices.patch b/security/sandbox/chromium-shim/patches/after_update/allow_rules_for_network_drive_and_non_file_devices.patch
new file mode 100644
index 0000000000..8d497e1ff9
--- /dev/null
+++ b/security/sandbox/chromium-shim/patches/after_update/allow_rules_for_network_drive_and_non_file_devices.patch
@@ -0,0 +1,190 @@
+# 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
+@@ -194,61 +194,66 @@ bool ResolveRegistryName(std::wstring na
+
+ 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 std::wstring& 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;
+
+ std::wstring 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 = std::wstring(kNTDotPrefix) + path;
+- added_implied_device = true;
++ // Add Win32 device namespace prefix, required for some Windows APIs.
++ path.insert(0, kNTDotPrefix);
+ }
+
+- std::wstring::size_type last_pos = std::wstring::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;
+- }
+ 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.
+@@ -258,63 +263,67 @@ bool SameObject(HANDLE handle, const wch
+ std::wstring actual_path;
+ if (!GetPathFromHandle(handle, &actual_path))
+ return false;
+
+ std::wstring 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) {
+ std::wstring 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(std::wstring* native_path,
+ const std::wstring* drive_letter) {
diff --git a/security/sandbox/chromium-shim/patches/after_update/arm64_set_LoaderThreads.patch b/security/sandbox/chromium-shim/patches/after_update/arm64_set_LoaderThreads.patch
new file mode 100644
index 0000000000..4d1817db17
--- /dev/null
+++ b/security/sandbox/chromium-shim/patches/after_update/arm64_set_LoaderThreads.patch
@@ -0,0 +1,99 @@
+# HG changeset patch
+# User Bob Owen <bobowencode@gmail.com>
+# Date 1549645620 0
+# Fri Feb 08 17:07:00 2019 +0000
+# Node ID fb5e7c1090a7ddfde22fd2fb5f8a957ccc61fa64
+# Parent 5ef34aa8c8918649528048dd60907862a4355e29
+Bug 1515088 Part 2: Set LoaderThreads to 1 in the RTL_USER_PROCESS_PARAMETERS structure on child process start-up. r=aklotz
+
+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
+@@ -456,20 +456,21 @@ bool GetNtPathFromWin32Path(const std::w
+ bool rv = GetPathFromHandle(file, nt_path);
+ ::CloseHandle(file);
+ return rv;
+ }
+
+ bool WriteProtectedChildMemory(HANDLE child_process,
+ void* address,
+ const void* buffer,
+- size_t length) {
++ size_t length,
++ DWORD writeProtection) {
+ // First, remove the protections.
+ DWORD old_protection;
+- if (!::VirtualProtectEx(child_process, address, length, PAGE_WRITECOPY,
++ if (!::VirtualProtectEx(child_process, address, length, writeProtection,
+ &old_protection))
+ return false;
+
+ SIZE_T written;
+ bool ok =
+ ::WriteProcessMemory(child_process, address, buffer, length, &written) &&
+ (length == written);
+
+@@ -544,16 +545,40 @@ void* GetProcessBaseAddress(HANDLE proce
+ &bytes_read) ||
+ (sizeof(magic) != bytes_read)) {
+ return nullptr;
+ }
+
+ if (magic[0] != 'M' || magic[1] != 'Z')
+ return nullptr;
+
++#if defined(_M_ARM64)
++ // Windows 10 on ARM64 has multi-threaded DLL loading that does not work with
++ // the sandbox. (On x86 this gets disabled by hook detection code that was not
++ // ported to ARM64). This overwrites the LoaderThreads value in the process
++ // parameters part of the PEB, if it is set to the default of 0 (which
++ // actually means it defaults to 4 loading threads). This is an undocumented
++ // field so there is a, probably small, risk that it might change or move in
++ // the future. In order to slightly guard against that we only update if the
++ // value is currently 0.
++ auto processParameters = reinterpret_cast<uint8_t*>(peb.ProcessParameters);
++ const uint32_t loaderThreadsOffset = 0x40c;
++ uint32_t maxLoaderThreads = 0;
++ BOOL memoryRead = ::ReadProcessMemory(
++ process, processParameters + loaderThreadsOffset, &maxLoaderThreads,
++ sizeof(maxLoaderThreads), &bytes_read);
++ if (memoryRead && (sizeof(maxLoaderThreads) == bytes_read) &&
++ (maxLoaderThreads == 0)) {
++ maxLoaderThreads = 1;
++ WriteProtectedChildMemory(process, processParameters + loaderThreadsOffset,
++ &maxLoaderThreads, sizeof(maxLoaderThreads),
++ PAGE_READWRITE);
++ }
++#endif
++
+ return base_address;
+ }
+
+ DWORD GetTokenInformation(HANDLE token,
+ TOKEN_INFORMATION_CLASS info_class,
+ std::unique_ptr<BYTE[]>* buffer) {
+ // Get the required buffer size.
+ DWORD size = 0;
+diff --git a/security/sandbox/chromium/sandbox/win/src/win_utils.h b/security/sandbox/chromium/sandbox/win/src/win_utils.h
+--- a/security/sandbox/chromium/sandbox/win/src/win_utils.h
++++ b/security/sandbox/chromium/sandbox/win/src/win_utils.h
+@@ -111,17 +111,18 @@ HKEY GetReservedKeyFromName(const std::w
+ bool ResolveRegistryName(std::wstring name, std::wstring* resolved_name);
+
+ // Writes |length| bytes from the provided |buffer| into the address space of
+ // |child_process|, at the specified |address|, preserving the original write
+ // protection attributes. Returns true on success.
+ bool WriteProtectedChildMemory(HANDLE child_process,
+ void* address,
+ const void* buffer,
+- size_t length);
++ size_t length,
++ DWORD writeProtection = PAGE_WRITECOPY);
+
+ // Allocates |buffer_bytes| in child (PAGE_READWRITE) and copies data
+ // from |local_buffer| in this process into |child|. |remote_buffer|
+ // contains the address in the chile. If a zero byte copy is
+ // requested |true| is returned and no allocation or copying is
+ // attempted. Returns false if allocation or copying fails. If
+ // copying fails, the allocation will be reversed.
+ bool CopyToChildMemory(HANDLE child,
diff --git a/security/sandbox/chromium-shim/patches/after_update/change_to_DCHECK_in_CloseHandleWrapper.patch b/security/sandbox/chromium-shim/patches/after_update/change_to_DCHECK_in_CloseHandleWrapper.patch
new file mode 100644
index 0000000000..3d6bfaa54f
--- /dev/null
+++ b/security/sandbox/chromium-shim/patches/after_update/change_to_DCHECK_in_CloseHandleWrapper.patch
@@ -0,0 +1,38 @@
+# HG changeset patch
+# User Bob Owen <bobowencode@gmail.com>
+# Date 1563194469 -3600
+# Mon Jul 15 13:41:09 2019 +0100
+# Node ID 6d4e1a08b36e4191bd5ba7a338965f42f09162a6
+# Parent 7d9b5d8c9b9b36b135237292785537fc13f40226
+Bug 1564899: Make CloseHandleWrapper CHECK a DCHECK on non-Nightly builds. r=handyman!
+
+This is because we are hitting it frequently during PolicyBase::OnJobEmpty and
+currently we can't work out how this can happen.
+
+diff --git a/security/sandbox/chromium/base/win/scoped_handle_verifier.cc b/security/sandbox/chromium/base/win/scoped_handle_verifier.cc
+--- a/security/sandbox/chromium/base/win/scoped_handle_verifier.cc
++++ b/security/sandbox/chromium/base/win/scoped_handle_verifier.cc
+@@ -65,17 +65,23 @@ ScopedHandleVerifier* ScopedHandleVerifi
+ if (!g_active_verifier)
+ ScopedHandleVerifier::InstallVerifier();
+
+ return g_active_verifier;
+ }
+
+ bool CloseHandleWrapper(HANDLE handle) {
+ if (!::CloseHandle(handle))
++ // Making this DCHECK on non-Nighly as we are hitting this frequently,
++ // looks like we are closing handles twice somehow. See bug 1564899.
++#if defined(NIGHTLY_BUILD)
+ CHECK(false); // CloseHandle failed.
++#else
++ DCHECK(false); // CloseHandle failed.
++#endif
+ return true;
+ }
+
+ // Assigns the g_active_verifier global within the GetLock() lock.
+ // If |existing_verifier| is non-null then |enabled| is ignored.
+ void ThreadSafeAssignOrCreateScopedHandleVerifier(
+ ScopedHandleVerifier* existing_verifier,
+ bool enabled) {
diff --git a/security/sandbox/chromium-shim/patches/after_update/linux_32bit_arg_fixup.patch b/security/sandbox/chromium-shim/patches/after_update/linux_32bit_arg_fixup.patch
new file mode 100644
index 0000000000..5cc66ad09b
--- /dev/null
+++ b/security/sandbox/chromium-shim/patches/after_update/linux_32bit_arg_fixup.patch
@@ -0,0 +1,84 @@
+commit e0a00891b67ec162a17aa241a83b171b313de9fe
+Author: Jed Davis <jld@mozilla.com>
+Date: Mon Apr 18 18:00:10 2022 -0600
+
+ Make the sandbox fix up non-extended 32-bit types.
+
+diff --git a/security/sandbox/chromium/sandbox/linux/bpf_dsl/policy_compiler.cc b/security/sandbox/chromium/sandbox/linux/bpf_dsl/policy_compiler.cc
+index 347304889eae4..b909fc37f6174 100644
+--- a/security/sandbox/chromium/sandbox/linux/bpf_dsl/policy_compiler.cc
++++ b/security/sandbox/chromium/sandbox/linux/bpf_dsl/policy_compiler.cc
+@@ -19,6 +19,7 @@
+ #include "sandbox/linux/bpf_dsl/policy.h"
+ #include "sandbox/linux/bpf_dsl/seccomp_macros.h"
+ #include "sandbox/linux/bpf_dsl/syscall_set.h"
++#include "sandbox/linux/seccomp-bpf/syscall.h"
+ #include "sandbox/linux/system_headers/linux_filter.h"
+ #include "sandbox/linux/system_headers/linux_seccomp.h"
+ #include "sandbox/linux/system_headers/linux_syscalls.h"
+@@ -318,8 +319,7 @@ CodeGen::Node PolicyCompiler::MaskedEqualHalf(int argno,
+ // Special logic for sanity checking the upper 32-bits of 32-bit system
+ // call arguments.
+
+- // TODO(mdempsky): Compile Unexpected64bitArgument() just per program.
+- CodeGen::Node invalid_64bit = Unexpected64bitArgument();
++ CodeGen::Node invalid_64bit = Unexpected64bitArgument(argno);
+
+ const uint32_t upper = SECCOMP_ARG_MSB_IDX(argno);
+ const uint32_t lower = SECCOMP_ARG_LSB_IDX(argno);
+@@ -335,8 +335,13 @@ CodeGen::Node PolicyCompiler::MaskedEqualHalf(int argno,
+ BPF_JMP + BPF_JEQ + BPF_K, 0, passed, invalid_64bit));
+ }
+
+- // On 64-bit platforms, the upper 32-bits may be 0 or ~0; but we only allow
+- // ~0 if the sign bit of the lower 32-bits is set too:
++ // On 64-bit platforms, the ABI (at least on x86_64) allows any value
++ // for the upper half, but to avoid potential vulnerabilties if an
++ // argument is incorrectly tested as a 32-bit type, we require it to be
++ // either zero-extended or sign-extended. That is, the upper 32-bits
++ // may be 0 or ~0; but we only allow ~0 if the sign bit of the lower
++ // 32-bits is set too:
++ //
+ // LDW [upper]
+ // JEQ 0, passed, (next)
+ // JEQ ~0, (next), invalid
+@@ -424,8 +429,18 @@ CodeGen::Node PolicyCompiler::MaskedEqualHalf(int argno,
+ BPF_JMP + BPF_JEQ + BPF_K, value, passed, failed)));
+ }
+
+-CodeGen::Node PolicyCompiler::Unexpected64bitArgument() {
+- return CompileResult(panic_func_("Unexpected 64bit argument detected"));
++CodeGen::Node PolicyCompiler::Unexpected64bitArgument(int argno) {
++ // This situation is unlikely, but possible. Return to userspace,
++ // zero-extend the problematic argument, and re-issue the syscall.
++ return CompileResult(bpf_dsl::Trap(
++ [](const arch_seccomp_data& args_ref, void* aux) -> intptr_t {
++ arch_seccomp_data args = args_ref;
++ int argno = (int)(intptr_t)aux;
++ args.args[argno] &= 0xFFFFFFFF;
++ return Syscall::Call(args.nr, args.args[0], args.args[1], args.args[2],
++ args.args[3], args.args[4], args.args[5]);
++ },
++ (void*)(intptr_t)argno));
+ }
+
+ CodeGen::Node PolicyCompiler::Return(uint32_t ret) {
+diff --git a/security/sandbox/chromium/sandbox/linux/bpf_dsl/policy_compiler.h b/security/sandbox/chromium/sandbox/linux/bpf_dsl/policy_compiler.h
+index 48b1d780d956f..2acf878474a7d 100644
+--- a/security/sandbox/chromium/sandbox/linux/bpf_dsl/policy_compiler.h
++++ b/security/sandbox/chromium/sandbox/linux/bpf_dsl/policy_compiler.h
+@@ -132,9 +132,11 @@ class SANDBOX_EXPORT PolicyCompiler {
+ CodeGen::Node passed,
+ CodeGen::Node failed);
+
+- // Returns the fatal CodeGen::Node that is used to indicate that somebody
+- // attempted to pass a 64bit value in a 32bit system call argument.
+- CodeGen::Node Unexpected64bitArgument();
++ // Returns the CodeGen::Node that is used to handle the case where a
++ // system call argument was expected to be a 32-bit type, but the
++ // value in the 64-bit register doesn't correspond to a
++ // zero-extended or sign-extended 32-bit value.
++ CodeGen::Node Unexpected64bitArgument(int argno);
+
+ const Policy* policy_;
+ TrapRegistry* registry_;
diff --git a/security/sandbox/chromium-shim/patches/after_update/move_shared_memory_duplication_after_initialization.patch b/security/sandbox/chromium-shim/patches/after_update/move_shared_memory_duplication_after_initialization.patch
new file mode 100644
index 0000000000..f8250b788d
--- /dev/null
+++ b/security/sandbox/chromium-shim/patches/after_update/move_shared_memory_duplication_after_initialization.patch
@@ -0,0 +1,94 @@
+# HG changeset patch
+# User Bob Owen <bobowencode@gmail.com>
+# Date 1577387989 0
+# Thu Dec 26 19:19:49 2019 +0000
+# Node ID 32adf437117bdca54be4959813acbb604f65137f
+# Parent 214214029beb6cca606e11ba519d11cc7dbb37af
+Bug 1605867: Don't duplicate IPC shared memory when we might fail to launch the process correctly. r=handyman
+
+Differential Revision: https://phabricator.services.mozilla.com/D58271
+
+diff --git a/security/sandbox/chromium/sandbox/win/src/target_process.cc b/security/sandbox/chromium/sandbox/win/src/target_process.cc
+--- a/security/sandbox/chromium/sandbox/win/src/target_process.cc
++++ b/security/sandbox/chromium/sandbox/win/src/target_process.cc
+@@ -286,45 +286,28 @@ ResultCode TargetProcess::Init(Dispatche
+ shared_section_.Set(::CreateFileMappingW(INVALID_HANDLE_VALUE, nullptr,
+ PAGE_READWRITE | SEC_COMMIT, 0,
+ shared_mem_size, nullptr));
+ if (!shared_section_.IsValid()) {
+ *win_error = ::GetLastError();
+ return SBOX_ERROR_CREATE_FILE_MAPPING;
+ }
+
+- DWORD access = FILE_MAP_READ | FILE_MAP_WRITE | SECTION_QUERY;
+- HANDLE target_shared_section;
+- if (!::DuplicateHandle(::GetCurrentProcess(), shared_section_.Get(),
+- sandbox_process_info_.process_handle(),
+- &target_shared_section, access, false, 0)) {
+- *win_error = ::GetLastError();
+- return SBOX_ERROR_DUPLICATE_SHARED_SECTION;
+- }
+-
+ void* shared_memory = ::MapViewOfFile(
+ shared_section_.Get(), FILE_MAP_WRITE | FILE_MAP_READ, 0, 0, 0);
+ if (!shared_memory) {
+ *win_error = ::GetLastError();
+ return SBOX_ERROR_MAP_VIEW_OF_SHARED_SECTION;
+ }
+
+ CopyPolicyToTarget(policy, shared_policy_size,
+ reinterpret_cast<char*>(shared_memory) + shared_IPC_size);
+
+ ResultCode ret;
+ // Set the global variables in the target. These are not used on the broker.
+- g_shared_section = target_shared_section;
+- ret = TransferVariable("g_shared_section", &g_shared_section,
+- sizeof(g_shared_section));
+- g_shared_section = nullptr;
+- if (SBOX_ALL_OK != ret) {
+- *win_error = ::GetLastError();
+- return ret;
+- }
+ g_shared_IPC_size = shared_IPC_size;
+ ret = TransferVariable("g_shared_IPC_size", &g_shared_IPC_size,
+ sizeof(g_shared_IPC_size));
+ g_shared_IPC_size = 0;
+ if (SBOX_ALL_OK != ret) {
+ *win_error = ::GetLastError();
+ return ret;
+ }
+@@ -339,16 +322,34 @@ ResultCode TargetProcess::Init(Dispatche
+
+ ipc_server_.reset(new SharedMemIPCServer(
+ sandbox_process_info_.process_handle(),
+ sandbox_process_info_.process_id(), thread_pool_, ipc_dispatcher));
+
+ if (!ipc_server_->Init(shared_memory, shared_IPC_size, kIPCChannelSize))
+ return SBOX_ERROR_NO_SPACE;
+
++ DWORD access = FILE_MAP_READ | FILE_MAP_WRITE | SECTION_QUERY;
++ HANDLE target_shared_section;
++ if (!::DuplicateHandle(::GetCurrentProcess(), shared_section_.Get(),
++ sandbox_process_info_.process_handle(),
++ &target_shared_section, access, false, 0)) {
++ *win_error = ::GetLastError();
++ return SBOX_ERROR_DUPLICATE_SHARED_SECTION;
++ }
++
++ g_shared_section = target_shared_section;
++ ret = TransferVariable("g_shared_section", &g_shared_section,
++ sizeof(g_shared_section));
++ g_shared_section = nullptr;
++ if (SBOX_ALL_OK != ret) {
++ *win_error = ::GetLastError();
++ return ret;
++ }
++
+ // After this point we cannot use this handle anymore.
+ ::CloseHandle(sandbox_process_info_.TakeThreadHandle());
+
+ return SBOX_ALL_OK;
+ }
+
+ void TargetProcess::Terminate() {
+ if (!sandbox_process_info_.IsValid())
diff --git a/security/sandbox/chromium-shim/patches/after_update/patch_order.txt b/security/sandbox/chromium-shim/patches/after_update/patch_order.txt
new file mode 100644
index 0000000000..4266bee9c0
--- /dev/null
+++ b/security/sandbox/chromium-shim/patches/after_update/patch_order.txt
@@ -0,0 +1,8 @@
+add_interception_logging.patch
+allow_rules_for_network_drive_and_non_file_devices.patch
+add_WOW64_flags_to_allowed_registry_read_flags.patch
+arm64_set_LoaderThreads.patch
+change_to_DCHECK_in_CloseHandleWrapper.patch
+move_shared_memory_duplication_after_initialization.patch
+allow_ntpath_in_SignedPolicy_GenerateRules.patch
+linux_32bit_arg_fixup.patch