Commit Graph
76 Commits
Author SHA1 Message Date
Dean 5d2eb583bf Merge pull request #9008 from verusferro/feat/libkernel-sys-fstat
feat(libkernel_sys): implement fstat
2026-10-23 13:58:39 +13:00
Dean f1db096084 Merge pull request #9200 from KernelPanicNT/feat/libkernel-sys-lchmod
feat(libkernel_sys): implement lchmod
2026-10-23 12:53:19 +13:00
Dean 287d539503 Merge pull request #9336 from ycbuzi/fix/libkernel-sys-link-follow-windows
fix(libkernel_sys): follow a symbolic link in link on Windows
2026-10-23 11:02:54 +13:00
Adrià a6fc8a467d Merge pull request #8797 from xXPBSXx/fix/unlink-rmdir-dot-component
fix(libkernel): fail unlink and rmdir of a path that ends in a dot component with EINVAL
2026-10-22 20:40:44 +02:00
xXPBSXxandClaude Sonnet 5.5 e56c6d2ba8 fix(libkernel_sys): keep ENOTDIR from fchdir on a character device
The EINVAL for a descriptor without a vnode now applies only to a pipe or socket. A character device is a vnode on FreeBSD, so getvnode succeeds and change_dir fails with ENOTDIR; File::IsCharacterDevice keeps that answer for the host character devices (a tty, NUL or /dev/null) and the guest random device. guest_kernel_sys pins it with /dev/random.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
2026-10-22 20:15:26 +02:00
xXPBSXxandClaude Sonnet 5.5 e1605dda52 fix(libkernel_sys): fail fchdir on a pipe or socket with EINVAL
FreeBSD 11.4's sys_fchdir resolves the descriptor with getvnode, which fails with EINVAL for a descriptor that has no vnode; only a vnode that is not a directory gives ENOTDIR from change_dir. fchdir returned ENOTDIR for a pipe or socket. A descriptor that is neither a vnode nor a random device now gets EINVAL; the debt entry records the order of the three errors.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
2026-10-22 20:15:26 +02:00
Adrià 6671bb3a17 Merge pull request #8723 from xXPBSXx/fix/symlink-target-too-long
fix(libkernel_sys): fail symlink with ENAMETOOLONG for a target of 1024 bytes or more
2026-10-22 19:36:50 +02:00
bluandClaude Opus 5.5 37ba44ce4d test(libkernel_sys): link through a symbolic link loop on Windows
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-22 07:54:57 -07:00
verusferro fa5fc8d5ac test(libkernel_sys): compare fstat with _fstat
fstat must fill the same FileStat as _fstat for an open descriptor, return EFAULT for a null buffer and EBADF for a closed or invalid descriptor, as the fstatfs check beside it does for _fstatfs.
2026-10-22 13:22:59 +03:00
blu 9897260c6e Merge branch 'boykopovar:main' into pr/windows-reparse-non-link 2026-10-21 19:08:16 -07:00
bluandClaude Opus 5.5 339d5c11d7 Merge upstream main into fix/libkernel-sys-link-follow-windows
Resolves the conflict with #8522 in link_nid_postfix: keep its ENOTDIR
return for a destination below a regular file and the Windows
symbolic-link follow after it.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-21 12:13:24 -07:00
Adrià 38d3c0858a Merge pull request #8522 from xXPBSXx/fix/enotdir-through-file-4
fix(libkernel_sys): fail link, symlink, pathconf and fchmodat through a regular file with ENOTDIR
2026-10-21 20:47:51 +02:00
bluandClaude Opus 5.5 a293868561 fix(libkernel_sys): follow a symbolic link in link on Windows
link_nid_postfix decided whether to follow the source with
std::filesystem::is_symlink, which MinGW-w64's libstdc++ never reports for
a Windows symbolic link, so on Windows link made a hard link to the link
itself. Follow a reparse-point source to its final path with
GetFinalPathNameByHandleW instead, and run the link-through-a-link case of
guest_kernel_sys on Windows too.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-21 11:00:06 -07:00
KernelPanicNT 0858e024fb feat(libkernel_sys): implement lchmod
lchmod forwards to fchmodat with AT_FDCWD and AT_SYMLINK_NOFOLLOW, as
FreeBSD 11.4's sys_lchmod does. On Linux and Windows, which cannot change
the mode of a symbolic link itself, a symbolic link throws instead of
succeeding without a change.
2026-10-21 14:54:33 +00:00
blu 04b1d6e5b5 Merge branch 'boykopovar:main' into pr/windows-reparse-non-link 2026-10-20 23:38:51 -07:00
xXPBSXxandClaude Sonnet 5.5 a2a77714d5 fix(libkernel): fail unlink and rmdir of a path that ends in a dot component with EINVAL
FreeBSD lookup() refuses "." and ".." as the last component of a DELETE
lookup with EINVAL (sys/kern/vfs_lookup.c:750-754 and 823-826), before the
unlink and rmdir checks run. unlink and sceKernelUnlink answered EPERM,
rmdir and sceKernelRmdir answered ENOTEMPTY for "..", and unlinkat without
AT_REMOVEDIR answered EPERM. Reuse the RenameDot check added for rename, so a
missing or non-directory parent still reports ENOENT or ENOTDIR first.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
2026-10-21 08:01:47 +02:00
xXPBSXxandClaude Sonnet 5.5 241c8d5973 test(libkernel_sys): keep a symlink target of 1023 bytes valid
The largest target below MAXPATHLEN must pass the length check, so the
comparison cannot slip from >= 1024 to >= 1023.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
2026-10-21 06:27:44 +02:00
bluandClaude Fable 5.1 338e2cbe97 test(libkernel): skip the reparse point checks when setting one is refused for rights
Both fixtures required FSCTL_SET_REPARSE_POINT to succeed; a user without the right would have
aborted guest_filesystem and guest_kernel_sys. They now print that the checks are skipped and carry
on, as the symbolic link checks do without Developer Mode. On this PC the control succeeds at
medium integrity, so the checks ran both elevated and unelevated.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-10-20 18:46:51 -07:00
Dean bfd6c27d65 Merge pull request #8312 from altuux/fix/libkernel-sys-readlink-notdir
fix(libkernel_sys): fail readlink through a regular file with ENOTDIR on Windows
2026-10-21 12:06:42 +13:00
xXPBSXxandClaude Sonnet 5.5 b3a9fbe3ea fix(libkernel_sys): fail symlink with ENAMETOOLONG for a target of MAXPATHLEN bytes or more
FreeBSD 11.4 kern_symlinkat copies the target with copyinstr(path1, ..., MAXPATHLEN)
(sys/kern/vfs_syscalls.c:1490), so a target of 1024 bytes or more fails with
ENAMETOOLONG before the link name is looked up. symlink_nid_postfix had no length
check on the target.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
2026-10-21 00:19:07 +02:00
altuuxandAntigravity a685523018 fix(libkernel_sys): fail readlink through a regular file with ENOTDIR on Windows
A path whose directory part is a regular file, such as file/child, failed
with ENOENT in readlink and readlinkat on Windows, where FreeBSD 11.4 fails
it with ENOTDIR (vfs_cache_lookup, sys/kern/vfs_cache.c). The not-found
error now checks whether the nearest existing ancestor is not a directory,
as was previously done for chmod, truncate, utimes, rename, remove, chdir,
opendir, and fopen.

Co-Authored-By: Antigravity <[email protected]>
2026-10-20 20:25:13 +02:00
xXPBSXxandClaude Sonnet 5.5 994fb42929 fix(libkernel_sys): check the readlink size before the path
FreeBSD 11.4 kern_readlinkat returns EINVAL for a count above IOSIZE_MAX
before namei looks at the path. readlink and readlinkat checked a NULL or
empty path first, so readlink(NULL, buf, SIZE_MAX) returned EFAULT and
readlink("", buf, SIZE_MAX) returned ENOENT where FreeBSD returns EINVAL.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
2026-10-20 20:02:22 +02:00
bluandClaude Opus 5.5 0ecef87c4c fix(libkernel): answer Windows reparse points that are not links
lstat and readlink threw NotImplemented for every Windows reparse point
other than a symbolic link or a drive junction. A tag without the name
surrogate bit (cloud files, deduplication) does not stand for another path,
so lstat now answers as stat does and readlink returns EINVAL, as FreeBSD
does for a file that is not a link and as CPython's os.lstat and os.readlink
do (bpo-37834). A name surrogate that is neither a symbolic link nor a
junction (a mounted volume, a WSL link) is reported as the reparse point
itself with the mode of its attributes, and readlink returns EINVAL.

The tests set reparse tags with FSCTL_SET_REPARSE_POINT, one without the
name surrogate bit and one with it. A compact /exe (WOF) file cannot serve
as the fixture: on Windows 11 24H2 the WOF filter hides the reparse point
from GetFileAttributesW and FileAttributeTagInfo alike. Windows refuses
every open of an unhandled tag without FILE_FLAG_OPEN_REPARSE_POINT, so the
test requires lstat to agree with stat rather than to succeed.

mashingaan's boykopovar/AnyPS5#6447 returned EINVAL for other reparse
points without the tag check.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-10-20 08:21:33 -07:00
xXPBSXxandClaude Sonnet 5.5 923a32c9c9 fix(libkernel_sys): fail link, symlink, pathconf and fchmodat through a regular file with ENOTDIR
FreeBSD 11.4 vfs_cache_lookup answers ENOTDIR when the directory it searches
is not a directory (sys/kern/vfs_cache.c:2104-2105), the lookup behind the
calls fixed in the earlier ENOTDIR changes. These four calls answered ENOENT
for a path such as file/child on Windows.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
2026-10-20 16:48:47 +02:00
Adrià 5f7aa5570c Merge pull request #7563 from babyhuey/feat/libkernel_sys-fstatat
feat(libkernel_sys): implement fstatat
2026-10-20 16:08:26 +02:00
Adrià 48790e0233 Merge pull request #7039 from nabil88/fix/windows-libkernel-and-tests
feat(libkernel): implement getdtablesize and fix Windows host-tree removal
2026-10-19 19:36:18 +02:00
Dean 0b6486704b Merge pull request #7915 from root-over/fix/libkernel-open-flags-before-path-v2
fix(libkernel): check open flags before the path in open, _open and openat
2026-10-20 05:52:06 +13:00
Giuseppe Magliano ff688b2146 fix(libkernel): check open flags before the path in open, _open and openat
FreeBSD 11.4 rejects access mode 3 in kern_openat and
O_CREAT|O_EXCL|O_DIRECTORY in vn_open_cred before namei reads the path
or resolves the directory descriptor. open, _open and openat checked a
NULL or empty path first and returned EFAULT or ENOENT for those flags.
InvalidOpenFlags moves to FileFlags.hpp and runs first in all three.
2026-10-19 15:34:43 +02:00
UAQ Taxi a968336825 fix(libc): remove Windows trees without the remove_all symlink hang
MinGW libstdc++ up to GCC 16 does not treat a reparse point as a link in
std::filesystem::remove_all, so a host tree that holds a symlink is walked
through the link and never returns. Add RemoveTree, which removes the tree
itself on Windows, and use it where save data, app content and the shader
disk cache removed host trees. The libstdc++ fix is in GCC 17 (88856ad855ae).
2026-10-19 14:49:49 +02:00
Rajkamalcode 2224903528 test(libkernel_sys): remove links and the fixture without std::filesystem on Windows
The MinGW libstdc++ reports a dangling symbolic link as missing and clears
the error, so std::filesystem::remove neither deletes it nor fails, and
remove_all loops forever over a tree that contains one. Remove reparse
points with DeleteFileW and RemoveDirectoryW and the fixture through the
shell; record the gap in the libs technical debt.
2026-10-19 14:34:35 +05:30
Adrià 408455bdac Merge pull request #6667 from DavidSamir/fix/libkernel-sys-macos-posix
fix(libkernel_sys): build and check fchdir search permission on macOS
2026-10-19 10:18:13 +02:00
Dean 0a3ba87dcc Merge pull request #6200 from valenciana-nc/fix/symlink-parent-escape
fix(libkernel_sys): reject parent-directory components in symlink targets
2026-10-19 15:22:00 +13:00
valenciana-nc 1a200a1e14 test(libkernel_sys): read accepted symlink targets back through readlink and remove them 2026-10-18 19:04:07 -06:00
Hannah Lyons 15649b702f feat(libkernel_sys): implement fstatat 2026-10-18 20:39:35 -04:00
Adrià ce8c71a78e Merge pull request #6411 from Nixitov/feat/fchown
feat(libkernel_sys): implement fchown
2026-10-19 01:56:48 +02:00
valenciana-nc 84d77798c2 fix(libkernel_sys): reject root names in symlink targets and test target restrictions
Replace the leading-slash absolute-target check with a root-name/root-directory
check so Windows targets like C:/ or \\server\share are rejected too, and
add guest tests covering rejected (.. , ../x, a/../b, a/../../x, /abs, plus
C:/ and UNC paths on Windows) and accepted (sub/dir, a..b, ...) targets.
2026-10-18 21:21:40 +00:00
Adrià ccf0f58785 Merge pull request #6228 from Ondra97/codex/fix-windows-directory-renames
fix(libkernel): preserve directory identity across Windows renames
2026-10-18 22:20:22 +02:00
Maz 7212dae71a fix(libkernel): reject Windows volume mount points in junction reads
A mounted folder uses the junction reparse tag and would otherwise be returned as a relative Volume GUID path. Only a drive path is reported, through the absolute-link text helpers.
2026-10-18 12:53:48 +04:00
Maz e964264d23 Merge branch fix/windows-absolute-symlink into fix/windows-junction
Keep the junction reader and try the absolute symbolic-link reader first.
2026-10-18 12:50:08 +04:00
Ondra97 739e451332 fix(libkernel): preserve directory identity across Windows renames 2026-10-17 23:17:39 +02:00
Maz 01f3938fe1 fix(libkernel): report Windows directory junctions from lstat and readlink 2026-10-18 01:05:40 +04:00
Maz dd70ca83fe test(libkernel): read absolute links into a buffer that fits 2026-10-17 17:06:37 +04:00
Maz 6e331b3823 test(libkernel): compare absolute links by the file they name 2026-10-17 16:46:55 +04:00
Maz 6ad392dad3 fix(libkernel): report absolute Windows symbolic links
lstat and readlink aborted on an absolute symbolic link because only a relative reparse point was accepted. Read the link text, and still refuse reparse points that are not symbolic links.
2026-10-17 16:03:12 +04:00
Hussein Kadhim fd407e34a0 fix(libkernel): fail open with EINVAL for an invalid access mode or O_CREAT|O_EXCL|O_DIRECTORY
FreeBSD rejects an access mode of 3 in kern_openat and the combination of O_CREAT, O_EXCL and O_DIRECTORY in vn_open_cred before it looks the path up. sceKernelOpen, open and openat threw std::invalid_argument for access mode 3 and, on Windows, created the file for the second combination.

(cherry picked from commit 038a07098ef38e95fade52154847b579dcb0f9d0)
2026-10-16 14:21:23 +00:00
David f9bc7d18e2 test(libkernel_sys): run the fchdir search permission check on macOS
The case that removes search permission from a directory and expects
fchdir to fail with EACCES, leave the working directory unchanged and
succeed again once search is allowed ran only on Linux. It now runs on
every host but Windows, with the POSIX headers it needs.
2026-10-16 07:20:14 +04:00
Nixitov 443df0551b feat(libkernel_sys): implement fchown
Morrowind imports fchown and stops at it once rtprio_thread and the pthread concurrency controls are in. Accept the guest's own owner and group (0) or unchanged (-1), fail an invalid descriptor with EBADF, and throw for another owner or group, since ownership is not modelled.
2026-10-15 16:02:36 +02:00
Dean f40b6930ff Merge pull request #4914 from MarcZX100/codex/carry-link-follow-symlink-4026
fix(libkernel_sys): follow symbolic links in link
2026-10-14 17:05:05 +13:00
Adrià d67a9e5a45 Merge pull request #4553 from Nixitov/feat/fchmodat
feat(libkernel_sys): implement fchmodat
2026-10-13 17:03:44 +02:00
Adrià Franch 603d94a53f test(libkernel_sys): reuse longName in the fchmodat check 2026-10-13 16:14:56 +02:00