move POSIX spawn, exec and child tracking into posixsrv, keep process transactions alive across reconnects and preserve stable PIDs across image replacement, flesh out spawn with ordered file actions, process-group selection and signal inheritance, implement execve with bootstrap validation and rollback before retiring the old process, add vfork children that share the native process while keeping separate POSIX descriptor and signal state, replace local spawn bookkeeping with child reaping, nonblocking and process-group waits and orphan cleanup, add signal dispositions, per-thread masks, pending delivery, process/group signalling and alarms, translate native exceptions into POSIX signals and inherit masks when creating threads, make pipe waits interruptible and raise SIGPIPE for broken pipes, pass arguments and environment into main and add getenv/environ, add direct user APC notifications that can run without an alertable wait, add current-thread capabilities and resume-and-wait, let accepted IPC endpoints open restricted peer process capabilities and preserve caller security during spawn and exec, make process preparation reusable and improve DLL lookup across current, executable and fallback directories, move keyboard repeat into RSSRV so PS/2 and USB share one repeat policy, fix video presentation, report launch failure stages and status codes, mooaaar tests.

This commit is contained in:
maksw committed 2026-09-23 09:39:42 +02:00
1 parent 73abd6f90d
commit 899225f551
57 files changed
+8817 -1216

No files matched your search

@@ -48,16 +48,24 @@ static KSTATUS query_port_stats(SYS_PORT_STATS* stats) {
return SysQueryKernelStats(SYS_KERNEL_STATS_PORT, stats, sizeof(*stats), (size_t*)0);
}
// Returns a newly created listener Port.
static KSTATUS create_listener(uint32_t backlog, SYS_HANDLE* handleOut) {
// Returns a listener with an explicit ceiling for accepted-endpoint peer process authority.
static KSTATUS create_listener_with_peer_rights(uint32_t backlog,
SYS_RIGHTS peerProcessRights,
SYS_HANDLE* handleOut) {
SYS_CREATE_PORT_REQUEST request;
memset(&request, 0, sizeof(request));
request.Size = sizeof(request);
request.Backlog = backlog;
request.PeerProcessRights = peerProcessRights;
request.HandleOut = handleOut;
return SysCreatePort(&request);
}
// Returns a listener that grants no process authority to accepted endpoints.
static KSTATUS create_listener(uint32_t backlog, SYS_HANDLE* handleOut) {
return create_listener_with_peer_rights(backlog, 0, handleOut);
}
// Connects directly to one listener handle.
static KSTATUS connect_listener(SYS_HANDLE listener, SYS_HANDLE* endpointOut) {
SYS_CONNECT_PORT_REQUEST request;
@@ -176,6 +184,64 @@ static int run_connection_lifetime_test(void) {
return 0;
}
// Verifies accepted-endpoint peer process authority, asymmetry, and the listener rights ceiling.
static int run_peer_process_test(void) {
SYS_HANDLE listener = SYS_HANDLE_INVALID;
KSTATUS status = create_listener_with_peer_rights(
1, SYS_RIGHT_QUERY | SYS_PROCESS_RIGHT_SECURITY_CONTEXT, &listener);
if (!KSUCCESS(status)) return fail("create peer-process listener", status);
SYS_HANDLE client = SYS_HANDLE_INVALID;
status = connect_listener(listener, &client);
if (!KSUCCESS(status)) return fail("connect peer-process listener", status);
SYS_HANDLE server = SYS_HANDLE_INVALID;
status = accept_listener(listener, 0, &server, (SYS_PORT_CONNECTION_INFO*)0);
if (!KSUCCESS(status)) return fail("accept peer-process listener", status);
SYS_HANDLE denied = SYS_HANDLE_INVALID;
status = SysOpenPortPeerProcess(client, SYS_RIGHT_QUERY, &denied);
if (status != NTLSTATUS_ACCESS_DENIED)
return fail("client peer-process authority", status);
status = SysOpenPortPeerProcess(server, SYS_RIGHT_QUERY | SYS_PROCESS_RIGHT_TERMINATE, &denied);
if (status != NTLSTATUS_ACCESS_DENIED)
return fail("peer-process rights ceiling", status);
SYS_HANDLE peer = SYS_HANDLE_INVALID;
status = SysOpenPortPeerProcess(
server, SYS_RIGHT_QUERY | SYS_PROCESS_RIGHT_SECURITY_CONTEXT, &peer);
if (!KSUCCESS(status)) return fail("open accepted peer process", status);
uint32_t peerPid = 0;
status = SysGetProcessPid(peer, &peerPid);
if (!KSUCCESS(status) || peerPid != SysGetCurrentPid())
return fail("peer-process identity", KSUCCESS(status) ? NTLSTATUS_FAILURE : status);
SYS_HANDLE context = SYS_HANDLE_INVALID;
status = SysOpenProcessSecurityContext(
peer, SYS_RIGHT_QUERY | SYS_SECURITY_CONTEXT_RIGHT_ASSIGN, &context);
if (!KSUCCESS(status)) return fail("open peer security context", status);
SYS_SECURITY_CONTEXT_INFO currentInfo;
SYS_SECURITY_CONTEXT_INFO peerInfo;
memset(&currentInfo, 0, sizeof(currentInfo));
memset(&peerInfo, 0, sizeof(peerInfo));
currentInfo.Size = sizeof(currentInfo);
peerInfo.Size = sizeof(peerInfo);
status = SysQuerySecurityContext(SYS_SECURITY_CONTEXT_CURRENT, &currentInfo);
if (!KSUCCESS(status)) return fail("query current security context", status);
status = SysQuerySecurityContext(context, &peerInfo);
if (!KSUCCESS(status)) return fail("query peer security context", status);
if (peerInfo.SecurityId != currentInfo.SecurityId)
return fail("peer security identity", NTLSTATUS_FAILURE);
(void)SysCloseHandle(context);
(void)SysCloseHandle(peer);
(void)SysCloseHandle(server);
(void)SysCloseHandle(client);
(void)SysCloseHandle(listener);
return 0;
}
// Exercises same-process connection semantics, waitability, buffering, and queue quotas.
static int run_local_transport_test(void) {
SYS_HANDLE listener = SYS_HANDLE_INVALID;
@@ -494,6 +560,7 @@ int main(void) {
print("port_ipc_smoke: start\n");
if (run_connection_lifetime_test() != 0) return 1;
if (run_peer_process_test() != 0) return 1;
if (run_local_transport_test() != 0) return 1;
if (run_service_test() != 0) return 1;
print("port_ipc_smoke: PASS\n");