Follow FreeBSD 11.4 sys_setresuid and sys_setresgid (sys/kern/kern_prot.c):
accept real, effective, and saved user and group IDs for the guest process,
which is assumed to run as root with IDs 0. Setting an ID to 0 or -1 (unchanged)
is accepted without changing credentials and returns 0; any other value throws.
Cover both in guest_credentials test and update libkernel debt documentation.
The call threw for lack of a signature. In the PS5 12.00 libkernel it takes
one int, passes it to syscall 601 (command 29) and returns the raw kernel
result. No dump is produced here, so it returns 0, as
sceCoredumpConfigDumpMode does.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01RbLgECLQ2bpDM7oe2urGZK
Follow FreeBSD 11.4 sys_getresuid and sys_getresgid (sys/kern/kern_prot.c):
retrieve real, effective, and saved user and group IDs for the guest process,
which is assumed to run as root with IDs 0. Pointers that are not null receive 0,
null pointers are ignored, and 0 is returned leaving errno unchanged on success.
Cover both in guest_credentials test and update libkernel debt documentation.
The public SDK's libkernel, libkernel_sys and libkernel_web stub tables declare _sigintr, the
sigset_t that FreeBSD's libc shares between signal and siginterrupt, and no built library
provided it (#8846). libkernel now exports the 16-byte object, zero at start, and signal records
a handler with SA_RESTART unless its signal is in the set, as lib/libc/gen/signal.c does.
siginterrupt, which fills the set, is a libSceLibcInternal export; libc does not link libkernel
and cannot reach the dispositions, so it stays out and a debt entry for signal says so.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
pthread_kill(thread, 0) returned 0 for every handle other than the caller's before it asked whether the thread was still alive. FreeBSD's _pthread_kill looks the thread up with _thr_find_thread before it checks for signal 0, so the call answers ESRCH for a thread that has ended or was never a thread. The liveness check now runs before the signal 0 shortcut; the calling thread still answers 0.
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Since #8512 a raise redirects a target running host code once 50 ms have
passed since the raise began. A target inside a system call that is not a
wait, such as the NtWriteFile of an fwrite that holds its stream lock, can
stay there longer; the redirect then ran the handler with the lock held.
SONIC SUPERSTARS froze at frame 67 again on main this way, with its GC
raise delivered at ntdll!ZwWriteFile+20.
A target stopped right after a syscall instruction in ntdll now restarts
the 50 ms host-code window, so the raise keeps sampling until the call
returns and the target leaves host code, bounded by the 1 s retry limit.
guest_raise_in_system_call holds a writer in NtWriteFile on a slowly
drained pipe; it times out on main and passes with this change.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
GetThreadContext can fail on a target that was just suspended. A raise
used to throw "cannot read the target thread context" at the first
failure; it now resumes the target and tries again, within the existing
1 s retry limit, before throwing. SONIC SUPERSTARS hit the throw once in
three runs. guest_raise_in_host_code prints the longest single raise.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Follow-up to #7652. A raise on a thread running host code waited up to the
1 s RetryLimit before falling back, so Windows guest_raise_exception (about
220 host-resident raises) went from ~15 s to 17-30 s. Host code now has its
own HostCodeLimit of 50 ms; RetryLimit still guards NtContinue and winpthreads.
A signal that is ignored is forgotten when it is sent: the call succeeds
(sys/kern/kern_sig.c:2178-2187). That covers SIG_IGN and the signals whose
default action is SA_IGNORE, SIGURG, SIGCONT, SIGCHLD, SIGIO, SIGWINCH and
SIGINFO (kern_sig.c:205-240); SIGCONT stays pending while blocked. The guest
failed with EINVAL for every such signal that has no host equivalent.
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
FreeBSD 11.4 raise is thr_kill(thr_self(), sig) (lib/libc/gen/raise.c:52),
and thr_kill with a thread id treats signal 0 as a pure existence check
that returns 0 (sys/kern/kern_thr.c:425). The guest returned EINVAL.
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
FreeBSD 11.4 kern_sigaction fails with EINVAL when a handler other than
SIG_DFL and SIG_IGN comes with flags outside SA_ONSTACK, SA_RESTART,
SA_RESETHAND, SA_NOCLDSTOP, SA_NODEFER, SA_NOCLDWAIT and SA_SIGINFO
(sys/kern/kern_sig.c:691-695). The guest accepted any flag word.
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
FreeBSD 11.4 kern_sigprocmask applies SIG_CANTMASK to the set for SIG_BLOCK
and SIG_SETMASK (sys/kern/kern_sig.c:1056, 1067), and sigsuspend sets its
mask through the same call (kern_sig.c:1534). The guest mask kept both bits,
so sigprocmask(SIG_BLOCK, {SIGKILL}) read back as blocked.
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
In a payload process on a PS5 (firmware 12.70), sysctlbyname returns -1
with ENOENT for thirteen names that threw here, and leaves the buffer and
the length alone, for a read, a size query, a null length and a null
buffer with a null length. sysctl does the same for the fixed MIBs of
seven of them. sysctlnametomib gives those seven MIBs and returns ENOENT
for hw.cacheline_size and hw.usermem, which threw too.
machdep.cacheline_size already returned ENOENT and is now tested with
the others. A write to the new names and MIBs throws, as the console's
answer to a write was not tried. The hw.realmem and vm.overcommit debt
entries now say that a payload process gets ENOENT for them as well.
AI-assisted: yes
Co-Authored-By: Claude Opus 5.5 <[email protected]>