Bug 1639030 - Part 3: Roll-up patch to apply remaining mozilla changes to chromium sandbox. r=bobowen

This commit applies patches under security/sandbox/chromium-shim/patches/after_update/.

Differential Revision: https://phabricator.services.mozilla.com/D79561
This commit is contained in:
Toshihito Kikuchi 2020-07-03 19:15:53 +00:00
Родитель 617828f9d5
Коммит e77485c628
13 изменённых файлов: 252 добавлений и 77 удалений

Просмотреть файл

@ -71,7 +71,13 @@ ScopedHandleVerifier* ScopedHandleVerifier::Get() {
bool CloseHandleWrapper(HANDLE handle) { bool CloseHandleWrapper(HANDLE handle) {
if (!::CloseHandle(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. CHECK(false); // CloseHandle failed.
#else
DCHECK(false); // CloseHandle failed.
#endif
return true; return true;
} }

Просмотреть файл

@ -17,6 +17,8 @@
#include "sandbox/win/src/sandbox.h" #include "sandbox/win/src/sandbox.h"
#include "sandbox/win/src/sandbox_nt_util.h" #include "sandbox/win/src/sandbox_nt_util.h"
#include "mozilla/sandboxing/permissionsService.h"
namespace sandbox { namespace sandbox {
FilesystemDispatcher::FilesystemDispatcher(PolicyBase* policy_base) FilesystemDispatcher::FilesystemDispatcher(PolicyBase* policy_base)
@ -110,6 +112,16 @@ bool FilesystemDispatcher::NtCreateFile(IPCInfo* ipc,
// knows what to do. // knows what to do.
EvalResult result = EvalResult result =
policy_base_->EvalPolicy(IpcTag::NTCREATEFILE, params.GetBase()); policy_base_->EvalPolicy(IpcTag::NTCREATEFILE, 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; HANDLE handle;
ULONG_PTR io_information = 0; ULONG_PTR io_information = 0;
NTSTATUS nt_status; NTSTATUS nt_status;
@ -155,6 +167,16 @@ bool FilesystemDispatcher::NtOpenFile(IPCInfo* ipc,
// knows what to do. // knows what to do.
EvalResult result = EvalResult result =
policy_base_->EvalPolicy(IpcTag::NTOPENFILE, params.GetBase()); policy_base_->EvalPolicy(IpcTag::NTOPENFILE, 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; HANDLE handle;
ULONG_PTR io_information = 0; ULONG_PTR io_information = 0;
NTSTATUS nt_status; NTSTATUS nt_status;
@ -196,6 +218,15 @@ bool FilesystemDispatcher::NtQueryAttributesFile(IPCInfo* ipc,
EvalResult result = EvalResult result =
policy_base_->EvalPolicy(IpcTag::NTQUERYATTRIBUTESFILE, params.GetBase()); policy_base_->EvalPolicy(IpcTag::NTQUERYATTRIBUTESFILE, 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 = FILE_BASIC_INFORMATION* information =
reinterpret_cast<FILE_BASIC_INFORMATION*>(info->Buffer()); reinterpret_cast<FILE_BASIC_INFORMATION*>(info->Buffer());
NTSTATUS nt_status; NTSTATUS nt_status;
@ -236,6 +267,15 @@ bool FilesystemDispatcher::NtQueryFullAttributesFile(IPCInfo* ipc,
EvalResult result = policy_base_->EvalPolicy( EvalResult result = policy_base_->EvalPolicy(
IpcTag::NTQUERYFULLATTRIBUTESFILE, params.GetBase()); IpcTag::NTQUERYFULLATTRIBUTESFILE, 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 = FILE_NETWORK_OPEN_INFORMATION* information =
reinterpret_cast<FILE_NETWORK_OPEN_INFORMATION*>(info->Buffer()); reinterpret_cast<FILE_NETWORK_OPEN_INFORMATION*>(info->Buffer());
NTSTATUS nt_status; NTSTATUS nt_status;
@ -289,6 +329,16 @@ bool FilesystemDispatcher::NtSetInformationFile(IPCInfo* ipc,
EvalResult result = EvalResult result =
policy_base_->EvalPolicy(IpcTag::NTSETINFO_RENAME, params.GetBase()); policy_base_->EvalPolicy(IpcTag::NTSETINFO_RENAME, 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 = IO_STATUS_BLOCK* io_status =
reinterpret_cast<IO_STATUS_BLOCK*>(status->Buffer()); reinterpret_cast<IO_STATUS_BLOCK*>(status->Buffer());
NTSTATUS nt_status; NTSTATUS nt_status;

Просмотреть файл

@ -15,6 +15,7 @@
#include "sandbox/win/src/sandbox_nt_util.h" #include "sandbox/win/src/sandbox_nt_util.h"
#include "sandbox/win/src/sharedmem_ipc_client.h" #include "sandbox/win/src/sharedmem_ipc_client.h"
#include "sandbox/win/src/target_services.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 // This status occurs when trying to access a network share on the machine from
// which it is shared. // which it is shared.
@ -42,6 +43,10 @@ NTSTATUS WINAPI TargetNtCreateFile(NtCreateFileFunction orig_CreateFile,
STATUS_NETWORK_OPEN_RESTRICTION != status) STATUS_NETWORK_OPEN_RESTRICTION != status)
return 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. // We don't trust that the IPC can work this early.
if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled()) if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
return status; return status;
@ -75,9 +80,6 @@ NTSTATUS WINAPI TargetNtCreateFile(NtCreateFileFunction orig_CreateFile,
params[OpenFile::OPTIONS] = ParamPickerMake(options_uint32); params[OpenFile::OPTIONS] = ParamPickerMake(options_uint32);
params[OpenFile::BROKER] = ParamPickerMake(broker); params[OpenFile::BROKER] = ParamPickerMake(broker);
if (!QueryBroker(IpcTag::NTCREATEFILE, params.GetBase()))
break;
SharedMemIPCClient ipc(memory); SharedMemIPCClient ipc(memory);
CrossCallReturn answer = {0}; CrossCallReturn answer = {0};
// The following call must match in the parameters with // The following call must match in the parameters with
@ -101,6 +103,9 @@ NTSTATUS WINAPI TargetNtCreateFile(NtCreateFileFunction orig_CreateFile,
} __except (EXCEPTION_EXECUTE_HANDLER) { } __except (EXCEPTION_EXECUTE_HANDLER) {
break; break;
} }
mozilla::sandboxing::LogAllowed("NtCreateFile",
object_attributes->ObjectName->Buffer,
object_attributes->ObjectName->Length);
} while (false); } while (false);
return status; return status;
@ -120,6 +125,10 @@ NTSTATUS WINAPI TargetNtOpenFile(NtOpenFileFunction orig_OpenFile,
STATUS_NETWORK_OPEN_RESTRICTION != status) STATUS_NETWORK_OPEN_RESTRICTION != status)
return 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. // We don't trust that the IPC can work this early.
if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled()) if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
return status; return status;
@ -153,9 +162,6 @@ NTSTATUS WINAPI TargetNtOpenFile(NtOpenFileFunction orig_OpenFile,
params[OpenFile::OPTIONS] = ParamPickerMake(options_uint32); params[OpenFile::OPTIONS] = ParamPickerMake(options_uint32);
params[OpenFile::BROKER] = ParamPickerMake(broker); params[OpenFile::BROKER] = ParamPickerMake(broker);
if (!QueryBroker(IpcTag::NTOPENFILE, params.GetBase()))
break;
SharedMemIPCClient ipc(memory); SharedMemIPCClient ipc(memory);
CrossCallReturn answer = {0}; CrossCallReturn answer = {0};
ResultCode code = ResultCode code =
@ -176,6 +182,9 @@ NTSTATUS WINAPI TargetNtOpenFile(NtOpenFileFunction orig_OpenFile,
} __except (EXCEPTION_EXECUTE_HANDLER) { } __except (EXCEPTION_EXECUTE_HANDLER) {
break; break;
} }
mozilla::sandboxing::LogAllowed("NtOpenFile",
object_attributes->ObjectName->Buffer,
object_attributes->ObjectName->Length);
} while (false); } while (false);
return status; return status;
@ -191,6 +200,10 @@ TargetNtQueryAttributesFile(NtQueryAttributesFileFunction orig_QueryAttributes,
STATUS_NETWORK_OPEN_RESTRICTION != status) STATUS_NETWORK_OPEN_RESTRICTION != status)
return 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. // We don't trust that the IPC can work this early.
if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled()) if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
return status; return status;
@ -219,9 +232,6 @@ TargetNtQueryAttributesFile(NtQueryAttributesFileFunction orig_QueryAttributes,
params[FileName::NAME] = ParamPickerMake(name_ptr); params[FileName::NAME] = ParamPickerMake(name_ptr);
params[FileName::BROKER] = ParamPickerMake(broker); params[FileName::BROKER] = ParamPickerMake(broker);
if (!QueryBroker(IpcTag::NTQUERYATTRIBUTESFILE, params.GetBase()))
break;
SharedMemIPCClient ipc(memory); SharedMemIPCClient ipc(memory);
CrossCallReturn answer = {0}; CrossCallReturn answer = {0};
ResultCode code = CrossCall(ipc, IpcTag::NTQUERYATTRIBUTESFILE, name.get(), ResultCode code = CrossCall(ipc, IpcTag::NTQUERYATTRIBUTESFILE, name.get(),
@ -232,6 +242,9 @@ TargetNtQueryAttributesFile(NtQueryAttributesFileFunction orig_QueryAttributes,
status = answer.nt_status; status = answer.nt_status;
mozilla::sandboxing::LogAllowed("NtQueryAttributesFile",
object_attributes->ObjectName->Buffer,
object_attributes->ObjectName->Length);
} while (false); } while (false);
return status; return status;
@ -248,6 +261,10 @@ NTSTATUS WINAPI TargetNtQueryFullAttributesFile(
STATUS_NETWORK_OPEN_RESTRICTION != status) STATUS_NETWORK_OPEN_RESTRICTION != status)
return 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. // We don't trust that the IPC can work this early.
if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled()) if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
return status; return status;
@ -277,9 +294,6 @@ NTSTATUS WINAPI TargetNtQueryFullAttributesFile(
params[FileName::NAME] = ParamPickerMake(name_ptr); params[FileName::NAME] = ParamPickerMake(name_ptr);
params[FileName::BROKER] = ParamPickerMake(broker); params[FileName::BROKER] = ParamPickerMake(broker);
if (!QueryBroker(IpcTag::NTQUERYFULLATTRIBUTESFILE, params.GetBase()))
break;
SharedMemIPCClient ipc(memory); SharedMemIPCClient ipc(memory);
CrossCallReturn answer = {0}; CrossCallReturn answer = {0};
ResultCode code = CrossCall(ipc, IpcTag::NTQUERYFULLATTRIBUTESFILE, ResultCode code = CrossCall(ipc, IpcTag::NTQUERYFULLATTRIBUTESFILE,
@ -289,6 +303,10 @@ NTSTATUS WINAPI TargetNtQueryFullAttributesFile(
break; break;
status = answer.nt_status; status = answer.nt_status;
mozilla::sandboxing::LogAllowed("NtQueryFullAttributesFile",
object_attributes->ObjectName->Buffer,
object_attributes->ObjectName->Length);
} while (false); } while (false);
return status; return status;
@ -307,6 +325,8 @@ TargetNtSetInformationFile(NtSetInformationFileFunction orig_SetInformationFile,
if (STATUS_ACCESS_DENIED != status) if (STATUS_ACCESS_DENIED != status)
return status; return status;
mozilla::sandboxing::LogBlocked("NtSetInformationFile");
// We don't trust that the IPC can work this early. // We don't trust that the IPC can work this early.
if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled()) if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
return status; return status;
@ -353,9 +373,6 @@ TargetNtSetInformationFile(NtSetInformationFileFunction orig_SetInformationFile,
params[FileName::NAME] = ParamPickerMake(name_ptr); params[FileName::NAME] = ParamPickerMake(name_ptr);
params[FileName::BROKER] = ParamPickerMake(broker); params[FileName::BROKER] = ParamPickerMake(broker);
if (!QueryBroker(IpcTag::NTSETINFO_RENAME, params.GetBase()))
break;
InOutCountedBuffer io_status_buffer(io_status, sizeof(IO_STATUS_BLOCK)); InOutCountedBuffer io_status_buffer(io_status, sizeof(IO_STATUS_BLOCK));
// This is actually not an InOut buffer, only In, but using InOut facility // This is actually not an InOut buffer, only In, but using InOut facility
// really helps to simplify the code. // really helps to simplify the code.
@ -371,6 +388,7 @@ TargetNtSetInformationFile(NtSetInformationFileFunction orig_SetInformationFile,
break; break;
status = answer.nt_status; status = answer.nt_status;
mozilla::sandboxing::LogAllowed("NtSetInformationFile");
} while (false); } while (false);
return status; return status;

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

@ -15,6 +15,7 @@
#include "sandbox/win/src/sandbox_nt_util.h" #include "sandbox/win/src/sandbox_nt_util.h"
#include "sandbox/win/src/sharedmem_ipc_client.h" #include "sandbox/win/src/sharedmem_ipc_client.h"
#include "sandbox/win/src/target_services.h" #include "sandbox/win/src/target_services.h"
#include "mozilla/sandboxing/sandboxLogging.h"
namespace sandbox { namespace sandbox {
@ -32,6 +33,7 @@ NTSTATUS WINAPI TargetNtOpenThread(NtOpenThreadFunction orig_OpenThread,
if (NT_SUCCESS(status)) if (NT_SUCCESS(status))
return status; return status;
mozilla::sandboxing::LogBlocked("NtOpenThread");
do { do {
if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled()) if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
break; break;
@ -96,6 +98,7 @@ NTSTATUS WINAPI TargetNtOpenThread(NtOpenThreadFunction orig_OpenThread,
break; break;
} }
mozilla::sandboxing::LogAllowed("NtOpenThread");
return answer.nt_status; return answer.nt_status;
} while (false); } while (false);
@ -181,6 +184,7 @@ TargetNtOpenProcessToken(NtOpenProcessTokenFunction orig_OpenProcessToken,
if (NT_SUCCESS(status)) if (NT_SUCCESS(status))
return status; return status;
mozilla::sandboxing::LogBlocked("NtOpenProcessToken");
do { do {
if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled()) if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
break; break;
@ -212,6 +216,7 @@ TargetNtOpenProcessToken(NtOpenProcessTokenFunction orig_OpenProcessToken,
break; break;
} }
mozilla::sandboxing::LogAllowed("NtOpenProcessToken");
return answer.nt_status; return answer.nt_status;
} while (false); } while (false);
@ -229,6 +234,7 @@ TargetNtOpenProcessTokenEx(NtOpenProcessTokenExFunction orig_OpenProcessTokenEx,
if (NT_SUCCESS(status)) if (NT_SUCCESS(status))
return status; return status;
mozilla::sandboxing::LogBlocked("NtOpenProcessTokenEx");
do { do {
if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled()) if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
break; break;
@ -260,6 +266,7 @@ TargetNtOpenProcessTokenEx(NtOpenProcessTokenExFunction orig_OpenProcessTokenEx,
break; break;
} }
mozilla::sandboxing::LogAllowed("NtOpenProcessTokenEx");
return answer.nt_status; return answer.nt_status;
} while (false); } while (false);
@ -285,6 +292,8 @@ BOOL WINAPI TargetCreateProcessW(CreateProcessWFunction orig_CreateProcessW,
return true; return true;
} }
mozilla::sandboxing::LogBlocked("CreateProcessW", application_name);
// We don't trust that the IPC can work this early. // We don't trust that the IPC can work this early.
if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled()) if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
return false; return false;
@ -325,6 +334,7 @@ BOOL WINAPI TargetCreateProcessW(CreateProcessWFunction orig_CreateProcessW,
if (ERROR_SUCCESS != answer.win32_result) if (ERROR_SUCCESS != answer.win32_result)
return false; return false;
mozilla::sandboxing::LogAllowed("CreateProcessW", application_name);
return true; return true;
} while (false); } while (false);
@ -351,6 +361,8 @@ BOOL WINAPI TargetCreateProcessA(CreateProcessAFunction orig_CreateProcessA,
return true; return true;
} }
mozilla::sandboxing::LogBlocked("CreateProcessA", application_name);
// We don't trust that the IPC can work this early. // We don't trust that the IPC can work this early.
if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled()) if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
return false; return false;
@ -425,6 +437,7 @@ BOOL WINAPI TargetCreateProcessA(CreateProcessAFunction orig_CreateProcessA,
if (ERROR_SUCCESS != answer.win32_result) if (ERROR_SUCCESS != answer.win32_result)
return false; return false;
mozilla::sandboxing::LogAllowed("CreateProcessA", application_name);
return true; return true;
} while (false); } while (false);

Просмотреть файл

@ -14,6 +14,7 @@
#include "sandbox/win/src/sandbox_nt_util.h" #include "sandbox/win/src/sandbox_nt_util.h"
#include "sandbox/win/src/sharedmem_ipc_client.h" #include "sandbox/win/src/sharedmem_ipc_client.h"
#include "sandbox/win/src/target_services.h" #include "sandbox/win/src/target_services.h"
#include "mozilla/sandboxing/sandboxLogging.h"
namespace sandbox { namespace sandbox {
@ -32,6 +33,12 @@ NTSTATUS WINAPI TargetNtCreateKey(NtCreateKeyFunction orig_CreateKey,
if (NT_SUCCESS(status)) if (NT_SUCCESS(status))
return 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. // We don't trust that the IPC can work this early.
if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled()) if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
return status; return status;
@ -119,6 +126,9 @@ NTSTATUS WINAPI TargetNtCreateKey(NtCreateKeyFunction orig_CreateKey,
} __except (EXCEPTION_EXECUTE_HANDLER) { } __except (EXCEPTION_EXECUTE_HANDLER) {
break; break;
} }
mozilla::sandboxing::LogAllowed("NtCreateKey",
object_attributes->ObjectName->Buffer,
object_attributes->ObjectName->Length);
} while (false); } while (false);
return status; return status;
@ -198,6 +208,9 @@ NTSTATUS WINAPI CommonNtOpenKey(NTSTATUS status,
} __except (EXCEPTION_EXECUTE_HANDLER) { } __except (EXCEPTION_EXECUTE_HANDLER) {
break; break;
} }
mozilla::sandboxing::LogAllowed("NtOpenKey[Ex]",
object_attributes->ObjectName->Buffer,
object_attributes->ObjectName->Length);
} while (false); } while (false);
return status; return status;
@ -212,6 +225,12 @@ NTSTATUS WINAPI TargetNtOpenKey(NtOpenKeyFunction orig_OpenKey,
if (NT_SUCCESS(status)) if (NT_SUCCESS(status))
return 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); return CommonNtOpenKey(status, key, desired_access, object_attributes);
} }
@ -230,6 +249,12 @@ NTSTATUS WINAPI TargetNtOpenKeyEx(NtOpenKeyExFunction orig_OpenKeyEx,
if (NT_SUCCESS(status) || open_options != 0) if (NT_SUCCESS(status) || open_options != 0)
return status; 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); return CommonNtOpenKey(status, key, desired_access, object_attributes);
} }

Просмотреть файл

@ -20,7 +20,8 @@ namespace {
static const uint32_t kAllowedRegFlags = static const uint32_t kAllowedRegFlags =
KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS | KEY_NOTIFY | KEY_READ | 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 // Opens the key referenced by |obj_attributes| with |access| and
// checks what permission was given. Remove the WRITE flags and update // checks what permission was given. Remove the WRITE flags and update

Просмотреть файл

@ -14,6 +14,7 @@
#include "sandbox/win/src/sandbox_nt_util.h" #include "sandbox/win/src/sandbox_nt_util.h"
#include "sandbox/win/src/sharedmem_ipc_client.h" #include "sandbox/win/src/sharedmem_ipc_client.h"
#include "sandbox/win/src/target_services.h" #include "sandbox/win/src/target_services.h"
#include "mozilla/sandboxing/sandboxLogging.h"
namespace sandbox { namespace sandbox {
@ -42,6 +43,8 @@ TargetNtCreateSection(NtCreateSectionFunction orig_CreateSection,
if (allocation_attributes != SEC_IMAGE) if (allocation_attributes != SEC_IMAGE)
break; break;
mozilla::sandboxing::LogBlocked("NtCreateSection");
// IPC must be fully started. // IPC must be fully started.
void* memory = GetGlobalIPCMemory(); void* memory = GetGlobalIPCMemory();
if (!memory) if (!memory)
@ -78,6 +81,7 @@ TargetNtCreateSection(NtCreateSectionFunction orig_CreateSection,
__try { __try {
*section_handle = answer.handle; *section_handle = answer.handle;
mozilla::sandboxing::LogAllowed("NtCreateSection");
return answer.nt_status; return answer.nt_status;
} __except (EXCEPTION_EXECUTE_HANDLER) { } __except (EXCEPTION_EXECUTE_HANDLER) {
break; break;

Просмотреть файл

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

Просмотреть файл

@ -291,15 +291,6 @@ ResultCode TargetProcess::Init(Dispatcher* ipc_dispatcher,
return SBOX_ERROR_CREATE_FILE_MAPPING; 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( void* shared_memory = ::MapViewOfFile(
shared_section_.Get(), FILE_MAP_WRITE | FILE_MAP_READ, 0, 0, 0); shared_section_.Get(), FILE_MAP_WRITE | FILE_MAP_READ, 0, 0, 0);
if (!shared_memory) { if (!shared_memory) {
@ -312,14 +303,6 @@ ResultCode TargetProcess::Init(Dispatcher* ipc_dispatcher,
ResultCode ret; ResultCode ret;
// Set the global variables in the target. These are not used on the broker. // 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; g_shared_IPC_size = shared_IPC_size;
ret = TransferVariable("g_shared_IPC_size", &g_shared_IPC_size, ret = TransferVariable("g_shared_IPC_size", &g_shared_IPC_size,
sizeof(g_shared_IPC_size)); sizeof(g_shared_IPC_size));
@ -344,6 +327,24 @@ ResultCode TargetProcess::Init(Dispatcher* ipc_dispatcher,
if (!ipc_server_->Init(shared_memory, shared_IPC_size, kIPCChannelSize)) if (!ipc_server_->Init(shared_memory, shared_IPC_size, kIPCChannelSize))
return SBOX_ERROR_NO_SPACE; 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. // After this point we cannot use this handle anymore.
::CloseHandle(sandbox_process_info_.TakeThreadHandle()); ::CloseHandle(sandbox_process_info_.TakeThreadHandle());

Просмотреть файл

@ -199,6 +199,7 @@ bool ResolveRegistryName(std::wstring name, std::wstring* resolved_name) {
// \??\c:\some\foo\bar // \??\c:\some\foo\bar
// \Device\HarddiskVolume0\some\foo\bar // \Device\HarddiskVolume0\some\foo\bar
// \??\HarddiskVolume0\some\foo\bar // \??\HarddiskVolume0\some\foo\bar
// \??\UNC\SERVER\Share\some\foo\bar
DWORD IsReparsePoint(const std::wstring& full_path) { DWORD IsReparsePoint(const std::wstring& full_path) {
// Check if it's a pipe. We can't query the attributes of a pipe. // Check if it's a pipe. We can't query the attributes of a pipe.
if (IsPipe(full_path)) if (IsPipe(full_path))
@ -212,28 +213,33 @@ DWORD IsReparsePoint(const std::wstring& full_path) {
if (!has_drive && !is_device_path && !nt_path) if (!has_drive && !is_device_path && !nt_path)
return ERROR_INVALID_NAME; return ERROR_INVALID_NAME;
bool added_implied_device = false;
if (!has_drive) { if (!has_drive) {
path = std::wstring(kNTDotPrefix) + path; // Add Win32 device namespace prefix, required for some Windows APIs.
added_implied_device = true; path.insert(0, kNTDotPrefix);
} }
std::wstring::size_type last_pos = std::wstring::npos; // Ensure that volume path matches start of path.
bool passed_once = false; 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 { do {
path = path.substr(0, last_pos);
DWORD attributes = ::GetFileAttributes(path.c_str()); DWORD attributes = ::GetFileAttributes(path.c_str());
if (INVALID_FILE_ATTRIBUTES == attributes) { if (INVALID_FILE_ATTRIBUTES == attributes) {
DWORD error = ::GetLastError(); DWORD error = ::GetLastError();
if (error != ERROR_FILE_NOT_FOUND && error != ERROR_PATH_NOT_FOUND && if (error != ERROR_FILE_NOT_FOUND && error != ERROR_PATH_NOT_FOUND &&
error != ERROR_INVALID_FUNCTION &&
error != ERROR_INVALID_NAME) { error != ERROR_INVALID_NAME) {
// Unexpected error. // Unexpected error.
if (passed_once && added_implied_device &&
(path.rfind(L'\\') == kNTDotPrefixLen - 1)) {
break;
}
return error; return error;
} }
} else if (FILE_ATTRIBUTE_REPARSE_POINT & attributes) { } else if (FILE_ATTRIBUTE_REPARSE_POINT & attributes) {
@ -241,9 +247,8 @@ DWORD IsReparsePoint(const std::wstring& full_path) {
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
passed_once = true; path.resize(path.rfind(L'\\'));
last_pos = path.rfind(L'\\'); } while (path.size() > vol_path_len); // Skip root dir.
} while (last_pos > 2); // Skip root dir.
return ERROR_NOT_A_REPARSE_POINT; return ERROR_NOT_A_REPARSE_POINT;
} }
@ -263,11 +268,11 @@ bool SameObject(HANDLE handle, const wchar_t* full_path) {
DCHECK_NT(!path.empty()); DCHECK_NT(!path.empty());
// This may end with a backslash. // This may end with a backslash.
const wchar_t kBackslash = '\\'; if (path.back() == L'\\') {
if (path.back() == kBackslash) path.pop_back();
path = path.substr(0, path.length() - 1); }
// Perfect match (case-insesitive check). // Perfect match (case-insensitive check).
if (EqualPath(actual_path, path)) if (EqualPath(actual_path, path))
return true; return true;
@ -276,40 +281,44 @@ bool SameObject(HANDLE handle, const wchar_t* full_path) {
if (!has_drive && nt_path) { if (!has_drive && nt_path) {
std::wstring simple_actual_path; std::wstring simple_actual_path;
if (!IsDevicePath(actual_path, &simple_actual_path)) if (IsDevicePath(path, &path)) {
return false; if (IsDevicePath(actual_path, &simple_actual_path)) {
// Perfect match (case-insensitive check).
// Perfect match (case-insesitive check). return (EqualPath(simple_actual_path, path));
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; return false;
}
// We only need 3 chars, but let's alloc a buffer for four. size_t vol_path_len = wcslen(vol_path);
wchar_t drive[4] = {0}; base::string16 nt_vol;
wchar_t vol_name[MAX_PATH]; if (!GetNtPathFromWin32Path(vol_path, &nt_vol)) {
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)
return false; return false;
}
// Ignore the nulls at the end.
vol_length = static_cast<DWORD>(wcslen(vol_name));
// The two paths should be the same length. // 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; return false;
}
// Check up to the drive letter. // Check the volume matches.
if (!EqualPath(actual_path, vol_name, vol_length)) if (!EqualPath(actual_path, nt_vol.c_str(), nt_vol.size())) {
return false; return false;
}
// Check the path after the drive letter. // Check the path after the volume matches.
if (!EqualPath(actual_path, vol_length, path, 2)) if (!EqualPath(actual_path, nt_vol.size(), path, vol_path_len)) {
return false; return false;
}
return true; return true;
} }
@ -452,10 +461,11 @@ bool GetNtPathFromWin32Path(const std::wstring& path, std::wstring* nt_path) {
bool WriteProtectedChildMemory(HANDLE child_process, bool WriteProtectedChildMemory(HANDLE child_process,
void* address, void* address,
const void* buffer, const void* buffer,
size_t length) { size_t length,
DWORD writeProtection) {
// First, remove the protections. // First, remove the protections.
DWORD old_protection; DWORD old_protection;
if (!::VirtualProtectEx(child_process, address, length, PAGE_WRITECOPY, if (!::VirtualProtectEx(child_process, address, length, writeProtection,
&old_protection)) &old_protection))
return false; return false;
@ -540,6 +550,30 @@ void* GetProcessBaseAddress(HANDLE process) {
if (magic[0] != 'M' || magic[1] != 'Z') if (magic[0] != 'M' || magic[1] != 'Z')
return nullptr; 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; return base_address;
} }

Просмотреть файл

@ -116,7 +116,8 @@ bool ResolveRegistryName(std::wstring name, std::wstring* resolved_name);
bool WriteProtectedChildMemory(HANDLE child_process, bool WriteProtectedChildMemory(HANDLE child_process,
void* address, void* address,
const void* buffer, const void* buffer,
size_t length); size_t length,
DWORD writeProtection = PAGE_WRITECOPY);
// Allocates |buffer_bytes| in child (PAGE_READWRITE) and copies data // Allocates |buffer_bytes| in child (PAGE_READWRITE) and copies data
// from |local_buffer| in this process into |child|. |remote_buffer| // from |local_buffer| in this process into |child|. |remote_buffer|