Skip to content

fix(libkernel): fail fcntl record locks with EFAULT on an unreadable flock pointer - #15081

Open
Gruzzberry wants to merge 1 commit into
boykopovar:mainfrom
Gruzzberry:fix/fcntl-record-lock-efault
Open

Gruzzberry wants to merge 1 commit into
boykopovar:mainfrom
Gruzzberry:fix/fcntl-record-lock-efault

Conversation

@Gruzzberry

Copy link
Copy Markdown
Contributor

What

fcntl with F_GETLK, F_SETLK, F_SETLKW and the old F_OGETLK, F_OSETLK, F_OSETLKW read the guest struct flock with a raw memcpy. A guest passing an invalid non-null pointer (for example 0x10) crashed the host emulator with an access violation. FreeBSD 11.4's sys_fcntl copies the structure in before kern_fcntl looks at the descriptor, so these commands fail with EFAULT for an unreadable pointer, ahead of EBADF and the other checks. The structure is now read with GuestCopyIn_nid_no_patch (24 bytes for the old commands, 32 for the new ones), and the virtual-directory EINVAL check moved after it. The F_GETLK result copy-out already failed with EFAULT and is unchanged.

Tested

Windows 11 (10.0.26200), WinLibs MinGW-w64 GCC 15.2.0 r7, Ninja, Release, -DBUILD_TESTING=ON, on current main.

  • guest_kernel_fcntl: new checks pass 0x10 to all six lock commands on a regular file and to SetLock on descriptor -1, expecting EFAULT. On main the test crashes with a segmentation fault; with this change it passes, three runs out of three.
  • Full suite: no failure touches this change. pr_overlap_encoding, agc_host_import_cut_lifetime and agc_driver_depth_plane_partial_store did not fail here. The failures are vulkan_validation_gate_reports and check_compile_test_windows_gcc_response_text_mode_is_not_reinterpreted (the WindowsApps python environment) and the two main_sync_renames_test_*_rename_with_detection_disabled tests (a non-ASCII file name assertion in a git script, 3 of 3 failing alone, not present in the earlier baseline).
  • python tools/check_conventions.py --base upstream/main: passes.
  • Not tested: Linux and macOS, a console, a title run.
  • Not fixed, same on main and here: on non-Windows hosts F_GETLK into readable but read-only guest memory is not caught by the result copy-out.

Overlaps

Checklist

AI-assisted (Claude Code).

🤖 Generated with Claude Code

…flock pointer

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

@BunnyFl BunnyFl left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This matches FreeBSD 11.4's sys_fcntl, which does copyin of the struct flock (and the old struct __oflock) before kern_fcntl looks at the descriptor. So EFAULT now comes before the virtual-directory EINVAL and before a bad descriptor, as the new -1 case pins.

Build and test on Windows (WinLibs GCC, BUILD_TESTING=ON), PR merged into current main:

  • guest_kernel_fcntl passes.
  • With main's DescriptorControl.cpp restored, it segfaults on the new 0x10 cases.

@github-actions

github-actions Bot commented Nov 2, 2026

Copy link
Copy Markdown

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.

Pull request Shared files not compared
PR 7121 core/libs/prx/libkernel/File/src/DescriptorControl.cpp
PR 9019 core/libs/prx/libkernel/File/src/DescriptorControl.cpp
PR 12682 core/libs/prx/libkernel/File/src/DescriptorControl.cpp
PR 12688 core/libs/prx/libkernel/File/src/DescriptorControl.cpp
PR 12700 core/libs/prx/libkernel/File/src/DescriptorControl.cpp
PR 12965 core/libs/prx/libkernel/File/src/DescriptorControl.cpp

@oneandonlydean oneandonlydean self-assigned this Nov 6, 2026

@ahmadmuj ahmadmuj left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Checked head 97da73eed49dac518ee6e06a8e2df7cd6771cb39, PR base 92d2fdc3438f83e39d624eb65f3195bf2701568c on Linux/WSL. Built the actual libkernel/libc modules; guest_kernel_fcntl passes.

A separate protected-page probe passes all 24 cases: 23/24/31/32 readable bytes, all six lock commands, descriptor -1. It checks exact -1 returns and guest EFAULT/EBADF, including the 24-byte old and 32-byte current cutoffs. This matches the copy-before-descriptor order in FreeBSD.

Forcing the old size to 32 breaks six cases; restoring raw memcpy crashes twelve. After restoring the source, all 24 pass again. The same probe crashes in twelve cases on main 0fbe14c15361c420c65bc22cf2c3dc14cbda81d1.

Looks good to me for input copying. This does not test result copyout, host locking, or console behavior.

This branch has not been deployed

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants