// Native syscall contract smoke test. // Verifies public syscall ABI contracts, tick units, and process exit-code round trips. #include #include #include #include #include #define CHILD_EXIT_CODE ((int32_t)-1234567) static void print(const char* s) { SYS_WRITE_CONSOLE_REQUEST req = { sizeof(SYS_WRITE_CONSOLE_REQUEST), SysSvFromCstr(s) }; SysWriteConsole(&req); } static void print_u64(uint64_t v) { char buf[32]; int i = 0; if (v == 0) { print("0"); return; } while (v && i < (int)sizeof(buf)) { buf[i++] = (char)('0' + (v % 10)); v /= 10; } while (i--) { char c = buf[i]; SYS_WRITE_CONSOLE_REQUEST req = { sizeof(SYS_WRITE_CONSOLE_REQUEST), SysSvFromParts(&c, 1) }; SysWriteConsole(&req); } } static void exit_now(int32_t code) { while (true) SysExitProcess(code); } // Checks whether a string view equals a NUL-terminated string. static bool view_equals_cstr(SYS_STRING_VIEW view, const char* text) { size_t n = 0; while (text[n]) n++; if (view.Length != n || (!view.Data && n != 0)) return false; for (size_t i = 0; i < n; i++) { if (view.Data[i] != text[i]) return false; } return true; } static void fail(const char* msg) { print("syscall_contract_smoke: "); print(msg); print("\n"); exit_now(1); } static void fail_status(const char* what, KSTATUS status) { print("syscall_contract_smoke: "); print(what); print(" status="); print_u64(status); print("\n"); exit_now(1); } // Verifies the documented tick unit without relying on wall-clock precision. static void check_tick_contract(void) { uint64_t frequency = 0; KSTATUS s = SysGetTickFrequency(&frequency); if (s != NTLSTATUS_SUCCESS) fail_status("query tick frequency", s); if (!frequency) fail("tick frequency was zero"); uint64_t t0 = SysGetTick(); s = SysSleep(1); if (s != NTLSTATUS_SUCCESS) fail_status("sleep", s); uint64_t t1 = SysGetTick(); if (t1 < t0) fail("tick moved backwards across sleep"); if (SysTicksToMicroseconds(t1 - t0, frequency) < 1000ULL) fail("tick delta was smaller than one millisecond"); } // Verifies process exit-code storage, wait, and query agree on int32_t. static void check_exit_code_contract(void) { SYS_PEB* peb = SysGetPeb(); if (!peb || !peb->ImagePath.Data || peb->ImagePath.Length == 0) fail("missing image path"); uint32_t child = 0; NTL_CREATE_SYSTEM_PROCESS_REQUEST req; memset(&req, 0, sizeof(req)); req.Size = sizeof(req); req.Flags = NTL_PROCESS_LOAD_FLAG_NONE; req.Path = peb->ImagePath; req.CommandLine = SysSvFromCstr("child"); req.SecurityContext = SYS_SECURITY_CONTEXT_CURRENT; req.ResolveModuleName = NtlResolveSystemModuleName; req.ProcessHandleOut = &child; KSTATUS s = NtlCreateSystemProcess(&req); if (s != NTLSTATUS_SUCCESS) fail_status("create child", s); s = SysWait(child, SYS_WAIT_FLAG_NONE); if (s != NTLSTATUS_SUCCESS) fail_status("wait child", s); int32_t exitCode = 0; s = SysGetProcessExitCode(child, &exitCode); if (s != NTLSTATUS_SUCCESS) fail_status("query child exit code", s); if (exitCode != CHILD_EXIT_CODE) fail("child exit code mismatch"); SysCloseHandle(child); } // Verifies request structures reject stale layouts instead of accepting compatibility prefixes. static void check_request_size_contract(void) { SYS_PRINT_DEBUG_REQUEST request = { sizeof(SYS_PRINT_DEBUG_REQUEST) - 1u, SysSvFromCstr("size check must not print"), }; KSTATUS s = SysPrintDebug(&request); if (s != NTLSTATUS_INVALID_PARAMETER) fail_status("undersized request was accepted", s); request.Size = sizeof(SYS_PRINT_DEBUG_REQUEST) + 8u; s = SysPrintDebug(&request); if (s != NTLSTATUS_INVALID_PARAMETER) fail_status("oversized request was accepted", s); } // Exercises strict Unicode scalar boundaries independent of the filesystem. static void check_utf8_contract(void) { static const char valid[] = { 'A', (char)0xC3, (char)0xA9, (char)0xE2, (char)0x82, (char)0xAC, (char)0xF4, (char)0x8F, (char)0xBF, (char)0xBF }; static const char overlong[] = { (char)0xC0, (char)0xAF }; static const char surrogate[] = { (char)0xED, (char)0xA0, (char)0x80 }; static const char tooLarge[] = { (char)0xF4, (char)0x90, (char)0x80, (char)0x80 }; static const char truncated[] = { (char)0xE2, (char)0x82 }; static const char nul[] = { 'A', 0, 'B' }; SYS_STRING_VIEW good = SysSvFromParts(valid, sizeof(valid)); if (!SysSvIsUtf8Text(good)) { print("utf8: valid rejected\n"); exit_now(1); } if (SysSvIsUtf8(SysSvFromParts(overlong, sizeof(overlong))) || SysSvIsUtf8(SysSvFromParts(surrogate, sizeof(surrogate))) || SysSvIsUtf8(SysSvFromParts(tooLarge, sizeof(tooLarge))) || SysSvIsUtf8(SysSvFromParts(truncated, sizeof(truncated))) || SysSvIsUtf8Text(SysSvFromParts(nul, sizeof(nul)))) { print("utf8: invalid accepted\n"); exit_now(1); } if (!SysSvIsUtf8(SysSvFromParts(nul, sizeof(nul))) || !SysSvIsUtf8Text(SYS_SV_NULL) || SysSvIsUtf8(SysSvFromParts((const char*)0, 1u))) { print("utf8: byte span mismatch\n"); exit_now(1); } // ext4 enumeration exposes lossy UTF-8 only for display; no raw byte // sequence or partial multibyte scalar may leak into a directory entry. static const char invalidName[] = { 'a', (char)0xFF, 'b' }; static const char displayName[] = { 'a', (char)0xEF, (char)0xBF, (char)0xBD, 'b', 0 }; char converted[16]; size_t copied = SysSvCopyUtf8WithReplacement( SysSvFromParts(invalidName, sizeof(invalidName)), converted, sizeof(converted)); if (copied != sizeof(displayName) - 1u || memcmp(converted, displayName, sizeof(displayName)) != 0 || !SysSvIsUtf8Text(SysSvFromParts(converted, copied))) { print("utf8: replacement projection mismatch\n"); exit_now(1); } char shortName[5]; copied = SysSvCopyUtf8WithReplacement( SysSvFromParts(invalidName, sizeof(invalidName)), shortName, sizeof(shortName)); if (copied != 4u || shortName[4] != '\0' || !SysSvIsUtf8Text(SysSvFromParts(shortName, copied))) { print("utf8: replacement truncation split a scalar\n"); exit_now(1); } static const char truncatedScalar[] = { 'x', (char)0xE2, (char)0x82 }; copied = SysSvCopyUtf8WithReplacement( SysSvFromParts(truncatedScalar, sizeof(truncatedScalar)), converted, sizeof(converted)); if (copied != 7u || !SysSvIsUtf8Text(SysSvFromParts(converted, copied))) { print("utf8: truncated sequence escaped replacement\n"); exit_now(1); } copied = SysSvCopyUtf8WithReplacement(good, converted, sizeof(converted)); if (copied != sizeof(valid) || memcmp(converted, valid, sizeof(valid)) != 0) { print("utf8: valid scalars modified by replacement\n"); exit_now(1); } static const char embeddedNul[] = { 'a', 0, 'b' }; copied = SysSvCopyUtf8WithReplacement( SysSvFromParts(embeddedNul, sizeof(embeddedNul)), converted, sizeof(converted)); if (copied != 5u || !SysSvIsUtf8Text(SysSvFromParts(converted, copied))) { print("utf8: embedded NUL escaped replacement\n"); exit_now(1); } static const char composed[] = { (char)0xC3, (char)0xA9 }; static const char decomposed[] = { 'e', (char)0xCC, (char)0x81 }; if (!SysSvIsUtf8Text(SysSvFromParts(decomposed, sizeof(decomposed))) || SysSvEqual(SysSvFromParts(composed, sizeof(composed)), SysSvFromParts(decomposed, sizeof(decomposed)))) { print("utf8: identity was normalized\n"); exit_now(1); } } // Runs the syscall ABI contract smoke test. int main(void) { SYS_PEB* peb = SysGetPeb(); if (peb && view_equals_cstr(peb->CommandLine, "child")) { exit_now(CHILD_EXIT_CODE); } print("syscall_contract_smoke: start\n"); check_utf8_contract(); check_tick_contract(); check_request_size_contract(); check_exit_code_contract(); print("syscall_contract_smoke: PASS\n"); exit_now(0); return 0; }