// Security-context smoke test. This validates authority attenuation, assignment, and ambient privilege enforcement. #include #include #include #include #include #include static void print(const char* text) { SYS_WRITE_CONSOLE_REQUEST request = { sizeof(request), SysSvFromCstr(text) }; (void)SysWriteConsole(&request); } static void print_u32(uint32_t value) { char digits[16]; uint32_t count = 0; if (value == 0) { print("0"); return; } while (value && count < sizeof(digits)) { digits[count++] = (char)('0' + value % 10u); value /= 10u; } while (count) { char one[2] = { digits[--count], 0 }; print(one); } } // Exits without relying on a C runtime return path. static void exit_now(int32_t code) { while (true) (void)SysExitProcess(code); } // Fails the privileged parent with a visible diagnostic. static void fail_status(const char* operation, KSTATUS status) { print("security_smoke: "); print(operation); print(" status="); print_u32(status); print("\n"); exit_now(1); } // Parses one unsigned decimal value without requiring formatted libc helpers. static bool parse_u32(SYS_STRING_VIEW text, size_t start, uint32_t* valueOut) { if (!valueOut || start >= text.Length) return false; uint32_t value = 0; bool any = false; for (size_t i = start; i < text.Length; i++) { char c = text.Data[i]; if (c < '0' || c > '9') return false; uint32_t digit = (uint32_t)(c - '0'); if (value > (UINT32_MAX - digit) / 10u) return false; value = value * 10u + digit; any = true; } if (!any) return false; *valueOut = value; return true; } // Appends one unsigned decimal value to a bounded command string. static bool append_u32(char* buffer, size_t capacity, size_t* lengthInOut, uint32_t value) { if (!buffer || !lengthInOut || *lengthInOut >= capacity) return false; char reverse[16]; size_t count = 0; do { reverse[count++] = (char)('0' + value % 10u); value /= 10u; } while (value && count < sizeof(reverse)); if (*lengthInOut + count + 1 > capacity) return false; while (count) buffer[(*lengthInOut)++] = reverse[--count]; buffer[*lengthInOut] = '\0'; return true; } // Runs inside the stripped child and returns a distinct failure code for each leaked ambient authority. static int run_restricted_child(uint32_t parentPid) { SYS_SECURITY_CONTEXT_INFO info; memset(&info, 0, sizeof(info)); info.Size = sizeof(info); KSTATUS status = SysQuerySecurityContext(SYS_SECURITY_CONTEXT_CURRENT, &info); if (!KSUCCESS(status)) return 10; if (info.EffectivePrivileges || info.DelegablePrivileges) return 11; SYS_HANDLE process = SYS_HANDLE_INVALID; status = SysOpenProcess(parentPid, SYS_RIGHT_QUERY, &process); if (status != NTLSTATUS_ACCESS_DENIED) return 12; size_t processCount = 0; status = SysGetProcessList((SYS_PROCESS_INFO*)0, 0, &processCount); if (status != NTLSTATUS_ACCESS_DENIED) return 13; size_t required = 0; status = SysQueryKernelStats(SYS_KERNEL_STATS_SCHEDULER, (void*)0, 0, &required); if (status != NTLSTATUS_ACCESS_DENIED) return 14; SYS_DISPLAY_INFO displayInfo; memset(&displayInfo, 0, sizeof(displayInfo)); status = SysQueryDisplayInfo(&displayInfo); if (status != NTLSTATUS_ACCESS_DENIED) return 16; SYS_HANDLE socketHandle = SYS_HANDLE_INVALID; status = SysCreateSocket(0, 0, 0, &socketHandle); if (status != NTLSTATUS_ACCESS_DENIED) return 17; SYS_PRINT_DEBUG_REQUEST debugRequest = { sizeof(debugRequest), SysSvFromParts((const char*)0, 0) }; status = SysPrintDebug(&debugRequest); if (status != NTLSTATUS_ACCESS_DENIED) return 18; SYS_WRITE_CONSOLE_REQUEST consoleRequest = { sizeof(consoleRequest), SysSvFromParts((const char*)0, 0) }; status = SysWriteConsole(&consoleRequest); if (status != NTLSTATUS_ACCESS_DENIED) return 19; SYS_PEB* peb = SysGetPeb(); if (!peb || !peb->ImagePath.Data || peb->ImagePath.Length == 0) return 20; SYS_HANDLE file = SYS_HANDLE_INVALID; status = NtlOpenFile(peb->ImagePath, SYS_FILE_ACCESS_READ | SYS_FILE_ACCESS_QUERY, SYS_FILE_OPEN_EXISTING, SYS_FILE_FLAG_NONE, &file); if (!KSUCCESS(status)) return 21; (void)SysCloseHandle(file); uint32_t endpointCount = 0; SYS_AUDIO_ENUMERATE_ENDPOINTS_REQUEST enumerateAudio; memset(&enumerateAudio, 0, sizeof(enumerateAudio)); enumerateAudio.Size = sizeof(enumerateAudio); enumerateAudio.CountOut = &endpointCount; status = SysAudioEnumerateEndpoints(&enumerateAudio); if (status != NTLSTATUS_ACCESS_DENIED) return 22; SYS_HANDLE listener = SYS_HANDLE_INVALID; SYS_CREATE_PORT_REQUEST createPort; memset(&createPort, 0, sizeof(createPort)); createPort.Size = sizeof(createPort); createPort.HandleOut = &listener; status = SysCreatePort(&createPort); if (!KSUCCESS(status)) return 25; status = SysRegisterSystemService(SYS_HANDLE_INVALID, listener); (void)SysCloseHandle(listener); if (status != NTLSTATUS_INVALID_HANDLE) return 26; uint32_t selfPid = SysGetCurrentPid(); status = SysOpenProcess(selfPid, SYS_RIGHT_QUERY, &process); if (!KSUCCESS(status)) return 27; status = SysCloseHandle(process); if (!KSUCCESS(status)) return 28; process = SYS_HANDLE_INVALID; status = SysOpenProcess(selfPid, SYS_RIGHT_QUERY | SYS_PROCESS_RIGHT_SECURITY_CONTEXT, &process); if (status != NTLSTATUS_ACCESS_DENIED) return 29; return 0; } // Creates one zero-authority security context from the caller's current delegable root. static SYS_HANDLE derive_stripped_context(void) { SYS_HANDLE handle = SYS_HANDLE_INVALID; SYS_DERIVE_SECURITY_CONTEXT_REQUEST request; memset(&request, 0, sizeof(request)); request.Size = sizeof(request); request.SourceContext = SYS_SECURITY_CONTEXT_CURRENT; request.Flags = SYS_SECURITY_CONTEXT_FLAG_NONE; request.ContextHandleOut = &handle; KSTATUS status = SysDeriveSecurityContext(&request); if (!KSUCCESS(status)) fail_status("derive stripped context", status); return handle; } // Runs the privileged parent half of the security-context smoke test. static int run_parent(void) { SYS_PEB* peb = SysGetPeb(); if (!peb || !peb->ImagePath.Data || peb->ImagePath.Length == 0) fail_status("missing image path", NTLSTATUS_FAILURE); SYS_SECURITY_CONTEXT_INFO rootInfo; memset(&rootInfo, 0, sizeof(rootInfo)); rootInfo.Size = sizeof(rootInfo); KSTATUS status = SysQuerySecurityContext(SYS_SECURITY_CONTEXT_CURRENT, &rootInfo); if (!KSUCCESS(status)) fail_status("query current context", status); if (rootInfo.EffectivePrivileges != SYS_PRIV_ALL || rootInfo.DelegablePrivileges != SYS_PRIV_ALL) fail_status("bootstrap context authority", NTLSTATUS_FAILURE); SYS_HANDLE selfProcess = SYS_HANDLE_INVALID; status = SysOpenProcess(SysGetCurrentPid(), SYS_RIGHT_QUERY | SYS_PROCESS_RIGHT_SECURITY_CONTEXT, &selfProcess); if (!KSUCCESS(status)) fail_status("open self security-context process", status); SYS_HANDLE exactContext = SYS_HANDLE_INVALID; status = SysOpenProcessSecurityContext( selfProcess, SYS_RIGHT_QUERY | SYS_SECURITY_CONTEXT_RIGHT_ASSIGN, &exactContext); if (!KSUCCESS(status)) fail_status("open exact process security context", status); SYS_SECURITY_CONTEXT_INFO exactInfo; memset(&exactInfo, 0, sizeof(exactInfo)); exactInfo.Size = sizeof(exactInfo); status = SysQuerySecurityContext(exactContext, &exactInfo); if (!KSUCCESS(status)) fail_status("query exact process security context", status); if (exactInfo.SecurityId != rootInfo.SecurityId || exactInfo.EffectivePrivileges != rootInfo.EffectivePrivileges || exactInfo.DelegablePrivileges != rootInfo.DelegablePrivileges) fail_status("exact process security context identity", NTLSTATUS_FAILURE); (void)SysCloseHandle(exactContext); (void)SysCloseHandle(selfProcess); SYS_HANDLE queryOnlyProcess = SYS_HANDLE_INVALID; status = SysOpenProcess(SysGetCurrentPid(), SYS_RIGHT_QUERY, &queryOnlyProcess); if (!KSUCCESS(status)) fail_status("open query-only self process", status); exactContext = SYS_HANDLE_INVALID; status = SysOpenProcessSecurityContext(queryOnlyProcess, SYS_RIGHT_QUERY, &exactContext); (void)SysCloseHandle(queryOnlyProcess); if (status != NTLSTATUS_ACCESS_DENIED) fail_status("process security-context right", status); SYS_HANDLE restricted = derive_stripped_context(); SYS_SECURITY_CONTEXT_INFO restrictedInfo; memset(&restrictedInfo, 0, sizeof(restrictedInfo)); restrictedInfo.Size = sizeof(restrictedInfo); status = SysQuerySecurityContext(restricted, &restrictedInfo); if (!KSUCCESS(status)) fail_status("query stripped context", status); if (restrictedInfo.SecurityId <= rootInfo.SecurityId || restrictedInfo.EffectivePrivileges || restrictedInfo.DelegablePrivileges) fail_status("stripped context contents", NTLSTATUS_FAILURE); SYS_HANDLE illegal = SYS_HANDLE_INVALID; SYS_DERIVE_SECURITY_CONTEXT_REQUEST amplify; memset(&lify, 0, sizeof(amplify)); amplify.Size = sizeof(amplify); amplify.SourceContext = restricted; amplify.EffectivePrivileges = SYS_PRIV_PROCESS_OPEN_ANY; amplify.ContextHandleOut = &illegal; status = SysDeriveSecurityContext(&lify); if (status != NTLSTATUS_ACCESS_DENIED) fail_status("blocked privilege amplification", status); SYS_HANDLE queryOnly = SYS_HANDLE_INVALID; SYS_DERIVE_HANDLE_REQUEST deriveHandle = { sizeof(deriveHandle), restricted, SYS_RIGHT_QUERY, &queryOnly }; status = SysDeriveHandle(&deriveHandle); if (!KSUCCESS(status)) fail_status("derive query-only context handle", status); SYS_HANDLE rejectedChild = SYS_HANDLE_INVALID; NTL_CREATE_SYSTEM_PROCESS_REQUEST rejectedCreate; memset(&rejectedCreate, 0, sizeof(rejectedCreate)); rejectedCreate.Size = sizeof(rejectedCreate); rejectedCreate.Flags = NTL_PROCESS_LOAD_FLAG_NONE; rejectedCreate.Path = peb->ImagePath; rejectedCreate.CommandLine = SysSvFromCstr("restricted:1"); rejectedCreate.SecurityContext = queryOnly; rejectedCreate.ResolveModuleName = NtlResolveSystemModuleName; rejectedCreate.ProcessHandleOut = &rejectedChild; status = NtlCreateSystemProcess(&rejectedCreate); if (status != NTLSTATUS_ACCESS_DENIED) fail_status("context assignment right", status); (void)SysCloseHandle(queryOnly); char command[48] = "restricted:"; size_t commandLength = strlen(command); if (!append_u32(command, sizeof(command), &commandLength, SysGetCurrentPid())) fail_status("build child command", NTLSTATUS_BUFFER_TOO_SMALL); SYS_HANDLE child = SYS_HANDLE_INVALID; NTL_CREATE_SYSTEM_PROCESS_REQUEST create; memset(&create, 0, sizeof(create)); create.Size = sizeof(create); create.Flags = NTL_PROCESS_LOAD_FLAG_NONE; create.Path = peb->ImagePath; create.CommandLine = SysSvFromCstr(command); create.SecurityContext = restricted; create.ResolveModuleName = NtlResolveSystemModuleName; create.ProcessHandleOut = &child; status = NtlCreateSystemProcess(&create); if (!KSUCCESS(status)) fail_status("create restricted child", status); status = SysWait(child, SYS_WAIT_FLAG_NONE); if (!KSUCCESS(status)) fail_status("wait restricted child", status); int32_t childExit = -1; status = SysGetProcessExitCode(child, &childExit); if (!KSUCCESS(status)) fail_status("query restricted child", status); (void)SysCloseHandle(child); if (childExit != 0) { print("security_smoke: restricted child failure="); print_u32((uint32_t)childExit); print("\n"); return 1; } status = SysCloseHandle(restricted); if (!KSUCCESS(status)) fail_status("close stripped context", status); SYS_HANDLE later = derive_stripped_context(); SYS_SECURITY_CONTEXT_INFO laterInfo; memset(&laterInfo, 0, sizeof(laterInfo)); laterInfo.Size = sizeof(laterInfo); status = SysQuerySecurityContext(later, &laterInfo); if (!KSUCCESS(status)) fail_status("query later context", status); if (laterInfo.SecurityId <= restrictedInfo.SecurityId) fail_status("security id reuse", NTLSTATUS_FAILURE); (void)SysCloseHandle(later); print("security_smoke: PASS\n"); return 0; } // Runs either the privileged parent or the stripped child based on the process command line. int main(void) { SYS_PEB* peb = SysGetPeb(); if (!peb) return 2; const char prefix[] = "restricted:"; if (peb->CommandLine.Length > sizeof(prefix) - 1u && memcmp(peb->CommandLine.Data, prefix, sizeof(prefix) - 1u) == 0) { uint32_t parentPid = 0; if (!parse_u32(peb->CommandLine, sizeof(prefix) - 1u, &parentPid)) return 3; return run_restricted_child(parentPid); } return run_parent(); }