1.1.0
This commit is contained in:
parent
d2373bf738
commit
339c72ff16
11
CHANGELOG.md
11
CHANGELOG.md
|
@ -10,18 +10,12 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
|||
|
||||
### Added
|
||||
- added support for NtRenameKey (this requires UseRegDeleteV2=y) [#205](https://github.com/sandboxie-plus/Sandboxie/issues/205)
|
||||
- FIXED SECURITY ISSUE: memory of unsandboxed processes can no longer be read, except for exceptions
|
||||
- added ReadIpcPath to enable more flexibility in IPC usage
|
||||
|
||||
|
||||
### Changed
|
||||
- reworked the mechanism sandboxie uses to mark host files as deleted
|
||||
-- the new behavioure creates a data file in the box root FilePaths.dat instead of creating dummy files
|
||||
-- it can be enabled with UseFileDeleteV2=y sane for the registry UseRegDeleteV2=y using RegPaths.dat
|
||||
- disabled a couple driver based workarounds for boxes in compartment mode as then thay should not be required
|
||||
- removed "AlwaysUseWin32kHooks", now these win32 hooks are always enabled
|
||||
-- note: you can use "UseWin32kHooks=program.exe,n" to disable them for sellected programs
|
||||
- EnableObjectFiltering is now set enabled by default, and replaces sbies old process/thread handle filter
|
||||
- reworked the TlsNameBuffer mechanism to be more versatile and less error prone
|
||||
|
||||
### Fixed
|
||||
- fixed folder rename issues (this requires UseFileDeleteV2=y) [#71](https://github.com/sandboxie-plus/Sandboxie/issues/71)
|
||||
|
@ -29,6 +23,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
|||
|
||||
|
||||
|
||||
|
||||
## [1.0.19 / 5.55.19] - 2022-04-21
|
||||
|
||||
### Added
|
||||
|
@ -64,7 +59,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
|||
|
||||
### Fixed
|
||||
- fixed pipe impersonation in compartment mode
|
||||
- fixed issue with box clean-up which was introduced in a recent build
|
||||
- fixed issue with box clean-up introduced in a recent build
|
||||
- fixed missing trace log clean-up command [#1773](https://github.com/sandboxie-plus/Sandboxie/issues/1773)
|
||||
- fixed inability to unpin programs that have been pinned to the run menu [#1694](https://github.com/sandboxie-plus/Sandboxie/issues/1694)
|
||||
|
||||
|
|
|
@ -545,6 +545,9 @@ BOOLEAN NetFw_ParseRule(NETFW_RULE* rule, const WCHAR* found_value)
|
|||
|
||||
static int isdigit_(int c) { return (c >= '0' && c <= '9'); }
|
||||
static int isxdigit_(int c) { return (isdigit_(c) || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f')); }
|
||||
#undef isascii
|
||||
static int isascii(int iChar) { return((iChar <= 127) && (iChar >= 0)); }
|
||||
static int isalnum_(int c) { return (isdigit_(c) || (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// from BSD sources: http://code.google.com/p/plan9front/source/browse/sys/src/ape/lib/bsd/?r=320990f52487ae84e28961517a4fa0d02d473bac
|
||||
|
|
|
@ -132,6 +132,20 @@ _FX UCHAR GetSetCustomLevel(UCHAR SetLevel)
|
|||
|
||||
if (! SetLevel) {
|
||||
|
||||
//
|
||||
// if UseRegDeleteV2 is set, check if RegPaths.dat was loaded
|
||||
// if not it means the box was previusly a V1 box,
|
||||
// hence return 0 and re run customization
|
||||
//
|
||||
// note: DeleteShellAssocKeys deletes the sandboxie shell integration keys
|
||||
// so the existence of a RegPaths.dat in a customized box is a reliable indicator
|
||||
//
|
||||
|
||||
extern BOOLEAN Key_Delete_v2;
|
||||
extern BOOLEAN Key_RegPaths_Loaded;
|
||||
if (Key_Delete_v2 && !Key_RegPaths_Loaded)
|
||||
return 0;
|
||||
|
||||
//
|
||||
// open the AutoExec key, also used to indicate if this sandbox
|
||||
// has already been customized
|
||||
|
|
|
@ -48,9 +48,9 @@ extern __declspec(dllexport) int __CRTDECL Sbie_snprintf(char *_Buffer, size_t C
|
|||
#define TRUE_NAME_BUFFER 0
|
||||
#define COPY_NAME_BUFFER 1
|
||||
#define TMPL_NAME_BUFFER 2
|
||||
#define MOVE_NAME_BUFFER 3
|
||||
#define NAME_BUFFER_COUNT 4
|
||||
#define NAME_BUFFER_DEPTH 24
|
||||
#define MISC_NAME_BUFFER 3 // 4, 5, 6, 7
|
||||
#define NAME_BUFFER_COUNT 8
|
||||
#define NAME_BUFFER_DEPTH 16 // 12
|
||||
|
||||
|
||||
#ifdef _WIN64
|
||||
|
@ -153,6 +153,7 @@ typedef struct _MY_LDR_WORKER_QUEUE_STUFF {
|
|||
}MY_LDR_WORKER_QUEUE_STUFF;
|
||||
#endif
|
||||
*/
|
||||
|
||||
typedef struct _THREAD_DATA {
|
||||
|
||||
//
|
||||
|
@ -161,7 +162,8 @@ typedef struct _THREAD_DATA {
|
|||
|
||||
WCHAR *name_buffer[NAME_BUFFER_COUNT][NAME_BUFFER_DEPTH];
|
||||
ULONG name_buffer_len[NAME_BUFFER_COUNT][NAME_BUFFER_DEPTH];
|
||||
int depth;
|
||||
int name_buffer_count[NAME_BUFFER_DEPTH];
|
||||
int name_buffer_depth;
|
||||
|
||||
//
|
||||
// locks
|
||||
|
|
|
@ -464,6 +464,16 @@ _FX void Dll_InitInjected(void)
|
|||
ExitProcess(-1);
|
||||
}
|
||||
|
||||
extern BOOLEAN File_Delete_v2;
|
||||
extern BOOLEAN File_InitDelete_v2();
|
||||
if (File_Delete_v2)
|
||||
File_InitDelete_v2();
|
||||
|
||||
extern BOOLEAN Key_Delete_v2;
|
||||
extern BOOLEAN Key_InitDelete_v2();
|
||||
if (Key_Delete_v2)
|
||||
Key_InitDelete_v2();
|
||||
|
||||
Dll_InitComplete = TRUE;
|
||||
|
||||
if (! Dll_RestrictedToken)
|
||||
|
@ -848,8 +858,10 @@ _FX ULONG_PTR Dll_Ordinal1(
|
|||
//
|
||||
|
||||
int MustRestartProcess = 0;
|
||||
if(Dll_ProcessFlags & SBIE_FLAG_PROCESS_IN_PCA_JOB)
|
||||
MustRestartProcess = 1;
|
||||
if (Dll_ProcessFlags & SBIE_FLAG_PROCESS_IN_PCA_JOB) {
|
||||
if (!SbieApi_QueryConfBool(NULL, L"NoRestartOnPAC", FALSE))
|
||||
MustRestartProcess = 1;
|
||||
}
|
||||
|
||||
else if (Dll_ProcessFlags & SBIE_FLAG_FORCED_PROCESS) {
|
||||
if (SbieApi_QueryConfBool(NULL, L"ForceRestartAll", FALSE)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright 2004-2020 Sandboxie Holdings, LLC
|
||||
* Copyright 2020 David Xanatos, xanasoft.com
|
||||
* Copyright 2020-2022 David Xanatos, xanasoft.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -283,7 +283,7 @@ _FX THREAD_DATA *Dll_GetTlsData(ULONG *pLastError)
|
|||
_FX void Dll_FreeTlsData(void)
|
||||
{
|
||||
THREAD_DATA *data;
|
||||
ULONG depth, type;
|
||||
ULONG depth, count;
|
||||
|
||||
if (Dll_TlsIndex == TLS_OUT_OF_INDEXES)
|
||||
data = NULL;
|
||||
|
@ -296,12 +296,12 @@ _FX void Dll_FreeTlsData(void)
|
|||
|
||||
for (depth = 0; depth < NAME_BUFFER_DEPTH; ++depth) {
|
||||
|
||||
for (type = 0; type < NAME_BUFFER_COUNT; ++type) {
|
||||
for (count = 0; count < NAME_BUFFER_COUNT; ++count) {
|
||||
|
||||
WCHAR* buf = data->name_buffer[type][depth];
|
||||
WCHAR* buf = data->name_buffer[count][depth];
|
||||
if (buf)
|
||||
Dll_Free(buf);
|
||||
data->name_buffer[type][depth] = NULL;
|
||||
data->name_buffer[count][depth] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -314,16 +314,38 @@ _FX void Dll_FreeTlsData(void)
|
|||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
ALIGNED WCHAR *Dll_GetTlsNameBuffer(
|
||||
THREAD_DATA *data, ULONG which, ULONG size)
|
||||
#ifdef NAME_BUFFER_DEBUG
|
||||
ALIGNED WCHAR *Dll_GetTlsNameBuffer_(THREAD_DATA *data, ULONG which, ULONG size, char* func)
|
||||
#else
|
||||
ALIGNED WCHAR *Dll_GetTlsNameBuffer(THREAD_DATA *data, ULONG which, ULONG size)
|
||||
#endif
|
||||
{
|
||||
WCHAR *old_name_buffer;
|
||||
ULONG old_name_buffer_len;
|
||||
WCHAR **name_buffer;
|
||||
ULONG *name_buffer_len;
|
||||
|
||||
name_buffer = &data->name_buffer [which][data->depth];
|
||||
name_buffer_len = &data->name_buffer_len[which][data->depth];
|
||||
//
|
||||
// since we have more places where we may need a name buffer now
|
||||
// instead of sticking to "which" and doing our best to not reuse a particualr buffer thats still needed
|
||||
// we just increment a counter and take a new buffer reach time we request one
|
||||
//
|
||||
|
||||
if (which >= MISC_NAME_BUFFER)
|
||||
which = MISC_NAME_BUFFER + data->name_buffer_count[data->name_buffer_depth]++;
|
||||
|
||||
#ifdef NAME_BUFFER_DEBUG
|
||||
DbgTrace("Dll_GetTlsNameBuffer, %s, %d\r\n", func, which);
|
||||
#endif
|
||||
|
||||
if (which >= NAME_BUFFER_COUNT - 4)
|
||||
SbieApi_Log(2310, L"%d", which);
|
||||
if (which >= NAME_BUFFER_COUNT) {
|
||||
ExitProcess(-1);
|
||||
}
|
||||
|
||||
name_buffer = &data->name_buffer [which][data->name_buffer_depth];
|
||||
name_buffer_len = &data->name_buffer_len[which][data->name_buffer_depth];
|
||||
|
||||
//
|
||||
// round up the requested size (+ extra padding of some bytes)
|
||||
|
@ -352,7 +374,7 @@ ALIGNED WCHAR *Dll_GetTlsNameBuffer(
|
|||
|
||||
//
|
||||
// debug checks: the name buffer is allocated at least 64 bytes
|
||||
// more than needed. fill these with 0xCC, and check that later
|
||||
// more than needed. fill these with 0xCC, andd check that later
|
||||
//
|
||||
|
||||
#ifdef DEBUG_MEMORY
|
||||
|
@ -380,13 +402,14 @@ ALIGNED void Dll_PushTlsNameBuffer(THREAD_DATA *data)
|
|||
#endif
|
||||
{
|
||||
#ifdef NAME_BUFFER_DEBUG
|
||||
DbgTrace("Dll_PushTlsNameBuffer, %s, %d\r\n", func, data->depth);
|
||||
DbgTrace("Dll_PushTlsNameBuffer, %s, %d\r\n", func, data->name_buffer_depth);
|
||||
#endif
|
||||
|
||||
++data->depth;
|
||||
if (data->depth > NAME_BUFFER_DEPTH - 4)
|
||||
SbieApi_Log(2310, L"%d", data->depth);
|
||||
if (data->depth >= NAME_BUFFER_DEPTH) {
|
||||
++data->name_buffer_depth;
|
||||
data->name_buffer_count[data->name_buffer_depth] = 0; // initialize
|
||||
if (data->name_buffer_depth > NAME_BUFFER_DEPTH - 4)
|
||||
SbieApi_Log(2310, L"%d", data->name_buffer_depth);
|
||||
if (data->name_buffer_depth >= NAME_BUFFER_DEPTH) {
|
||||
ExitProcess(-1);
|
||||
}
|
||||
}
|
||||
|
@ -404,12 +427,12 @@ _FX void Dll_PopTlsNameBuffer(THREAD_DATA *data)
|
|||
#endif
|
||||
{
|
||||
#ifdef NAME_BUFFER_DEBUG
|
||||
DbgTrace("Dll_PopTlsNameBuffer, %s, %d\r\n", func, data->depth-1);
|
||||
DbgTrace("Dll_PopTlsNameBuffer, %s, %d\r\n", func, data->name_buffer_depth-1);
|
||||
#endif
|
||||
|
||||
//
|
||||
// debug checks: the name buffer is allocated at least 64 bytes
|
||||
// more than needed. fill these with 0xCC, and check that later
|
||||
// more than needed. fill these with 0xCC, andd check that later
|
||||
//
|
||||
|
||||
#ifdef DEBUG_MEMORY
|
||||
|
@ -447,14 +470,12 @@ _FX void Dll_PopTlsNameBuffer(THREAD_DATA *data)
|
|||
__debugbreak();
|
||||
}
|
||||
|
||||
// todo: snapshots TMPL_NAME_BUFFER
|
||||
|
||||
}
|
||||
|
||||
#endif // DEBUG_MEMORY
|
||||
|
||||
--data->depth;
|
||||
if (data->depth < 0) {
|
||||
SbieApi_Log(2310, L"%d", data->depth);
|
||||
--data->name_buffer_depth;
|
||||
if (data->name_buffer_depth < 0) {
|
||||
SbieApi_Log(2310, L"%d", data->name_buffer_depth);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -81,6 +81,7 @@
|
|||
#define FGN_REPARSED_CLOSED_PATH 0x0200
|
||||
#define FGN_REPARSED_WRITE_PATH 0x0400
|
||||
|
||||
#define NO_RELOCATION ((PUNICODE_STRING)-1)
|
||||
|
||||
#ifndef _WIN64
|
||||
#define WOW64_FS_REDIR
|
||||
|
@ -258,7 +259,7 @@ static BOOLEAN File_RecordRecover(HANDLE FileHandle, const WCHAR *TruePath);
|
|||
static NTSTATUS File_SetReparsePoint(
|
||||
HANDLE FileHandle, PREPARSE_DATA_BUFFER Data, ULONG DataLen);
|
||||
|
||||
static NTSTATUS File_GetFileName(HANDLE FileHandle, ULONG NameLen, WCHAR *NameBuf);
|
||||
NTSTATUS File_GetFileName(HANDLE FileHandle, ULONG NameLen, WCHAR *NameBuf);
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
@ -337,7 +338,7 @@ static ULONG File_PublicUserLen = 0;
|
|||
|
||||
static BOOLEAN File_DriveAddSN = FALSE;
|
||||
|
||||
static BOOLEAN File_Delete_v2 = FALSE;
|
||||
BOOLEAN File_Delete_v2 = FALSE;
|
||||
static BOOLEAN File_NoReparse = FALSE;
|
||||
|
||||
static BOOLEAN File_Windows2000 = FALSE;
|
||||
|
@ -425,13 +426,20 @@ _FX NTSTATUS File_GetName(
|
|||
#else
|
||||
const BOOLEAN convert_wow64_link = FALSE;
|
||||
#endif WOW64_FS_REDIR
|
||||
|
||||
BOOLEAN no_relocation = FALSE;
|
||||
WCHAR snapshot_id[FILE_MAX_SNAPSHOT_ID];
|
||||
snapshot_id[0] = L'\0';
|
||||
|
||||
*OutTruePath = NULL;
|
||||
*OutCopyPath = NULL;
|
||||
if (OutFlags)
|
||||
*OutFlags = 0;
|
||||
|
||||
if (ObjectName == NO_RELOCATION) {
|
||||
no_relocation = TRUE;
|
||||
ObjectName = NULL;
|
||||
}
|
||||
|
||||
if (ObjectName) {
|
||||
objname_len = ObjectName->Length & ~1;
|
||||
objname_buf = ObjectName->Buffer;
|
||||
|
@ -453,16 +461,6 @@ _FX NTSTATUS File_GetName(
|
|||
|
||||
UNICODE_STRING *uni = NULL;
|
||||
|
||||
name = Handle_GetRelocationPath(RootDirectory, objname_len + sizeof(UNICODE_STRING));
|
||||
if (name) {
|
||||
|
||||
length = (wcslen(name) + 1) * sizeof(WCHAR);
|
||||
uni = ((UCHAR*)name) + (length + objname_len);
|
||||
RtlInitUnicodeString(uni, name);
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
length = 256;
|
||||
name = Dll_GetTlsNameBuffer(
|
||||
TlsData, TRUE_NAME_BUFFER, length + objname_len);
|
||||
|
@ -500,7 +498,6 @@ _FX NTSTATUS File_GetName(
|
|||
return status;
|
||||
|
||||
uni = &((OBJECT_NAME_INFORMATION *)name)->Name;
|
||||
}
|
||||
|
||||
#ifdef WOW64_FS_REDIR
|
||||
//
|
||||
|
@ -536,8 +533,8 @@ _FX NTSTATUS File_GetName(
|
|||
name += prefixLen;
|
||||
length -= prefixLen;
|
||||
|
||||
if (length >= 10 && 0 == Dll_NlsStrCmp(name, L"\\snapshot-", 10)) {
|
||||
WCHAR* ptr = wcschr(name + 10, L'\\');
|
||||
if (length >= 10 && 0 == Dll_NlsStrCmp(name + 1, File_Snapshot_Prefix, File_Snapshot_PrefixLen)) {
|
||||
WCHAR* ptr = wcschr(name + 1 + File_Snapshot_PrefixLen, L'\\');
|
||||
if (ptr) {
|
||||
length -= (ULONG)(ptr - name);
|
||||
name = ptr;
|
||||
|
@ -815,20 +812,27 @@ check_sandbox_prefix:
|
|||
//
|
||||
|
||||
if (is_boxed_path) {
|
||||
if (length >= 10 &&
|
||||
0 == Dll_NlsStrCmp(
|
||||
*OutTruePath, L"\\snapshot-", 10))
|
||||
if (length >= 10 && 0 == Dll_NlsStrCmp(*OutTruePath + 1, File_Snapshot_Prefix, File_Snapshot_PrefixLen))
|
||||
{
|
||||
WCHAR* path = wcschr(*OutTruePath + 10, L'\\');
|
||||
|
||||
WCHAR* path = wcschr(*OutTruePath + 1 + File_Snapshot_PrefixLen, L'\\');
|
||||
if (path == NULL) {
|
||||
|
||||
//
|
||||
// caller specified just the sandbox snapshot prefix
|
||||
// caller specified just the sandbox snapshot prefix, or the path is to long
|
||||
//
|
||||
|
||||
*OutTruePath = TruePath;
|
||||
return STATUS_BAD_INITIAL_PC;
|
||||
}
|
||||
|
||||
if (no_relocation) {
|
||||
ULONG len = (ULONG)(path - (*OutTruePath + 1 + File_Snapshot_PrefixLen));
|
||||
if (len < FILE_MAX_SNAPSHOT_ID) {
|
||||
wmemcpy(snapshot_id, *OutTruePath + 1 + File_Snapshot_PrefixLen, len);
|
||||
snapshot_id[len] = L'\0';
|
||||
}
|
||||
}
|
||||
|
||||
length -= (ULONG)(path - *OutTruePath);
|
||||
*OutTruePath = path;
|
||||
}
|
||||
|
@ -1069,6 +1073,34 @@ check_sandbox_prefix:
|
|||
} else
|
||||
TruePath = *OutTruePath;
|
||||
|
||||
//
|
||||
// if this is a unboxed path, and we opened it by object,
|
||||
// check path relocation and update true path accordingly.
|
||||
//
|
||||
|
||||
if (!is_boxed_path && RootDirectory && !no_relocation) {
|
||||
|
||||
name = Handle_GetRelocationPath(RootDirectory, objname_len);
|
||||
if (name) {
|
||||
|
||||
*OutTruePath = name;
|
||||
TruePath = *OutTruePath;
|
||||
|
||||
name = (*OutTruePath) + wcslen(*OutTruePath);
|
||||
|
||||
if (objname_len) {
|
||||
|
||||
*name = L'\\';
|
||||
++name;
|
||||
memcpy(name, objname_buf, objname_len);
|
||||
|
||||
name += objname_len / sizeof(WCHAR);
|
||||
}
|
||||
|
||||
*name = L'\0';
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// now create the copy path, which is the box prefix prepended
|
||||
// to the true path that we have. note that the copy path will
|
||||
|
@ -1083,6 +1115,21 @@ check_sandbox_prefix:
|
|||
wmemcpy(name, Dll_BoxFilePath, Dll_BoxFilePathLen);
|
||||
name += Dll_BoxFilePathLen;
|
||||
|
||||
//
|
||||
// if we requested real paths, re add the snapshot prefix
|
||||
//
|
||||
|
||||
if (*snapshot_id) {
|
||||
|
||||
*name++ = L'\\';
|
||||
wmemcpy(name, File_Snapshot_Prefix, File_Snapshot_PrefixLen);
|
||||
name += File_Snapshot_PrefixLen;
|
||||
ULONG len = wcslen(snapshot_id);
|
||||
wmemcpy(name, snapshot_id, len);
|
||||
name += len;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// if the true path points to a remote share or mapped drive,
|
||||
// convert that to box the portable form "\share\computer\folder"
|
||||
|
@ -1354,7 +1401,6 @@ _FX WCHAR *File_GetName_TranslateSymlinks(
|
|||
if (NT_SUCCESS(status))
|
||||
break;
|
||||
|
||||
if (!Dll_CompartmentMode) // NoDriverAssist
|
||||
if (status == STATUS_ACCESS_DENIED &&
|
||||
objname.Length <= 1020 * sizeof(WCHAR)) {
|
||||
|
||||
|
@ -1969,12 +2015,12 @@ _FX NTSTATUS File_GetName_FromFileId(
|
|||
if (1) {
|
||||
|
||||
BOOLEAN IsBoxedPath;
|
||||
WCHAR *path = Dll_AllocTemp(8192);
|
||||
status = SbieDll_GetHandlePath(
|
||||
ObjectAttributes->RootDirectory, path, &IsBoxedPath);
|
||||
ObjectAttributes->RootDirectory, NULL, &IsBoxedPath);
|
||||
if (IsBoxedPath && (
|
||||
NT_SUCCESS(status) || (status == STATUS_BAD_INITIAL_PC))) {
|
||||
|
||||
WCHAR *path = Dll_AllocTemp(8192);
|
||||
status = SbieDll_GetHandlePath(
|
||||
ObjectAttributes->RootDirectory, path, NULL);
|
||||
if (NT_SUCCESS(status)) {
|
||||
|
@ -2012,9 +2058,9 @@ _FX NTSTATUS File_GetName_FromFileId(
|
|||
NtClose(hTrueRoot);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Dll_Free(path);
|
||||
Dll_Free(path);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -2176,6 +2222,53 @@ _FX ULONG File_MatchPath2(const WCHAR *path, ULONG *FileFlags, BOOLEAN bCheckObj
|
|||
}
|
||||
}
|
||||
|
||||
//
|
||||
// check for network paths
|
||||
//
|
||||
|
||||
if (_wcsnicmp(path, File_Redirector, File_RedirectorLen) == 0)
|
||||
PrefixLen = File_RedirectorLen;
|
||||
else if (_wcsnicmp(path, File_DfsClientRedir, File_DfsClientRedirLen) == 0)
|
||||
PrefixLen = File_DfsClientRedirLen;
|
||||
else if (_wcsnicmp(path, File_HgfsRedir, File_HgfsRedirLen) == 0)
|
||||
PrefixLen = File_HgfsRedirLen;
|
||||
else if (_wcsnicmp(path, File_MupRedir, File_MupRedirLen) == 0)
|
||||
PrefixLen = File_MupRedirLen;
|
||||
else
|
||||
PrefixLen = 0;
|
||||
|
||||
//
|
||||
// if we have a path that looks like
|
||||
// \Device\LanmanRedirector\;Q:000000000000b09f\server\share\f1.txt
|
||||
// \Device\Mup\;LanmanRedirector\;Q:000000000000b09f\server\share\f1.txt
|
||||
// then translate to
|
||||
// \Device\Mup\server\share\f1.txt
|
||||
// and test again. We do this because the SbieDrv records paths
|
||||
// in the \Device\Mup format. See SbieDrv::File_TranslateShares.
|
||||
//
|
||||
|
||||
if (PrefixLen) {
|
||||
|
||||
ptr = path + PrefixLen;
|
||||
if (*ptr == L';')
|
||||
ptr = wcschr(ptr, L'\\');
|
||||
else
|
||||
--ptr;
|
||||
if (ptr && ptr[0] && ptr[1]) {
|
||||
|
||||
ULONG len1 = wcslen(ptr + 1);
|
||||
ULONG len2 = (File_MupLen + len1 + 8) * sizeof(WCHAR);
|
||||
WCHAR* path2 = Dll_AllocTemp(len2);
|
||||
wmemcpy(path2, File_Mup, File_MupLen);
|
||||
wmemcpy(path2 + File_MupLen, ptr + 1, len1 + 1);
|
||||
|
||||
mp_flags = SbieDll_MatchPath2(L'f', path2, bCheckObjectExists, bMonitorLog);
|
||||
|
||||
Dll_Free(path2);
|
||||
goto finish;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// match path
|
||||
//
|
||||
|
@ -2213,49 +2306,6 @@ _FX ULONG File_MatchPath2(const WCHAR *path, ULONG *FileFlags, BOOLEAN bCheckObj
|
|||
}
|
||||
}
|
||||
|
||||
//
|
||||
// check for network paths
|
||||
//
|
||||
|
||||
if (_wcsnicmp(path, File_Redirector, File_RedirectorLen) == 0)
|
||||
PrefixLen = File_RedirectorLen;
|
||||
else if (_wcsnicmp(path, File_DfsClientRedir, File_DfsClientRedirLen) == 0)
|
||||
PrefixLen = File_DfsClientRedirLen;
|
||||
else if (_wcsnicmp(path, File_HgfsRedir, File_HgfsRedirLen) == 0)
|
||||
PrefixLen = File_HgfsRedirLen;
|
||||
else if (_wcsnicmp(path, File_MupRedir, File_MupRedirLen) == 0)
|
||||
PrefixLen = File_MupRedirLen;
|
||||
else
|
||||
goto finish;
|
||||
|
||||
//
|
||||
// if we have a path that looks like
|
||||
// \Device\LanmanRedirector\;Q:000000000000b09f\server\share\f1.txt
|
||||
// \Device\Mup\;LanmanRedirector\;Q:000000000000b09f\server\share\f1.txt
|
||||
// then translate to
|
||||
// \Device\Mup\server\share\f1.txt
|
||||
// and test again. We do this because the SbieDrv records paths
|
||||
// in the \Device\Mup format. See SbieDrv::File_TranslateShares.
|
||||
//
|
||||
|
||||
ptr = path + PrefixLen;
|
||||
if (*ptr == L';')
|
||||
ptr = wcschr(ptr, L'\\');
|
||||
else
|
||||
--ptr;
|
||||
if (ptr && ptr[0] && ptr[1]) {
|
||||
|
||||
ULONG len1 = wcslen(ptr + 1);
|
||||
ULONG len2 = (File_MupLen + len1 + 8) * sizeof(WCHAR);
|
||||
WCHAR *path2 = Dll_AllocTemp(len2);
|
||||
wmemcpy(path2, File_Mup, File_MupLen);
|
||||
wmemcpy(path2 + File_MupLen, ptr + 1, len1 + 1);
|
||||
|
||||
mp_flags = SbieDll_MatchPath2(L'f', path2, bCheckObjectExists, bMonitorLog);
|
||||
|
||||
Dll_Free(path2);
|
||||
}
|
||||
|
||||
//
|
||||
// finish
|
||||
//
|
||||
|
@ -3618,7 +3668,8 @@ ReparseLoop:
|
|||
}
|
||||
|
||||
//
|
||||
// Relocation, if we opened the true file and its relocated set the path info
|
||||
// Relocation, if we opened a relocated location we need to
|
||||
// store the original true path for the File_GetName function
|
||||
//
|
||||
|
||||
if (TrueOpened && OriginalPath) {
|
||||
|
@ -4634,33 +4685,13 @@ _FX NTSTATUS File_QueryFullAttributesDirectoryFile(
|
|||
HANDLE FileHandle;
|
||||
NTSTATUS status;
|
||||
|
||||
if (!Dll_CompartmentMode) { // NoDriverAssist
|
||||
|
||||
//
|
||||
// try to use SbieApi_OpenFile which will open the file, bypassing
|
||||
// ClosedFilePath settings, but only if it a directory file. it
|
||||
// returns a handle that can only be used to query file attributes
|
||||
//
|
||||
|
||||
status = SbieApi_OpenFile(&FileHandle, TruePath);
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
OBJECT_ATTRIBUTES objattrs;
|
||||
UNICODE_STRING objname;
|
||||
|
||||
InitializeObjectAttributes(
|
||||
&objattrs, &objname, OBJ_CASE_INSENSITIVE, NULL, NULL);
|
||||
|
||||
RtlInitUnicodeString(&objname, TruePath);
|
||||
|
||||
status = __sys_NtCreateFile(
|
||||
&FileHandle, FILE_GENERIC_READ, &objattrs, &MyIoStatusBlock,
|
||||
NULL, 0, FILE_SHARE_VALID_FLAGS,
|
||||
FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0);
|
||||
}
|
||||
//
|
||||
// try to use SbieApi_OpenFile which will open the file, bypassing
|
||||
// ClosedFilePath settings, but only if it a directory file. it
|
||||
// returns a handle that can only be used to query file attributes
|
||||
//
|
||||
|
||||
status = SbieApi_OpenFile(&FileHandle, TruePath);
|
||||
if (NT_SUCCESS(status)) {
|
||||
|
||||
status = __sys_NtQueryInformationFile(
|
||||
|
@ -5166,17 +5197,14 @@ _FX NTSTATUS File_NtQueryInformationFile(
|
|||
if (FileId && FileId->QuadPart) {
|
||||
|
||||
BOOLEAN IsBoxedPath;
|
||||
WCHAR *path = Dll_AllocTemp(8192);
|
||||
NTSTATUS status2 =
|
||||
SbieDll_GetHandlePath(FileHandle, path, &IsBoxedPath);
|
||||
SbieDll_GetHandlePath(FileHandle, NULL, &IsBoxedPath);
|
||||
if (IsBoxedPath && (NT_SUCCESS(status2)
|
||||
|| (status2 == STATUS_BAD_INITIAL_PC))) {
|
||||
|
||||
FileId->LowPart ^= 0xFFFFFFFF;
|
||||
FileId->HighPart ^= 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
Dll_Free(path);
|
||||
}
|
||||
|
||||
return status;
|
||||
|
@ -5317,15 +5345,15 @@ _FX ULONG File_GetFinalPathNameByHandleW(
|
|||
WCHAR *path, *result;
|
||||
BOOLEAN IsBoxedPath;
|
||||
|
||||
path = Dll_AllocTemp(8192);
|
||||
status = SbieDll_GetHandlePath(hFile, path, &IsBoxedPath);
|
||||
status = SbieDll_GetHandlePath(hFile, NULL, &IsBoxedPath);
|
||||
if (IsBoxedPath &&
|
||||
(NT_SUCCESS(status) || (status == STATUS_BAD_INITIAL_PC))) {
|
||||
|
||||
//
|
||||
// the specified file is inside the sandbox, so handle the request
|
||||
//
|
||||
|
||||
|
||||
path = Dll_AllocTemp(8192);
|
||||
status = SbieDll_GetHandlePath(hFile, path, NULL);
|
||||
if (! NT_SUCCESS(status)) {
|
||||
|
||||
|
@ -5359,6 +5387,8 @@ _FX ULONG File_GetFinalPathNameByHandleW(
|
|||
Dll_Free(result);
|
||||
}
|
||||
}
|
||||
|
||||
Dll_Free(path);
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -5372,7 +5402,6 @@ _FX ULONG File_GetFinalPathNameByHandleW(
|
|||
err = GetLastError();
|
||||
}
|
||||
|
||||
Dll_Free(path);
|
||||
SetLastError(err);
|
||||
return rc;
|
||||
}
|
||||
|
@ -6593,10 +6622,10 @@ _FX NTSTATUS File_RenameFile(
|
|||
if (! ReparsedPath)
|
||||
ReparsedPath = TargetTruePath;
|
||||
|
||||
if (!Dll_CompartmentMode) // NoDriverAssist
|
||||
//if (!Dll_CompartmentMode) // NoDriverAssist
|
||||
status = SbieApi_RenameFile(SourceHandle, ReparsedPath, TargetFileName, info->ReplaceIfExists);
|
||||
else
|
||||
status = File_RenameOpenFile(SourceHandle, ReparsedPath, TargetFileName, info->ReplaceIfExists);
|
||||
//else
|
||||
// status = File_RenameOpenFile(SourceHandle, ReparsedPath, TargetFileName, info->ReplaceIfExists);
|
||||
|
||||
if (ReparsedPath != TargetTruePath)
|
||||
Dll_Free(ReparsedPath);
|
||||
|
@ -6732,6 +6761,7 @@ _FX NTSTATUS File_RenameFile(
|
|||
}
|
||||
|
||||
} else {
|
||||
|
||||
WCHAR* TargetTruePath2 = TargetTruePath;
|
||||
|
||||
ULONG TargetTruePathFlags = 0;
|
||||
|
@ -6912,9 +6942,9 @@ after_rename:
|
|||
// if this is a directory and if so update/create the appropriate remapping
|
||||
//
|
||||
|
||||
if (IsDirectroy) {
|
||||
if (TrueExists && IsDirectroy) {
|
||||
|
||||
File_SetRelocation(SourceTruePath, TargetTruePath, TrueExists);
|
||||
File_SetRelocation(SourceTruePath, TargetTruePath);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -7062,8 +7092,16 @@ _FX ULONG SbieDll_GetHandlePath(
|
|||
|
||||
Dll_PushTlsNameBuffer(TlsData);
|
||||
|
||||
//
|
||||
// This function returns actual paths as thay exist in the real filesystem
|
||||
// copy paths may point to the snapshot if the file is there
|
||||
// and true paths will point to the original location if thay rere redirected
|
||||
// ther for calling hooked file functions on these paths may run into file not found
|
||||
// when the original location is marked as deleted
|
||||
//
|
||||
|
||||
status = File_GetName(
|
||||
FileHandle, NULL, &TruePath, &CopyPath, &FileFlags);
|
||||
FileHandle, NO_RELOCATION, &TruePath, &CopyPath, &FileFlags);
|
||||
|
||||
if (IsBoxedPath) {
|
||||
|
||||
|
@ -7075,20 +7113,16 @@ _FX ULONG SbieDll_GetHandlePath(
|
|||
} else if (status == STATUS_BAD_INITIAL_PC)
|
||||
status = STATUS_SUCCESS;
|
||||
|
||||
if (NT_SUCCESS(status)) {
|
||||
if (NT_SUCCESS(status) && OutWchar8192) {
|
||||
|
||||
ULONG len;
|
||||
WCHAR *src = TruePath;
|
||||
if (Dll_BoxName && // sandboxed process
|
||||
IsBoxedPath && *IsBoxedPath) {
|
||||
|
||||
if (File_Snapshot != NULL) {
|
||||
WCHAR* TmplName = File_FindSnapshotPath(CopyPath);
|
||||
if (TmplName) CopyPath = TmplName;
|
||||
}
|
||||
|
||||
src = CopyPath;
|
||||
}
|
||||
|
||||
len = wcslen(src);
|
||||
if (len > 8192 / sizeof(WCHAR) - 4)
|
||||
len = 8192 / sizeof(WCHAR) - 4;
|
||||
|
|
|
@ -278,7 +278,6 @@ _FX NTSTATUS File_MigrateFile(
|
|||
|
||||
if (status == STATUS_SHARING_VIOLATION) {
|
||||
|
||||
if (!Dll_CompartmentMode) // NoDriverAssist
|
||||
status = SbieApi_OpenFile(&TrueHandle, TruePath);
|
||||
|
||||
if (!NT_SUCCESS(status)) {
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "../../common/my_version.h"
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// File (Delete)
|
||||
//---------------------------------------------------------------------------
|
||||
|
@ -74,13 +76,17 @@ static ULONG File_GetPathFlags(const WCHAR* Path, WCHAR** pRelocation);
|
|||
static BOOLEAN File_SavePathTree();
|
||||
static BOOLEAN File_LoadPathTree();
|
||||
static VOID File_RefreshPathTree();
|
||||
static BOOLEAN File_InitDelete_v2();
|
||||
BOOLEAN File_InitDelete_v2();
|
||||
|
||||
static NTSTATUS File_MarkDeleted_v2(const WCHAR *TruePath);
|
||||
static ULONG File_IsDeleted_v2(const WCHAR* TruePath);
|
||||
static BOOLEAN File_HasDeleted_v2(const WCHAR* TruePath);
|
||||
static WCHAR* File_GetRelocation(const WCHAR* TruePath);
|
||||
static NTSTATUS File_SetRelocation(const WCHAR *OldTruePath, const WCHAR *NewTruePath, BOOLEAN TrueExists);
|
||||
static NTSTATUS File_SetRelocation(const WCHAR *OldTruePath, const WCHAR *NewTruePath);
|
||||
|
||||
HANDLE File_AcquireMutex(const WCHAR* MutexName);
|
||||
void File_ReleaseMutex(HANDLE hMutex);
|
||||
#define FILE_VFS_MUTEX SBIE L"_VFS_Mutex"
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// File_ClearPathBranche
|
||||
|
@ -288,7 +294,7 @@ _FX ULONG File_GetPathFlags_internal(LIST* Root, const WCHAR* Path, WCHAR** pRel
|
|||
|
||||
THREAD_DATA *TlsData = Dll_GetTlsData(NULL);
|
||||
|
||||
*pRelocation = Dll_GetTlsNameBuffer(TlsData, MOVE_NAME_BUFFER, (wcslen(Relocation) + wcslen(SubPath) + 16) * sizeof(WCHAR)); // +16 some room for changes
|
||||
*pRelocation = Dll_GetTlsNameBuffer(TlsData, MISC_NAME_BUFFER, (wcslen(Relocation) + wcslen(SubPath) + 16) * sizeof(WCHAR)); // +16 some room for changes
|
||||
wcscpy(*pRelocation, Relocation);
|
||||
wcscat(*pRelocation, SubPath);
|
||||
}
|
||||
|
@ -418,12 +424,45 @@ _FX BOOLEAN File_SavePathTree()
|
|||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// File_AcquireMutex
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
_FX HANDLE File_AcquireMutex(const WCHAR *MutexName)
|
||||
{
|
||||
HANDLE hMutex = OpenMutex(MUTEX_ALL_ACCESS, FALSE, MutexName);
|
||||
if (! hMutex)
|
||||
hMutex = CreateMutex(NULL, FALSE, MutexName);
|
||||
if (hMutex)
|
||||
WaitForSingleObject(hMutex, 5000);
|
||||
|
||||
return hMutex;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Scm_ReleaseMutex
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
_FX void File_ReleaseMutex(HANDLE hMutex)
|
||||
{
|
||||
if (hMutex) {
|
||||
|
||||
ReleaseMutex(hMutex);
|
||||
|
||||
CloseHandle(hMutex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// File_LoadPathTree_internal
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
_FX VOID File_LoadPathTree_internal(LIST* Root, const WCHAR* name)
|
||||
_FX BOOLEAN File_LoadPathTree_internal(LIST* Root, const WCHAR* name)
|
||||
{
|
||||
WCHAR PathsFile[MAX_PATH] = { 0 };
|
||||
wcscpy(PathsFile, Dll_BoxFilePath);
|
||||
|
@ -434,7 +473,7 @@ _FX VOID File_LoadPathTree_internal(LIST* Root, const WCHAR* name)
|
|||
HANDLE hPathsFile;
|
||||
hPathsFile = CreateFile(PathsFile, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (hPathsFile == INVALID_HANDLE_VALUE)
|
||||
return;
|
||||
return FALSE;
|
||||
|
||||
File_ClearPathBranche_internal(Root);
|
||||
|
||||
|
@ -480,6 +519,8 @@ _FX VOID File_LoadPathTree_internal(LIST* Root, const WCHAR* name)
|
|||
Dll_Free(Buffer);
|
||||
|
||||
CloseHandle(hPathsFile);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
@ -490,12 +531,16 @@ _FX VOID File_LoadPathTree_internal(LIST* Root, const WCHAR* name)
|
|||
|
||||
_FX BOOLEAN File_LoadPathTree()
|
||||
{
|
||||
HANDLE hMutex = File_AcquireMutex(FILE_VFS_MUTEX);
|
||||
|
||||
EnterCriticalSection(File_PathRoot_CritSec);
|
||||
|
||||
File_LoadPathTree_internal(&File_PathRoot, FILE_PATH_FILE_NAME);
|
||||
|
||||
LeaveCriticalSection(File_PathRoot_CritSec);
|
||||
|
||||
File_ReleaseMutex(hMutex);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -558,6 +603,8 @@ _FX BOOLEAN File_InitDelete_v2()
|
|||
|
||||
_FX VOID File_MarkDeleted_internal(LIST* Root, const WCHAR* Path)
|
||||
{
|
||||
HANDLE hMutex = File_AcquireMutex(FILE_VFS_MUTEX);
|
||||
|
||||
EnterCriticalSection(File_PathRoot_CritSec);
|
||||
|
||||
// 1. remove deleted branche
|
||||
|
@ -581,6 +628,8 @@ _FX VOID File_MarkDeleted_internal(LIST* Root, const WCHAR* Path)
|
|||
LeaveCriticalSection(File_PathRoot_CritSec);
|
||||
|
||||
File_SavePathTree();
|
||||
|
||||
File_ReleaseMutex(hMutex);
|
||||
}
|
||||
|
||||
|
||||
|
@ -595,6 +644,8 @@ _FX NTSTATUS File_MarkDeleted_v2(const WCHAR* TruePath)
|
|||
// add a file or directory to the deleted list
|
||||
//
|
||||
|
||||
HANDLE hMutex = File_AcquireMutex(FILE_VFS_MUTEX);
|
||||
|
||||
EnterCriticalSection(File_PathRoot_CritSec);
|
||||
|
||||
File_MarkDeleted_internal(&File_PathRoot, TruePath);
|
||||
|
@ -603,6 +654,8 @@ _FX NTSTATUS File_MarkDeleted_v2(const WCHAR* TruePath)
|
|||
|
||||
File_SavePathTree();
|
||||
|
||||
File_ReleaseMutex(hMutex);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -647,7 +700,7 @@ _FX BOOLEAN File_HasDeleted_v2(const WCHAR* TruePath)
|
|||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
_FX VOID File_SetRelocation_internal(LIST* Root, const WCHAR *OldTruePath, const WCHAR *NewTruePath, BOOLEAN TrueExists)
|
||||
_FX VOID File_SetRelocation_internal(LIST* Root, const WCHAR *OldTruePath, const WCHAR *NewTruePath)
|
||||
{
|
||||
// 1. separate branche from OldTruePath
|
||||
|
||||
|
@ -667,45 +720,44 @@ _FX VOID File_SetRelocation_internal(LIST* Root, const WCHAR *OldTruePath, const
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// 3. add true delete entry OldTruePath
|
||||
|
||||
File_SetPathFlags_internal(Root, OldTruePath, FILE_DELETED_FLAG, 0, NULL);
|
||||
|
||||
|
||||
// 4. set redirection NewTruePath -> OldTruePath
|
||||
|
||||
if (TrueExists || HasRelocation || (Node && Node->items.count > 0)) {
|
||||
PATH_NODE* NewNode = File_FindPathBranche_internal(Root, NewTruePath, NULL, TRUE);
|
||||
|
||||
PATH_NODE* NewNode = File_FindPathBranche_internal(Root, NewTruePath, NULL, TRUE);
|
||||
|
||||
// OldTruePath may have a relocated parent, if so unwrap it
|
||||
if (!HasRelocation) {
|
||||
WCHAR* OldOldTruePath = NULL;
|
||||
File_GetPathFlags_internal(&File_PathRoot, OldTruePath, &OldOldTruePath, TRUE);
|
||||
if (OldOldTruePath) OldTruePath = OldOldTruePath;
|
||||
}
|
||||
|
||||
if (TrueExists || HasRelocation) {
|
||||
NewNode->flags |= FILE_RELOCATION_FLAG;
|
||||
NewNode->relocation = Dll_Alloc((wcslen(OldTruePath) + 1) * sizeof(WCHAR));
|
||||
wcscpy(NewNode->relocation, OldTruePath);
|
||||
}
|
||||
// OldTruePath may have a relocated parent, if so unwrap it
|
||||
if (!HasRelocation) {
|
||||
WCHAR* OldOldTruePath = NULL;
|
||||
File_GetPathFlags_internal(Root, OldTruePath, &OldOldTruePath, TRUE);
|
||||
if (OldOldTruePath) OldTruePath = OldOldTruePath;
|
||||
}
|
||||
|
||||
NewNode->flags |= FILE_RELOCATION_FLAG;
|
||||
NewNode->relocation = Dll_Alloc((wcslen(OldTruePath) + 1) * sizeof(WCHAR));
|
||||
wcscpy(NewNode->relocation, OldTruePath);
|
||||
|
||||
|
||||
// 5. reatach branche to NewTruePath
|
||||
|
||||
if (Node) {
|
||||
PATH_NODE* child = List_Head(&Node->items);
|
||||
while (child) {
|
||||
if (Node) {
|
||||
PATH_NODE* child = List_Head(&Node->items);
|
||||
while (child) {
|
||||
|
||||
PATH_NODE* next_child = List_Next(child);
|
||||
PATH_NODE* next_child = List_Next(child);
|
||||
|
||||
List_Remove(&Node->items, child);
|
||||
List_Remove(&Node->items, child);
|
||||
|
||||
List_Insert_After(&NewNode->items, NULL, child);
|
||||
List_Insert_After(&NewNode->items, NULL, child);
|
||||
|
||||
child = next_child;
|
||||
}
|
||||
child = next_child;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 6. clean up
|
||||
|
||||
|
@ -724,20 +776,24 @@ _FX VOID File_SetRelocation_internal(LIST* Root, const WCHAR *OldTruePath, const
|
|||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
_FX NTSTATUS File_SetRelocation(const WCHAR* OldTruePath, const WCHAR* NewTruePath, BOOLEAN TrueExists)
|
||||
_FX NTSTATUS File_SetRelocation(const WCHAR* OldTruePath, const WCHAR* NewTruePath)
|
||||
{
|
||||
//
|
||||
// List a mapping for the new location
|
||||
//
|
||||
|
||||
HANDLE hMutex = File_AcquireMutex(FILE_VFS_MUTEX);
|
||||
|
||||
EnterCriticalSection(File_PathRoot_CritSec);
|
||||
|
||||
File_SetRelocation_internal(&File_PathRoot, OldTruePath, NewTruePath, TrueExists);
|
||||
File_SetRelocation_internal(&File_PathRoot, OldTruePath, NewTruePath);
|
||||
|
||||
LeaveCriticalSection(File_PathRoot_CritSec);
|
||||
|
||||
File_SavePathTree();
|
||||
|
||||
File_ReleaseMutex(hMutex);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -620,8 +620,7 @@ _FX NTSTATUS File_OpenForMerge(
|
|||
if (File_Delete_v2) {
|
||||
|
||||
//
|
||||
// test if the path is deleted and find the oldest snapshot with a relocation,
|
||||
// or
|
||||
// test if the path is deleted and find the oldest snapshot with a relocation
|
||||
//
|
||||
|
||||
WCHAR* OldTruePath = File_ResolveTruePath(TruePath, NULL, &TruePathFlags);
|
||||
|
@ -3018,14 +3017,13 @@ _FX NTSTATUS File_NtQueryVolumeInformationFile(
|
|||
// then open the real drive X to get the correct result
|
||||
//
|
||||
|
||||
path = Dll_AllocTemp(8192);
|
||||
|
||||
handle = FileHandle;
|
||||
|
||||
status = SbieDll_GetHandlePath(FileHandle, path, &IsBoxedPath);
|
||||
status = SbieDll_GetHandlePath(FileHandle, NULL, &IsBoxedPath);
|
||||
if (IsBoxedPath && (
|
||||
NT_SUCCESS(status) || (status == STATUS_BAD_INITIAL_PC))) {
|
||||
|
||||
|
||||
path = Dll_AllocTemp(8192);
|
||||
status = SbieDll_GetHandlePath(FileHandle, path, NULL);
|
||||
if (NT_SUCCESS(status)) {
|
||||
|
||||
|
@ -3085,9 +3083,10 @@ _FX NTSTATUS File_NtQueryVolumeInformationFile(
|
|||
LeaveCriticalSection(File_DrivesAndLinks_CritSec);
|
||||
}
|
||||
}
|
||||
|
||||
Dll_Free(path);
|
||||
}
|
||||
|
||||
Dll_Free(path);
|
||||
|
||||
status = __sys_NtQueryVolumeInformationFile(
|
||||
handle, IoStatusBlock, FsInformation, Length, FsInformationClass);
|
||||
|
|
|
@ -236,16 +236,6 @@ _FX BOOLEAN File_Init(void)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
if (File_Delete_v2)
|
||||
File_InitDelete_v2();
|
||||
|
||||
// Note: loading the file tha way its done now only works once file hooks are installed so this must eb here
|
||||
extern BOOLEAN Key_Delete_v2;
|
||||
extern BOOLEAN Key_InitDelete_v2();
|
||||
if (Key_Delete_v2)
|
||||
Key_InitDelete_v2();
|
||||
|
||||
//
|
||||
// support for Google Chrome flash plugin process
|
||||
//
|
||||
|
@ -515,7 +505,6 @@ _FX BOOLEAN File_InitDrives(ULONG DriveMask)
|
|||
status = NtOpenSymbolicLinkObject(
|
||||
&handle, SYMBOLIC_LINK_QUERY, &objattrs);
|
||||
|
||||
if (!Dll_CompartmentMode) // NoDriverAssist
|
||||
if (status == STATUS_ACCESS_DENIED) {
|
||||
|
||||
//
|
||||
|
@ -1746,7 +1735,6 @@ _FX void File_GetSetDeviceMap(WCHAR *DeviceMap96)
|
|||
|
||||
status = NtOpenDirectoryObject(&handle, DIRECTORY_QUERY, &objattrs);
|
||||
|
||||
if (!Dll_CompartmentMode) // NoDriverAssist
|
||||
if (status == STATUS_ACCESS_DENIED) {
|
||||
|
||||
//
|
||||
|
|
|
@ -798,13 +798,12 @@ _FX WCHAR *File_TranslateTempLinks_2(WCHAR *input_str, ULONG input_len)
|
|||
|
||||
_FX NTSTATUS File_GetFileName(HANDLE FileHandle, ULONG NameLen, WCHAR* NameBuf)
|
||||
{
|
||||
if (!Dll_CompartmentMode || !__sys_GetFinalPathNameByHandleW) // NoDriverAssist
|
||||
return SbieApi_GetFileName(FileHandle, NameLen, NameBuf);
|
||||
//extern P_GetFinalPathNameByHandle __sys_GetFinalPathNameByHandleW;
|
||||
//if (__sys_GetFinalPathNameByHandleW(FileHandle, NameBuf, NameLen, VOLUME_NAME_NT) > 0)
|
||||
// return STATUS_SUCCESS;
|
||||
//return STATUS_UNSUCCESSFUL;
|
||||
|
||||
// available in vista and later
|
||||
if (__sys_GetFinalPathNameByHandleW(FileHandle, NameBuf, NameLen, VOLUME_NAME_NT) > 0)
|
||||
return STATUS_SUCCESS;
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
return SbieApi_GetFileName(FileHandle, NameLen, NameBuf);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -265,107 +265,143 @@ _FX ULONG File_GetPathFlagsEx(const WCHAR *TruePath, const WCHAR *CopyPath, WCHA
|
|||
|
||||
THREAD_DATA *TlsData = Dll_GetTlsData(NULL);
|
||||
|
||||
//
|
||||
// this function handles the Delete V2 as well as with snapshots
|
||||
//
|
||||
if (File_Delete_v2)
|
||||
{
|
||||
File_RefreshPathTree();
|
||||
|
||||
if (File_Delete_v2) {
|
||||
if(!pRelocation)
|
||||
Dll_PushTlsNameBuffer(TlsData);
|
||||
|
||||
EnterCriticalSection(File_PathRoot_CritSec);
|
||||
|
||||
//
|
||||
// check true path relocation and deleteion for the active state
|
||||
//
|
||||
|
||||
Relocation = NULL;
|
||||
Flags = File_GetPathFlags(TruePath, &Relocation);
|
||||
Flags = File_GetPathFlags_internal(&File_PathRoot, TruePath, &Relocation, TRUE); // this requires a name buffer
|
||||
if (FILE_PATH_DELETED(Flags))
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (Relocation) {
|
||||
if (!File_Snapshot)
|
||||
{
|
||||
if (pRelocation) *pRelocation = Relocation; // return a MISC_NAME_BUFFER buffer valid at the current name buffer depth
|
||||
|
||||
if (!File_Snapshot)
|
||||
goto finish; // take a shortcut
|
||||
goto finish;
|
||||
}
|
||||
|
||||
TruePath = Dll_GetTlsNameBuffer(TlsData, TRUE_NAME_BUFFER, wcslen(Relocation));
|
||||
wcscpy((WCHAR*)TruePath, Relocation);
|
||||
//
|
||||
// Handle snapshots
|
||||
//
|
||||
|
||||
NTSTATUS status;
|
||||
OBJECT_ATTRIBUTES objattrs;
|
||||
UNICODE_STRING objname;
|
||||
ULONG FileType;
|
||||
|
||||
InitializeObjectAttributes(&objattrs, &objname, OBJ_CASE_INSENSITIVE, NULL, NULL);
|
||||
|
||||
//
|
||||
// we need a few helper buffers here, to make it efficient we will exploit
|
||||
// an implementation artefact of the TlsNameBuffer mechanism, namely
|
||||
// the property that after a pop the buffers remain valid untill the next push
|
||||
//
|
||||
// so we can pop out of the current frame request a buffer of the required size
|
||||
// and still read from the buffer that was filled in the previosue frame
|
||||
//
|
||||
|
||||
Dll_PushTlsNameBuffer(TlsData);
|
||||
|
||||
WCHAR* TmplRelocation = Relocation;
|
||||
|
||||
for (FILE_SNAPSHOT* Cur_Snapshot = File_Snapshot; Cur_Snapshot != lastSnapshot; Cur_Snapshot = Cur_Snapshot->Parent)
|
||||
{
|
||||
if (TmplRelocation)
|
||||
{
|
||||
//
|
||||
// update the true file name
|
||||
//
|
||||
|
||||
TruePath = Dll_GetTlsNameBuffer(TlsData, TRUE_NAME_BUFFER, (wcslen(TmplRelocation) + 1) * sizeof(WCHAR));
|
||||
wcscpy((WCHAR*)TruePath, TmplRelocation);
|
||||
|
||||
if (CopyPath)
|
||||
{
|
||||
//
|
||||
// update the copy file name
|
||||
//
|
||||
|
||||
Dll_PushTlsNameBuffer(TlsData);
|
||||
|
||||
WCHAR* TruePath2, * CopyPath2;
|
||||
RtlInitUnicodeString(&objname, TmplRelocation);
|
||||
File_GetName(NULL, &objname, &TruePath2, &CopyPath2, NULL);
|
||||
|
||||
Dll_PopTlsNameBuffer(TlsData);
|
||||
|
||||
// note: pop leaves TruePath2 valid we can still use it
|
||||
|
||||
CopyPath = Dll_GetTlsNameBuffer(TlsData, COPY_NAME_BUFFER, (wcslen(CopyPath2) + 1) * sizeof(WCHAR));
|
||||
wcscpy((WCHAR*)CopyPath, CopyPath2);
|
||||
}
|
||||
}
|
||||
|
||||
if (CopyPath)
|
||||
{
|
||||
//
|
||||
// check if the specified file is present in the current snapshot
|
||||
//
|
||||
|
||||
WCHAR* TmplName = File_MakeSnapshotPath(Cur_Snapshot, CopyPath);
|
||||
if (!TmplName)
|
||||
break; // something went wrong
|
||||
|
||||
RtlInitUnicodeString(&objname, TmplName);
|
||||
status = File_GetFileType(&objattrs, FALSE, &FileType, NULL);
|
||||
if (!(status == STATUS_OBJECT_NAME_NOT_FOUND || status == STATUS_OBJECT_PATH_NOT_FOUND))
|
||||
{
|
||||
Flags |= FILE_INSNAPSHOT_FLAG;
|
||||
Relocation = TmplName;
|
||||
goto complete;
|
||||
}
|
||||
}
|
||||
|
||||
if (File_Delete_v2)
|
||||
{
|
||||
//
|
||||
// check true path relocation and deleteion for the current snapshot
|
||||
//
|
||||
|
||||
TmplRelocation = NULL;
|
||||
Flags = File_GetPathFlags_internal(&Cur_Snapshot->PathRoot, TruePath, &TmplRelocation, TRUE);
|
||||
if(TmplRelocation)
|
||||
Relocation = TmplRelocation;
|
||||
if (FILE_PATH_DELETED(Flags))
|
||||
goto complete;
|
||||
}
|
||||
}
|
||||
|
||||
if (File_Snapshot != NULL) {
|
||||
complete:
|
||||
Dll_PopTlsNameBuffer(TlsData);
|
||||
|
||||
NTSTATUS status;
|
||||
OBJECT_ATTRIBUTES objattrs;
|
||||
UNICODE_STRING objname;
|
||||
ULONG FileType;
|
||||
// note: pop leaves the buffers valid we can still use them
|
||||
|
||||
InitializeObjectAttributes(&objattrs, &objname, OBJ_CASE_INSENSITIVE, NULL, NULL);
|
||||
|
||||
for (FILE_SNAPSHOT* Cur_Snapshot = File_Snapshot; Cur_Snapshot != lastSnapshot; Cur_Snapshot = Cur_Snapshot->Parent)
|
||||
{
|
||||
if (CopyPath) {
|
||||
|
||||
//
|
||||
// check if the specified file is present in the current snapshot
|
||||
//
|
||||
|
||||
WCHAR* TmplName = File_MakeSnapshotPath(Cur_Snapshot, CopyPath);
|
||||
if (!TmplName)
|
||||
break; // something went wrong
|
||||
|
||||
RtlInitUnicodeString(&objname, TmplName);
|
||||
status = File_GetFileType(&objattrs, FALSE, &FileType, NULL);
|
||||
if (!(status == STATUS_OBJECT_NAME_NOT_FOUND || status == STATUS_OBJECT_PATH_NOT_FOUND)) {
|
||||
|
||||
Flags |= FILE_INSNAPSHOT_FLAG;
|
||||
Relocation = TmplName;
|
||||
goto finish;
|
||||
}
|
||||
}
|
||||
|
||||
if (File_Delete_v2) {
|
||||
|
||||
//
|
||||
// check true path relocation and deleteion for the current snapshot
|
||||
//
|
||||
|
||||
Flags = File_GetPathFlags_internal(&Cur_Snapshot->PathRoot, TruePath, &Relocation, TRUE);
|
||||
if (FILE_PATH_DELETED(Flags))
|
||||
goto finish;
|
||||
|
||||
if (Relocation) {
|
||||
|
||||
if (!Cur_Snapshot->Parent)
|
||||
break; // take a shortcut
|
||||
|
||||
TruePath = Dll_GetTlsNameBuffer(TlsData, TRUE_NAME_BUFFER, (wcslen(Relocation) + 1) * sizeof(WCHAR));
|
||||
wcscpy((WCHAR*)TruePath, Relocation);
|
||||
|
||||
if (!CopyPath)
|
||||
continue;
|
||||
|
||||
//
|
||||
// update the copy file name
|
||||
//
|
||||
|
||||
Dll_PushTlsNameBuffer(TlsData);
|
||||
|
||||
WCHAR* TruePath2, *CopyPath2;
|
||||
RtlInitUnicodeString(&objname, Relocation);
|
||||
File_GetName(NULL, &objname, &TruePath2, &CopyPath2, NULL);
|
||||
|
||||
Dll_PopTlsNameBuffer(TlsData);
|
||||
|
||||
// note: pop leaves TruePath2 valid we can still use it
|
||||
|
||||
CopyPath = Dll_GetTlsNameBuffer(TlsData, COPY_NAME_BUFFER, (wcslen(CopyPath2) + 1) * sizeof(WCHAR));
|
||||
wcscpy((WCHAR*)CopyPath, CopyPath2);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pRelocation && Relocation) // return a new TMPL_NAME_BUFFER buffer valid at the current name buffer depth
|
||||
{
|
||||
*pRelocation = Dll_GetTlsNameBuffer(TlsData, TMPL_NAME_BUFFER, (wcslen(Relocation) + 1) * sizeof(WCHAR));
|
||||
wcscpy(*pRelocation, Relocation);
|
||||
}
|
||||
|
||||
finish:
|
||||
|
||||
if (pRelocation) *pRelocation = Relocation; // can be template buffer or move buffer
|
||||
if (File_Delete_v2)
|
||||
{
|
||||
LeaveCriticalSection(File_PathRoot_CritSec);
|
||||
|
||||
if(!pRelocation)
|
||||
Dll_PopTlsNameBuffer(TlsData);
|
||||
}
|
||||
|
||||
return Flags;
|
||||
}
|
||||
|
||||
|
@ -433,8 +469,8 @@ _FX void File_InitSnapshots(void)
|
|||
WCHAR ShapshotId[26] = L"Snapshot_";
|
||||
wcscat(ShapshotId, Shapshot);
|
||||
|
||||
if (File_Delete_v2) {
|
||||
|
||||
if (File_Delete_v2)
|
||||
{
|
||||
WCHAR PathFile[MAX_PATH];
|
||||
wcscpy(PathFile, File_Snapshot_Prefix);
|
||||
wcscat(PathFile, Cur_Snapshot->ID);
|
||||
|
|
|
@ -618,15 +618,13 @@ _FX void Gdi_AddFontsInBox(void)
|
|||
|
||||
if (hFile != INVALID_HANDLE_VALUE) {
|
||||
|
||||
WCHAR *path1 = Dll_AllocTemp(8192);
|
||||
BOOLEAN is_copy = FALSE;
|
||||
NTSTATUS status = SbieDll_GetHandlePath(hFile, path1, &is_copy);
|
||||
NTSTATUS status = SbieDll_GetHandlePath(hFile, NULL, &is_copy);
|
||||
if (NT_SUCCESS(status) && is_copy) {
|
||||
|
||||
Gdi_AddFontsInBox_2(hFile, path1, WinFonts);
|
||||
Gdi_AddFontsInBox_2(hFile, WinFonts);
|
||||
}
|
||||
|
||||
Dll_Free(path1);
|
||||
|
||||
CloseHandle(hFile);
|
||||
}
|
||||
}
|
||||
|
@ -642,7 +640,7 @@ _FX void Gdi_AddFontsInBox(void)
|
|||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
_FX void Gdi_AddFontsInBox_2(HANDLE hFontsDir, void *buf8k, WCHAR *WinFonts)
|
||||
_FX void Gdi_AddFontsInBox_2(HANDLE hFontsDir, WCHAR *WinFonts)
|
||||
{
|
||||
NTSTATUS status;
|
||||
FILE_DIRECTORY_INFORMATION *info;
|
||||
|
@ -651,6 +649,8 @@ _FX void Gdi_AddFontsInBox_2(HANDLE hFontsDir, void *buf8k, WCHAR *WinFonts)
|
|||
ULONG WinFonts_len = wcslen(WinFonts);
|
||||
WinFonts[WinFonts_len] = L'\\';
|
||||
|
||||
WCHAR *buf8k = Dll_AllocTemp(8192);
|
||||
|
||||
while (1) {
|
||||
|
||||
info = (FILE_DIRECTORY_INFORMATION *)buf8k;
|
||||
|
@ -680,6 +680,8 @@ _FX void Gdi_AddFontsInBox_2(HANDLE hFontsDir, void *buf8k, WCHAR *WinFonts)
|
|||
info = (FILE_DIRECTORY_INFORMATION *)next_entry;
|
||||
}
|
||||
}
|
||||
|
||||
Dll_Free(buf8k);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -3496,15 +3496,11 @@ _FX BOOLEAN Ipc_IsKnownDllInSandbox(
|
|||
if (NT_SUCCESS(status)) {
|
||||
|
||||
BOOLEAN IsBoxedPath;
|
||||
WCHAR *path8k = Dll_AllocTemp(8192 * sizeof(WCHAR));
|
||||
|
||||
status = SbieDll_GetHandlePath(handle, path8k, &IsBoxedPath);
|
||||
status = SbieDll_GetHandlePath(handle, NULL, &IsBoxedPath);
|
||||
|
||||
if (NT_SUCCESS(status) && IsBoxedPath)
|
||||
is_known_dll_in_sandbox = TRUE;
|
||||
|
||||
Dll_Free(path8k);
|
||||
|
||||
NtClose(handle);
|
||||
}
|
||||
|
||||
|
|
|
@ -439,6 +439,7 @@ _FX NTSTATUS Key_GetName(
|
|||
ULONG length;
|
||||
WCHAR *name;
|
||||
ULONG objname_len;
|
||||
BOOLEAN is_boxed_path;
|
||||
|
||||
*OutTruePath = NULL;
|
||||
*OutCopyPath = NULL;
|
||||
|
@ -457,16 +458,6 @@ _FX NTSTATUS Key_GetName(
|
|||
|
||||
if (RootDirectory) {
|
||||
|
||||
name = Handle_GetRelocationPath(RootDirectory, objname_len);
|
||||
if (name) {
|
||||
|
||||
*OutTruePath = name;
|
||||
|
||||
name = (*OutTruePath) + wcslen(*OutTruePath);
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
length = 256;
|
||||
name = Dll_GetTlsNameBuffer(
|
||||
TlsData, TRUE_NAME_BUFFER, length + objname_len);
|
||||
|
@ -521,8 +512,6 @@ _FX NTSTATUS Key_GetName(
|
|||
+ ((KEY_NAME_INFORMATION *)name)->NameLength / sizeof(WCHAR);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (objname_len) {
|
||||
|
||||
*name = L'\\';
|
||||
|
@ -605,6 +594,8 @@ _FX NTSTATUS Key_GetName(
|
|||
// and restore the "\REGISTRY" prefix that would have been lost.
|
||||
//
|
||||
|
||||
is_boxed_path = FALSE;
|
||||
|
||||
check_sandbox_prefix:
|
||||
|
||||
if (length >= Dll_BoxKeyPathLen &&
|
||||
|
@ -616,6 +607,7 @@ check_sandbox_prefix:
|
|||
length -= Dll_BoxKeyPathLen - Key_RegistryLen;
|
||||
if (OutIsBoxedPath)
|
||||
*OutIsBoxedPath = TRUE;
|
||||
is_boxed_path = TRUE;
|
||||
|
||||
goto check_sandbox_prefix;
|
||||
}
|
||||
|
@ -669,6 +661,33 @@ check_sandbox_prefix:
|
|||
return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
}
|
||||
|
||||
//
|
||||
// if this is a unboxed path, and we opened it by object,
|
||||
// check path relocation and update true path accordingly.
|
||||
//
|
||||
|
||||
if (!is_boxed_path && RootDirectory) {
|
||||
|
||||
name = Handle_GetRelocationPath(RootDirectory, objname_len);
|
||||
if (name) {
|
||||
|
||||
*OutTruePath = name;
|
||||
|
||||
name = (*OutTruePath) + wcslen(*OutTruePath);
|
||||
|
||||
if (objname_len) {
|
||||
|
||||
*name = L'\\';
|
||||
++name;
|
||||
memcpy(name, ObjectName->Buffer, objname_len);
|
||||
|
||||
name += objname_len / sizeof(WCHAR);
|
||||
}
|
||||
|
||||
*name = L'\0';
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// now create the copy path, which is the box prefix prepended
|
||||
// to the true path that we have. note that the copy path will
|
||||
|
@ -1380,7 +1399,6 @@ _FX NTSTATUS Key_NtCreateKeyImpl(
|
|||
// requested copy key so that we can open it
|
||||
//
|
||||
|
||||
if (!Dll_CompartmentMode) // NoDriverAssist
|
||||
if (status == STATUS_ACCESS_DENIED && Secure_IsRestrictedToken(TRUE)) {
|
||||
|
||||
NTSTATUS status2 = SbieApi_SetLowLabelKey(CopyPath);
|
||||
|
@ -1543,10 +1561,7 @@ _FX NTSTATUS Key_NtCreateKeyImpl(
|
|||
|
||||
int depth = Key_CheckDepthForIsWritePath(TruePath);
|
||||
if (depth == 0) {
|
||||
if (Dll_CompartmentMode) { // NoDriverAssist
|
||||
status = __sys_NtOpenKey(KeyHandle, Wow64KeyReadAccess, &objattrs);
|
||||
} else
|
||||
status = SbieApi_OpenKey(KeyHandle, TruePath);
|
||||
status = SbieApi_OpenKey(KeyHandle, TruePath);
|
||||
if (NT_SUCCESS(status))
|
||||
goto SkipReadOnlyCheck;
|
||||
} else
|
||||
|
@ -1576,9 +1591,13 @@ _FX NTSTATUS Key_NtCreateKeyImpl(
|
|||
// the reason is that if NtSetValueKey has to re-open this key
|
||||
// for write access, it would not be able to pass the WOW64 flag
|
||||
//
|
||||
// this special case makes IMHO no sense, wow registry redirection
|
||||
// acts only on specific paths, and our sanboxed paths do not fall
|
||||
// into that category, hence thay dont need KEY_WOW64_xxKEY flags!
|
||||
//
|
||||
|
||||
if (OriginalDesiredAccess & (KEY_WOW64_32KEY | KEY_WOW64_64KEY))
|
||||
goto SkipReadOnlyCheck;
|
||||
//if (OriginalDesiredAccess & (KEY_WOW64_32KEY | KEY_WOW64_64KEY))
|
||||
// goto SkipReadOnlyCheck;
|
||||
|
||||
if (((DesiredAccess & ~MAXIMUM_ALLOWED) & KEY_DENIED_ACCESS) == 0) {
|
||||
|
||||
|
@ -1731,7 +1750,8 @@ SkipReadOnlyCheck:
|
|||
Key_DiscardMergeByPath(TruePath, TRUE);
|
||||
|
||||
//
|
||||
// Relocation, if we opened the true key and its relocated set the path info
|
||||
// Relocation, if we opened a relocated location we need to
|
||||
// store the original true path for the Key_GetName function
|
||||
//
|
||||
|
||||
if (TrueOpened && OriginalPath) {
|
||||
|
@ -1891,7 +1911,6 @@ _FX NTSTATUS Key_CreatePath(
|
|||
|
||||
status = Key_CreatePath_Key(&handle, objattrs, &disp);
|
||||
|
||||
if (!Dll_CompartmentMode) // NoDriverAssist
|
||||
if (status == STATUS_ACCESS_DENIED && Dll_RestrictedToken) {
|
||||
|
||||
//
|
||||
|
@ -4317,124 +4336,132 @@ _FX NTSTATUS Key_NtRenameKey(
|
|||
status = Key_GetName(KeyHandle, NULL, &TruePath, &CopyPath, NULL);
|
||||
|
||||
WCHAR* TruePathSlash = wcsrchr(TruePath, L'\\');
|
||||
if (!TruePathSlash) {
|
||||
if (!TruePathSlash){
|
||||
status = STATUS_INVALID_PARAMETER;
|
||||
__leave;
|
||||
}
|
||||
|
||||
ULONG len = (ULONG)(TruePathSlash - TruePath + 1);
|
||||
|
||||
NewTruePath = Dll_GetTlsNameBuffer(TlsData, MOVE_NAME_BUFFER,
|
||||
NewTruePath = Dll_GetTlsNameBuffer(TlsData, MISC_NAME_BUFFER,
|
||||
len * sizeof(WCHAR) + ReplacementName->Length + sizeof(WCHAR));
|
||||
|
||||
wmemcpy(NewTruePath, TruePath, len);
|
||||
wmemcpy(NewTruePath + len, ReplacementName->Buffer, ReplacementName->Length / sizeof(WCHAR));
|
||||
NewTruePath[len + ReplacementName->Length / sizeof(WCHAR)] = L'\0';
|
||||
|
||||
}
|
||||
__except (EXCEPTION_EXECUTE_HANDLER) {
|
||||
} __except (EXCEPTION_EXECUTE_HANDLER) {
|
||||
status = GetExceptionCode();
|
||||
}
|
||||
|
||||
if (!NT_SUCCESS(status))
|
||||
goto finish;
|
||||
|
||||
//
|
||||
// check if the target key already exists in the true path
|
||||
//
|
||||
|
||||
WCHAR* NewTruePath2 = NewTruePath;
|
||||
WCHAR* OldTruePath = Key_GetRelocation(NewTruePath);
|
||||
if (OldTruePath)
|
||||
NewTruePath2 = OldTruePath;
|
||||
|
||||
RtlInitUnicodeString(&objname, NewTruePath2);
|
||||
InitializeObjectAttributes(
|
||||
&objattrs, &objname, OBJ_CASE_INSENSITIVE, NULL, NULL);
|
||||
|
||||
status = __sys_NtOpenKey(&handle, KEY_READ, &objattrs);
|
||||
|
||||
if (NT_SUCCESS(status)) {
|
||||
|
||||
if(Key_IsDeleted_v2(NewTruePath))
|
||||
status = STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
|
||||
File_NtCloseImpl(handle);
|
||||
}
|
||||
|
||||
if (status != STATUS_OBJECT_NAME_NOT_FOUND)
|
||||
goto finish;
|
||||
|
||||
//
|
||||
// rename the key ensuring we wil have a boxed copy
|
||||
// try renaming if it fails with access denided try again with a new handle
|
||||
//
|
||||
|
||||
status = __sys_NtRenameKey(KeyHandle, ReplacementName);
|
||||
|
||||
if (status == STATUS_ACCESS_DENIED) {
|
||||
|
||||
//
|
||||
// if we get STATUS_ACCESS_DENIED, the caller may be using a
|
||||
// TruePath handle that was opened with MAXIMUM_ALLOWED, but
|
||||
// reduced to read-only access in our NtCreateKey
|
||||
//
|
||||
|
||||
OBJECT_ATTRIBUTES objattrs;
|
||||
UNICODE_STRING objname;
|
||||
HANDLE handle;
|
||||
|
||||
RtlInitUnicodeString(&objname, L"");
|
||||
InitializeObjectAttributes(
|
||||
&objattrs, &objname, OBJ_CASE_INSENSITIVE, KeyHandle, NULL);
|
||||
|
||||
status = NtOpenKey(&handle, KEY_WRITE, &objattrs);
|
||||
|
||||
if (NT_SUCCESS(status)) {
|
||||
|
||||
status = __sys_NtRenameKey(handle, ReplacementName);
|
||||
|
||||
NtClose(handle);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// check if the true path exists and if so mark path deleted
|
||||
//
|
||||
|
||||
BOOLEAN TrueExists = FALSE;
|
||||
|
||||
WCHAR* TruePath2 = TruePath;
|
||||
|
||||
OldTruePath = Key_GetRelocation(TruePath);
|
||||
if (OldTruePath)
|
||||
TruePath2 = OldTruePath;
|
||||
|
||||
RtlInitUnicodeString(&objname, TruePath2);
|
||||
InitializeObjectAttributes(
|
||||
&objattrs, &objname, OBJ_CASE_INSENSITIVE, NULL, NULL);
|
||||
|
||||
status = __sys_NtOpenKey(&handle, KEY_READ, &objattrs);
|
||||
|
||||
if (NT_SUCCESS(status)) {
|
||||
|
||||
//
|
||||
// check if the target key already exists in the true path
|
||||
// if the true key exists mark it deleted
|
||||
//
|
||||
|
||||
RtlInitUnicodeString(&objname, NewTruePath);
|
||||
InitializeObjectAttributes(
|
||||
&objattrs, &objname, OBJ_CASE_INSENSITIVE, NULL, NULL);
|
||||
TrueExists = TRUE;
|
||||
|
||||
status = __sys_NtOpenKey(&handle, KEY_READ, &objattrs);
|
||||
|
||||
if (NT_SUCCESS(status)) {
|
||||
|
||||
if(!Key_IsDeleted_v2(NewTruePath))
|
||||
status = STATUS_OBJECT_NAME_COLLISION;
|
||||
|
||||
File_NtCloseImpl(handle);
|
||||
}
|
||||
|
||||
//
|
||||
// try renaming if it fails with access denided try again with a new handle
|
||||
//
|
||||
|
||||
if (NT_SUCCESS(status))
|
||||
status = __sys_NtRenameKey(KeyHandle, ReplacementName);
|
||||
|
||||
if (status == STATUS_ACCESS_DENIED) {
|
||||
|
||||
//
|
||||
// if we get STATUS_ACCESS_DENIED, the caller may be using a
|
||||
// TruePath handle that was opened with MAXIMUM_ALLOWED, but
|
||||
// reduced to read-only access in our NtCreateKey
|
||||
//
|
||||
|
||||
OBJECT_ATTRIBUTES objattrs;
|
||||
UNICODE_STRING objname;
|
||||
HANDLE handle;
|
||||
|
||||
RtlInitUnicodeString(&objname, L"");
|
||||
InitializeObjectAttributes(
|
||||
&objattrs, &objname, OBJ_CASE_INSENSITIVE, KeyHandle, NULL);
|
||||
|
||||
status = NtOpenKey(&handle, KEY_WRITE, &objattrs);
|
||||
|
||||
if (NT_SUCCESS(status)) {
|
||||
|
||||
status = __sys_NtRenameKey(handle, ReplacementName);
|
||||
|
||||
NtClose(handle);
|
||||
}
|
||||
}
|
||||
File_NtCloseImpl(handle);
|
||||
}
|
||||
|
||||
//
|
||||
// set the redirection information
|
||||
//
|
||||
|
||||
if (NT_SUCCESS(status)) {
|
||||
if (TrueExists) {
|
||||
|
||||
//*TruePathSlash = L'\0';
|
||||
//Key_DiscardMergeByPath(TruePath, TRUE); // fix-me: act on Key_MergeCacheList
|
||||
//*TruePathSlash = L'\\';
|
||||
|
||||
//
|
||||
// check if the true path exists and if so mark path deleted
|
||||
//
|
||||
|
||||
BOOLEAN TrueExists = FALSE;
|
||||
|
||||
RtlInitUnicodeString(&objname, TruePath);
|
||||
InitializeObjectAttributes(
|
||||
&objattrs, &objname, OBJ_CASE_INSENSITIVE, NULL, NULL);
|
||||
|
||||
status = __sys_NtOpenKey(&handle, KEY_READ, &objattrs);
|
||||
|
||||
if (NT_SUCCESS(status)) {
|
||||
|
||||
//
|
||||
// if the true key exists mark it deleted
|
||||
//
|
||||
|
||||
TrueExists = TRUE;
|
||||
|
||||
File_NtCloseImpl(handle);
|
||||
}
|
||||
|
||||
//
|
||||
// setup/update the key relocation
|
||||
//
|
||||
|
||||
Key_SetRelocation(TruePath, NewTruePath, TrueExists);
|
||||
|
||||
status = STATUS_SUCCESS;
|
||||
Key_SetRelocation(TruePath, NewTruePath);
|
||||
}
|
||||
|
||||
//*TruePathSlash = L'\0';
|
||||
//Key_DiscardMergeByPath(TruePath, TRUE); // fix-me: act on Key_MergeCacheList
|
||||
//*TruePathSlash = L'\\';
|
||||
|
||||
status = STATUS_SUCCESS;
|
||||
|
||||
finish:
|
||||
|
||||
Dll_PopTlsNameBuffer(TlsData);
|
||||
|
||||
return status;
|
||||
|
@ -4474,10 +4501,6 @@ _FX NTSTATUS Key_NtLoadKey(
|
|||
FILE_LOAD_KEY_REQ *req;
|
||||
|
||||
status = __sys_NtLoadKey(TargetObjectAttributes, SourceObjectAttributes);
|
||||
|
||||
if (Dll_CompartmentMode) // NoDriverAssist
|
||||
return status;
|
||||
|
||||
if (status != STATUS_PRIVILEGE_NOT_HELD)
|
||||
return status;
|
||||
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "../../common/my_version.h"
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Key (Delete)
|
||||
//---------------------------------------------------------------------------
|
||||
|
@ -53,6 +55,8 @@
|
|||
static LIST Key_PathRoot;
|
||||
static CRITICAL_SECTION *Key_PathRoot_CritSec = NULL;
|
||||
|
||||
BOOLEAN Key_RegPaths_Loaded = FALSE;
|
||||
|
||||
static HANDLE Key_BoxRootWatcher = NULL;
|
||||
static volatile ULONGLONG Key_PathsVersion = 0; // count reloads
|
||||
|
||||
|
@ -76,13 +80,16 @@ static ULONG Key_IsDeletedEx_v2(const WCHAR* TruePath, const WCHAR* ValueName, B
|
|||
|
||||
VOID File_ClearPathBranche_internal(LIST* parent);
|
||||
VOID File_SavePathTree_internal(LIST* Root, const WCHAR* name);
|
||||
VOID File_LoadPathTree_internal(LIST* Root, const WCHAR* name);
|
||||
BOOLEAN File_LoadPathTree_internal(LIST* Root, const WCHAR* name);
|
||||
VOID File_SetPathFlags_internal(LIST* Root, const WCHAR* Path, ULONG setFlags, ULONG clrFlags, const WCHAR* Relocation);
|
||||
ULONG File_GetPathFlags_internal(LIST* Root, const WCHAR* Path, WCHAR** pRelocation, BOOLEAN CheckChildren);
|
||||
VOID File_SavePathNode_internal(HANDLE hPathsFile, LIST* parent, WCHAR* Path, ULONG Length, ULONG SetFlags);
|
||||
VOID File_MarkDeleted_internal(LIST* Root, const WCHAR* Path);
|
||||
VOID File_SetRelocation_internal(LIST* Root, const WCHAR* OldTruePath, const WCHAR* NewTruePath, BOOLEAN TrueExists);
|
||||
VOID File_SetRelocation_internal(LIST* Root, const WCHAR* OldTruePath, const WCHAR* NewTruePath);
|
||||
|
||||
HANDLE File_AcquireMutex(const WCHAR* MutexName);
|
||||
void File_ReleaseMutex(HANDLE hMutex);
|
||||
#define KEY_VCM_MUTEX SBIE L"_VCM_Mutex"
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
@ -132,11 +139,15 @@ _FX BOOLEAN Key_SavePathTree()
|
|||
|
||||
_FX BOOLEAN Key_LoadPathTree()
|
||||
{
|
||||
HANDLE hMutex = File_AcquireMutex(KEY_VCM_MUTEX);
|
||||
|
||||
EnterCriticalSection(Key_PathRoot_CritSec);
|
||||
|
||||
File_LoadPathTree_internal(&Key_PathRoot, KEY_PATH_FILE_NAME);
|
||||
Key_RegPaths_Loaded = File_LoadPathTree_internal(&Key_PathRoot, KEY_PATH_FILE_NAME);
|
||||
|
||||
LeaveCriticalSection(Key_PathRoot_CritSec);
|
||||
|
||||
File_ReleaseMutex(hMutex);
|
||||
|
||||
Key_PathsVersion++;
|
||||
|
||||
|
@ -206,6 +217,8 @@ _FX NTSTATUS Key_MarkDeletedEx_v2(const WCHAR* TruePath, const WCHAR* ValueName)
|
|||
// add a key/value or directory to the deleted list
|
||||
//
|
||||
|
||||
HANDLE hMutex = File_AcquireMutex(KEY_VCM_MUTEX);
|
||||
|
||||
THREAD_DATA *TlsData = Dll_GetTlsData(NULL);
|
||||
|
||||
WCHAR* FullPath = Dll_GetTlsNameBuffer(TlsData, TMPL_NAME_BUFFER,
|
||||
|
@ -225,6 +238,8 @@ _FX NTSTATUS Key_MarkDeletedEx_v2(const WCHAR* TruePath, const WCHAR* ValueName)
|
|||
|
||||
Key_SavePathTree();
|
||||
|
||||
File_ReleaseMutex(hMutex);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -294,20 +309,24 @@ _FX BOOLEAN Key_HasDeleted_v2(const WCHAR* TruePath)
|
|||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
_FX NTSTATUS Key_SetRelocation(const WCHAR *OldTruePath, const WCHAR *NewTruePath, BOOLEAN TrueExists)
|
||||
_FX NTSTATUS Key_SetRelocation(const WCHAR *OldTruePath, const WCHAR *NewTruePath)
|
||||
{
|
||||
//
|
||||
// List a mapping for the new location
|
||||
//
|
||||
|
||||
HANDLE hMutex = File_AcquireMutex(KEY_VCM_MUTEX);
|
||||
|
||||
EnterCriticalSection(Key_PathRoot_CritSec);
|
||||
|
||||
File_SetRelocation_internal(&Key_PathRoot, OldTruePath, NewTruePath, TrueExists);
|
||||
File_SetRelocation_internal(&Key_PathRoot, OldTruePath, NewTruePath);
|
||||
|
||||
LeaveCriticalSection(Key_PathRoot_CritSec);
|
||||
|
||||
Key_SavePathTree();
|
||||
|
||||
File_ReleaseMutex(hMutex);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -462,7 +462,7 @@ _FX NTSTATUS Key_OpenForMerge(
|
|||
//
|
||||
|
||||
if (use_rule_specificity)
|
||||
Key_MergeCache(NULL, &info.LastWriteTime, TruePath, out_TrueMerge);
|
||||
Key_MergeCache(NULL, &info.LastWriteTime, OriginalPath ? OriginalPath : TruePath, out_TrueMerge);
|
||||
}
|
||||
|
||||
if (! NT_SUCCESS(status)) {
|
||||
|
|
|
@ -28,7 +28,10 @@
|
|||
#include "core/drv/api_defs.h"
|
||||
#include "core/svc/msgids.h"
|
||||
#include "common/my_version.h"
|
||||
|
||||
//#include "core/low/lowdata.h"
|
||||
//
|
||||
//extern SBIELOW_DATA* SbieApi_data;
|
||||
//#define SBIELOW_CALL(x) ((P_##x)&SbieApi_data->x##_code)
|
||||
|
||||
#pragma optimize("",off)
|
||||
|
||||
|
@ -141,9 +144,28 @@ _FX NTSTATUS SbieApi_Ioctl(ULONG64 *parms)
|
|||
// processing a request before sending the next request
|
||||
//
|
||||
|
||||
status = NtDeviceIoControlFile(
|
||||
SbieApi_DeviceHandle, NULL, NULL, NULL, &MyIoStatusBlock,
|
||||
API_SBIEDRV_CTLCODE, parms, sizeof(ULONG64) * 8, NULL, 0);
|
||||
extern P_NtDeviceIoControlFile __sys_NtDeviceIoControlFile;
|
||||
if (__sys_NtDeviceIoControlFile) {
|
||||
|
||||
//
|
||||
// once NtDeviceIoControlFile is hooked, bypass it
|
||||
//
|
||||
|
||||
status = __sys_NtDeviceIoControlFile(
|
||||
SbieApi_DeviceHandle, NULL, NULL, NULL, &MyIoStatusBlock,
|
||||
API_SBIEDRV_CTLCODE, parms, sizeof(ULONG64) * 8, NULL, 0);
|
||||
|
||||
} else {
|
||||
|
||||
status = NtDeviceIoControlFile(
|
||||
SbieApi_DeviceHandle, NULL, NULL, NULL, &MyIoStatusBlock,
|
||||
API_SBIEDRV_CTLCODE, parms, sizeof(ULONG64) * 8, NULL, 0);
|
||||
}
|
||||
|
||||
// that would be even better but would only work in the native case
|
||||
//status = SBIELOW_CALL(NtDeviceIoControlFile)(
|
||||
// SbieApi_DeviceHandle, NULL, NULL, NULL, &MyIoStatusBlock,
|
||||
// API_SBIEDRV_CTLCODE, parms, sizeof(ULONG64) * 8, NULL, 0);
|
||||
}
|
||||
|
||||
return status;
|
||||
|
|
|
@ -615,6 +615,11 @@ void* Driver_FindMissingService(const char* ProcName, int prmcnt)
|
|||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Driver_FindMissingServices
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
_FX BOOLEAN Driver_FindMissingServices(void)
|
||||
{
|
||||
#ifdef OLD_DDK
|
||||
|
|
|
@ -644,7 +644,6 @@ _FX POBJECT_TYPE Obj_GetTypeObjectType(void)
|
|||
(POBJECT_TYPE *)(ptr + i + 7 + offset);
|
||||
}
|
||||
}
|
||||
DbgPrint("pObTypeIndexTable = %p\n", pObTypeIndexTable);
|
||||
}
|
||||
#else ! _WIN64
|
||||
UCHAR k = 0;
|
||||
|
@ -661,9 +660,8 @@ _FX POBJECT_TYPE Obj_GetTypeObjectType(void)
|
|||
pObTypeIndexTable = (POBJECT_TYPE *)*ptr2;
|
||||
}
|
||||
}
|
||||
|
||||
#endif _WIN64
|
||||
|
||||
//DbgPrint("pObTypeIndexTable = %p\n", pObTypeIndexTable);
|
||||
}
|
||||
|
||||
if (! pObTypeIndexTable) {
|
||||
|
|
Loading…
Reference in New Issue