-
Notifications
You must be signed in to change notification settings - Fork 18k
os: possible to remove or change internal finalizer on a Root
#71617
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Agreed that this is a bug. I have no opinion on whether we should get it into 1.24, or just backport into 1.24.1. It's pretty obscure. |
Change https://go.dev/cl/647876 mentions this issue: |
Since this release-blocker is in the Go 1.24 milestone, re-opening to track cherry-picking to release-branch.go1.24. |
Change https://go.dev/cl/648135 mentions this issue: |
Currently Root embeds a root and calls SetFinalizer on &r.root. This sets the finalizer on the outer root, which is visible to users of os.Root, and thus they can mutate the finalizer attached to it. This change modifies Root to not embed its inner root, but rather to refer to it by pointer. This allows us to set the finalizer on this independent inner object, preventing users of os.Root from changing the finalizer. This follows the same pattern as os.File's finalizer. Fixes #71617. Change-Id: Ibd199bab1b3c877d5e12ef380fd4647b4e10221f Reviewed-on: https://go-review.googlesource.com/c/go/+/647876 Auto-Submit: Michael Knyszek <[email protected]> Reviewed-by: Damien Neil <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]> (cherry picked from commit a704d39) Reviewed-on: https://go-review.googlesource.com/c/go/+/648135 TryBot-Bypass: Michael Knyszek <[email protected]> Reviewed-by: Dmitri Shuralyov <[email protected]> Reviewed-by: Dmitri Shuralyov <[email protected]>
It feels like a newbie question, but why does making root a pointer hide SetFinalizer? root ist not embedded? Because SetFinalizer works on the address (i.e. allocation reference) of the object? Please ignore me if too OT, will move question to golang-nuts. |
A finalizer is associated with an allocation, and there's at most one finalizer per allocation. CL 648135 changes a Root into two allocations: ( |
The implementation of
os.Root
sets its finalizer on theRoot
itself (it targets the internalroot
, but that struct is just embedded inRoot
) meaning that callers can callSetFinalizer
on aRoot
to mutate the finalizer. Other APIs in std, likeFile
, explicitly make this impossible by setting the finalizer on an internal object (aFile
contains a pointer to afile
, which actually has the finalizer).The main issue with this behavior is that it exposes an internal implementation detail, and may prevent switching from finalizers to cleanups in the future (since the cleanup is not removable unless you have the handle to it). The fix is straightforward: the internal
root
should be stored by reference inRoot
.CC @neild
The text was updated successfully, but these errors were encountered: