symlink fix

This commit is contained in:
DavidXanatos 2024-04-28 11:03:12 +02:00
parent 9df1e546cd
commit fe10924e71
4 changed files with 116 additions and 68 deletions

View File

@ -11,12 +11,10 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- added file version information for SbieDll.dll and SbieSvc.exe in the Sandboxie Plus About dialog
### Changed
- when creating reparse points (symlinks/junctions), the target path remains the TruePath [#3852](https://github.com/sandboxie-plus/Sandboxie/issues/3852)
- the old behaviour can be restored with "BoxReparseTarget=y"
- this change should work fine with the recent improvements in handling reparse points
- improved checkboxes about DropAdminRights in SandMan [#3851](https://github.com/sandboxie-plus/Sandboxie/pull/3851) (thanks offhub)
### Fixed
- Issue with symbolic linking of files [#3852](https://github.com/sandboxie-plus/Sandboxie/issues/3852)
- fixed issue with start agent option [#3844](https://github.com/sandboxie-plus/Sandboxie/pull/3844) (thanks offhub)
- fixed issue with Delete V2 introduced in 1.13.5

View File

@ -262,6 +262,9 @@ static NTSTATUS File_NtDeleteFile(OBJECT_ATTRIBUTES *ObjectAttributes);
static NTSTATUS File_NtDeleteFileImpl(OBJECT_ATTRIBUTES *ObjectAttributes);
static NTSTATUS File_OpenForRenameFile(
HANDLE* pSourceHandle, const WCHAR *TruePath);
static NTSTATUS File_RenameFile(
HANDLE FileHandle, void *info, BOOLEAN LinkOp);
@ -6659,6 +6662,63 @@ _FX LONG File_RenameOpenFile(
}
//---------------------------------------------------------------------------
// File_OpenForRenameFile
//---------------------------------------------------------------------------
_FX NTSTATUS File_OpenForRenameFile(
HANDLE* pSourceHandle, const WCHAR *TruePath)
{
THREAD_DATA *TlsData = Dll_GetTlsData(NULL);
NTSTATUS status;
OBJECT_ATTRIBUTES objattrs;
UNICODE_STRING objname;
IO_STATUS_BLOCK IoStatusBlock;
InitializeObjectAttributes(
&objattrs, &objname, OBJ_CASE_INSENSITIVE, NULL, Secure_NormalSD);
//
// open the file for write access. this should cause the file
// to be migrated into the sandbox, including its parent directories
//
RtlInitUnicodeString(&objname, TruePath);
++TlsData->file_dont_strip_write_access;
status = NtCreateFile(
pSourceHandle, FILE_GENERIC_WRITE | DELETE, &objattrs,
&IoStatusBlock, NULL, 0, FILE_SHARE_VALID_FLAGS,
FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0);
if (status == STATUS_SHARING_VIOLATION ||
status == STATUS_ACCESS_DENIED) {
//
// Windows Mail opens *.eml files with a combination of
// FILE_SHARE_READ | FILE_SHARE_DELETE, but not FILE_SHARE_WRITE,
// which means we can't open them with FILE_GENERIC_WRITE
// during rename processing here
//
// also, for read-only files, we get an error when we open them
// for FILE_GENERIC_WRITE, but just DELETE should also work
//
status = NtCreateFile(
pSourceHandle, SYNCHRONIZE | DELETE, &objattrs,
&IoStatusBlock, NULL, 0, FILE_SHARE_VALID_FLAGS,
FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0);
}
--TlsData->file_dont_strip_write_access;
return status;
}
//---------------------------------------------------------------------------
// File_RenameFile
//---------------------------------------------------------------------------
@ -6718,52 +6778,23 @@ _FX NTSTATUS File_RenameFile(
__leave;
//
// open the file for write access. this should cause the file
// to be migrated into the sandbox, including its parent directories
// migrate into the sandbox, including its parent directories
//
RtlInitUnicodeString(&objname, TruePath);
status = File_OpenForRenameFile(&SourceHandle, TruePath);
++TlsData->file_dont_strip_write_access;
//
// if we still get STATUS_SHARING_VIOLATION, give up on trying
// to make sure the file is migrated into the sandbox, and hope
// that the input FileHandle is suitable for a rename operation
//
status = NtCreateFile(
&SourceHandle, FILE_GENERIC_WRITE | DELETE, &objattrs,
&IoStatusBlock, NULL, 0, FILE_SHARE_VALID_FLAGS,
FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0);
if (status == STATUS_SHARING_VIOLATION) {
if (status == STATUS_SHARING_VIOLATION ||
status == STATUS_ACCESS_DENIED) {
//
// Windows Mail opens *.eml files with a combination of
// FILE_SHARE_READ | FILE_SHARE_DELETE, but not FILE_SHARE_WRITE,
// which means we can't open them with FILE_GENERIC_WRITE
// during rename processing here
//
// also, for read-only files, we get an error when we open them
// for FILE_GENERIC_WRITE, but just DELETE should also work
//
status = NtCreateFile(
&SourceHandle, SYNCHRONIZE | DELETE, &objattrs,
&IoStatusBlock, NULL, 0, FILE_SHARE_VALID_FLAGS,
FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0);
//
// if we still get STATUS_SHARING_VIOLATION, give up on trying
// to make sure the file is migrated into the sandbox, and hope
// that the input FileHandle is suitable for a rename operation
//
if (status == STATUS_SHARING_VIOLATION) {
SourceHandle = FileHandle;
status = STATUS_SUCCESS;
}
SourceHandle = FileHandle;
status = STATUS_SUCCESS;
}
--TlsData->file_dont_strip_write_access;
if (! NT_SUCCESS(status))
__leave;

View File

@ -3170,7 +3170,8 @@ _FX NTSTATUS File_NtQueryVolumeInformationFile(
_FX NTSTATUS File_SetReparsePoint(
HANDLE FileHandle, PREPARSE_DATA_BUFFER Data, ULONG DataLen)
{
THREAD_DATA *TlsData;
THREAD_DATA *TlsData = Dll_GetTlsData(NULL);
NTSTATUS status;
UNICODE_STRING objname;
OBJECT_ATTRIBUTES objattrs;
@ -3180,13 +3181,15 @@ _FX NTSTATUS File_SetReparsePoint(
PREPARSE_DATA_BUFFER NewData = NULL;
ULONG NewDataLen;
IO_STATUS_BLOCK MyIoStatusBlock;
BOOLEAN MigrateTarget = FALSE;
if (! Data)
return STATUS_BAD_INITIAL_PC;
//
// get paths to source and target directories
//
TlsData = Dll_GetTlsData(NULL);
Dll_PushTlsNameBuffer(TlsData);
__try {
@ -3194,10 +3197,6 @@ _FX NTSTATUS File_SetReparsePoint(
WCHAR* SubstituteNameBuffer;
USHORT PrintNameLength;
WCHAR* PrintNameBuffer;
//BOOLEAN RelativePath = FALSE;
if (! Data)
return STATUS_BAD_INITIAL_PC;
if (Data->ReparseTag == IO_REPARSE_TAG_SYMLINK)
{
@ -3205,8 +3204,16 @@ _FX NTSTATUS File_SetReparsePoint(
SubstituteNameBuffer = &Data->SymbolicLinkReparseBuffer.PathBuffer[Data->SymbolicLinkReparseBuffer.SubstituteNameOffset/sizeof(WCHAR)];
PrintNameLength = Data->SymbolicLinkReparseBuffer.PrintNameLength;
PrintNameBuffer = &Data->SymbolicLinkReparseBuffer.PathBuffer[Data->SymbolicLinkReparseBuffer.PrintNameOffset/sizeof(WCHAR)];
if (Data->SymbolicLinkReparseBuffer.Flags & SYMLINK_FLAG_RELATIVE)
return STATUS_BAD_INITIAL_PC; //RelativePath = TRUE; // let it be done normally
if (Data->SymbolicLinkReparseBuffer.Flags & SYMLINK_FLAG_RELATIVE) {
//
// We can allow for a relative path in the box but must ensure the hatget gets migrated
//
MigrateTarget = TRUE;
status = STATUS_BAD_INITIAL_PC;
__leave;
}
NewDataLen = (UFIELD_OFFSET(REPARSE_DATA_BUFFER, SymbolicLinkReparseBuffer.PathBuffer) - UFIELD_OFFSET(REPARSE_DATA_BUFFER, GenericReparseBuffer));
}
@ -3219,14 +3226,17 @@ _FX NTSTATUS File_SetReparsePoint(
NewDataLen = (UFIELD_OFFSET(REPARSE_DATA_BUFFER, MountPointReparseBuffer.PathBuffer) - UFIELD_OFFSET(REPARSE_DATA_BUFFER, GenericReparseBuffer));
}
else
return STATUS_BAD_INITIAL_PC;
else {
status = STATUS_BAD_INITIAL_PC;
__leave;
}
//
// get copy path of reparse source
//
RtlInitUnicodeString(&objname, L"");
InitializeObjectAttributes(
&objattrs, &objname, OBJ_CASE_INSENSITIVE, NULL, NULL);
@ -3320,17 +3330,14 @@ _FX NTSTATUS File_SetReparsePoint(
if (NT_SUCCESS(status)) {
File_CreateBoxedPath(TruePath);
status = __sys_NtFsControlFile(
FileHandle, NULL, NULL, NULL,
&MyIoStatusBlock, FSCTL_SET_REPARSE_POINT,
NewData, NewDataLen,
NULL, 0);
}
if (NewData)
Dll_Free(NewData);
MigrateTarget = NT_SUCCESS(status);
}
/*
//
@ -3378,6 +3385,23 @@ _FX NTSTATUS File_SetReparsePoint(
if (TargetPath)
Dll_Free(TargetPath);*/
if (MigrateTarget) {
//
// We must migrate the file or directory into the sandbox as the path reparsing by NtCreateFile
// is done by the kernel and we do not "manually" reparse the path before invoking it,
// hence there must be the expected file at the path we are linking to.
//
HANDLE SourceHandle;
status = File_OpenForRenameFile(&SourceHandle, TruePath);
if (NT_SUCCESS(status))
NtClose(SourceHandle);
}
if (NewData)
Dll_Free(NewData);
Dll_PopTlsNameBuffer(TlsData);
return status;

View File

@ -1152,17 +1152,11 @@ _FX NTSTATUS File_NtFsControlFile(
handle = File_GetProxyPipe(FileHandle, NULL);
if (! handle) {
status = STATUS_BAD_INITIAL_PC;
if (IoControlCode == FSCTL_SET_REPARSE_POINT) {
BOOLEAN BoxReparseTarget = SbieApi_QueryConfBool(NULL, L"BoxReparseTarget", FALSE);
if(BoxReparseTarget) {
status = File_SetReparsePoint(
FileHandle, InputBuffer, InputBufferLength);
SetLastError(LastError);
}
status = File_SetReparsePoint(
FileHandle, InputBuffer, InputBufferLength);
SetLastError(LastError);
} else if (IoControlCode == FSCTL_PIPE_WAIT) {
@ -1178,7 +1172,8 @@ _FX NTSTATUS File_NtFsControlFile(
else
status = STATUS_ACCESS_DENIED;
}
} else
status = STATUS_BAD_INITIAL_PC;
if (status == STATUS_BAD_INITIAL_PC) {