-
Notifications
You must be signed in to change notification settings - Fork 75
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
Terminate CapTP in non-hardened Realm without SES shim #1686
Comments
For review by @erights and @michaelfig |
So there is the question of getters and setters in this split world: who is responsible for hardening them? I believe that in most cases these are not shared with other objects, and that a "surface" harden should thus freeze them as part of the "walking transitive properties" step. Btw in this world, it's not really the |
It looks to me like initialization of the marshal package and use for marshalling/unmarshalling CapData currently has three firm dependencies that are satisfied by
The first two dependencies seem relevant, although they could in principle be parameterized, and the third can be addressed by #1687. The bar is actually rather low: run with
|
I'm confused as to what I'm in wholehearted agreement that the |
Ah, yes. We can’t avoid shimming |
The problem with not installing |
That’ll be even more true with CapTP when we support 3-party-handoff. That will take a dependency on a shared nonce locator, and that in turn will require WeakRef and FinalizationRegistry to track the retention of objects that were transported between sessions (if I grok right). |
I have been giving more thoughts about the different harden semantics before and after lockdown. I had been uneasy about the possibility of an object to be considered hardened before lockdown, but not satisfy the prototype checks post lockdown. I think this can be remediated by a weak list of prototype objects to check during lockdown. Assuming that harden is implemented as a flag on the object (not as a transitive frozen check), here would be the suggested semantics:
There is a single remaining pre/post lockdown discrepancy with this scheme: pre lockdown, an object can be hardened without its prototype ever being hardened. If the prototype is hardened after the object, hardening of the prototype fails. If lockdown is called without the prototype being an intrinsic, or having been manually hardened (before the objects using it as prototype), lockdown fails. As such the possibility of code working pre lockdown but not post lockdown is reduced, and can easily be fixed by adding the Regarding the cost of maintaining the "CheckIsHardenedAtLockdownList". For user code correctly using hardening, only the intrinsics should ever be present in this list. Even if lockdown is never called, the cost to maintain this list should be minimal. As a specification construct, the content of the list is never observable, and its entries can be garbage collected. As a shim, to avoid leaks it may have to be implemented using WeakRef and FinalizationRegistry. A shim implementing |
@danfinlay raises an issue we have struggled with: it’s currently not possible to terminate CapTP in a realm that does not also use the SES shim, because these layers depend upon
harden
. We have yet to find a nice compromise that allows us to write these libraries in a way that works well in both hardened and unhardened JavaScript without compromising the readability or audit-ability of that code in the hardened case. Some of the difficulty lies in the dichotomy:harden
walks up prototype chains, so hardening an object before lockdown would cause the repair phase to throw errorsharden
that does not walk up the prototype chain does not provide assurance that the object is transitively hardenedHowever, it is clearly the responsibility of the creator of instances to harden the instance and also clearly the responsibility of a library to harden its classes, constructors, prototypes, return values, and so on. Currently,
harden
does both as a safeguard against a library that failed to harden itself.So, I propose we can break this logjam with the following strategy:
@endo/harden
user-space implementation ofharden
that is a ponyfill forglobalThis.harden
and otherwise provides an implementation that freeze an object by walking transitive properties and not prototype chains. This is a version ofharden
that is suitable for use in both unhardened JavaScript and hardened JavaScript.globalThis.harden
so that it freezes exactly the same objects as the ponyfill, and asserts that every hardened object is transitively frozen over both property and prototype, throwing an error that indicates that the hardened instance must stand on top of only hardened prototypes.This would allow us to refactor CapTP and all its dependencies to depend on the
@endo/harden
ponyfill, making CapTP usable without shims, equally safe with shims, and otherwise identical verbatim to the current implementation.The text was updated successfully, but these errors were encountered: