Repository navigation
fix(libkernel): return ESRCH from join, detach and cancel of a released thread handle - #10817
Conversation
|
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.
|
765c97f to
b883eae
Compare
|
@MarcZX10 The temporary holder still permits a retain after destruction is committed. ReleaseThread decrements references from 1 to 0 before the destructor removes the registry entry; a concurrent lookup can find that entry and Retain can increment 0 to 1, but the original release still deletes the object. Please coordinate final retirement with reference admission or reject zero-reference objects atomically, and add a controlled test of last release racing successful join/detach/cancel admission. The current observer only calls Getprio, then those operations run after release. |
b883eae to
9e1a0a6
Compare
|
Rebase follow-up: head |
9e1a0a6 to
53ce237
Compare
a72c2d5 to
bfd8a29
Compare
|
I independently confirmed the remaining last-release race in the exact current head |
bfd8a29 to
075ed1d
Compare
|
Addressed the final-release race on the rebased head |
075ed1d to
9e05be2
Compare
|
Rebased once more because upstream advanced to |
9e05be2 to
8f275c4
Compare
|
Rebased again onto current upstream |
4c5f290 to
a5462f9
Compare
a5462f9 to
e782144
Compare
What
scePthreadJoin(and the timed join that shares its code),scePthreadDetachandscePthreadCanceldereferenced thePthreadhandle before checking that the thread object still exists. A detached thread frees itsPthreadPrivatewhen it ends, so a join, detach or cancel on that handle could read freed memory. The originalguest_pthread_released_handletest reproduced a heap-use-after-free inJoinThread_nid_no_patchafter the object was freed, and returned EINVAL during a destruction race instead of ESRCH.Each operation now checks the guest thread registry while the object is protected. Join, detach and cancel retain a temporary reference while they release the registry lock and continue using the object; join releases it before its blocking wait. The short getters and setters keep the registry lock for the duration of their access. Calls on an already released handle return
SCE_KERNEL_ERROR_ESRCH, consistent with a second join (#4481),scePthreadAttrGet(#7957) and the name, priority and affinity calls (#10816).Joined threads that are still retained and detached threads that have not ended behave as before.
Tested
Before this follow-up, the author reported a Linux x86-64 AddressSanitizer + UBSan build (
ANYPS5_ENABLE_ASAN=ONwith-fsanitize=undefined, RelWithDebInfo), with the host CPU gate bypassed locally for the run only. The author reportedguest_pthread_released_handlepassing in five runs and theguest_pthread_*,guest_cond_*,guest_rwlock_*,guest_signal*,guest_semaphoreandguest_kernel_sys*tests giving the same results as before. The author reportedguest_pthread_stackaborting onmainunder ASan because its 4 KiB frame-distance assertion is exceeded by ASan frames;guest_semaphore_tracewas not built. No Windows, ThreadSanitizer or console hardware run was reported.For earlier follow-up work, local checks included GCC C++20 syntax-only compilation for
Thread.cppandGuestPthreadReleasedHandle.cpp, MinGW C++20 syntax-only compilation forGuestPthreadReleasedHandle.cpp, andgit diff --check. The installed MinGW headers do not providePROCESSOR_RELATIONSHIP::EfficiencyClassorSetThreadDescription, which existingThread.cppcode uses. Full CMake configuration could not proceed because SDL2 and required host development packages were unavailable. The pthread runtime tests were not run locally for that follow-up.Rebase validation (2026-10-25)
This PR's four commits are now stacked on #10810 head
b79959c5e3; #10810 is stacked on #10816 head8eaa2bbad5, and that stack is based on upstreammaina5a780eaaa7f187fe8f5c7f2ef244f6a6dab2762. The rebase completed without conflicts. I retained the test registrations from all three PRs.After updating the complete stack to the latest upstream
main, strict GCC C++20 syntax-only checks with-Wall -Wextra -Werrorpassed forThread.cpp(suppressing its existing missing-field-initializer warning) andGuestPthreadFinalReleaseRace.cpp.git diff --check upstream/main...HEADandpython3 tools/check_conventions.py --base upstream/main --head HEADalso passed. The runtime/ASan test was not rerun, and full local CMake configuration remains unavailable because the SDL2 submodule/development dependencies are missing. No post-rebase runtime result is claimed.Checklist
main; no other open PR implements the same functionsNotImplemented_nid_no_patch); silent stubs are listed under Silent stubs in their library's technical debt file (none added).mdfiles or images added to the repository