From 5b2cf70e4ffeda1d908768f55495801ee2b01f6a Mon Sep 17 00:00:00 2001 From: DavidXanatos <3890945+DavidXanatos@users.noreply.github.com> Date: Sun, 25 Feb 2024 16:27:25 +0100 Subject: [PATCH] #3632 --- CHANGELOG.md | 5 ++ Sandboxie/core/dll/file.c | 15 +++--- Sandboxie/core/dll/file_init.c | 31 ++++++++++-- Sandboxie/core/dll/file_link.c | 90 ++++++++++++++++------------------ 4 files changed, 82 insertions(+), 59 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8b3e6610..6bc7181c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,11 @@ This project adheres to [Semantic Versioning](http://semver.org/). ### Changed - changed DynData format to add flags +- Revert or provide a way to opt out of the new sandbox directory structure for volumes without drive letters [#3632](https://github.com/sandboxie-plus/Sandboxie/issues/3632) + - guid usage can be re-enabled with "UseVolumeGuidWhenNoLetter=y" + +### Removed +- removed UseNewSymlinkResolver setting new mechanism is always used diff --git a/Sandboxie/core/dll/file.c b/Sandboxie/core/dll/file.c index 724c30b6..89d8d164 100644 --- a/Sandboxie/core/dll/file.c +++ b/Sandboxie/core/dll/file.c @@ -363,9 +363,9 @@ static WCHAR *File_PublicUser = NULL; static ULONG File_PublicUserLen = 0; static BOOLEAN File_DriveAddSN = FALSE; +static BOOLEAN File_UseVolumeGuid = FALSE; BOOLEAN File_Delete_v2 = FALSE; -static BOOLEAN File_NoReparse = FALSE; static WCHAR *File_AltBoxPath = NULL; static ULONG File_AltBoxPathLen = 0; @@ -572,13 +572,13 @@ _FX NTSTATUS File_GetCopyPathImpl(WCHAR* TruePath, WCHAR **OutCopyPath, ULONG *O ULONG drive_len; + guid = NULL; drive = File_GetDriveForPath(TruePath, length); if (drive) drive_len = drive->len; else drive = File_GetDriveForUncPath(TruePath, length, &drive_len); - - if (!drive) + if (!drive && File_UseVolumeGuid) guid = File_GetGuidForPath(TruePath, length); if (drive || guid) { @@ -763,9 +763,8 @@ check_sandbox_prefix: drive = NULL; guid = NULL; - if (name[_DriveLen - 1] == L'\\') { - if (name[_DriveLen] == L'{') + if (name[_DriveLen] == L'{' && File_UseVolumeGuid) guid = File_GetLinkForGuid(&name[_DriveLen]); else drive = File_GetDriveForLetter(name[_DriveLen]); @@ -1131,8 +1130,10 @@ _FX NTSTATUS File_GetName( // the next section of code from trying to translate symlinks // - drive = File_GetDriveForPath(objname_buf, objname_len / sizeof(WCHAR)); - if(!drive) + guid = NULL; + drive = File_GetDriveForPath( + objname_buf, objname_len / sizeof(WCHAR)); + if(!drive && File_UseVolumeGuid) guid = File_GetGuidForPath(objname_buf, objname_len / sizeof(WCHAR)); if (drive || guid) { diff --git a/Sandboxie/core/dll/file_init.c b/Sandboxie/core/dll/file_init.c index b607bd82..3a0fab4d 100644 --- a/Sandboxie/core/dll/file_init.c +++ b/Sandboxie/core/dll/file_init.c @@ -144,7 +144,7 @@ _FX BOOLEAN File_Init(void) File_DriveAddSN = SbieApi_QueryConfBool(NULL, L"UseVolumeSerialNumbers", FALSE); - File_NoReparse = SbieApi_QueryConfBool(NULL, L"NoPathReparse", FALSE); + File_UseVolumeGuid = SbieApi_QueryConfBool(NULL, L"UseVolumeGuidWhenNoLetter", FALSE); if (! File_InitDrives(0xFFFFFFFF)) return FALSE; @@ -878,6 +878,25 @@ _FX void File_InitLinks(THREAD_DATA *TlsData) DosPath += wcslen(DosPath) + 1; } + } else if (File_UseVolumeGuid) { + + // handle the case where the volume is not mounted as a + // drive letter: + // add reparse points for all mounted directories + + // + // This behavioure creates \[BoxRoot]\drive\{guid} fodlers + // instead of using the first mount point on a volume with a letter + // + + WCHAR *FirstDosPath = DosPath; + File_AddLink(TRUE, FirstDosPath, DeviceName); + DosPath += DosPathLen + 1; + while (*DosPath) { + File_AddLink(TRUE, DosPath, DeviceName); + DosPath += wcslen(DosPath) + 1; + } + } else { // @@ -889,11 +908,17 @@ _FX void File_InitLinks(THREAD_DATA *TlsData) // also to the first mounted directory // + // + // Note: this behavioure makes the first mounted directory + // the location in the box where all files for that volume will be located + // other mount points will be redirected to this folder + // + WCHAR *FirstDosPath = DosPath; - File_AddLink(TRUE, FirstDosPath, DeviceName); + File_AddLink(TRUE, DeviceName, FirstDosPath); DosPath += DosPathLen + 1; while (*DosPath) { - File_AddLink(TRUE, DosPath, DeviceName); + File_AddLink(TRUE, DosPath, FirstDosPath); DosPath += wcslen(DosPath) + 1; } } diff --git a/Sandboxie/core/dll/file_link.c b/Sandboxie/core/dll/file_link.c index 81f8582f..9969cd88 100644 --- a/Sandboxie/core/dll/file_link.c +++ b/Sandboxie/core/dll/file_link.c @@ -604,9 +604,6 @@ _FX WCHAR *File_TranslateTempLinks( WCHAR *ret; ULONG TruePath_len, ret_len; - if (File_NoReparse) - return NULL; - // // entry // @@ -1022,72 +1019,67 @@ _FX FILE_LINK *File_AddTempLink(WCHAR *path) stop = TRUE; newpath = NULL; + + status = File_OpenForAddTempLink(&handle, path, FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_REPARSE_POINT); - BOOLEAN UserReparse = SbieApi_QueryConfBool(NULL, L"UseNewSymlinkResolver", TRUE); + if (NT_SUCCESS(status)) { - if (UserReparse) { - - status = File_OpenForAddTempLink(&handle, path, FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_REPARSE_POINT); + REPARSE_DATA_BUFFER* reparseDataBuffer = Dll_AllocTemp(MAXIMUM_REPARSE_DATA_BUFFER_SIZE); + status = pNtFsControlFile(handle, NULL, NULL, NULL, &IoStatusBlock, FSCTL_GET_REPARSE_POINT, NULL, 0, reparseDataBuffer, MAXIMUM_REPARSE_DATA_BUFFER_SIZE); if (NT_SUCCESS(status)) { - REPARSE_DATA_BUFFER* reparseDataBuffer = Dll_AllocTemp(MAXIMUM_REPARSE_DATA_BUFFER_SIZE); - status = pNtFsControlFile(handle, NULL, NULL, NULL, &IoStatusBlock, FSCTL_GET_REPARSE_POINT, NULL, 0, reparseDataBuffer, MAXIMUM_REPARSE_DATA_BUFFER_SIZE); + WCHAR* SubstituteNameBuffer = NULL; + //WCHAR* PrintNameBuffer = NULL; + BOOL RelativePath = FALSE; - if (NT_SUCCESS(status)) { + if (reparseDataBuffer->ReparseTag == IO_REPARSE_TAG_SYMLINK) + { + SubstituteNameBuffer = &reparseDataBuffer->SymbolicLinkReparseBuffer.PathBuffer[reparseDataBuffer->SymbolicLinkReparseBuffer.SubstituteNameOffset/sizeof(WCHAR)]; + if (reparseDataBuffer->SymbolicLinkReparseBuffer.Flags & SYMLINK_FLAG_RELATIVE) + RelativePath = TRUE; + SubstituteNameBuffer[reparseDataBuffer->SymbolicLinkReparseBuffer.SubstituteNameLength / sizeof(WCHAR)] = 0; + } + else if (reparseDataBuffer->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT) + { + SubstituteNameBuffer = &reparseDataBuffer->MountPointReparseBuffer.PathBuffer[reparseDataBuffer->MountPointReparseBuffer.SubstituteNameOffset/sizeof(WCHAR)]; + SubstituteNameBuffer[reparseDataBuffer->MountPointReparseBuffer.SubstituteNameLength / sizeof(WCHAR)] = 0; + } - WCHAR* SubstituteNameBuffer = NULL; - //WCHAR* PrintNameBuffer = NULL; - BOOL RelativePath = FALSE; - - if (reparseDataBuffer->ReparseTag == IO_REPARSE_TAG_SYMLINK) + if (SubstituteNameBuffer) + { + if (RelativePath) { - SubstituteNameBuffer = &reparseDataBuffer->SymbolicLinkReparseBuffer.PathBuffer[reparseDataBuffer->SymbolicLinkReparseBuffer.SubstituteNameOffset/sizeof(WCHAR)]; - if (reparseDataBuffer->SymbolicLinkReparseBuffer.Flags & SYMLINK_FLAG_RELATIVE) - RelativePath = TRUE; - SubstituteNameBuffer[reparseDataBuffer->SymbolicLinkReparseBuffer.SubstituteNameLength / sizeof(WCHAR)] = 0; + // todo RelativePath - for now we fall back to the old method } - else if (reparseDataBuffer->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT) + else { - SubstituteNameBuffer = &reparseDataBuffer->MountPointReparseBuffer.PathBuffer[reparseDataBuffer->MountPointReparseBuffer.SubstituteNameOffset/sizeof(WCHAR)]; - SubstituteNameBuffer[reparseDataBuffer->MountPointReparseBuffer.SubstituteNameLength / sizeof(WCHAR)] = 0; - } + WCHAR* input_str = SubstituteNameBuffer; + if (_wcsnicmp(input_str, L"\\??\\Volume{", 11) == 0) + input_str = File_TranslateGuidToNtPath(SubstituteNameBuffer); + else if (_wcsnicmp(input_str, File_BQQB, 4) == 0) + input_str = File_TranslateDosToNtPath(SubstituteNameBuffer + 4); - if (SubstituteNameBuffer) - { - if (RelativePath) - { - // todo RelativePath - for now we fall back to the old method - } - else - { - WCHAR* input_str = SubstituteNameBuffer; - if (_wcsnicmp(input_str, L"\\??\\Volume{", 11) == 0) - input_str = File_TranslateGuidToNtPath(SubstituteNameBuffer); - else if (_wcsnicmp(input_str, File_BQQB, 4) == 0) - input_str = File_TranslateDosToNtPath(SubstituteNameBuffer + 4); + if (input_str) { - if (input_str) { + ULONG input_len = wcslen(input_str); + while (input_len > 0 && input_str[input_len - 1] == L'\\') + input_len -= 1; // remove trailing backslash - ULONG input_len = wcslen(input_str); - while (input_len > 0 && input_str[input_len - 1] == L'\\') - input_len -= 1; // remove trailing backslash + newpath = File_TranslateTempLinks_2(input_str, input_len); - newpath = File_TranslateTempLinks_2(input_str, input_len); - - if (input_str != SubstituteNameBuffer) - Dll_Free(input_str); - } + if (input_str != SubstituteNameBuffer) + Dll_Free(input_str); } } } - //else if (status == STATUS_NOT_A_REPARSE_POINT) + } + //else if (status == STATUS_NOT_A_REPARSE_POINT) - Dll_Free(reparseDataBuffer); + Dll_Free(reparseDataBuffer); - pNtClose(handle); - } + pNtClose(handle); } const ULONG PATH_BUF_LEN = 1024;