FreeBSD 11.4 ufs_setattr refuses a change of any SF_* flag to a caller without PRIV_VFS_SYSFLAGS, which prison_priv_check denies a jailed root without allow.chflags. Under the credential model agreed on #11216 every SF_* flag now fails with EPERM, after the EOPNOTSUPP check for unknown bits, instead of throwing.
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
sceKernelUnlink takes its Windows directory-link path only when
std::filesystem::symlink_status reports a directory, but MinGW's
symlink_status follows the link. A directory symbolic link whose target
is missing therefore looked like a file, went to the file delete, and
failed with EACCES, because Windows removes a directory link only
through RemoveDirectoryW. guest_filesystem stops there on any Windows
host that may create symbolic links.
The directory path is now also taken when the link itself carries both
FILE_ATTRIBUTE_DIRECTORY and FILE_ATTRIBUTE_REPARSE_POINT, which
GetFileAttributesW reports without following the link.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
The macOS sceKernelGetdirentries wrote *basep and the entry records into buf
without entering GuestArena::HostWrite, so the write-watch host-write path
never saw those writes. It now opens HostWrite guards for buf over nbytes and
for basep before it moves the descriptor offset, and holds them through every
write, as the Linux path does. It also rejects a non-directory with EINVAL
before the guards, matching Linux.
The long-path fallback in NativeStat opened each intermediate directory with
O_RDONLY | O_DIRECTORY, which needs read permission on it. stat and fstatat
only need search permission, so a path through an execute-only directory
failed with EACCES once it crossed PATH_MAX. O_SEARCH (O_EXEC | O_DIRECTORY
on Darwin) needs only search permission and still rejects a non-directory.
NativeStat, SharedMemory, Stdio, DynamicLoader, ModuleInfo and Rtld used
Linux-only APIs (st_atim, memfd_create, sys/vfs.h, link.h and dl_iterate_phdr),
so libkernel did not compile on macOS. Add macOS paths behind __APPLE__:
st_*timespec and a long-path fstatat walk, an unlinked temp file for shared
memory, statfs, dlopen/dladdr and Mach-O segment walks for module and rtld
queries. The Linux and Windows paths are unchanged.
Extracted from feat/macos-port (#8658).
Co-authored-by: Himansh Raj <[email protected]>
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Emscripten targets wasm64 without x86 assembly, Linux-only headers or the
x87 long double. These changes add __EMSCRIPTEN__ paths beside the host
ones; native builds compile the same code as before.
- libc: long doubles in guest varargs and scanf go through
GuestLongDouble, a plain copy where long double is the x87 format;
APS5_EXPORT emits no assembler alias; the guest arena is one aligned
allocation that zeroes pages when they are committed again; getifaddrs
keeps its link-level entries on Linux; /proc lookups and the host
stderr duplicate are left out.
- libkernel: file-backed mmap, EVFILT_VNODE watches, getcontext and
setcontext throw; getdents replaces the raw getdents64 syscall;
getdtablesize takes the resource limit alone.
- VideoOut leaves SDL, the display window and the HDR probe out,
Sysmodule asks libkernel for unwind information and Net includes
sys/time.h.
A PS4 Pro (firmware 10.71) reports st_blksize 0x10000 from stat and fstat
for /app0, its subdirectories and the system library directory. Titles
size one getdents buffer from it: CUSA18659's CryPak reads st_blksize +
264 bytes once, so the 512 reported here cut its shader directory listing
short. Directories, app0.zar ones included, now report 0x10000; /data
directories (0x8000 on the console) and files are recorded as debt.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
On macOS a guest named shm_open descriptor reports S_IFMT 0 as well,
so the fallback there would hide a descriptor the guest owns.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
ioctl(FIONBIO) read its int argument directly after the existing null
check, so a non-null pointer into unmapped memory crashed the host.
FIONBIO is an _IOW request, which FreeBSD copies in and fails with
EFAULT; the argument is now copied in with GuestCopyIn_nid_no_patch
before the status change.
utimes, lutimes, futimes, sceKernelUtimes and sceKernelFutimes read the
guest times array directly, so a non-null pointer into unmapped memory
crashed the host. Each now copies the two timevals in with
GuestCopyIn_nid_no_patch before anything else, as FreeBSD's getutimes
does before the path or descriptor lookup, and continues on the local
copy. A failed copy returns EFAULT, or 0x8002000e from the sceKernel
forms. A null times array still means the current time.
On Windows, std::filesystem::symlink_status and is_symlink report a directory symbolic link as a plain directory, so rmdir removed the link instead of failing with ENOTDIR (20) and unlink failed with EPERM (1) instead of removing it, unlike FreeBSD. Detect the symlink reparse tag with FindFirstFileW: rmdir returns ENOTDIR, unlink removes the link with RemoveDirectoryW. Junctions and volume mounts keep their previous behaviour. Enable the directory-link and dangling-link blocks of guest_filesystem on Windows (created with CreateSymbolicLinkW).
AI-assisted: yes
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01GtXavMkgCTCdmRpweviHcQ
The PS5 3.20 export lists have ksem_* in libkernel as well as
libkernel_sys, and on Windows a libkernel import never reaches
libkernel_sys, so titles importing them from libkernel did not find
them. Following pipe1os's review on #9284, also: ENOSPC from
ksem_init when no descriptor is left, the SEM_MAX limit of 30 with
ENOSPC, and dup/dup2 from a ksem id throwing as for a kqueue.