15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/filesystem_interception.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/crosscall_client.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/ipc_tags.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/policy_params.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/policy_target.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/sandbox_factory.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/sandbox_nt_util.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/sharedmem_ipc_client.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/target_services.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace sandbox {
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NTSTATUS WINAPI TargetNtCreateFile(NtCreateFileFunction orig_CreateFile,
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   PHANDLE file, ACCESS_MASK desired_access,
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   POBJECT_ATTRIBUTES object_attributes,
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   PIO_STATUS_BLOCK io_status,
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   PLARGE_INTEGER allocation_size,
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   ULONG file_attributes, ULONG sharing,
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   ULONG disposition, ULONG options,
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   PVOID ea_buffer, ULONG ea_length) {
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check if the process can open it first.
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NTSTATUS status = orig_CreateFile(file, desired_access, object_attributes,
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    io_status, allocation_size,
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    file_attributes, sharing, disposition,
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    options, ea_buffer, ea_length);
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (STATUS_ACCESS_DENIED != status)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return status;
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We don't trust that the IPC can work this early.
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return status;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  wchar_t* name = NULL;
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  do {
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ValidParameter(file, sizeof(HANDLE), WRITE))
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ValidParameter(io_status, sizeof(IO_STATUS_BLOCK), WRITE))
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void* memory = GetGlobalIPCMemory();
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (NULL == memory)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint32 attributes = 0;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NTSTATUS ret = AllocAndCopyName(object_attributes, &name, &attributes,
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    NULL);
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!NT_SUCCESS(ret) || NULL == name)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ULONG broker = FALSE;
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CountedParameterSet<OpenFile> params;
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    params[OpenFile::NAME] = ParamPickerMake(name);
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    params[OpenFile::ACCESS] = ParamPickerMake(desired_access);
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    params[OpenFile::OPTIONS] = ParamPickerMake(options);
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    params[OpenFile::BROKER] = ParamPickerMake(broker);
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!QueryBroker(IPC_NTCREATEFILE_TAG, params.GetBase()))
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SharedMemIPCClient ipc(memory);
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CrossCallReturn answer = {0};
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The following call must match in the parameters with
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // FilesystemDispatcher::ProcessNtCreateFile.
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ResultCode code = CrossCall(ipc, IPC_NTCREATEFILE_TAG, name, attributes,
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                desired_access, file_attributes, sharing,
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                disposition, options, &answer);
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (SBOX_ALL_OK != code)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!NT_SUCCESS(answer.nt_status))
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return answer.nt_status;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    __try {
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *file = answer.handle;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      io_status->Status = answer.nt_status;
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      io_status->Information = answer.extended[0].ulong_ptr;
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      status = io_status->Status;
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } __except(EXCEPTION_EXECUTE_HANDLER) {
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } while (false);
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (name)
891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    operator delete(name, NT_ALLOC);
901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return status;
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NTSTATUS WINAPI TargetNtOpenFile(NtOpenFileFunction orig_OpenFile, PHANDLE file,
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 ACCESS_MASK desired_access,
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 POBJECT_ATTRIBUTES object_attributes,
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 PIO_STATUS_BLOCK io_status, ULONG sharing,
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 ULONG options) {
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check if the process can open it first.
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NTSTATUS status = orig_OpenFile(file, desired_access, object_attributes,
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  io_status, sharing, options);
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (STATUS_ACCESS_DENIED != status)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return status;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We don't trust that the IPC can work this early.
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return status;
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  wchar_t* name = NULL;
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  do {
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ValidParameter(file, sizeof(HANDLE), WRITE))
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ValidParameter(io_status, sizeof(IO_STATUS_BLOCK), WRITE))
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void* memory = GetGlobalIPCMemory();
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (NULL == memory)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint32 attributes;
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NTSTATUS ret = AllocAndCopyName(object_attributes, &name, &attributes,
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    NULL);
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!NT_SUCCESS(ret) || NULL == name)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ULONG broker = FALSE;
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CountedParameterSet<OpenFile> params;
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    params[OpenFile::NAME] = ParamPickerMake(name);
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    params[OpenFile::ACCESS] = ParamPickerMake(desired_access);
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    params[OpenFile::OPTIONS] = ParamPickerMake(options);
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    params[OpenFile::BROKER] = ParamPickerMake(broker);
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!QueryBroker(IPC_NTOPENFILE_TAG, params.GetBase()))
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SharedMemIPCClient ipc(memory);
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CrossCallReturn answer = {0};
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ResultCode code = CrossCall(ipc, IPC_NTOPENFILE_TAG, name, attributes,
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                desired_access, sharing, options, &answer);
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (SBOX_ALL_OK != code)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!NT_SUCCESS(answer.nt_status))
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return answer.nt_status;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    __try {
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *file = answer.handle;
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      io_status->Status = answer.nt_status;
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      io_status->Information = answer.extended[0].ulong_ptr;
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      status = io_status->Status;
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } __except(EXCEPTION_EXECUTE_HANDLER) {
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } while (false);
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (name)
1571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    operator delete(name, NT_ALLOC);
1581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return status;
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NTSTATUS WINAPI TargetNtQueryAttributesFile(
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NtQueryAttributesFileFunction orig_QueryAttributes,
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    POBJECT_ATTRIBUTES object_attributes,
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PFILE_BASIC_INFORMATION file_attributes) {
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check if the process can query it first.
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NTSTATUS status = orig_QueryAttributes(object_attributes, file_attributes);
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (STATUS_ACCESS_DENIED != status)
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return status;
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We don't trust that the IPC can work this early.
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return status;
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  wchar_t* name = NULL;
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  do {
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ValidParameter(file_attributes, sizeof(FILE_BASIC_INFORMATION), WRITE))
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void* memory = GetGlobalIPCMemory();
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (NULL == memory)
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint32 attributes = 0;
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NTSTATUS ret = AllocAndCopyName(object_attributes, &name, &attributes,
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    NULL);
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!NT_SUCCESS(ret) || NULL == name)
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    InOutCountedBuffer file_info(file_attributes,
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 sizeof(FILE_BASIC_INFORMATION));
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ULONG broker = FALSE;
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CountedParameterSet<FileName> params;
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    params[FileName::NAME] = ParamPickerMake(name);
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    params[FileName::BROKER] = ParamPickerMake(broker);
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!QueryBroker(IPC_NTQUERYATTRIBUTESFILE_TAG, params.GetBase()))
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SharedMemIPCClient ipc(memory);
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CrossCallReturn answer = {0};
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ResultCode code = CrossCall(ipc, IPC_NTQUERYATTRIBUTESFILE_TAG, name,
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                attributes, file_info, &answer);
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    operator delete(name, NT_ALLOC);
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (SBOX_ALL_OK != code)
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return answer.nt_status;
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } while (false);
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (name)
2161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    operator delete(name, NT_ALLOC);
2171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return status;
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NTSTATUS WINAPI TargetNtQueryFullAttributesFile(
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NtQueryFullAttributesFileFunction orig_QueryFullAttributes,
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    POBJECT_ATTRIBUTES object_attributes,
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PFILE_NETWORK_OPEN_INFORMATION file_attributes) {
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check if the process can query it first.
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NTSTATUS status = orig_QueryFullAttributes(object_attributes,
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             file_attributes);
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (STATUS_ACCESS_DENIED != status)
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return status;
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We don't trust that the IPC can work this early.
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return status;
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  wchar_t* name = NULL;
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  do {
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ValidParameter(file_attributes, sizeof(FILE_NETWORK_OPEN_INFORMATION),
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        WRITE))
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void* memory = GetGlobalIPCMemory();
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (NULL == memory)
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint32 attributes = 0;
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NTSTATUS ret = AllocAndCopyName(object_attributes, &name, &attributes,
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    NULL);
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!NT_SUCCESS(ret) || NULL == name)
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    InOutCountedBuffer file_info(file_attributes,
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 sizeof(FILE_NETWORK_OPEN_INFORMATION));
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ULONG broker = FALSE;
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CountedParameterSet<FileName> params;
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    params[FileName::NAME] = ParamPickerMake(name);
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    params[FileName::BROKER] = ParamPickerMake(broker);
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!QueryBroker(IPC_NTQUERYFULLATTRIBUTESFILE_TAG, params.GetBase()))
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SharedMemIPCClient ipc(memory);
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CrossCallReturn answer = {0};
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ResultCode code = CrossCall(ipc, IPC_NTQUERYFULLATTRIBUTESFILE_TAG, name,
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                attributes, file_info, &answer);
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    operator delete(name, NT_ALLOC);
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (SBOX_ALL_OK != code)
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return answer.nt_status;
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } while (false);
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (name)
2761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    operator delete(name, NT_ALLOC);
2771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return status;
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NTSTATUS WINAPI TargetNtSetInformationFile(
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NtSetInformationFileFunction orig_SetInformationFile, HANDLE file,
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PIO_STATUS_BLOCK io_status, PVOID file_info, ULONG length,
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FILE_INFORMATION_CLASS file_info_class) {
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check if the process can open it first.
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NTSTATUS status = orig_SetInformationFile(file, io_status, file_info, length,
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            file_info_class);
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (STATUS_ACCESS_DENIED != status)
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return status;
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We don't trust that the IPC can work this early.
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return status;
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  wchar_t* name = NULL;
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  do {
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void* memory = GetGlobalIPCMemory();
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (NULL == memory)
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ValidParameter(io_status, sizeof(IO_STATUS_BLOCK), WRITE))
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ValidParameter(file_info, length, READ))
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FILE_RENAME_INFORMATION* file_rename_info =
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        reinterpret_cast<FILE_RENAME_INFORMATION*>(file_info);
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OBJECT_ATTRIBUTES object_attributes;
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UNICODE_STRING object_name;
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    InitializeObjectAttributes(&object_attributes, &object_name, 0, NULL, NULL);
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    __try {
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!IsSupportedRenameCall(file_rename_info, length, file_info_class))
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      object_attributes.RootDirectory = file_rename_info->RootDirectory;
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      object_name.Buffer = file_rename_info->FileName;
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      object_name.Length = object_name.MaximumLength =
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          static_cast<USHORT>(file_rename_info->FileNameLength);
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } __except(EXCEPTION_EXECUTE_HANDLER) {
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NTSTATUS ret = AllocAndCopyName(&object_attributes, &name, NULL, NULL);
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!NT_SUCCESS(ret) || !name)
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ULONG broker = FALSE;
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CountedParameterSet<FileName> params;
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    params[FileName::NAME] = ParamPickerMake(name);
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    params[FileName::BROKER] = ParamPickerMake(broker);
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!QueryBroker(IPC_NTSETINFO_RENAME_TAG, params.GetBase()))
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    InOutCountedBuffer io_status_buffer(io_status, sizeof(IO_STATUS_BLOCK));
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // This is actually not an InOut buffer, only In, but using InOut facility
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // really helps to simplify the code.
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    InOutCountedBuffer file_info_buffer(file_info, length);
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SharedMemIPCClient ipc(memory);
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CrossCallReturn answer = {0};
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ResultCode code = CrossCall(ipc, IPC_NTSETINFO_RENAME_TAG, file,
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                io_status_buffer, file_info_buffer, length,
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                file_info_class, &answer);
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (SBOX_ALL_OK != code)
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    status = answer.nt_status;
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } while (false);
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (name)
3551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    operator delete(name, NT_ALLOC);
3561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return status;
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace sandbox
361