clean up and standardize types across the codebase, unify atomic operations, improve UTF-8 handling throughout the system, remove obsolete input and named queue interfaces, redesign process preparation and creation, tighten IPC and service boundaries, improve error handling and reliability, minor documentation cleanup, fix doom surfaces, fix panic in ini parsing.

This commit is contained in:
maksw committed 2026-10-12 18:17:43 +02:00
1 parent 899225f551
commit c0ad63c27f
226 files changed
+6562 -4147

No files matched your search

+91 -92
View File
@@ -1,5 +1,7 @@
// POSIX personality-server bootstrap, stable process identity, shared attributes, and transaction plumbing.
#include <ntlite/atomic.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
@@ -20,7 +22,7 @@ typedef struct POSIXSRV_CONSTRUCTION_STRING {
char* Data;
uint32_t Length;
uint32_t Capacity;
uint32_t Complete;
bool Complete;
} POSIXSRV_CONSTRUCTION_STRING;
typedef struct POSIXSRV_SPAWN_ACTION {
@@ -140,16 +142,16 @@ struct POSIXSRV_PROCESS_RECORD {
uint32_t Generation;
uint32_t State;
uint32_t ConnectionCount;
uint32_t MonitorActive;
bool MonitorActive;
POSIXSRV_PROCESS_RECORD* BorrowedHostProcess;
uint32_t BorrowedHostGeneration;
uint32_t BorrowedNativeThreadId;
uint64_t BorrowedToken;
uint32_t BorrowedMonitorActive;
bool BorrowedMonitorActive;
uint32_t BorrowedTerminalKind;
int32_t BorrowedExitCode;
POSIXSRV_EXEC_HOLDER_PLAN* PendingExecHolderPlan;
uint32_t AlarmMonitorActive;
bool AlarmMonitorActive;
uint64_t BootstrapToken;
SYS_HANDLE BootstrapReadyEvent;
uint32_t PendingNativeProcessId;
@@ -157,7 +159,7 @@ struct POSIXSRV_PROCESS_RECORD {
uint64_t PendingBootstrapToken;
SYS_HANDLE PendingBootstrapReadyEvent;
SYS_HANDLE PendingBootstrapReleaseEvent;
uint32_t PendingBootstrapReadyObserved;
bool PendingBootstrapReadyObserved;
SYS_HANDLE PendingProcessHandle;
uint64_t PendingFdInheritanceToken;
uint32_t UserId;
@@ -236,21 +238,21 @@ static void PosixsrvDestroyTransaction(POSIXSRV_TRANSACTION* transaction);
static void PosixsrvFreeProcessRecord(POSIXSRV_PROCESS_RECORD* record);
// Returns whether the stable POSIX process still has a committed native generation.
static int PosixsrvProcessHasCommittedGeneration(const POSIXSRV_PROCESS_RECORD* process) {
static bool PosixsrvProcessHasCommittedGeneration(const POSIXSRV_PROCESS_RECORD* process) {
return process && (process->State == NTL_POSIX_PROCESS_STATE_RUNNING ||
process->State == NTL_POSIX_PROCESS_STATE_EXEC_PREPARING ||
process->State == NTL_POSIX_PROCESS_STATE_EXEC_COMMITTING);
}
// Returns whether ordinary operations may still run in the committed old generation.
static int PosixsrvCommittedGenerationOperational(const POSIXSRV_CLIENT* client) {
static bool PosixsrvCommittedGenerationOperational(const POSIXSRV_CLIENT* client) {
return client && client->Process && client->NativeGeneration == client->Process->Generation &&
(client->Process->State == NTL_POSIX_PROCESS_STATE_RUNNING ||
client->Process->State == NTL_POSIX_PROCESS_STATE_EXEC_PREPARING);
}
// Returns whether this connection belongs to the not-yet-committed replacement generation.
static int PosixsrvClientIsPendingExecGeneration(const POSIXSRV_CLIENT* client) {
static bool PosixsrvClientIsPendingExecGeneration(const POSIXSRV_CLIENT* client) {
return client && client->Process && client->Process->PendingGeneration != 0 &&
client->NativeGeneration == client->Process->PendingGeneration &&
(client->Process->State == NTL_POSIX_PROCESS_STATE_EXEC_PREPARING ||
@@ -258,7 +260,7 @@ static int PosixsrvClientIsPendingExecGeneration(const POSIXSRV_CLIENT* client)
}
// Returns whether this routed client represents one borrowed vfork logical process.
static int PosixsrvClientIsBorrowedProcess(const POSIXSRV_CLIENT* client) {
static bool PosixsrvClientIsBorrowedProcess(const POSIXSRV_CLIENT* client) {
return client && client->Process &&
client->Process->State == NTL_POSIX_PROCESS_STATE_VFORK_BORROWED &&
client->NativeGeneration == client->Process->Generation;
@@ -342,24 +344,24 @@ static POSIXSRV_PROCESS_RECORD* PosixsrvFindPosixProcessLocked(uint32_t posixPid
}
// Returns whether a process group currently exists in one POSIX session.
static int PosixsrvProcessGroupExistsLocked(uint32_t sessionId, uint32_t processGroupId) {
if (processGroupId == 0) return 0;
static bool PosixsrvProcessGroupExistsLocked(uint32_t sessionId, uint32_t processGroupId) {
if (processGroupId == 0) return false;
for (POSIXSRV_PROCESS_RECORD* record = gProcessRegistry; record; record = record->Next) {
if (PosixsrvProcessHasCommittedGeneration(record) && record->SessionId == sessionId &&
record->ProcessGroupId == processGroupId)
return 1;
return true;
}
return 0;
return false;
}
// Returns whether one protocol open-description type requires a retained native handle.
static int PosixsrvOpenDescriptionNeedsHandle(uint32_t type) {
static bool PosixsrvOpenDescriptionNeedsHandle(uint32_t type) {
return type == NTL_POSIX_OPEN_TYPE_FILE || type == NTL_POSIX_OPEN_TYPE_SOCKET ||
type == NTL_POSIX_OPEN_TYPE_PIPE_READ || type == NTL_POSIX_OPEN_TYPE_PIPE_WRITE;
}
// Returns whether one protocol open-description type is known.
static int PosixsrvOpenDescriptionTypeValid(uint32_t type) {
static bool PosixsrvOpenDescriptionTypeValid(uint32_t type) {
return type >= NTL_POSIX_OPEN_TYPE_FILE && type <= NTL_POSIX_OPEN_TYPE_PIPE_WRITE;
}
@@ -480,8 +482,7 @@ static void PosixsrvReleaseFdInheritanceForProcessLocked(POSIXSRV_PROCESS_RECORD
// Returns the process-local rights needed by one imported native capability.
static SYS_RIGHTS PosixsrvOpenDescriptionClientRights(POSIXSRV_OPEN_DESCRIPTION* description) {
if (!description || !description->Shared) return 0;
uint32_t statusFlags = (uint32_t)_InterlockedCompareExchange(
&description->Shared->StatusFlags, 0, 0);
uint32_t statusFlags = NtlAtomicLoadU32(&description->Shared->StatusFlags);
SYS_RIGHTS rights = SYS_RIGHT_QUERY;
if (description->Type == NTL_POSIX_OPEN_TYPE_FILE) {
rights |= SYS_FILE_RIGHT_LOCK;
@@ -771,7 +772,7 @@ static KSTATUS PosixsrvCreateOpenDescription(POSIXSRV_CLIENT* client,
shared->Version = NTL_POSIX_SHARED_OPEN_VERSION;
shared->Type = type;
shared->DescriptionId = id;
shared->StatusFlags = (long)statusFlags;
shared->StatusFlags = statusFlags;
holder->Description = description;
holder->Next = client->Process->OpenDescriptions;
@@ -961,8 +962,7 @@ static KSTATUS PosixsrvSetOpenStatus(POSIXSRV_CLIENT* client,
}
POSIXSRV_OPEN_DESCRIPTION* description = holder->Description;
uint32_t current = (uint32_t)_InterlockedCompareExchange(
&description->Shared->StatusFlags, 0, 0);
uint32_t current = NtlAtomicLoadU32(&description->Shared->StatusFlags);
uint32_t updated = (current & ~(NTL_POSIX_OPEN_STATUS_APPEND |
NTL_POSIX_OPEN_STATUS_NONBLOCK)) |
(requestedFlags & (NTL_POSIX_OPEN_STATUS_APPEND |
@@ -990,7 +990,7 @@ static KSTATUS PosixsrvSetOpenStatus(POSIXSRV_CLIENT* client,
}
if (KSUCCESS(status))
_InterlockedExchange(&description->Shared->StatusFlags, (long)updated);
NtlAtomicExchangeU32(&description->Shared->StatusFlags, updated);
*statusFlagsOut = KSUCCESS(status) ? updated : current;
*typeOut = description->Type;
PosixsrvUnlockRegistry();
@@ -1022,20 +1022,20 @@ static const POSIXSRV_GROUP_RECORD* PosixsrvFindGroup(uint32_t lookupKind,
}
// Validates one length-delimited canonical native current-directory string.
static int PosixsrvValidateCurrentDirectory(const NTL_POSIX_REQUEST* request) {
static bool PosixsrvValidateCurrentDirectory(const NTL_POSIX_REQUEST* request) {
if (!request || request->PathLength == 0 || request->PathLength > SYS_PATH_MAX)
return 0;
return false;
if (request->Path[0] != '/' || request->Path[request->PathLength] != '\0')
return 0;
return false;
return strlen(request->Path) == request->PathLength;
}
// Validates one optional length-delimited identity lookup name.
static int PosixsrvValidateLookupName(const NTL_POSIX_REQUEST* request) {
static bool PosixsrvValidateLookupName(const NTL_POSIX_REQUEST* request) {
if (!request || request->NameLength == 0 || request->NameLength > NTL_POSIX_IDENTITY_NAME_MAX)
return 0;
return false;
if (request->Name[request->NameLength] != '\0')
return 0;
return false;
return strlen(request->Name) == request->NameLength;
}
@@ -1176,8 +1176,8 @@ static KSTATUS PosixsrvUnregisterThread(POSIXSRV_CLIENT* client,
// Returns whether the server should discard this signal for one process.
static int PosixsrvSignalIgnoredLocked(const POSIXSRV_PROCESS_RECORD* process, int signalNumber) {
if (!process || !NtlPosixSignalValid(signalNumber)) return 0;
static bool PosixsrvSignalIgnoredLocked(const POSIXSRV_PROCESS_RECORD* process, int signalNumber) {
if (!process || !NtlPosixSignalValid(signalNumber)) return false;
return (process->IgnoredSignals & NTL_POSIX_SIGNAL_BIT(signalNumber)) != 0;
}
@@ -1317,10 +1317,10 @@ static KSTATUS PosixsrvSetSignalDisposition(POSIXSRV_CLIENT* client,
}
// Returns whether a sender is permitted to signal one synthetic POSIX identity.
static int PosixsrvCanSignalLocked(const POSIXSRV_PROCESS_RECORD* sender,
static bool PosixsrvCanSignalLocked(const POSIXSRV_PROCESS_RECORD* sender,
const POSIXSRV_PROCESS_RECORD* target) {
if (!sender || !target) return 0;
if (sender->EffectiveUserId == 0) return 1;
if (!sender || !target) return false;
if (sender->EffectiveUserId == 0) return true;
return sender->UserId == target->UserId || sender->UserId == target->EffectiveUserId ||
sender->EffectiveUserId == target->UserId ||
sender->EffectiveUserId == target->EffectiveUserId;
@@ -1341,10 +1341,10 @@ static KSTATUS PosixsrvSendSignal(POSIXSRV_CLIENT* client, int32_t targetPid, in
for (POSIXSRV_PROCESS_RECORD* target = gProcessRegistry; target; target = target->Next) {
if (!PosixsrvProcessHasCommittedGeneration(target)) continue;
int selected = 0;
bool selected = false;
if (targetPid > 0) selected = target->PosixPid == (uint32_t)targetPid;
else if (targetPid == 0) selected = target->ProcessGroupId == sender->ProcessGroupId;
else if (targetPid == -1) selected = 1;
else if (targetPid == -1) selected = true;
else selected = target->ProcessGroupId == (uint32_t)(-targetPid);
if (!selected) continue;
++matched;
@@ -1433,7 +1433,7 @@ static void PosixsrvReleaseBorrowedChildrenForHostLocked(POSIXSRV_PROCESS_RECORD
}
// Returns whether one exited process record has no remaining owner that requires retention.
static int PosixsrvCanFreeProcessLocked(const POSIXSRV_PROCESS_RECORD* record) {
static bool PosixsrvCanFreeProcessLocked(const POSIXSRV_PROCESS_RECORD* record) {
return record && record->State == NTL_POSIX_PROCESS_STATE_EXITED &&
record->ParentPosixPid == 0 && record->ConnectionCount == 0 &&
!record->MonitorActive && !record->AlarmMonitorActive && !record->BorrowedMonitorActive;
@@ -1622,11 +1622,11 @@ static KSTATUS PosixsrvSetAlarm(POSIXSRV_CLIENT* client,
}
// Tests whether one waiter selection includes the supplied direct child.
static int PosixsrvWaiterMatchesChild(const POSIXSRV_WAITER* waiter,
static bool PosixsrvWaiterMatchesChild(const POSIXSRV_WAITER* waiter,
const POSIXSRV_PROCESS_RECORD* child) {
if (!waiter || !child || child->ParentPosixPid != waiter->ParentPosixPid) return 0;
if (!waiter || !child || child->ParentPosixPid != waiter->ParentPosixPid) return false;
if (waiter->WaitPid > 0) return child->PosixPid == (uint32_t)waiter->WaitPid;
if (waiter->WaitPid == -1) return 1;
if (waiter->WaitPid == -1) return true;
if (waiter->WaitPid == 0) return child->ProcessGroupId == waiter->ParentProcessGroupId;
uint64_t group = (uint64_t)(-(int64_t)waiter->WaitPid);
return group <= UINT32_MAX && child->ProcessGroupId == (uint32_t)group;
@@ -1882,13 +1882,11 @@ static KSTATUS PosixsrvReplyPipe(POSIXSRV_CLIENT* client,
reply.OpenDescriptionId = readDescription->DescriptionId;
reply.OpenDescriptionType = readDescription->Type;
reply.OpenStatusFlags = (uint32_t)_InterlockedCompareExchange(
&readDescription->Shared->StatusFlags, 0, 0);
reply.OpenStatusFlags = NtlAtomicLoadU32(&readDescription->Shared->StatusFlags);
reply.SharedOpenDescription = (uint64_t)(uintptr_t)readDescription->Shared;
reply.OpenDescriptionId2 = writeDescription->DescriptionId;
reply.OpenDescriptionType2 = writeDescription->Type;
reply.OpenStatusFlags2 = (uint32_t)_InterlockedCompareExchange(
&writeDescription->Shared->StatusFlags, 0, 0);
reply.OpenStatusFlags2 = NtlAtomicLoadU32(&writeDescription->Shared->StatusFlags);
reply.SharedOpenDescription2 = (uint64_t)(uintptr_t)writeDescription->Shared;
SYS_PORT_HANDLE_TRANSFER transfers[2];
@@ -1920,14 +1918,14 @@ static KSTATUS PosixsrvReplyFdInheritance(POSIXSRV_CLIENT* client,
if (!KSUCCESS(status)) return status;
POSIXSRV_FD_INHERITANCE* snapshot = PosixsrvFindFdInheritanceLocked(token);
int execImport = snapshot && PosixsrvClientIsPendingExecGeneration(client) &&
bool execImport = snapshot && PosixsrvClientIsPendingExecGeneration(client) &&
client->Process->PendingFdInheritanceToken == token &&
snapshot->SourceProcess == client->Process && !snapshot->ClaimProcess;
int processStateValid = client->Process->State == NTL_POSIX_PROCESS_STATE_RUNNING ||
client->Process->State == NTL_POSIX_PROCESS_STATE_CONSTRUCTING ||
client->Process->State == NTL_POSIX_PROCESS_STATE_VFORK_BORROWED ||
execImport;
int ownershipValid = snapshot && (execImport || snapshot->ClaimProcess == client->Process ||
bool ownershipValid = snapshot && (execImport || snapshot->ClaimProcess == client->Process ||
(!snapshot->ClaimProcess && snapshot->SecurityId == client->Process->SecurityId));
if (!snapshot || !ownershipValid || !processStateValid) {
PosixsrvUnlockRegistry();
@@ -1970,8 +1968,7 @@ static KSTATUS PosixsrvReplyFdInheritance(POSIXSRV_CLIENT* client,
out->OpenDescriptionId = description->DescriptionId;
out->SharedOpenDescription = (uint64_t)(uintptr_t)description->Shared;
out->OpenDescriptionType = description->Type;
out->OpenStatusFlags = (uint32_t)_InterlockedCompareExchange(
&description->Shared->StatusFlags, 0, 0);
out->OpenStatusFlags = NtlAtomicLoadU32(&description->Shared->StatusFlags);
out->HandleIndex = NTL_POSIX_FD_HANDLE_NONE;
if (PosixsrvOpenDescriptionNeedsHandle(description->Type)) {
if (description->MasterHandle == SYS_HANDLE_INVALID || handleCount >= NTL_POSIX_FD_IMPORT_BATCH_MAX) {
@@ -2782,7 +2779,7 @@ static KSTATUS PosixsrvWaitProcess(POSIXSRV_CLIENT* client,
}
KSTATUS result = NTLSTATUS_SUCCESS;
int waiterOwned = waiter != (POSIXSRV_WAITER*)0;
bool waiterOwned = waiter != (POSIXSRV_WAITER*)0;
for (;;) {
POSIXSRV_PROCESS_RECORD* freeRecord = (POSIXSRV_PROCESS_RECORD*)0;
KSTATUS status = PosixsrvLockRegistry();
@@ -2799,14 +2796,14 @@ static KSTATUS PosixsrvWaitProcess(POSIXSRV_CLIENT* client,
match->ParentPosixPid = parent->PosixPid;
match->ParentProcessGroupId = parent->ProcessGroupId;
POSIXSRV_PROCESS_RECORD* exited = (POSIXSRV_PROCESS_RECORD*)0;
int hasMatchingChild = 0;
bool hasMatchingChild = false;
for (POSIXSRV_PROCESS_RECORD* child = gProcessRegistry; child; child = child->Next) {
if (!PosixsrvProcessHasCommittedGeneration(child) &&
child->State != NTL_POSIX_PROCESS_STATE_VFORK_BORROWED &&
child->State != NTL_POSIX_PROCESS_STATE_EXITED)
continue;
if (!PosixsrvWaiterMatchesChild(match, child)) continue;
hasMatchingChild = 1;
hasMatchingChild = true;
if (child->State == NTL_POSIX_PROCESS_STATE_EXITED &&
(!exited || child->PosixPid < exited->PosixPid))
exited = child;
@@ -3356,15 +3353,15 @@ static KSTATUS PosixsrvSpawnSetAttributes(POSIXSRV_CLIENT* client,
}
// Returns whether one absolute path already names a native global namespace root.
static int PosixsrvPathUsesNativeRoot(const char* path) {
static bool PosixsrvPathUsesNativeRoot(const char* path) {
static const char* roots[] = { "/SystemRoot", "/Device", "/Sessions", "/Services" };
if (!path || path[0] != '/') return 0;
if (!path || path[0] != '/') return false;
for (size_t i = 0; i < sizeof(roots) / sizeof(roots[0]); ++i) {
size_t length = strlen(roots[i]);
if (strncmp(path, roots[i], length) == 0 && (path[length] == '\0' || path[length] == '/'))
return 1;
return true;
}
return 0;
return false;
}
// Resolves one POSIX pathname against the server-owned cwd into native global syntax.
@@ -3425,7 +3422,7 @@ static KSTATUS PosixsrvCreateUnheldDescriptionLocked(uint32_t type,
shared->Version = NTL_POSIX_SHARED_OPEN_VERSION;
shared->Type = type;
shared->DescriptionId = description->DescriptionId;
shared->StatusFlags = (long)statusFlags;
shared->StatusFlags = statusFlags;
description->Next = gOpenDescriptionRegistry;
gOpenDescriptionRegistry = description;
++gRegisteredOpenDescriptions;
@@ -3573,15 +3570,15 @@ static KSTATUS PosixsrvApplySpawnFileActionsLocked(POSIXSRV_PROCESS_RECORD* pare
}
// Verifies that every streamed argv/envp element reached a final chunk.
static int PosixsrvConstructionVectorsComplete(const POSIXSRV_CONSTRUCTION* construction) {
if (!construction) return 0;
static bool PosixsrvConstructionVectorsComplete(const POSIXSRV_CONSTRUCTION* construction) {
if (!construction) return false;
for (uint32_t i = 0; i < construction->ArgumentCount; ++i) {
if (!construction->Arguments[i].Complete) return 0;
if (!construction->Arguments[i].Complete) return false;
}
for (uint32_t i = 0; i < construction->EnvironmentCount; ++i) {
if (!construction->Environment[i].Complete) return 0;
if (!construction->Environment[i].Complete) return false;
}
return 1;
return true;
}
// Marks a failed constructing child non-waitable and releases its server-owned state.
@@ -3617,12 +3614,12 @@ static KSTATUS PosixsrvPrepareConstruction(POSIXSRV_PROCESS_RECORD* process,
SYS_HANDLE securityContext,
const NTL_POSIX_BOOTSTRAP_DATA* bootstrap,
int synthesizeArgumentZero,
NTL_PROCESS_BUILDER* builderOut,
NTL_PROCESS_PREPARATION** preparationOut,
uint32_t* nativePidOut) {
if (!process || !construction || !construction->Executable ||
securityContext == SYS_HANDLE_INVALID || !bootstrap || !builderOut || !nativePidOut)
securityContext == SYS_HANDLE_INVALID || !bootstrap || !preparationOut || !nativePidOut)
return NTLSTATUS_INVALID_PARAMETER;
memset(builderOut, 0, sizeof(*builderOut));
*preparationOut = 0;
*nativePidOut = 0;
char executable[SYS_PATH_MAX + 1u];
@@ -3666,7 +3663,7 @@ static KSTATUS PosixsrvPrepareConstruction(POSIXSRV_PROCESS_RECORD* process,
environment[i] = SysSvFromParts(construction->Environment[i].Data,
construction->Environment[i].Length);
NTL_PROCESS_BUILDER_REQUEST build;
NTL_PREPARE_PROCESS_REQUEST build;
memset(&build, 0, sizeof(build));
build.Size = sizeof(build);
build.Flags = NTL_PROCESS_LOAD_FLAG_NONE;
@@ -3685,7 +3682,7 @@ static KSTATUS PosixsrvPrepareConstruction(POSIXSRV_PROCESS_RECORD* process,
build.StartupData = bootstrap;
build.StartupDataSize = sizeof(*bootstrap);
status = NtlProcessBuilderPrepare(builderOut, &build, imageFile);
status = NtlPrepareProcess(&build, imageFile, preparationOut);
free(arguments);
free(environment);
(void)SysCloseHandle(systemRoot);
@@ -3693,14 +3690,16 @@ static KSTATUS PosixsrvPrepareConstruction(POSIXSRV_PROCESS_RECORD* process,
if (!KSUCCESS(status)) return status;
SYS_HANDLE preparedProcess = SYS_HANDLE_INVALID;
status = NtlProcessBuilderGetProcessHandle(builderOut, &preparedProcess);
status = NtlPreparedProcessGetHandle(*preparationOut, &preparedProcess);
if (!KSUCCESS(status)) {
NtlProcessBuilderAbort(builderOut);
NtlAbortPreparedProcess(*preparationOut);
*preparationOut = 0;
return status;
}
status = SysGetProcessPid(preparedProcess, nativePidOut);
if (!KSUCCESS(status) || *nativePidOut == 0) {
NtlProcessBuilderAbort(builderOut);
NtlAbortPreparedProcess(*preparationOut);
*preparationOut = 0;
return KSUCCESS(status) ? NTLSTATUS_FAILURE : status;
}
return NTLSTATUS_SUCCESS;
@@ -3818,19 +3817,19 @@ static KSTATUS PosixsrvCommitSpawn(POSIXSRV_CLIENT* client,
bootstrap.InitialSignalMask = spawn->SignalMask;
bootstrap.IgnoredSignals = child->ExplicitIgnoredSignals;
NTL_PROCESS_BUILDER builder;
NTL_PROCESS_PREPARATION* preparation = 0;
status = PosixsrvPrepareConstruction(child, construction, securityContext, &bootstrap, 1,
&builder, &child->NativeProcessId);
&preparation, &child->NativeProcessId);
if (!KSUCCESS(status)) goto before_insert_fail;
status = PosixsrvLockRegistry();
if (!KSUCCESS(status)) { NtlProcessBuilderAbort(&builder); goto before_insert_fail; }
if (!KSUCCESS(status)) { NtlAbortPreparedProcess(preparation); goto before_insert_fail; }
snapshot = PosixsrvFindFdInheritanceLocked(request->FdInheritanceToken);
if (!snapshot || snapshot->SourceProcess != parent || snapshot->ClaimProcess ||
!PosixsrvCommittedGenerationOperational(client)) {
status = snapshot ? NTLSTATUS_ACCESS_DENIED : NTLSTATUS_NOT_FOUND;
PosixsrvUnlockRegistry();
NtlProcessBuilderAbort(&builder);
NtlAbortPreparedProcess(preparation);
goto before_insert_fail;
}
child->Next = gProcessRegistry;
@@ -3840,13 +3839,13 @@ static KSTATUS PosixsrvCommitSpawn(POSIXSRV_CLIENT* client,
if (!KSUCCESS(status)) {
PosixsrvUnlinkProcessLocked(child);
PosixsrvUnlockRegistry();
NtlProcessBuilderAbort(&builder);
NtlAbortPreparedProcess(preparation);
goto before_insert_fail;
}
PosixsrvUnlockRegistry();
SYS_HANDLE processHandle = SYS_HANDLE_INVALID;
status = NtlProcessBuilderStart(&builder, &processHandle);
status = NtlStartPreparedProcess(preparation, &processHandle);
if (!KSUCCESS(status)) {
PosixsrvFailConstructingProcess(child, (int32_t)status);
return status;
@@ -4001,7 +4000,7 @@ static KSTATUS PosixsrvCommitExec(POSIXSRV_CLIENT* client,
}
POSIXSRV_PROCESS_RECORD* process = client->Process;
int borrowedExec = PosixsrvClientIsBorrowedProcess(client);
bool borrowedExec = PosixsrvClientIsBorrowedProcess(client);
uint32_t pendingGeneration = 0;
uint64_t bootstrapToken = 0;
uint64_t fdToken = request->FdInheritanceToken;
@@ -4073,10 +4072,10 @@ static KSTATUS PosixsrvCommitExec(POSIXSRV_CLIENT* client,
bootstrap.InitialSignalMask = request->SignalMask & ~NTL_POSIX_SIGNAL_UNBLOCKABLE_MASK;
bootstrap.IgnoredSignals = process->ExplicitIgnoredSignals;
NTL_PROCESS_BUILDER builder;
NTL_PROCESS_PREPARATION* preparation = 0;
uint32_t pendingNativePid = 0;
status = PosixsrvPrepareConstruction(process, transaction->Construction, securityContext,
&bootstrap, 0, &builder, &pendingNativePid);
&bootstrap, 0, &preparation, &pendingNativePid);
(void)SysCloseHandle(securityContext);
securityContext = SYS_HANDLE_INVALID;
if (!KSUCCESS(status)) {
@@ -4086,7 +4085,7 @@ static KSTATUS PosixsrvCommitExec(POSIXSRV_CLIENT* client,
status = PosixsrvLockRegistry();
if (!KSUCCESS(status)) {
NtlProcessBuilderAbort(&builder);
NtlAbortPreparedProcess(preparation);
PosixsrvRollbackExec(process, fdToken, SYS_HANDLE_INVALID, 0);
return status;
}
@@ -4095,7 +4094,7 @@ static KSTATUS PosixsrvCommitExec(POSIXSRV_CLIENT* client,
process->PendingBootstrapToken != bootstrapToken ||
process->PendingFdInheritanceToken != fdToken) {
PosixsrvUnlockRegistry();
NtlProcessBuilderAbort(&builder);
NtlAbortPreparedProcess(preparation);
PosixsrvRollbackExec(process, fdToken, SYS_HANDLE_INVALID, 0);
return NTLSTATUS_OBJECT_DEAD;
}
@@ -4103,7 +4102,7 @@ static KSTATUS PosixsrvCommitExec(POSIXSRV_CLIENT* client,
PosixsrvUnlockRegistry();
SYS_HANDLE pendingProcess = SYS_HANDLE_INVALID;
status = NtlProcessBuilderStart(&builder, &pendingProcess);
status = NtlStartPreparedProcess(preparation, &pendingProcess);
if (!KSUCCESS(status)) {
PosixsrvRollbackExec(process, fdToken, SYS_HANDLE_INVALID, 0);
return status;
@@ -4246,13 +4245,13 @@ static KSTATUS PosixsrvCommitExec(POSIXSRV_CLIENT* client,
}
// Returns whether operation-specific bootstrap fields are all unused.
static int PosixsrvHasNoBootstrap(const NTL_POSIX_REQUEST* request) {
static bool PosixsrvHasNoBootstrap(const NTL_POSIX_REQUEST* request) {
return request && request->BootstrapToken == 0 && request->BootstrapPosixPid == 0 &&
request->BootstrapGeneration == 0;
}
// Returns whether all P3 shared-attribute payload fields are unused.
static int PosixsrvHasNoAttributePayload(const NTL_POSIX_REQUEST* request) {
static bool PosixsrvHasNoAttributePayload(const NTL_POSIX_REQUEST* request) {
return request && request->TargetPosixPid == 0 && request->UserId == 0 &&
request->GroupId == 0 && request->ProcessGroupId == 0 &&
request->LookupKind == NTL_POSIX_LOOKUP_NONE &&
@@ -4262,21 +4261,21 @@ static int PosixsrvHasNoAttributePayload(const NTL_POSIX_REQUEST* request) {
}
// Returns whether one request carries no descriptor-inheritance payload.
static int PosixsrvHasNoFdInheritancePayload(const NTL_POSIX_REQUEST* request) {
static bool PosixsrvHasNoFdInheritancePayload(const NTL_POSIX_REQUEST* request) {
if (!request || request->FdInheritanceToken != 0 || request->FdInheritanceIndex != 0 ||
request->FdInheritanceCount != 0 || request->FdInheritanceFlags != 0)
return 0;
return false;
for (uint32_t i = 0; i < NTL_POSIX_FD_INHERIT_MAX; ++i) {
if (request->FdManifest[i].Descriptor != 0 ||
request->FdManifest[i].DescriptorFlags != 0 ||
request->FdManifest[i].OpenDescriptionId != 0)
return 0;
return false;
}
return 1;
return true;
}
// Returns whether one request carries no P5 spawn transaction payload.
static int PosixsrvHasNoSpawnPayload(const NTL_POSIX_REQUEST* request) {
static bool PosixsrvHasNoSpawnPayload(const NTL_POSIX_REQUEST* request) {
return request && request->ConstructionVectorKind == 0 && request->ConstructionVectorIndex == 0 &&
request->ConstructionVectorOffset == 0 && request->ConstructionVectorFlags == 0 &&
request->SpawnActionKind == 0 && request->SpawnFileDescriptor == 0 &&
@@ -4286,36 +4285,36 @@ static int PosixsrvHasNoSpawnPayload(const NTL_POSIX_REQUEST* request) {
}
// Returns whether one request carries no child-wait selection payload.
static int PosixsrvHasNoWaitPayload(const NTL_POSIX_REQUEST* request) {
static bool PosixsrvHasNoWaitPayload(const NTL_POSIX_REQUEST* request) {
return request && request->WaitPid == 0 && request->WaitOptions == 0;
}
// Returns whether one request carries no P6 signal payload.
static int PosixsrvHasNoSignalPayload(const NTL_POSIX_REQUEST* request) {
static bool PosixsrvHasNoSignalPayload(const NTL_POSIX_REQUEST* request) {
return request && request->SignalTargetPid == 0 && request->SignalNumber == 0 &&
request->SignalDisposition == 0 && request->SignalReserved == 0 &&
request->SignalMask == 0 && request->SignalApcRoutine == 0;
}
// Returns whether one request carries no alarm payload.
static int PosixsrvHasNoAlarmPayload(const NTL_POSIX_REQUEST* request) {
static bool PosixsrvHasNoAlarmPayload(const NTL_POSIX_REQUEST* request) {
return request && request->AlarmSeconds == 0 && request->AlarmReserved == 0;
}
// Returns whether one request carries no borrowed-vfork lifecycle payload.
static int PosixsrvHasNoVforkPayload(const NTL_POSIX_REQUEST* request) {
static bool PosixsrvHasNoVforkPayload(const NTL_POSIX_REQUEST* request) {
return request && request->VforkToken == 0 && request->VforkExitCode == 0 &&
request->VforkReserved == 0;
}
// Returns whether one request carries no transaction state.
static int PosixsrvHasNoTransaction(const NTL_POSIX_REQUEST* request) {
static bool PosixsrvHasNoTransaction(const NTL_POSIX_REQUEST* request) {
return request && request->TransactionId == 0 &&
request->TransactionKind == NTL_POSIX_TRANSACTION_NONE;
}
// Returns whether all payload domains other than P6 signals are unused.
static int PosixsrvHasOnlySignalPayload(const NTL_POSIX_REQUEST* request) {
static bool PosixsrvHasOnlySignalPayload(const NTL_POSIX_REQUEST* request) {
return request && PosixsrvHasNoBootstrap(request) && PosixsrvHasNoTransaction(request) &&
PosixsrvHasNoAttributePayload(request) && PosixsrvHasNoFdInheritancePayload(request) &&
PosixsrvHasNoSpawnPayload(request) && PosixsrvHasNoWaitPayload(request) &&