Skip to content

Add POSIX user-mode subsystem, NT syscall wrappers, and console-logon utility; update build files and docs#2

Merged
thepanoc95 merged 4 commits into
mainfrom
codex/fix-build-problem-in-librent.shell-srb5bp
May 16, 2026
Merged

Add POSIX user-mode subsystem, NT syscall wrappers, and console-logon utility; update build files and docs#2
thepanoc95 merged 4 commits into
mainfrom
codex/fix-build-problem-in-librent.shell-srb5bp

Conversation

@thepanoc95
Copy link
Copy Markdown
Owner

Motivation

  • Provide a supported, safe POSIX compatibility layer implemented in user mode rather than patching the kernel or ntoskrnl.exe.
  • Expose a set of NT-native syscall wrappers to allow other components to call NT APIs through the ntos2nd syscall dispatcher.
  • Ship a small admin utility to toggle console-style logon by disabling authui.dll for online/offline Windows roots and document it.
  • Clean up project metadata to rely on SDK defaults where appropriate.

Description

  • Add a POSIX subsystem scaffold under ntos2nd/posix/ including a user-mode runtime posixsubsystem.dll (posixsubsystem.c, posixsubsystem.def), a kernel-mode driver stub driver/posixsubsys_driver.c, a shared ABI header include/posix_abi.h, a POSIX_SUBSYSTEM.md design doc, and a short posix/README.md describing the approach.
  • Wire the POSIX runtime into the build by updating ntos2nd/CMakeLists.txt to build/install posixsubsystem and install the shared header, and add brief README notes about the NT wrapper coverage.
  • Implement NT syscall wrapper entry points in ntos2nd/NTCall.c and declare them in ntos2nd/NTCall.h, providing wrappers for NtCloseWrap, NtOpenProcessWrap, NtReadFileWrap, NtWriteFileWrap, and NtAllocateVirtualMemoryWrap routed through NTOS2NDHandleSyscall and using NTOS2NDGetHandlePointer where appropriate.
  • Add utils/Enable-ConsoleLogon.ps1 and update top-level README.md to document the utility and usage examples for online and offline Windows roots.
  • Remove an explicit ItemGroup listing source files from mswindows/shell/LibreNT.Shell.csproj to fall back to SDK/project defaults.

Testing

  • No automated tests were executed as part of this change.
  • Existing CMake test harness remains enabled in ntos2nd/CMakeLists.txt under enable_testing() and add_subdirectory(tests), but no new tests were added or run in this rollout.

Codex Task

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request implements a POSIX subsystem scaffold, featuring a user-mode runtime DLL, a kernel-mode driver stub, and comprehensive strategy documentation. It also expands NT syscall wrapper coverage and adds a PowerShell utility for toggling console logon. Key feedback includes a critical error in PosixSpawnProcess where Win32 error codes are incorrectly treated as NTSTATUS, along with suggestions to improve type safety in function declarations, optimize string construction, and eliminate duplicated type definitions and documentation.

Comment on lines +41 to +45
if (!ok) {
resp->pid = -1;
resp->ntstatus = (int32_t)GetLastError();
return PosixTranslateNtStatusToErrno(resp->ntstatus);
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

When CreateProcessA fails, GetLastError() returns a Win32 error code (DWORD), but it is then passed to PosixTranslateNtStatusToErrno, which expects an NTSTATUS code. This mismatch will lead to incorrect errno values being returned. You should map the Win32 error to errno directly.

    if (!ok) {
        resp->pid = -1;
        DWORD win32Error = GetLastError();
        resp->ntstatus = (int32_t)win32Error;
        switch (win32Error) {
            case ERROR_FILE_NOT_FOUND:
            case ERROR_PATH_NOT_FOUND:
                return 2; /* ENOENT */
            case ERROR_ACCESS_DENIED:
                return 13; /* EACCES */
            default:
                return 5; /* EIO */
        }
    }

Comment thread ntos2nd/CMakeLists.txt
add_library(posixsubsystem SHARED
posix/runtime/posixsubsystem.c
posix/runtime/posixsubsystem.def
posix/include/posix_abi.h
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Header files should generally not be listed as sources in add_library. CMake automatically tracks dependencies from #include directives. While this may not break the build, it's unconventional and can be confusing. Please remove the header from the source list.

Comment thread ntos2nd/NTCall.c

#include "ntos2nd/syscall.h"
#include "ntos2nd/kernel.h"
#include "ntos2nd/apibridge.h" /* For NT type definitions */
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The apibridge.h header is removed, but the type definitions it provided (like POBJECT_ATTRIBUTES) are now duplicated in NTCall.c and needed by NTCall.h. To improve maintainability and avoid type definition duplication, consider moving these common NT type definitions into a shared header file that both NTCall.c and consumers of NTCall.h can include.

Comment thread ntos2nd/NTCall.h
Comment on lines +8 to +10
NTSTATUS NTAPI NtOpenProcessWrap(PHANDLE ProcessHandle, ACCESS_MASK DesiredAccess, void* ObjectAttributes, void* ClientId);
NTSTATUS NTAPI NtReadFileWrap(HANDLE FileHandle, HANDLE Event, PVOID ApcRoutine, PVOID ApcContext, void* IoStatusBlock, PVOID Buffer, ULONG Length, PLARGE_INTEGER ByteOffset, PULONG Key);
NTSTATUS NTAPI NtWriteFileWrap(HANDLE FileHandle, HANDLE Event, PVOID ApcRoutine, PVOID ApcContext, void* IoStatusBlock, const VOID* Buffer, ULONG Length, PLARGE_INTEGER ByteOffset, PULONG Key);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The function declarations for NtOpenProcessWrap, NtReadFileWrap, and NtWriteFileWrap use void* for parameters that have more specific types in their implementations. Using void* bypasses compiler type-checking and reduces type safety. Please use the specific pointer types as used in NTCall.c to allow for better static analysis and prevent potential bugs. You will need to make the type definitions for POBJECT_ATTRIBUTES, PCLIENT_ID, and PIO_STATUS_BLOCK available to this header's consumers.

NTSTATUS NTAPI NtOpenProcessWrap(PHANDLE ProcessHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PCLIENT_ID ClientId);
NTSTATUS NTAPI NtReadFileWrap(HANDLE FileHandle, HANDLE Event, PVOID ApcRoutine, PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, PVOID Buffer, ULONG Length, PLARGE_INTEGER ByteOffset, PULONG Key);
NTSTATUS NTAPI NtWriteFileWrap(HANDLE FileHandle, HANDLE Event, PVOID ApcRoutine, PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, const VOID* Buffer, ULONG Length, PLARGE_INTEGER ByteOffset, PULONG Key);

Comment thread ntos2nd/README.md
Comment on lines +218 to +230
### NT Native Wrapper Coverage

`NTCall.c` provides direct wrapper entry points routed through `NTOS2NDHandleSyscall`.
Current wrappers include:

- `NtCloseWrap`
- `NtOpenProcessWrap`
- `NtReadFileWrap`
- `NtWriteFileWrap`
- `NtAllocateVirtualMemoryWrap`

These wrappers are declared in `NTCall.h` for consumers embedding ntos2nd.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The section "NT Native Wrapper Coverage" is a duplicate of the one starting at line 141. Please remove this redundant section to keep the documentation clean and concise.

Comment on lines +32 to +38
char cmdLine[4096];
cmdLine[0] = '\0';
strncat(cmdLine, req->path, sizeof(cmdLine) - 1);
if (req->argv_blob[0]) {
strncat(cmdLine, " ", sizeof(cmdLine) - strlen(cmdLine) - 1);
strncat(cmdLine, req->argv_blob, sizeof(cmdLine) - strlen(cmdLine) - 1);
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The command line string is constructed using multiple strncat calls. Each call requires a strlen call to find the end of the string, which is inefficient. This approach can also be error-prone when calculating remaining buffer sizes. Using snprintf is a safer, more efficient, and more readable way to build the string.

    char cmdLine[4096];
    int ret = snprintf(cmdLine, sizeof(cmdLine), "%s%s%s",
                     req->path,
                     req->argv_blob[0] ? " " : "",
                     req->argv_blob[0] ? req->argv_blob : "");

    if (ret < 0 || (size_t)ret >= sizeof(cmdLine)) {
        resp->pid = -1;
        resp->ntstatus = 0xC000000D; /* STATUS_INVALID_PARAMETER */
        return 22; /* EINVAL */
    }

@thepanoc95 thepanoc95 merged commit 351f683 into main May 16, 2026
1 check failed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant