Repository navigation
fix(libkernel): fail sendto and recvfrom with EFAULT on an unusable pointer - #13756
Conversation
|
Other open pull requests touch the same code. Merging one will break the other, or both implement the same thing. If this one builds on them, list them in Depends on.
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.
|
|
@Gruzzberry Reviewed at
The two receive cases were reproduced with the exact Linux checked-copy and probe bodies, real protected mappings and native datagram sockets (a focused source harness, not the full guest library). Separately, |
jotitadev
left a comment
There was a problem hiding this comment.
Linux run of head f6681e1bc0, merged (--no-commit) onto main 6a691f69ee. Ubuntu 26.04 (kernel 7.0), GCC 15.2.0, CMake 4.2.3, Ninja, Release, BUILD_TESTING=ON, i7-8700.
guest_udp: passes 3/3.- Full build ok. Related subset
guest_socket|guest_udp|guest_tcp|guest_poll|guest_net|guest_select|guest_kernel_fcntl: 35/35. public_headers: 65/65.- Red: with
Udp.cppreverted tomainand the new test kept,guest_udpcrashes (SEGFAULT) 3/3. - Udp.cpp stack:
main+ #13695 + #13738 + #13742 + #13752 + #13756 merged in that order (all touchUdp.cpp) merges cleanly; full build ok, the five focal tests (guest_socket_pair,guest_socket_options,guest_udp,guest_poll,guest_kernel_fcntl) pass 3/3, the socket subset 35/35 andpublic_headers65/65.
Written with AI assistance (Claude Code). I ran the builds and tests above on my machine.
…ointer Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
@oneandonlydean thank you. Rebased on current
Known differences, in that entry: on Linux and macOS a stream receive or send that faults after copying some bytes returns the short count (FreeBSD returns Tested on Windows 11, WinLibs GCC 15.2.0, Release: AI-assisted: yes (Claude Code). |
f6681e1 to
736f3c9
Compare
|
Checked the three points from the earlier review against the new head: |
What
sendtoandrecvfromon a guest socket crashed or returned a wrong errno when a guest pointer could not be used: a send buffer or destination address that is null,0x10or on an unreadable page, a receive buffer on an unwritable page, and an unreadable or unwritable address or address-length pointer. FreeBSD 11.4 fails these withEFAULT(sys_sendto/kern_sendit/getsockaddr,sys_recvfrom/kern_recvit/recvit). Native Windowsrecvwith a bad pointer answeredECONNABORTED(53) here.sendtocopies the destination address into a local buffer (after the existingENAMETOOLONG/EINVALlength checks, before the descriptor lookup, asgetsockaddrdoes) and fails withEFAULTif it cannot be read. The send buffer is checked page by page right before the native send, after the existingEINVAL, address and port-zero checks.recvfromcopies*addressLengthin before the descriptor lookup (sys_recvfromdoes thecopyinbeforekern_recvitlooks up the descriptor). An unwritable receive buffer is probed after the wait; if the socket would answer with its own error first (EAGAIN,ENOTCONN, a reset) that errno is returned, an empty stream or datagram returns 0, otherwise a datagram is dropped and the call fails withEFAULT, assoreceivedoes after dequeuing. The address and its length are written with the checked copy; as inrecvit, the length is written back (the caller's value when no address buffer is given) and a failed write isEFAULTafter the data is consumed.Tested
Windows 11 (10.0.26200), WinLibs MinGW-w64 GCC 15.2.0 r7, Ninja, Release,
-DBUILD_TESTING=ON, on currentmain.guest_udp: newCheckPointerFaultsfor UDP and TCP on loopback.sendtowith a null,0x10, unreadable and page-crossing buffer, and (UDP) a0x10, unreadable and page-crossing destination; a read-only page is a valid send buffer.recvfromwith a0x10, unreadable, read-only and page-crossing address-length pointer, a0x10, unreadable and read-only receive buffer, and a0x10, unreadable and page-crossing address buffer (data consumed); an empty nonblocking socket with a bad buffer answersEAGAIN; with no address buffer the length comes back unchanged. Onmainthe test crashes (segfault); with this change it passes, three runs out of three, together with the 95 socket, datagram, TCP and net tests.pr_overlap_encoding,agc_host_import_cut_lifetimeandagc_driver_depth_plane_partial_store(fail onmainhere too), plusvulkan_validation_gate_reportsandcheck_compile_test_windows_gcc_response_text_mode_is_not_reinterpreted, which fail because the WindowsAppspython.execannot be opened by those scripts.python tools/check_conventions.py --base upstream/main: passes.main: the earlyEFAULTfor a null buffer with a non-zero length and for an address buffer without an address-length pointer (fix(libkernel): accept an address buffer without a length pointer in recvfrom #7507 changes the second) still come before the descriptor state checks. The writability probe covers the whole requested length, not only the bytes that arrive, so a short message into a buffer whose tail is unmapped fails here where FreeBSD would succeed. A send with an unreadable buffer on an unconnected, shut-down or oversized-datagram socket answersEFAULTwhere FreeBSD answersEDESTADDRREQ,EPIPE,ENOTCONNorEMSGSIZEfirst, because a native send cannot be tried without side effects. For datagram sockets the buffer is checked before the destination address is validated, assosend_dgramcopies the data in beforeudp_outputchecks the address.Overlaps
recvfromaddress buffer without a length pointer) edits the check next to my length copy-in inUdp.cpp(L1603, L1615-1621): it was opened first, so it goes first and this PR rebases.MSG_WAITALLstream receive) edits the receive call inrecvfrom(L1608-1621): it was opened first, so it goes first and this PR rebases.tools/pr_overlap.pycould not compareUdp.cppagainst feat(aot): consolidate native ARM64 compiler, runtime and consumers #5021, feat(libkernel): support kevent read and write events on regular files #7088, fix(libkernel): clear fstat read bits on a socket after the peer closes #8605, feat(libkernel_sys): implement scePthreadMutexIsowned, utrace and tcsetsid #9713, feat(libkernel): add pipe write events and socket low watermarks to sceKernelAdd*Event #10645, fix(libkernel): preserve blocking sockets over nonblocking native transport #12688, feat(libkernel): cancel blocked POSIX writes with partial progress #12700 and feat(libkernel): support deferred cancellation in POSIX accept #12965, which conflict withmainthemselves; those touch other functions in the file and none implementssendto/recvfrompointer checks.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