Check within target process for policy match on registry intercepts before sending to the broker process.
BUG= Review URL: https://codereview.chromium.org/700373005 Cr-Commit-Position: refs/heads/master@{#303773}
This commit is contained in:
sandbox/win/src
@ -6,6 +6,8 @@
|
||||
|
||||
#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"
|
||||
@ -56,6 +58,29 @@ NTSTATUS WINAPI TargetNtCreateKey(NtCreateKeyFunction orig_CreateKey,
|
||||
if (!NT_SUCCESS(ret) || NULL == name)
|
||||
break;
|
||||
|
||||
uint32 desired_access_uint32 = desired_access;
|
||||
CountedParameterSet<OpenKey> params;
|
||||
params[OpenKey::ACCESS] = ParamPickerMake(desired_access_uint32);
|
||||
|
||||
wchar_t* full_name = NULL;
|
||||
|
||||
if (root_directory) {
|
||||
ret = sandbox::AllocAndGetFullPath(root_directory, name, &full_name);
|
||||
if (!NT_SUCCESS(ret) || NULL == full_name)
|
||||
break;
|
||||
params[OpenKey::NAME] = ParamPickerMake(full_name);
|
||||
} else {
|
||||
params[OpenKey::NAME] = ParamPickerMake(name);
|
||||
}
|
||||
|
||||
bool query_broker = QueryBroker(IPC_NTCREATEKEY_TAG, params.GetBase());
|
||||
|
||||
if (full_name != NULL)
|
||||
operator delete(full_name, NT_ALLOC);
|
||||
|
||||
if (!query_broker)
|
||||
break;
|
||||
|
||||
SharedMemIPCClient ipc(memory);
|
||||
CrossCallReturn answer = {0};
|
||||
|
||||
@ -115,6 +140,29 @@ NTSTATUS WINAPI CommonNtOpenKey(NTSTATUS status, PHANDLE key,
|
||||
if (!NT_SUCCESS(ret) || NULL == name)
|
||||
break;
|
||||
|
||||
uint32 desired_access_uint32 = desired_access;
|
||||
CountedParameterSet<OpenKey> params;
|
||||
params[OpenKey::ACCESS] = ParamPickerMake(desired_access_uint32);
|
||||
|
||||
wchar_t* full_name = NULL;
|
||||
|
||||
if (root_directory) {
|
||||
ret = sandbox::AllocAndGetFullPath(root_directory, name, &full_name);
|
||||
if (!NT_SUCCESS(ret) || NULL == full_name)
|
||||
break;
|
||||
params[OpenKey::NAME] = ParamPickerMake(full_name);
|
||||
} else {
|
||||
params[OpenKey::NAME] = ParamPickerMake(name);
|
||||
}
|
||||
|
||||
bool query_broker = QueryBroker(IPC_NTOPENKEY_TAG, params.GetBase());
|
||||
|
||||
if (full_name != NULL)
|
||||
operator delete(full_name, NT_ALLOC);
|
||||
|
||||
if (!query_broker)
|
||||
break;
|
||||
|
||||
SharedMemIPCClient ipc(memory);
|
||||
CrossCallReturn answer = {0};
|
||||
ResultCode code = CrossCall(ipc, IPC_NTOPENKEY_TAG, name, attributes,
|
||||
|
@ -215,6 +215,78 @@ NTSTATUS CopyData(void* destination, const void* source, size_t bytes) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
NTSTATUS AllocAndGetFullPath(HANDLE root,
|
||||
wchar_t* path,
|
||||
wchar_t** full_path) {
|
||||
if (!InitHeap())
|
||||
return STATUS_NO_MEMORY;
|
||||
|
||||
DCHECK_NT(full_path);
|
||||
DCHECK_NT(path);
|
||||
*full_path = NULL;
|
||||
OBJECT_NAME_INFORMATION* handle_name = NULL;
|
||||
NTSTATUS ret = STATUS_UNSUCCESSFUL;
|
||||
__try {
|
||||
do {
|
||||
static NtQueryObjectFunction NtQueryObject = NULL;
|
||||
if (!NtQueryObject)
|
||||
ResolveNTFunctionPtr("NtQueryObject", &NtQueryObject);
|
||||
|
||||
ULONG size = 0;
|
||||
// Query the name information a first time to get the size of the name.
|
||||
ret = NtQueryObject(root, ObjectNameInformation, NULL, 0, &size);
|
||||
|
||||
if (size) {
|
||||
handle_name = reinterpret_cast<OBJECT_NAME_INFORMATION*>(
|
||||
new(NT_ALLOC) BYTE[size]);
|
||||
|
||||
// Query the name information a second time to get the name of the
|
||||
// object referenced by the handle.
|
||||
ret = NtQueryObject(root, ObjectNameInformation, handle_name, size,
|
||||
&size);
|
||||
}
|
||||
|
||||
if (STATUS_SUCCESS != ret)
|
||||
break;
|
||||
|
||||
// Space for path + '\' + name + '\0'.
|
||||
size_t name_length = handle_name->ObjectName.Length +
|
||||
(wcslen(path) + 2) * sizeof(wchar_t);
|
||||
*full_path = new(NT_ALLOC) wchar_t[name_length/sizeof(wchar_t)];
|
||||
if (NULL == *full_path)
|
||||
break;
|
||||
wchar_t* off = *full_path;
|
||||
ret = CopyData(off, handle_name->ObjectName.Buffer,
|
||||
handle_name->ObjectName.Length);
|
||||
if (!NT_SUCCESS(ret))
|
||||
break;
|
||||
off += handle_name->ObjectName.Length / sizeof(wchar_t);
|
||||
*off = L'\\';
|
||||
off += 1;
|
||||
ret = CopyData(off, path, wcslen(path) * sizeof(wchar_t));
|
||||
if (!NT_SUCCESS(ret))
|
||||
break;
|
||||
off += wcslen(path);
|
||||
*off = L'\0';
|
||||
} while (false);
|
||||
} __except(EXCEPTION_EXECUTE_HANDLER) {
|
||||
ret = GetExceptionCode();
|
||||
}
|
||||
|
||||
if (!NT_SUCCESS(ret)) {
|
||||
if (*full_path) {
|
||||
operator delete(*full_path, NT_ALLOC);
|
||||
*full_path = NULL;
|
||||
}
|
||||
if (handle_name) {
|
||||
operator delete(handle_name, NT_ALLOC);
|
||||
handle_name = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Hacky code... replace with AllocAndCopyObjectAttributes.
|
||||
NTSTATUS AllocAndCopyName(const OBJECT_ATTRIBUTES* in_object,
|
||||
wchar_t** out_name, uint32* attributes,
|
||||
|
@ -103,6 +103,11 @@ NTSTATUS CopyData(void* destination, const void* source, size_t bytes);
|
||||
NTSTATUS AllocAndCopyName(const OBJECT_ATTRIBUTES* in_object,
|
||||
wchar_t** out_name, uint32* attributes, HANDLE* root);
|
||||
|
||||
// Determine full path name from object root and path.
|
||||
NTSTATUS AllocAndGetFullPath(HANDLE root,
|
||||
wchar_t* path,
|
||||
wchar_t** full_path);
|
||||
|
||||
// Initializes our ntdll level heap
|
||||
bool InitHeap();
|
||||
|
||||
|
Reference in New Issue
Block a user