-
Notifications
You must be signed in to change notification settings - Fork 375
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
Passing a pointer to another realm that assigns it allows to steal objects ownership #974
Comments
I'm curious to know if this happens also when moving around slices. They are actually "mutable" data types, so they probably suffer the same problem for the underlying pointer... |
huh, there is something weird, my test on values and pointer now fail at the but I added the same test for slices and it fails on slice element mutation after successful steal I double checked in #1072 and assigning Also, the way |
I believe that both #974 and #1072 reflect intended behavior, these are two different use cases.
|
No, both do the same thing, A passes a pointer to it's state to B, when B stores this pointer, A then cannot modify it's own state (because it loose ownership of the state) It happens on interfaces and slices for sure. For raw pointers I thought it was the case but I couldn't reproduce afterwards so maybe not The Just to reassess because I'm not sure we understand each other:
I understand that this is the intended behavior This is not true currently, this is the bug I'm trying to describe:
(zomg, didn't mean to close the issue -_-) |
@deelawn do you have some local work on this? I've talked with @zivkovicmilos and it seems we won't ever need to keep this as a possible feature, the transfer of ownership. |
I think the issue is that we shouldn't be transferring ownership in the first place. I think there is a deeper issue here. In this case, ownership was transferred inadvertently when it shouldn't have been. mis_ownership should have remained the owner of the underlying data with steal_ownership simply having a pointer to that data. I was debugging this this week and found something interesting -- the block that is the parent object of the pointer saved as part of the steal_ownership realm still has a realm path of the mis_ownership realm. Something strange is happening here. Then there is the question of how pointer references are maintained by a realm that doesn't have ownership of the data its pointer references. What is the expected behavior if the owner realm (mis_ownership) no longer maintains any references to this data? The ref count would still be one because of the reference from steal_ownership, but should it be? If we get to the point where realms pay rent for the amount of data stored, then a realm might be stuck paying for data it no longer references itself -- it's only referenced by other realms. Given that, I'm not sure we should disable realms from saving pointer variables that reference data in other realms; this could be very convenient versus having to retrieve a large object directly. I can see two obvious options:
Those are just a few observations and ideas we can discuss before we make a decision. |
We need to specs out the behaviors too
|
I think I was wrong in my earlier comment and maybe we have been misunderstanding the issue. This only appears to be an issue during realm initialization. I think this is because the pointer that is passed to the steal realm has not yet been persisted in the originating realm. So when it exits the steal realm, it persists a pointer that has not yet been persisted. Perhaps this is just an edge case we must address; not something larger. For example, the following txtar test passes with no issues because the steal function is not called during initialization. loadpkg gno.land/r/steal_ownership $WORK/steal
loadpkg gno.land/r/mis_ownership $WORK/mis
gnoland start
gnokey maketx call -pkgpath gno.land/r/mis_ownership -func Steal -gas-fee 1000000ugnot -gas-wanted 2000000 -broadcast -chainid=tendermint_test test1
stdout OK!
gnokey maketx call -pkgpath gno.land/r/mis_ownership -func MutateDeref -gas-fee 1000000ugnot -gas-wanted 2000000 -broadcast -chainid=tendermint_test test1
stdout OK!
-- steal/steal.gno --
package steal_ownership
var ptr *uint32
func Steal(xptr *uint32) {
ptr = xptr
}
-- mis/mis.gno --
package mis_ownership
import "gno.land/r/steal_ownership"
var (
x = uint32(42)
ptr = &x
)
/*
func init() {
steal_ownership.Steal(ptr)
}
*/
func Steal() {
steal_ownership.Steal(ptr)
}
func MutateDeref() {
*ptr = 21
}
func MutatePtr() {
y := uint32(21)
ptr = &y
}
func MutateValue() {
x = 21
} Edit: fixing what is described above is not the definitive solution. I edited the original realm's func Steal() {
n := uint32(10)
ptr = &n
steal_ownership.Steal(ptr)
} Or maybe it is right to fail in this case. If so, we can make it return a more detailed error message. I will dig a bit deeper on this. |
Looking at the init function... that init function which calls "steal_ownership.Steal(ptr)" must fail because before init:
after init:
desired invariant: after every transaction (and also after init() functions to initialize a realm), there must not be any pointers that cross the realm boundary; every value/slot has a clear owner realm, and references cannot pass the realm boundary, except possibly temporarily during transactions. still looking... |
Just confirmed this was fixed by #2255 |
Passing a pointer to another realm that assigns it allows to steal objects ownership
Description
If you pass a pointer to an object
x
in realmA
to a method of a realmB
that stores this pointer, the ownership is set toB
Your environment
Steps to reproduce
MutateDeref
orMutatePtr
orMutateValue
onmis_ownership
realmExpected behaviour
Mutations run correctly
Actual behaviour
Mutations error out
Additional info
You can find the full code here TERITORI#4
I discovered it while passing interfaces in this way so this is not limited to raw pointers
I edited the gnovm code to print realm package path in the error, you can see the code here https://github.com/TERITORI/gno/pull/4/files#diff-7041eca77b078f22ee334239995c403673f040b3726bcffa5a8a053b68a951a7
The text was updated successfully, but these errors were encountered: