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

fix(ses): Distinguish intrinsics in start and non-start compartments #372

Merged
merged 1 commit into from
Jul 24, 2020

Conversation

erights
Copy link
Contributor

@erights erights commented Jul 2, 2020

Whitelists no longer painfully redundant.
Placeholder for multiple Compartment constructors, including one which only throws.

Start compartment has initial authority. Others do not. Independent of *Taming options.
{ *Taming: 'unsafe' } is no longer about initial authority in start compartment, as long as it obeys ocap rules.
'unsafe' is now about enabling violations of ocap rules, such as primordials that are no longer powerless.
Lockdown *Taming options have much milder meaning.

  • We still check that they are only set to 'safe' or 'unsafe', with default 'safe'.
  • dateTaming is ignored. Maybe we should just get rid of this flag. Transition problem?
  • mathTaming is ignored. Maybe we should just get rid of this flag. Transition problem?
  • regExpTaming is effectively ignored. But we may decide that 'unsafe' suppresses the deletion of RegExp.prototype.compile.
  • The new localeTaming, if set to 'unsafe', leaves the original *Locale* methods in place.

Finally we get to Error taming. Independent of the errorTaming option, the tamed powerful v8 API emulation remains on the start compartment's Error constructor. None of these are on the Error constructor of other compartments. However, this shows that we need a different knob: whether to expose engine-specific (e.g., v8 specific) APIs.

In a step towards https://tc39.es/proposal-error-stacks/ , we leave on the start compartment the powerful getStackString(error) function, which gives the stacktrace string associated with that error. Because this special power is only on the start compartment, we do not consider it a material violation of ocap rules, so it is there independent of errorTaming.

The violation of ocap rules which is pervasively available is the legacy behavior of error.stack, since it takes no privilege but violates information hiding. Accordingly, on v8 where we have control, under errorTaming: 'safe' (or default) this is truncated to the empty string. The 'unsafe' setting leaves the legacy behavior alone, providing the same string that the new getStackString(error) provides.

Fixes #317
Fixes #385 by getting rid of the realmRec altogether.

@erights erights self-assigned this Jul 11, 2020
@erights erights force-pushed the default-prepareFn branch 3 times, most recently from 88cb07b to f5c2e1b Compare July 19, 2020 06:23
@erights erights changed the title fix: [WIP] preserve stack trace info fix: Massive intrinsic reform. Start vs other compartments. Jul 19, 2020
@erights erights marked this pull request as ready for review July 19, 2020 06:52
@erights
Copy link
Contributor Author

erights commented Jul 19, 2020

@kriskowal @warner I hit the "ready for review" button, though I am aware that this needs to be divided into smaller reviewable PRs. Nevertheless, it works, is a big improvement of the status quo, and even seems to work. Comments appreciated, especially on strategy for breaking it up.

@dckc
Copy link
Contributor

dckc commented Jul 20, 2020

@erights writes:

In a step towards https://tc39.es/proposal-error-stacks/ , we leave on the start compartment the powerful getStackString(error) function, which gives the stacktrace string associated with that error. Because this special power is only on the start compartment, we do not consider it a material violation of ocap rules ...

yay! unsealException restored to its former glory. (actually, I don't see it in erights.org nor https://github.com/kpreid/e-on-java ; did E have unsealException?)

@erights
Copy link
Contributor Author

erights commented Jul 20, 2020

yay! unsealException restored to its former glory. (actually, I don't see it in erights.org nor https://github.com/kpreid/e-on-java ; did E have unsealException?)

@kpreid Did you implement something like that? (I remember us talking about it.)

@kpreid
Copy link

kpreid commented Jul 20, 2020

I implemented sealed exceptions in E-on-CL only.

Let me know if any other pointers would be useful.

Copy link
Member

@kriskowal kriskowal left a comment

Choose a reason for hiding this comment

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

Reverse engineering of this change’s internal chronology:

  1. Change StaticModuleRecord from class to function.
  2. Create shared inert StaticModuleRecord.
  3. Convert Compartment class to Compartment function and prototype
  4. Rewrite createGlobalObject into initGlobalObject
    a. Accept globalObject as an argument instead of creating one on behalf of caller
    a. Thread intrinsics and sharedGlobalPropertyNames through initGlobalObject
    a. Refactor switch to property loops
  5. Create conventions for referring to distinct intrinsics for start and shared compartments.
    a. Reframe taming functions not in terms of “start vs shared” but a single object bag that captures the intrinsics for both environments using %Names%
    a. Reframe allow list keys %AllAllowListKeys%
  6. nit: Fix misaligned JSDoc for performEval
  7. Factor realmRec argument out of createScopeHandler and makeEvaluateFactory. The realmRec is cruft from before compartments and we only need the original, “feral” Function constructor from it. Better to just capture that. (Delete realm-rec.js)
  8. nit: Rename XPrototypeConstructor to XOnlyThrows generally.
  9. Add CompartmentOnlyThrows and StaticModuleRecordOnlyThrows to anonymous intrinsics
  10. Delete get-named-intrinsic.js
  11. Delete intrinsics-global.js
  12. Reframe defineProperty as initProperty
  13. Factor an “intrinsics manager” out of getGlobalIntrinsics. Reuse this part to initialize intrinsics on new global objects for compartments.
  14. Factor repairIntrinsics and hardenIntrinsics out of lockdown using the intrinsics manager.
  15. Rename the taming modules. (This obscures changes within these modules so needs to be effected in an isolated mechanical commit)
  16. nit: Fix non-descriptive performEval x / source local variable.
  17. nit: Fix unreported!? linting problem with scope-handler unused shadow argument.

packages/ses/src/compartment-shim.js Outdated Show resolved Hide resolved
packages/ses/src/compartment-shim.js Show resolved Hide resolved
packages/ses/src/compartment-shim.js Outdated Show resolved Hide resolved
packages/ses/src/compartment-shim.js Outdated Show resolved Hide resolved
packages/ses/src/intrinsics.js Outdated Show resolved Hide resolved
packages/ses/src/intrinsics.js Show resolved Hide resolved
packages/ses/src/intrinsics.js Outdated Show resolved Hide resolved
packages/ses/src/lockdown-shim.js Outdated Show resolved Hide resolved
packages/ses/src/make-evaluate-factory.js Show resolved Hide resolved
@@ -33,8 +33,6 @@ test('identity Array', t => {

// Compartment is a shared global
test('identity Compartment', t => {
t.plan(7);
Copy link
Member

Choose a reason for hiding this comment

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

Should bring this back.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sigh. I understand why we need it for async tests. But can't we omit it for purely sequential-synchronous tests?

@erights
Copy link
Contributor Author

erights commented Jul 21, 2020

What is %AllAllowListKeys%? I don't think I have seen it before.

@erights
Copy link
Contributor Author

erights commented Jul 21, 2020

Your extended comment of how to unpack this PR seems exactly right. Thanks!

@kriskowal
Copy link
Member

I’ve decided to review this monolithically. That generally means more rounds of back-and-forth, but separating the mechanical changes from the semantic changes will in this case probably take longer than the review. So, I’m releasing the lock on this branch. I may instead push nit fix commits to the end in the process of a local holistic review, but will not force push.

Copy link
Member

@kriskowal kriskowal left a comment

Choose a reason for hiding this comment

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

I’ve left some comments that I resolved myself by pushing commits.

Looks great to me!

packages/ses/src/intrinsics.js Outdated Show resolved Hide resolved
packages/ses/src/intrinsics.js Outdated Show resolved Hide resolved
packages/ses/src/lockdown-shim.js Show resolved Hide resolved
packages/ses/test/tame-regexp-unit.test.js Show resolved Hide resolved
packages/ses/src/whitelist-intrinsics.js Outdated Show resolved Hide resolved
packages/ses/test/get-intrinsics.test.js Outdated Show resolved Hide resolved
Comment on lines 15 to 16
t.assert(Number.isInteger(Date.now()));
t.ok(isDate(new Date()));
Copy link
Member

Choose a reason for hiding this comment

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

Let’s use ok instead of assert throughout. They are aliases.

Copy link
Member

Choose a reason for hiding this comment

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

Addressed with a follow-up commit.

packages/ses/src/compartment-shim.js Show resolved Hide resolved
packages/ses/src/lockdown-shim.js Outdated Show resolved Hide resolved
@kriskowal kriskowal changed the title fix: Massive intrinsic reform. Start vs other compartments. fix(ses): Distinguish intrinsics in start and non-start compartments Jul 23, 2020
Copy link
Contributor Author

@erights erights left a comment

Choose a reason for hiding this comment

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

For some of your comments, github won't let me answer inline.

Answering #372 (comment)

Let’s carry this through or link an issue to track.

See #390

Answering #372 (comment)

Let’s use ok instead of assert throughout. They are aliases.
Addressed with a follow-up commit.

Ok. I made no further changes along these lines. But should we do this everywhere? I like strong "there are very few ways to do that" conventions, so I'd be happier if we did it everywhere.

packages/ses/src/compartment-shim.js Outdated Show resolved Hide resolved
packages/ses/src/compartment-shim.js Outdated Show resolved Hide resolved
packages/ses/src/whitelist-intrinsics.js Outdated Show resolved Hide resolved
@@ -33,8 +33,6 @@ test('identity Array', t => {

// Compartment is a shared global
test('identity Compartment', t => {
t.plan(7);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sigh. I understand why we need it for async tests. But can't we omit it for purely sequential-synchronous tests?

@erights erights merged commit 5cf2a20 into master Jul 24, 2020
@erights erights deleted the default-prepareFn branch July 24, 2020 03:10
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.

SES: Improve realm record layering Simplify intrinsic handling
4 participants