redo boot around an explicit system volume and fixed kernel/HAL images, redo volumes and filesystem paths around capabilities instead of drive numbers and kernel CWD state, add a capability/security model with derived and revocable handles and security contexts, add port IPC and rssrv to manage the userspace resource namespace and publish the system volume, move process, dll and path loading to userspace and add process builder syscalls, init now supervises rssrv and the session process, redo the syscall ABI around request structs and four arguments, add a volume manager and proper partition arrival/removal handling so FAT and NTFS mount dynamically, clean up the HAL/DDK boundary so drivers don't depend on HAL internals, save fpu state properly now, the serial driver doesn't hang on a missing port, fix AHCI startup races, fix timeout accounting, fix shared mmap writeback, more smoke tests
This commit is contained in:
1 parent
4add6789ba
commit
f882d339fb
232 files changed
+20934
-8898
No files matched your search
@@ -0,0 +1,117 @@
|
||||
// Userspace current-directory smoke test.
|
||||
// Verifies CWD inheritance and parent traversal clamped at the owning RSSRV resource binding.
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <ntlite/syscall.h>
|
||||
#include <ntlite/path.h>
|
||||
#include <ntlite/resource.h>
|
||||
|
||||
static void print(const char* s) {
|
||||
SYS_WRITE_CONSOLE_REQUEST req = { sizeof(req), SysSvFromCstr(s) };
|
||||
SysWriteConsole(&req);
|
||||
}
|
||||
|
||||
static void exit_now(int code) {
|
||||
while (true) SysExitProcess(code);
|
||||
}
|
||||
|
||||
static void fail_status(const char* what, uint32_t status) {
|
||||
(void)status;
|
||||
print("cwd_userspace_smoke: "); print(what); print("\n");
|
||||
exit_now(1);
|
||||
}
|
||||
|
||||
static void fail(const char* what) {
|
||||
print("cwd_userspace_smoke: "); print(what); print("\n");
|
||||
exit_now(1);
|
||||
}
|
||||
|
||||
static void get_cwd_or_fail(char out[SYS_PATH_MAX + 1u]) {
|
||||
size_t required = 0;
|
||||
uint32_t status = NtlGetCurrentDirectory(out, SYS_PATH_MAX + 1u, &required);
|
||||
if (status != NTLSTATUS_SUCCESS || required == 0 || required > SYS_PATH_MAX + 1u)
|
||||
fail_status("get cwd", status);
|
||||
}
|
||||
|
||||
static void set_cwd_or_fail(const char* path, const char* what) {
|
||||
uint32_t status = NtlSetCurrentDirectory(SysSvFromCstr(path));
|
||||
if (status != NTLSTATUS_SUCCESS) fail_status(what, status);
|
||||
}
|
||||
|
||||
static void expect_cwd(const char* expected) {
|
||||
char current[SYS_PATH_MAX + 1u];
|
||||
get_cwd_or_fail(current);
|
||||
if (strcmp(current, expected) != 0) fail("cwd value mismatch");
|
||||
}
|
||||
|
||||
// Resolves the current absolute resource path and returns the owning namespace-prefix length.
|
||||
static size_t resource_root_length_or_fail(const char* cwd) {
|
||||
SYS_HANDLE session = SYS_HANDLE_INVALID;
|
||||
uint32_t status = NtlResourceConnect(&session);
|
||||
if (status != NTLSTATUS_SUCCESS) fail_status("resource connect", status);
|
||||
|
||||
SYS_HANDLE root = SYS_HANDLE_INVALID;
|
||||
uint32_t kind = NTL_RESOURCE_KIND_INVALID;
|
||||
uint32_t resolvedLength = 0;
|
||||
status = NtlResourceResolve(session, SysSvFromCstr(cwd), NTL_RESOURCE_FLAG_NONE,
|
||||
&root, &kind, &resolvedLength);
|
||||
(void)NtlResourceClose(session);
|
||||
if (root != SYS_HANDLE_INVALID) (void)SysCloseHandle(root);
|
||||
if (status != NTLSTATUS_SUCCESS) fail_status("resolve cwd root", status);
|
||||
|
||||
size_t length = strlen(cwd);
|
||||
if (kind == NTL_RESOURCE_KIND_INVALID || resolvedLength < 2u || resolvedLength > length ||
|
||||
(resolvedLength != length && cwd[resolvedLength] != '/'))
|
||||
fail("initial cwd malformed");
|
||||
return resolvedLength;
|
||||
}
|
||||
|
||||
static void parent_of_cwd(const char* cwd, size_t rootLength, char* out, size_t cap) {
|
||||
size_t length = strlen(cwd);
|
||||
if (rootLength < 2u || rootLength > length || length + 1u > cap ||
|
||||
(rootLength != length && cwd[rootLength] != '/'))
|
||||
fail("initial cwd malformed");
|
||||
|
||||
memcpy(out, cwd, length + 1u);
|
||||
if (length == rootLength) return;
|
||||
while (length > rootLength && out[length - 1u] == '/') out[--length] = '\0';
|
||||
while (length > rootLength && out[length - 1u] != '/') length--;
|
||||
if (length <= rootLength + 1u) length = rootLength;
|
||||
else length--;
|
||||
out[length] = '\0';
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
char original[SYS_PATH_MAX + 1u];
|
||||
char parent[SYS_PATH_MAX + 1u];
|
||||
char root[SYS_PATH_MAX + 1u];
|
||||
|
||||
print("cwd_userspace_smoke: start\n");
|
||||
get_cwd_or_fail(original);
|
||||
size_t rootLength = resource_root_length_or_fail(original);
|
||||
parent_of_cwd(original, rootLength, parent, sizeof(parent));
|
||||
memcpy(root, original, rootLength);
|
||||
root[rootLength] = '\0';
|
||||
|
||||
// Refresh the cached binding boundary without changing the path.
|
||||
set_cwd_or_fail(".", "set dot cwd");
|
||||
expect_cwd(original);
|
||||
|
||||
set_cwd_or_fail("..", "set parent cwd");
|
||||
expect_cwd(parent);
|
||||
|
||||
// Relative traversal stops at the actual bound resource, including multi-component roots.
|
||||
set_cwd_or_fail(root, "set resource root cwd");
|
||||
expect_cwd(root);
|
||||
set_cwd_or_fail("..", "clamp parent at resource root");
|
||||
expect_cwd(root);
|
||||
|
||||
set_cwd_or_fail(original, "restore original cwd");
|
||||
expect_cwd(original);
|
||||
|
||||
print("cwd_userspace_smoke: PASS\n");
|
||||
exit_now(0);
|
||||
return 0;
|
||||
}
|
||||
Reference in new issue
Block a user