Skip to content

feat(libkernel_sys): add chroot that keeps the guest root - #5191

Merged
adriadam10 merged 2 commits into
boykopovar:mainfrom
p3n1cillin:claude/carry-chroot
Oct 13, 2026
Merged

adriadam10 merged 2 commits into
boykopovar:mainfrom
p3n1cillin:claude/carry-chroot

Conversation

@p3n1cillin

Copy link
Copy Markdown

What

Carries @screamm's two chroot commits from screamm:feat/libkernel-sys-chroot (059d98cf, 15f673ee, author kept), which they offered in #3632 for anyone eligible to carry.

Porpoise (PPSA99764, catalog release) imports chroot (AKknh8Cx-V8) from libkernel_sys.prx. On Windows, current main refuses to load it:

FAIL: unresolved ELF import AKknh8Cx-V8 from libkernel_sys.prx
  • First commit: chroot follows FreeBSD 11.4 sys_chroot/change_dir up to the lookup: EFAULT for a null path, ENOENT for an empty or missing one, and ENOTDIR for a file or a path through a file.
  • Second commit: the title's only call is in put_root_back (Porpoise src/porpoise_jailbreak.cpp). It calls fchdir on the / it opened at start, then chroot("."). So a directory that is already the guest root succeeds without a change, as FreeBSD's pwd_chroot would leave fd_rdir where it is. Any other directory still throws, because the resolver's root and mount aliases are fixed.
  • The details and FreeBSD references are in the commit messages and the libkernel_sys debt entry.

Tested

Checklist

🤖 Generated with Claude Code

screamm and others added 2 commits October 13, 2026 15:11
Porpoise (PPSA99764) imports chroot (AKknh8Cx-V8) from
libkernel_sys.prx, not libkernel.prx, one reference. Predicted stop
once pathconf, the pthread_attr calls and ftrylockfile ahead of it are
covered (not a run):

  FAIL: unresolved ELF import AKknh8Cx-V8 from libkernel_sys.prx

The NID is computed with tools/nid_names.py and matches aerolib.

Follows FreeBSD 11.4 sys/kern/vfs_syscalls.c sys_chroot and change_dir
(8c639945a44588f6cfdddfb057bb5aad88735da0) for a root caller up to the
lookup: EFAULT for a null path, ENOENT for an empty or missing one,
ENOTDIR for a file or a path through a file. A directory that is found
throws with the path named: the resolver's root is fixed and the mount
aliases (/app0, /savedata0) are host paths that do not move with it,
so it cannot be re-based, and a real chroot is not modelled. Nothing
shows that Porpoise calls it.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Porpoise (PPSA99764) stops on its weak chroot import (boykopovar#3632, boykopovar#4497).
Run 5 on main c2565f0, and again on a copy of that runtime:

  FAIL: unresolved ELF import AKknh8Cx-V8 from libkernel_sys.prx

Its only call is in put_root_back (src/porpoise_jailbreak.cpp,
elripalda/Porpoise-Dolphin-Emulator-for-PS5 2ed1ab5a06995aa1): after a
jailbreak daemon has made the console's root its root and /app0 is
gone, it calls fchdir on the descriptor of "/" it opened at start, then
chroot("."), and checks the result. So it only ever puts back the root
it started in, and it does not use paths under any other root.

On top of the lookup errors of the previous commit, chroot now follows
FreeBSD 11.4 sys_chroot and pwd_chroot (8c639945, vfs_syscalls.c and
kern_descrip.c) for that case: a directory that is the guest root
("/", "/..", "." after fchdir to "/") succeeds without a change, since
fd_rdir would be set to the vnode it already is. The guest is taken
never to have changed its root, so with chroot_allow_open_directories 1
an open directory does not give EPERM. ENAMETOOLONG is added as in
pathconf, and a ".." through a file reports ENOTDIR instead of
escaping as a filesystem_error. Any other directory still throws: the
resolver's root and mount aliases are fixed, and no title is known that
needs a real new root.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

Progress report (8c772ad → 41b0ca5)

➖ System libraries: 88.04% (+0.0%, +1 implemented functions)

✅ 1 implemented
Library Name
libkernel_sys chroot_nid_postfix

@adriadam10

Copy link
Copy Markdown
Collaborator

Checked on main merged with the PR: guest_kernel_sys passes (partial build, 24 libs tests green) and fails to link without the change. The chroot errors, the root-no-op and the throw for other directories match the debt entry. The Porpoise log in the description covers the only call site. Merging once the full Build is green.

@MarcZX10

Copy link
Copy Markdown
Contributor

Linux validation on the exact PR head: GCC 12.2, Release, BUILD_TESTING=ON; built guest_kernel_sys_tests, and CTest guest_kernel_sys passed (1/1). This confirms the focused guest test on Linux; it does not add Windows or console coverage.

@adriadam10

Copy link
Copy Markdown
Collaborator

Checked on main merged with the PR: guest_kernel_sys passes (24 libs tests green) and fails to link without the change. The chroot errors, the no-op for the guest root and the throw for other directories match the FreeBSD references and the debt entry. Porpoise's only call site (fchdir then chroot(".")) is covered. Merging once the full Build is green.

@p3n1cillin

Copy link
Copy Markdown
Author

Linux run: Ubuntu in WSL2, GCC 15.2.0, Ninja Release, BUILD_TESTING=ON, full build of a local test head 838d4fd85. That head is main 3faa9cb40 with this PR, my other open libkernel PRs (#5013, #5061, #5078, #5098, #5183–#5187, #5191) and the open PRs the catalog titles need (#4377, #4379, #4374, #4383, #3798, #4467, #4863, #4105). All 123 libkernel and 69 libc tests pass, including guest_system_configuration, guest_getrlimit, guest_kernel_fcntl, guest_freebsd_clocks, guest_kernel_sys and guest_filesystem. Not built alone on Linux; no title run on Linux.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants