leobalter / shadowrealms-polyfill

MIT License
58 stars 0 forks source link

Implicit references of function wrappers #14

Open mhofman opened 3 years ago

mhofman commented 3 years ago

In the SES meeting today I mentioned that a red object held live by a red function solely exposed to the incubator/blue realm would be tied to the liveness of the wrapper function in the blue realm.

As discussed this has an implication on confidentiality as this could be used as a side channel with red observing if the blue realm keeps the wrapped function live, unless WeakRef / FinalizationRegistry is disabled in the red realm. (I'm not sure I followed @erights' explanation that the target of the ref/registry could be made "strong" as that would require detecting if that target object deep in the graph is in fact rooted in the wrapped function)

I actually wanted to simply point out that wrapping functions like proposed do not fully isolate the object graphs of the realms like I believe the original proposal in https://github.com/tc39/proposal-realms/issues/289 did since it relied on structured cloning and eval / global function calls. This wrapper function capability allows cross realm cycles to be created, something that was explicitly called out as a possible nice thing to prevent.

I personally think that without cross-realm references, it is pretty much impossible to implement anything useful without leaking memory, and that relying on UUIDs and userland memory management is too error prone and cycles cannot be handled at all without new language features.

My question is then: should the cross-realm references be implicit like through the proposed wrapper function mechanism, or explicit through a special object/primitive that preserves identity?

Btw, it should be possible to build a shareable object identity mechanism on top of WeakRefs and the implicit references of these function wrappers, without the need for symbols as weakmap keys.

leobalter commented 3 years ago

should the cross-realm references be implicit like through the proposed wrapper function mechanism, or explicit through a special object/primitive that preserves identity?

I'd say implicit as it follows the current model. We can explore more of this when we have Records and Tuples available. This might help with e.g. the structured cloning process suggested in the #289. I believe trying to roll a structure cloning or special object (non primitive) might become overkill if we don't observe the Records and Tuples, they might be the primitives we're looking for.