Skip to content
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

refactor: prepare for non-trapping integrity trait #2679

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

erights
Copy link
Contributor

@erights erights commented Jan 2, 2025

Closes: #XXXX
Refs: Agoric/agoric-sdk#10795

Description

Prepare for anticipated introduction and use of the non-trapping integrity trait as explained at https://github.com/endojs/endo/blob/b12eb434b6672f0ceae41be55aac7f24c4562b7b/packages/ses/docs/preparing-for-stabilize.md

These preparations must work now, before these traits are introduced, and should continue to work after these traits are introduced and used.

Security Considerations

Some things that had been deeply frozen automatically by harden are now manually frozen by explicit calls to freeze. We need to review these carefully to ensure that nothing has inadvertently be left unfrozen as a result of the changes in this PR.

Some proxies will become unhardenable, but they will still be hardenable as of now, so mistaken hardenings will not be detected.

Scaling Considerations

For this PR by itself, none. Using the shim-based implementation of the non-trapping trait will have scaling consequences: #2675

Documentation Considerations

https://github.com/endojs/endo/blob/b12eb434b6672f0ceae41be55aac7f24c4562b7b/packages/ses/docs/preparing-for-stabilize.md will need to be reflected in developer docs.

Testing Considerations

Since this PR by itself should be a pure refactor with no observable changes, there is nothing to test at this stage. The testing burden will come with #2675 to see how adequate these preparations were.

Compatibility Considerations

The point. This changes to coding patterns that should be compat both with the current status quo and with #2675

Upgrade Considerations

As a pure refactor, none.

@erights erights self-assigned this Jan 2, 2025
@erights erights force-pushed the markm-prepare-for-stabilize-2 branch 2 times, most recently from ce2d645 to 526e404 Compare January 2, 2025 20:42
@erights erights changed the base branch from master to markm-cleanup-type-warning January 2, 2025 20:43
@erights erights changed the title refactor: prepare for non-trapping integrity level refactor: prepare for non-trapping integrity trait Jan 2, 2025
@erights erights force-pushed the markm-prepare-for-stabilize-2 branch from 526e404 to b12eb43 Compare January 2, 2025 21:30
@erights erights marked this pull request as ready for review January 2, 2025 22:35
@erights erights force-pushed the markm-prepare-for-stabilize-2 branch 2 times, most recently from 9925c0c to 6ff2c89 Compare January 2, 2025 23:43
Base automatically changed from markm-cleanup-type-warning to master January 3, 2025 02:30
Copy link
Contributor

@mhofman mhofman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reading this and thinking through the implications, I have concerns we may be painting ourselves in a corner. Our recommendation is that one should harden values before passing them around. That implies we will never be able to use a Proxy as a remotable value. Is that something we're ok with? I know you have reservations with using O style objects as presences, but I'm a little worried about forever closing the door to this possibility.

Comment on lines +174 to +183
/**
* `freeze` but not `harden` the proxy target so it remains trapping.
* @see https://github.com/endojs/endo/blob/master/packages/ses/docs/preparing-for-stabilize.md
*/
const funcTarget = freeze(() => {});
/**
* `freeze` but not `harden` the proxy target so it remains trapping.
* @see https://github.com/endojs/endo/blob/master/packages/ses/docs/preparing-for-stabilize.md
*/
const objTarget = freeze(create(null));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe mention it's safe to share these targets between multiple E proxy instances because they're never actually used?


## How passable objects should prepare

Although we think of `passStyleOf` as requiring its input to be hardened, `passStyleOf` instead checked that each relevant object is frozen. Manually freezing all objects reachable from a root object had been equivalent to hardening that root object. With these changes, even such manual transitive freezing will not make an object passable. To prepare for these changes, use `harden` explicitly instead.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yeah I didn't think of that. That will potentially create a decent amount of churn on code that was manually freezing. It would be so much easier if frozen regular object would automatically pass trapping checks, but that would effectively transform non-trapping into a "is proxy" predicate.

* non-trapping integrity trait, we have to `freeze` here but not `harden`.
* However, once we do have that support, and `passStyleOf` checks that
* its argument is also non-trapping, we still need to avoid `harden`
* because that would also hardden `__proto__`. So we will need to
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* because that would also hardden `__proto__`. So we will need to
* because that would also harden `__proto__`. So we will need to

Comment on lines +200 to +207
/**
* TODO In order to run this test before we have explicit support for a
* non-trapping integrity trait, we have to `freeze` here but not `harden`.
* However, once we do have that support, and `passStyleOf` checks that
* its argument is also non-trapping, we still need to avoid `harden`
* because that would also hardden `__proto__`. So we will need to
* explicitly make this non-trapping, which we cannot yet express.
* @see https://github.com/endojs/endo/blob/master/packages/ses/docs/preparing-for-stabilize.md
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok I was confused at first, but this is a test that explicitly verifies that an object with a non-hardened proto is not passable. Can we make that more clear in the prelude of this comment?

Comment on lines -215 to +223
const tagRecord3 = Object.freeze(
makeTagishRecord('Alleged: both manually frozen'),
);
const tagRecord3 = harden(makeTagishRecord('Alleged: both manually frozen'));
/** @type {any} UNTIL https://github.com/microsoft/TypeScript/issues/38385 */
const farObj3 = Object.freeze({
__proto__: tagRecord3,
});
const farObj3 = harden({ __proto__: tagRecord3 });
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should get a TODO to be switched to both manually "non-trapping" instead of using harden.

Comment on lines 32 to 33
get(_shadow, prop) {
Fail`Please report unexpected scope handler trap: ${q(String(prop))}`;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So thinking about this, unless we do something wrong inside ses itself, we should never trigger this for the isNonTrapping trap, right? And even if we did, it would be a safe failure.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants