Repository navigation
fix(libkernel_sys): fchmodat follows a symbolic link like chmod - #11288
Conversation
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
MarcZX10
left a comment
There was a problem hiding this comment.
The implementation does not change the Windows operation that this PR is meant to fix. The removed fchmodat branch called _wchmod(native.wstring().c_str(), mode & 07777). The new ChmodNative_nid_no_patch wrapper calls NativeChmod with the same path and masked mode, and the Windows NativeChmod implementation in Stdio.cpp calls that same _wchmod API. Its only additional effect is registering the path with RecordWrittenPath; the old fchmodat path already registers it after success. That bookkeeping does not make the filesystem operation follow the link.
So the link, dangling-link, and loop outcomes on Windows should remain unchanged by this patch. The reported Windows test result conflicts with the actual call paths. Please verify the test is running the changed fchmodat implementation in the built binary and add a Windows-specific operation that follows the target, with the file-link, dangling-link, and loop cases passing. The POSIX branch already called chmod and is not changed semantically by this wrapper.
|
Some comparisons could not be completed because a pull request conflicts with the base branch. Review these shared files manually before concluding that there is no overlap.
|
MarcZX10
left a comment
There was a problem hiding this comment.
Correction to my earlier CHANGES_REQUESTED review: I had inspected the POSIX NativeChmod implementation and missed the distinct _WIN32 branch. On Windows, NativeChmod detects a reparse point, opens it without FILE_FLAG_OPEN_REPARSE_POINT so the handle follows the link, resolves the target with HandlePath, and calls _wchmod on that target. The new ChmodNative_nid_no_patch wrapper routes fchmodat(..., flag=0) through this behavior; the old branch called _wchmod on the link path directly. The added Windows test covers a file symlink, dangling link, loop, and a child path through a link. The author reports three passing runs on Windows; I did not independently run that Windows test here. The specific blocker in my previous review was incorrect, and I found no other blocking issue in the current diff.
|
Windows and Linux runs of head
AI-assisted: yes (Claude Code); results above were run on this machine. |
|
The implementation review and Windows report remain useful: the reported |
What
fchmodatwithoutAT_SYMLINK_NOFOLLOWcalled the CRT_wchmoddirectly, which on Windows acts on the link itself. Through a symbolic link FreeBSD 11.4'skern_fchmodatlooks the path up withFOLLOW, so the mode must change on the target. Onmaina file link returned success and left the target untouched, a dangling link returned success instead ofENOENT, and a link loop returned success instead ofELOOP.chmodalready handles all of this throughNativeChmodinStdio.cpp(#9487);fchmodatnow calls the same function through a newChmodNative_nid_no_patch, for theAT_FDCWD, absolute-path and directory-descriptor cases alike. TheAT_SYMLINK_NOFOLLOWbranch and the existing debt entries are untouched.I also probed
fstatat,lchmodandlinkatwithAT_SYMLINK_NOFOLLOW/AT_SYMLINK_FOLLOWon file, directory, dangling and looping links against the same source. Those link cases match:fstatatwithNOFOLLOWreports the link itself (S_IFLNK),linkatwithAT_SYMLINK_FOLLOWlinks the target and refuses a directory link withEPERM, a dangling link withENOENTand a loop withELOOP, andlchmodand theNOFOLLOWlink cases are already in the debt file. Not fixed here, found while probing, all older than this PR:dangling/child,loop/child) givesENOTDIRfromfchmodat,linkatandchmod, where FreeBSD givesENOENTorELOOP:std::filesystem::statusreports such a link as an existing regular file, in bothHasNonDirectoryPrefixcopies (Export.cppandFilesystemError.hpp).fstatatwith a directory descriptor andAT_SYMLINK_NOFOLLOWgivesENOENTforlink-to-file/child(Open.cpp,StatInDirectory_nid_no_patch), wherelstatandfstatat(AT_FDCWD, ...)giveENOTDIRas FreeBSD does.fchmodat,chmodandlchmodgivesEINVAL(Windows error 267 fromGetFileAttributesW), where FreeBSD givesENOTDIR,ENOTDIR,ENOENTandELOOP.Tested
Windows 11 (10.0.26200), WinLibs MinGW-w64 GCC 15.2.0 r7, Ninja, Release,
-DBUILD_TESTING=ON, Developer Mode on, onmainacb900c (four commits behind now, none touching these files).guest_kernel_sys: new checks, where the guestsymlinkcan create links, thatfchmodatwith flag0through a file link changes the target (relative to a descriptor, and withAT_FDCWDand a relative path), and that a dangling link givesENOENT, a loopELOOPandlink/childENOTDIR. Onmainthe test fails; with this change it passes, three runs out of three.pr_overlap_encoding,agc_host_import_cut_lifetimeandagc_driver_depth_plane_partial_store, which fail onmainin this environment too.python tools/check_conventions.py --base upstream/main: passes.chmod), a console, a title run.Overlaps
lchflags) editsStdio.cppat L721-722, next to the new function: feat(libkernel_sys): implement lchflags #9442 was opened first, so it goes first and this PR rebases.app0-overlay, another author, opened earlier) edits the descriptor-join line insidefchmodat_nid_postfix; the two merge cleanly, and no order is needed.tools/pr_overlap.pycould not compareExport.cpp,Stdio.cpporGuestKernelSys.cppagainst 14 older pull requests that conflict withmainthemselves, and reports no other overlap.Checklist
main; no other open PR implements the same functionNotImplemented_nid_no_patch); no silent stubs added.mdfiles or images added to the repositoryAI-assisted (Claude Code).
🤖 Generated with Claude Code