BreakoutProcess support

This commit is contained in:
DavidXanatos 2022-01-08 16:53:22 +01:00
parent ade657bb14
commit 0da573a7bd
7 changed files with 399 additions and 357 deletions

View File

@ -958,7 +958,11 @@ _FX BOOL Proc_CreateProcessInternalW(
resume_thread = TRUE;
dwCreationFlags |= CREATE_SUSPENDED;
dwCreationFlags &= ~CREATE_BREAKAWAY_FROM_JOB;
// no longer required see comment in GuiServer::GetJobObjectForAssign
//extern BOOLEAN SysInfo_UseSbieJob;
//if (SysInfo_UseSbieJob) {
// dwCreationFlags &= ~CREATE_BREAKAWAY_FROM_JOB;
//}
//

View File

@ -58,10 +58,10 @@ static void Process_NotifyProcess(
#endif
static void Process_NotifyProcessEx(
HANDLE ParentId, HANDLE ProcessId, PPS_CREATE_NOTIFY_INFO CreateInfo);
PEPROCESS ParentId, HANDLE ProcessId, PPS_CREATE_NOTIFY_INFO CreateInfo);
static PROCESS *Process_Create(
HANDLE ProcessId, const BOX *box, const WCHAR *image_path,
HANDLE ProcessId, HANDLE StarterId, const BOX *box, const WCHAR *image_path,
KIRQL *out_irql);
static void Process_NotifyProcess_Delete(HANDLE ProcessId);
@ -587,7 +587,7 @@ _FX void Process_CreateTerminated(HANDLE ProcessId, ULONG SessionId)
_FX PROCESS *Process_Create(
HANDLE ProcessId, const BOX *box, const WCHAR *image_path,
HANDLE ProcessId, HANDLE StarterId, const BOX *box, const WCHAR *image_path,
KIRQL *out_irql)
{
POOL *pool;
@ -620,6 +620,7 @@ _FX PROCESS *Process_Create(
memzero(proc, sizeof(PROCESS));
proc->pid = ProcessId;
proc->starter_id = StarterId; // the pid of teh process that called CreateProcess, usually the parent
proc->pool = pool;
proc->box = Box_Clone(pool, box);
@ -1164,6 +1165,29 @@ _FX BOOLEAN Process_NotifyProcess_Create(
ExReleaseResourceLite(Process_ListLock);
KeLowerIrql(irql);
//
// check if this process is set up as break out program,
// it must't be located in a sandboxed for this to work.
//
BOX* breakout_box = NULL;
if (box && Process_IsBreakoutProcess(box, ImagePath)) {
UNICODE_STRING image_uni;
RtlInitUnicodeString(&image_uni, ImagePath);
if (!Box_IsBoxedPath(box, file, &image_uni)) {
check_forced_program = TRUE; // the break out process of one mox may be the forced process of an otehr
breakout_box = box;
box = NULL;
}
}
//
// check forced processes
//
if (check_forced_program) {
//
@ -1171,7 +1195,7 @@ _FX BOOLEAN Process_NotifyProcess_Create(
// check if it might be a forced process
//
box = Process_GetForcedStartBox(ProcessId, ParentId, ImagePath, FALSE);
box = Process_GetForcedStartBox(ProcessId, ParentId, ImagePath, FALSE, breakout_box ? breakout_box->sid : NULL);
if (box == (BOX *)-1) {
@ -1185,7 +1209,7 @@ _FX BOOLEAN Process_NotifyProcess_Create(
}
else
{
box = Process_GetForcedStartBox(ProcessId, ParentId, ImagePath, TRUE);
box = Process_GetForcedStartBox(ProcessId, ParentId, ImagePath, TRUE, breakout_box ? breakout_box->sid : NULL);
if (box == (BOX *)-1) {
@ -1202,6 +1226,24 @@ _FX BOOLEAN Process_NotifyProcess_Create(
}
}
//
// if this is a break out process and no other box clamed it as forced,
// set bHostInject and threat it accordingly, we need this in order for
// the custom SetInformationProcess call from CreateProcessInternalW to succeed
//
if (breakout_box) {
if (!box) {
bHostInject = TRUE;
add_process_to_job = FALSE;
box = breakout_box;
}
else {
Box_Free(breakout_box);
breakout_box = NULL;
}
}
//
// if parent is a sandboxed process but for some reason we don't
// have a box at this point, then terminate the new process
@ -1244,7 +1286,7 @@ _FX BOOLEAN Process_NotifyProcess_Create(
if (box) {
PROCESS *new_proc = Process_Create(ProcessId, box, ImagePath, &irql);
PROCESS *new_proc = Process_Create(ProcessId, CallerId, box, ImagePath, &irql);
if (!new_proc) {
create_terminated = TRUE;
@ -1262,8 +1304,12 @@ _FX BOOLEAN Process_NotifyProcess_Create(
new_proc->rights_dropped = parent_had_rights_dropped;
new_proc->forced_process = process_is_forced;
if (! bHostInject)
{
if (! bHostInject) {
//
// Notify the agent about the new process using a specialized silent message
//
WCHAR msg[48], *buf = msg;
RtlStringCbPrintfW(buf, sizeof(msg), L"%s%c%d", new_proc->box->name, L'\0', (ULONG)ParentId);
buf += wcslen(buf) + 1;
@ -1272,8 +1318,11 @@ _FX BOOLEAN Process_NotifyProcess_Create(
if (! add_process_to_job)
new_proc->parent_was_sandboxed = TRUE;
add_process_to_job = TRUE; // we need this because of JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK used in GuiServer::GetJobObjectForAssign
//
// don't put the process into a job if OpenWinClass=*
// don't put the process into a job if NoSecurityIsolation=y
//
if (new_proc->open_all_win_classes || new_proc->bAppCompartment || Conf_Get_Boolean(new_proc->box->name, L"NoAddProcessToJob", 0, FALSE)) {
@ -1291,7 +1340,6 @@ _FX BOOLEAN Process_NotifyProcess_Create(
new_proc->can_use_jobs = Conf_Get_Boolean(new_proc->box->name, L"AllowBoxedJobs", 0, FALSE);
}
//
// on Windows Vista, a forced process may start inside a
// Program Compatibility Assistant (PCA) job, if its parent

View File

@ -58,6 +58,7 @@ struct _PROCESS {
// process id
HANDLE pid;
HANDLE starter_id;
// process pool. created on process creation. it is freed in its
// entirety when the process terminates
@ -242,6 +243,10 @@ BOOLEAN Process_NotifyProcess_Create(
BOOLEAN Process_IsSameBox(PROCESS *proc, PROCESS *proc2, ULONG_PTR proc2_pid);
// Process_IsStarter returns TRUE if proc2 was started by proc1
BOOLEAN Process_IsStarter(PROCESS* proc1, PROCESS* proc2);
// Process_MatchImage: given an image name pattern 'pat_str', which
// may contain wild cards, tests the image name 'test_str' against
// the pattern. If 'pat_len' is specified, only the first 'pat_len'
@ -382,9 +387,11 @@ NTSTATUS Process_GetSidStringAndSessionId(
// Get a box for a forced sandboxed process
BOX *Process_GetForcedStartBox(
HANDLE ProcessId, HANDLE ParentId, const WCHAR *ImagePath, BOOLEAN bHostInject);
HANDLE ProcessId, HANDLE ParentId, const WCHAR *ImagePath, BOOLEAN bHostInject, const WCHAR *pSidString);
BOOLEAN Process_IsBreakoutProcess(BOX *box, const WCHAR *ImagePath);
// Manipulation of the List of Disabled Forced Processes: (Process_List2)
// Add ProcessId to list if ParentId is already listed
// Hold Process_ListLock before calling, if ParentId != PROCESS_TERMINATED

View File

@ -129,13 +129,14 @@ static void Process_CheckAlertProcess(
static BOX *Process_CheckHostInjectProcess(
LIST *boxes, const WCHAR *name);
//---------------------------------------------------------------------------
// Process_GetForcedStartBox
//---------------------------------------------------------------------------
_FX BOX *Process_GetForcedStartBox(
HANDLE ProcessId, HANDLE ParentId, const WCHAR *ImagePath, BOOLEAN bHostInject)
HANDLE ProcessId, HANDLE ParentId, const WCHAR *ImagePath, BOOLEAN bHostInject, const WCHAR *pSidString)
{
NTSTATUS status;
ULONG SessionId;
@ -165,13 +166,16 @@ _FX BOX *Process_GetForcedStartBox(
ProcessObject = Process_OpenAndQuery(ProcessId, &SidString, &SessionId);
if (! pSidString)
pSidString = SidString.Buffer;
if (! ProcessObject)
return NULL;
if ( !bHostInject && (
(_wcsicmp(SidString.Buffer, Driver_S_1_5_18) == 0 ||
_wcsicmp(SidString.Buffer, Driver_S_1_5_19) == 0 ||
_wcsicmp(SidString.Buffer, Driver_S_1_5_20) == 0)
(_wcsicmp(pSidString, Driver_S_1_5_18) == 0 || // System
_wcsicmp(pSidString, Driver_S_1_5_19) == 0 || // Local Service
_wcsicmp(pSidString, Driver_S_1_5_20) == 0) // Network Service
&& (! Process_IsDcomLaunchParent(ParentId))) ){
status = STATUS_SERVER_SID_MISMATCH; // random status code
@ -222,7 +226,7 @@ _FX BOX *Process_GetForcedStartBox(
alert = 0;
Process_CreateForceData(&boxes, SidString.Buffer, SessionId);
Process_CreateForceData(&boxes, pSidString, SessionId);
//
// check if process can be forced
@ -832,6 +836,153 @@ _FX BOOLEAN Process_IsImmersiveProcess(
}
//---------------------------------------------------------------------------
// Process_AddForceFolders
//---------------------------------------------------------------------------
_FX void Process_AddForceFolders(
LIST* Folders, const WCHAR* Setting, FORCE_BOX *box, const WCHAR *section)
{
ULONG index2;
const WCHAR *value;
FORCE_FOLDER *folder;
index2 = 0;
while (1) {
WCHAR *expnd, *buf;
ULONG buf_len;
value = Conf_Get(section, Setting, index2);
if (! value)
break;
++index2;
expnd = Conf_Expand(box->box->expand_args, value, Setting);
buf = NULL;
if (expnd) {
//
// remove duplicate backslashes and translate reparse points
//
WCHAR *tmp1, *tmp2;
buf_len = (wcslen(expnd) + 1) * sizeof(WCHAR);
tmp1 = Mem_Alloc(Driver_Pool, buf_len);
if (tmp1) {
WCHAR *src_ptr = expnd;
WCHAR *dst_ptr = tmp1;
while (*src_ptr) {
if (src_ptr[0] == L'\\' && src_ptr[1] == L'\\') {
++src_ptr;
continue;
}
*dst_ptr = *src_ptr;
++src_ptr;
++dst_ptr;
}
*dst_ptr = L'\0';
tmp2 = File_TranslateReparsePoints(tmp1, Driver_Pool);
if (tmp2) {
Mem_Free(tmp1, buf_len);
buf = tmp2;
buf_len = (wcslen(buf) + 1) * sizeof(WCHAR);
} else
buf = tmp1;
}
Mem_FreeString(expnd);
}
if (! buf)
continue;
folder = Mem_Alloc(Driver_Pool, sizeof(FORCE_FOLDER));
if (! folder) {
Mem_Free(buf, buf_len);
break;
}
if (wcschr(buf, L'*')) {
folder->pat =
Pattern_Create(box->box->expand_args->pool, buf, TRUE, 0);
Mem_Free(buf, buf_len);
if (! folder->pat) {
Mem_Free(folder, sizeof(FORCE_FOLDER));
break;
}
folder->buf_len = 0;
folder->len = 0;
folder->buf = NULL;
} else {
ULONG len = wcslen(buf);
while (len && buf[len - 1] == L'\\')
--len;
folder->buf_len = buf_len;
folder->len = len;
folder->buf = buf;
folder->pat = NULL;
}
List_Insert_After(Folders, NULL, folder);
}
}
//---------------------------------------------------------------------------
// Process_AddForceProcesses
//---------------------------------------------------------------------------
_FX void Process_AddForceProcesses(
LIST* Processes, const WCHAR* Setting, const WCHAR *section)
{
ULONG index2;
const WCHAR *value;
FORCE_PROCESS *process;
index2 = 0;
while (1) {
value = Conf_Get(section, Setting, index2);
if (! value)
break;
++index2;
process = Mem_Alloc(Driver_Pool, sizeof(FORCE_PROCESS));
if (! process)
break;
// Ideally, RtlStringCchCopy() would be used here - Build issues
RtlZeroMemory(process->value, sizeof(process->value));
if (wcslen(value) < MAX_FORCE_PROCESS_VALUE_LEN)
{
wcscpy(process->value, value);
}
List_Insert_After(Processes, NULL, process);
}
}
//---------------------------------------------------------------------------
// Process_CreateForceData
//---------------------------------------------------------------------------
@ -840,12 +991,9 @@ _FX BOOLEAN Process_IsImmersiveProcess(
_FX void Process_CreateForceData(
LIST *boxes, const WCHAR *SidString, ULONG SessionId)
{
ULONG index1, index2;
ULONG index1;
const WCHAR *section;
const WCHAR *value;
FORCE_BOX *box;
FORCE_FOLDER *folder;
FORCE_PROCESS *process;
//
// scan list of boxes and create FORCE_BOX elements
@ -894,291 +1042,86 @@ _FX void Process_CreateForceData(
// scan list of ForceFolder settings for the box
//
index2 = 0;
while (1) {
static const WCHAR *_ForceFolder = L"ForceFolder";
WCHAR *expnd, *buf;
ULONG buf_len;
value = Conf_Get(section, _ForceFolder, index2);
if (! value)
break;
++index2;
expnd = Conf_Expand(box->box->expand_args, value, _ForceFolder);
buf = NULL;
if (expnd) {
//
// remove duplicate backslashes and translate reparse points
//
WCHAR *tmp1, *tmp2;
buf_len = (wcslen(expnd) + 1) * sizeof(WCHAR);
tmp1 = Mem_Alloc(Driver_Pool, buf_len);
if (tmp1) {
WCHAR *src_ptr = expnd;
WCHAR *dst_ptr = tmp1;
while (*src_ptr) {
if (src_ptr[0] == L'\\' && src_ptr[1] == L'\\') {
++src_ptr;
continue;
}
*dst_ptr = *src_ptr;
++src_ptr;
++dst_ptr;
}
*dst_ptr = L'\0';
tmp2 = File_TranslateReparsePoints(tmp1, Driver_Pool);
if (tmp2) {
Mem_Free(tmp1, buf_len);
buf = tmp2;
buf_len = (wcslen(buf) + 1) * sizeof(WCHAR);
} else
buf = tmp1;
}
Mem_FreeString(expnd);
}
if (! buf)
continue;
folder = Mem_Alloc(Driver_Pool, sizeof(FORCE_FOLDER));
if (! folder) {
Mem_Free(buf, buf_len);
break;
}
if (wcschr(buf, L'*')) {
folder->pat =
Pattern_Create(box->box->expand_args->pool, buf, TRUE, 0);
Mem_Free(buf, buf_len);
if (! folder->pat) {
Mem_Free(folder, sizeof(FORCE_FOLDER));
break;
}
folder->buf_len = 0;
folder->len = 0;
folder->buf = NULL;
} else {
ULONG len = wcslen(buf);
while (len && buf[len - 1] == L'\\')
--len;
folder->buf_len = buf_len;
folder->len = len;
folder->buf = buf;
folder->pat = NULL;
}
List_Insert_After(&box->ForceFolder, NULL, folder);
}
Process_AddForceFolders(&box->ForceFolder, L"ForceFolder", box, section);
//
// scan list of ForceProcess settings for the box
//
index2 = 0;
while (1) {
value = Conf_Get(section, L"ForceProcess", index2);
if (! value)
break;
++index2;
process = Mem_Alloc(Driver_Pool, sizeof(FORCE_PROCESS));
if (! process)
break;
// Ideally, RtlStringCchCopy() would be used here - Build issues
RtlZeroMemory(process->value, sizeof(process->value));
if (wcslen(value) < MAX_FORCE_PROCESS_VALUE_LEN)
{
wcscpy(process->value, value);
}
List_Insert_After(&box->ForceProcess, NULL, process);
}
Process_AddForceProcesses(&box->ForceProcess, L"ForceProcess", section);
//
// scan list of AlertFolder settings for the box
//
index2 = 0;
while (1) {
static const WCHAR *_AlertFolder = L"AlertFolder";
WCHAR *expnd, *buf;
ULONG buf_len;
value = Conf_Get(section, _AlertFolder, index2);
if (! value)
break;
++index2;
expnd = Conf_Expand(box->box->expand_args, value, _AlertFolder);
buf = NULL;
if (expnd) {
//
// remove duplicate backslashes and translate reparse points
//
WCHAR *tmp1, *tmp2;
buf_len = (wcslen(expnd) + 1) * sizeof(WCHAR);
tmp1 = Mem_Alloc(Driver_Pool, buf_len);
if (tmp1) {
WCHAR *src_ptr = expnd;
WCHAR *dst_ptr = tmp1;
while (*src_ptr) {
if (src_ptr[0] == L'\\' && src_ptr[1] == L'\\') {
++src_ptr;
continue;
}
*dst_ptr = *src_ptr;
++src_ptr;
++dst_ptr;
}
*dst_ptr = L'\0';
tmp2 = File_TranslateReparsePoints(tmp1, Driver_Pool);
if (tmp2) {
Mem_Free(tmp1, buf_len);
buf = tmp2;
buf_len = (wcslen(buf) + 1) * sizeof(WCHAR);
} else
buf = tmp1;
}
Mem_FreeString(expnd);
}
if (! buf)
continue;
folder = Mem_Alloc(Driver_Pool, sizeof(FORCE_FOLDER));
if (! folder) {
Mem_Free(buf, buf_len);
break;
}
if (wcschr(buf, L'*')) {
folder->pat =
Pattern_Create(box->box->expand_args->pool, buf, TRUE, 0);
Mem_Free(buf, buf_len);
if (! folder->pat) {
Mem_Free(folder, sizeof(FORCE_FOLDER));
break;
}
folder->buf_len = 0;
folder->len = 0;
folder->buf = NULL;
} else {
ULONG len = wcslen(buf);
while (len && buf[len - 1] == L'\\')
--len;
folder->buf_len = buf_len;
folder->len = len;
folder->buf = buf;
folder->pat = NULL;
}
List_Insert_After(&box->AlertFolder, NULL, folder);
}
Process_AddForceFolders(&box->AlertFolder, L"AlertFolder", box, section);
//
// scan list of AlertProcess settings for the box
//
index2 = 0;
while (1) {
value = Conf_Get(section, L"AlertProcess", index2);
if (! value)
break;
++index2;
process = Mem_Alloc(Driver_Pool, sizeof(FORCE_PROCESS));
if (! process)
break;
// Ideally, RtlStringCchCopy() would be used here - Build issues
RtlZeroMemory(process->value, sizeof(process->value));
if (wcslen(value) < MAX_FORCE_PROCESS_VALUE_LEN)
{
wcscpy(process->value, value);
}
List_Insert_After(&box->AlertProcess, NULL, process);
}
Process_AddForceProcesses(&box->AlertProcess, L"AlertProcess", section);
//
// scan list of HostInjectProcess settings for the box
//
index2 = 0;
while (1) {
value = Conf_Get(section, L"HostInjectProcess", index2);
if (! value)
break;
++index2;
process = Mem_Alloc(Driver_Pool, sizeof(FORCE_PROCESS));
if (! process)
break;
// Ideally, RtlStringCchCopy() would be used here - Build issues
RtlZeroMemory(process->value, sizeof(process->value));
if (wcslen(value) < MAX_FORCE_PROCESS_VALUE_LEN)
{
wcscpy(process->value, value);
}
List_Insert_After(&box->HostInjectProcess, NULL, process);
}
Process_AddForceProcesses(&box->HostInjectProcess, L"HostInjectProcess", section);
}
Conf_AdjustUseCount(FALSE);
}
//---------------------------------------------------------------------------
// Process_DeleteForceDataFolders
//---------------------------------------------------------------------------
_FX void Process_DeleteForceDataFolders(LIST* Folders)
{
FORCE_FOLDER *folder;
while (1) {
folder = List_Head(Folders);
if (!folder)
break;
List_Remove(Folders, folder);
if (folder->pat)
Pattern_Free(folder->pat);
else
Mem_Free(folder->buf, folder->buf_len);
Mem_Free(folder, sizeof(FORCE_FOLDER));
}
}
//---------------------------------------------------------------------------
// Process_DeleteForceDataProcesses
//---------------------------------------------------------------------------
_FX void Process_DeleteForceDataProcesses(LIST* Folders)
{
FORCE_PROCESS *process;
while (1) {
process = List_Head(Folders);
if (! process)
break;
List_Remove(Folders, process);
Mem_Free(process, sizeof(FORCE_PROCESS));
}
}
//---------------------------------------------------------------------------
// Process_DeleteForceData
//---------------------------------------------------------------------------
@ -1187,8 +1130,6 @@ _FX void Process_CreateForceData(
_FX void Process_DeleteForceData(LIST *boxes)
{
FORCE_BOX *box;
FORCE_FOLDER *folder;
FORCE_PROCESS *process;
while (1) {
@ -1198,70 +1139,11 @@ _FX void Process_DeleteForceData(LIST *boxes)
List_Remove(boxes, box);
while (1) {
folder = List_Head(&box->ForceFolder);
if (! folder)
break;
List_Remove(&box->ForceFolder, folder);
if (folder->pat)
Pattern_Free(folder->pat);
else
Mem_Free(folder->buf, folder->buf_len);
Mem_Free(folder, sizeof(FORCE_FOLDER));
}
while (1) {
process = List_Head(&box->ForceProcess);
if (! process)
break;
List_Remove(&box->ForceProcess, process);
Mem_Free(process, sizeof(FORCE_PROCESS));
}
while (1) {
folder = List_Head(&box->AlertFolder);
if (!folder)
break;
List_Remove(&box->AlertFolder, folder);
if (folder->pat)
Pattern_Free(folder->pat);
else
Mem_Free(folder->buf, folder->buf_len);
Mem_Free(folder, sizeof(FORCE_FOLDER));
}
while (1) {
process = List_Head(&box->AlertProcess);
if (! process)
break;
List_Remove(&box->AlertProcess, process);
Mem_Free(process, sizeof(FORCE_PROCESS));
}
while (1) {
process = List_Head(&box->HostInjectProcess);
if (! process)
break;
List_Remove(&box->HostInjectProcess, process);
Mem_Free(process, sizeof(FORCE_PROCESS));
}
Process_DeleteForceDataFolders(&box->ForceFolder);
Process_DeleteForceDataProcesses(&box->ForceProcess);
Process_DeleteForceDataFolders(&box->AlertFolder);
Process_DeleteForceDataProcesses(&box->AlertProcess);
Process_DeleteForceDataProcesses(&box->HostInjectProcess);
Box_Free(box->box);
@ -1627,6 +1509,73 @@ _FX BOX *Process_CheckHostInjectProcess(
return NULL;
}
//---------------------------------------------------------------------------
// Process_DfpInsert
//---------------------------------------------------------------------------
_FX BOOLEAN Process_IsBreakoutProcess(
BOX *box, const WCHAR *ImagePath)
{
NTSTATUS status;
LIST BreakoutProcess;
WCHAR *ImagePath2 = L"";
ULONG ImagePath2_len;
const WCHAR *ImageName = L"";
BOOLEAN IsBreakout = FALSE;
//
// get adjusted image path and image name
//
status = Process_TranslateDosToNt(
ImagePath, &ImagePath2, &ImagePath2_len);
if (NT_SUCCESS(status)) {
ImageName = wcsrchr(ImagePath2, L'\\');
if (ImageName && ImageName[1])
++ImageName;
else
status = STATUS_OBJECT_PATH_SYNTAX_BAD; // random
}
if (!NT_SUCCESS(status)) {
return FALSE;
}
List_Init(&BreakoutProcess);
Conf_AdjustUseCount(TRUE);
Process_AddForceProcesses(&BreakoutProcess, L"BreakoutProcess", box->name);
Conf_AdjustUseCount(FALSE);
FORCE_PROCESS *process = List_Head(&BreakoutProcess);
while (process) {
const WCHAR *value = process->value;
if (Process_MatchImage(box, value, 0, ImageName, 1)) {
IsBreakout = TRUE;
break;
}
process = List_Next(process);
}
Process_DeleteForceDataProcesses(&BreakoutProcess);
Mem_Free(ImagePath2, ImagePath2_len);
return IsBreakout;
}
//---------------------------------------------------------------------------
// Process_DfpInsert
//---------------------------------------------------------------------------

View File

@ -113,6 +113,24 @@ _FX BOOLEAN Process_IsSameBox(
}
//---------------------------------------------------------------------------
// Process_IsStarter
//---------------------------------------------------------------------------
_FX BOOLEAN Process_IsStarter(
PROCESS* proc1, PROCESS* proc2)
{
if (proc1->create_time > proc2->create_time)
return FALSE; // reused pid? the new process can not be older than the on that started it
if (proc1->box->session_id != proc2->box->session_id)
return FALSE; // SID must be same
return proc1->pid == proc2->starter_id;
}
//---------------------------------------------------------------------------
// Process_MatchImage
//---------------------------------------------------------------------------

View File

@ -376,7 +376,7 @@ _FX PROCESS *Thread_FindAndInitProcess(
PROCESS *proc2 = Process_Find(PsGetProcessId(ProcessObject2), out_irql);
if (proc2) {
if (! Process_IsSameBox(proc1, proc2, 0))
if (! Process_IsSameBox(proc1, proc2, 0) && ! Process_IsStarter(proc1, proc2))
proc2 = NULL;
else if (! proc2->threads_lock) {

View File

@ -1031,16 +1031,6 @@ HANDLE GuiServer::GetJobObjectForAssign(const WCHAR *boxname)
hJobObject = CreateJobObject(&sa, jobname);
if (hJobObject) {
//
// set UI restrictions on the job object
//
JOBOBJECT_BASIC_UI_RESTRICTIONS info;
info.UIRestrictionsClass = JOB_OBJECT_UILIMIT_EXITWINDOWS
| JOB_OBJECT_UILIMIT_HANDLES
| JOB_OBJECT_UILIMIT_SYSTEMPARAMETERS
| JOB_OBJECT_UILIMIT_READCLIPBOARD;
BOOL ok = FALSE; // set TRUE to skip UIRestrictions
// OriginalToken BEGIN
@ -1053,6 +1043,17 @@ HANDLE GuiServer::GetJobObjectForAssign(const WCHAR *boxname)
// UnrestrictedToken END
if (! ok) {
//
// set UI restrictions on the job object
//
JOBOBJECT_BASIC_UI_RESTRICTIONS info;
info.UIRestrictionsClass = JOB_OBJECT_UILIMIT_EXITWINDOWS
| JOB_OBJECT_UILIMIT_HANDLES
| JOB_OBJECT_UILIMIT_SYSTEMPARAMETERS
| JOB_OBJECT_UILIMIT_READCLIPBOARD;
ok = SetInformationJobObject(
hJobObject, JobObjectBasicUIRestrictions,
&info, sizeof(info));
@ -1067,6 +1068,21 @@ HANDLE GuiServer::GetJobObjectForAssign(const WCHAR *boxname)
ok = UserHandleGrantAccess(
GetDesktopWindow(), hJobObject, TRUE);
}
//
// we want to allow sandboxed processes to use jobs of thair own
// with windows 8 we can have nested, a boxed process may want to use BREAKAWAY
// hence we no longer prevent breaking away from our job,
// instead we re assign the job on each initialization, like it was done for the initial one
//
if (ok) {
JOBOBJECT_EXTENDED_LIMIT_INFORMATION jobELInfo = {0};
jobELInfo.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_BREAKAWAY_OK
| JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK;
ok = SetInformationJobObject(hJobObject, JobObjectExtendedLimitInformation, &jobELInfo, sizeof(jobELInfo));
}
}
if (! ok) {
// this should not happen