From 4747d0ecf9fe4e079bb898fa222cbb2565be3485 Mon Sep 17 00:00:00 2001 From: DavidXanatos <3890945+DavidXanatos@users.noreply.github.com> Date: Tue, 17 Dec 2024 11:19:09 +0100 Subject: [PATCH] 1.15.4 --- CHANGELOG.md | 3 +++ Sandboxie/core/drv/process_api.c | 20 ++++++++++++++++-- Sandboxie/core/drv/thread_token.c | 15 ++++++++++++-- Sandboxie/core/svc/ProcessServer.cpp | 31 ++++++++++++++++++++++------ 4 files changed, 59 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f30ff21e..9fceef80 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,9 @@ This project adheres to [Semantic Versioning](http://semver.org/). - fixed Firefox tab crashes when running with `ProtectHostImages=y` enabled [#4394](https://github.com/sandboxie-plus/Sandboxie/issues/4394) - Only default installation locations are considered; Firefox-based browsers installed outside of these locations may still crash. - To prevent this, manually add `DontCopy=` for custom installation paths to your configuration +- fixed BSOD "SYSTEM_SERVICE_EXCEPTION (3b)" when opening a DLL from AlertFolder using x64dbg [#4421](https://github.com/sandboxie-plus/Sandboxie/issues/4421) +- fixed BSoD "CRITICAL_PROCESS_DIED" when terminate all sandboxed programs [#1316](https://github.com/sandboxie-plus/Sandboxie/issues/1316) + - Note: we now terminate boxed processes individually instead of terminating using the job object, unless "TerminateJobObject=y" is set diff --git a/Sandboxie/core/drv/process_api.c b/Sandboxie/core/drv/process_api.c index f8284948..51fdbf3c 100644 --- a/Sandboxie/core/drv/process_api.c +++ b/Sandboxie/core/drv/process_api.c @@ -1173,12 +1173,28 @@ _FX NTSTATUS Process_Api_Kill(PROCESS *proc, ULONG64 *parms) if (NT_SUCCESS(status)) { - status = ObOpenObjectByPointer(ProcessObject, OBJ_KERNEL_HANDLE, NULL, PROCESS_TERMINATE, NULL, KernelMode, &handle); + status = ObOpenObjectByPointer(ProcessObject, OBJ_KERNEL_HANDLE, NULL, PROCESS_TERMINATE | PROCESS_QUERY_INFORMATION | PROCESS_SET_INFORMATION, NULL, KernelMode, &handle); ObDereferenceObject(ProcessObject); if (NT_SUCCESS(status)) { - ZwTerminateProcess(handle, DBG_TERMINATE_PROCESS); + // + // Check and if needed clear critical process flag + // + + ULONG breakOnTermination; + status = ZwQueryInformationProcess(handle, ProcessBreakOnTermination, &breakOnTermination, sizeof(ULONG), NULL); + if (NT_SUCCESS(status) && breakOnTermination) { + breakOnTermination = 0; + status = ZwSetInformationProcess(handle, ProcessBreakOnTermination, &breakOnTermination, sizeof(ULONG)); + } + + // + // Terminate + // + + if (NT_SUCCESS(status)) + ZwTerminateProcess(handle, DBG_TERMINATE_PROCESS); ZwClose(handle); } } diff --git a/Sandboxie/core/drv/thread_token.c b/Sandboxie/core/drv/thread_token.c index 1041808e..51e982a2 100644 --- a/Sandboxie/core/drv/thread_token.c +++ b/Sandboxie/core/drv/thread_token.c @@ -319,8 +319,15 @@ _FX NTSTATUS Thread_SetInformationProcess( PROCESS *proc, SYSCALL_ENTRY *syscall_entry, ULONG_PTR *user_args) { NTSTATUS status; + + ULONG InfoClass = (ULONG)user_args[1]; + + if (InfoClass == ProcessBreakOnTermination) { + + status = STATUS_ACCESS_DENIED; + //Windows RS5 adds a new "undocumented" Process Information class: 0x5d (93) that is likely ProcessAccessTokenEx - if (((user_args[1] == ProcessAccessToken) || (user_args[1] == ProcessAccessTokenEx)) && proc->primary_token) { + } else if (((InfoClass == ProcessAccessToken) || (InfoClass == ProcessAccessTokenEx)) && proc->primary_token) { HANDLE ProcessHandle = (HANDLE)user_args[0]; void *InfoBuffer = (void *)user_args[2]; ULONG InfoLength = (ULONG)user_args[3]; @@ -1151,7 +1158,11 @@ _FX NTSTATUS Thread_SetInformationThread( ULONG InfoClass = (ULONG)user_args[1]; - if (InfoClass == ThreadImpersonationToken && proc->primary_token) { + if (InfoClass == ThreadBreakOnTermination){ + + status = STATUS_ACCESS_DENIED; + + } else if (InfoClass == ThreadImpersonationToken && proc->primary_token) { HANDLE ThreadHandle = (HANDLE)user_args[0]; void *InfoBuffer = (void *)user_args[2]; diff --git a/Sandboxie/core/svc/ProcessServer.cpp b/Sandboxie/core/svc/ProcessServer.cpp index dc6b8dfe..05e0291e 100644 --- a/Sandboxie/core/svc/ProcessServer.cpp +++ b/Sandboxie/core/svc/ProcessServer.cpp @@ -130,13 +130,32 @@ BOOL ProcessServer::KillProcess(ULONG ProcessId) { ULONG LastError = 0; BOOL ok = FALSE; - HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, ProcessId); + HANDLE hProcess = OpenProcess(PROCESS_TERMINATE | PROCESS_QUERY_LIMITED_INFORMATION, FALSE, ProcessId); if (! hProcess) LastError = GetLastError() * 10000; else { - ok = TerminateProcess(hProcess, DBG_TERMINATE_PROCESS); - if (! ok) - LastError = GetLastError(); + + // + // Bevore terminating any process, check if still its a sandboxed process as PID's get reused, + // but not as long as a handle is open, hence chacking after OpenProcess remains valid untill CloseHandle + // + // also check if process was marked as critical process + // + + if (!SbieApi_QueryProcessInfo((HANDLE)(ULONG_PTR)ProcessId, 0)) + ok = TRUE; + else { + + NTSTATUS status; + ULONG breakOnTermination; + status = NtQueryInformationProcess(hProcess, ProcessBreakOnTermination, &breakOnTermination, sizeof(ULONG), NULL); + if (NT_SUCCESS(status) && !breakOnTermination) { + + ok = TerminateProcess(hProcess, DBG_TERMINATE_PROCESS); + if (!ok) + LastError = GetLastError(); + } + } CloseHandle(hProcess); } @@ -269,8 +288,8 @@ MSG_HEADER *ProcessServer::KillAllHandler(MSG_HEADER *msg) if (status != STATUS_INVALID_CID) // if this is true the caller is boxed, should be rpcss TerminateJob = FALSE; // if rpcss requests box termination, don't use the job method, fix-me: we get some stuck request in the queue - else - TerminateJob = !SbieApi_QueryConfBool(TargetBoxName, L"NoAddProcessToJob", FALSE); + else if (!SbieApi_QueryConfBool(TargetBoxName, L"NoAddProcessToJob", FALSE) && !SbieApi_QueryConfBool(TargetBoxName, L"NoSecurityIsolation", FALSE)) + TerminateJob = SbieApi_QueryConfBool(TargetBoxName, L"TerminateJobObject", FALSE); // // match session id and box name