This commit is contained in:
DavidXanatos 2022-04-30 21:52:52 +02:00
parent d2373bf738
commit 339c72ff16
21 changed files with 650 additions and 427 deletions

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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);
}
}

View File

@ -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;

View File

@ -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)) {

View File

@ -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;
}

View File

@ -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);

View File

@ -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) {
//

View File

@ -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);
}

View File

@ -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);

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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)) {

View File

@ -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;

View File

@ -615,6 +615,11 @@ void* Driver_FindMissingService(const char* ProcName, int prmcnt)
}
//---------------------------------------------------------------------------
// Driver_FindMissingServices
//---------------------------------------------------------------------------
_FX BOOLEAN Driver_FindMissingServices(void)
{
#ifdef OLD_DDK

View File

@ -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) {