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

feat(import-bundle): Support Endo zip hex bundle format #1983

Merged
merged 8 commits into from
Nov 19, 2020

Conversation

kriskowal
Copy link
Member

This change introduces endoZipHex as a supported bundle format for importBundle. A corresponding change to bundleSource is forthcoming. I may quickly amend this to a base64 format, given that we have a library for that in SwingSet that we can factor into a shared dependency package.

@kriskowal kriskowal force-pushed the kris-endo-zip-hex branch 2 times, most recently from a9f305e to 50aa8c4 Compare November 5, 2020 06:06
@kriskowal kriskowal force-pushed the kris-endo-zip-hex branch 3 times, most recently from f3af331 to a12116b Compare November 13, 2020 03:38
Copy link
Member

@warner warner left a comment

Choose a reason for hiding this comment

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

Minor questions, if you're satisfied with your answers to them then please go ahead and land.

packages/bundle-source/src/index.js Outdated Show resolved Hide resolved
}

export function f8ReadGlobalSubmodule() {
export function f7ReadGlobalSubmodule() {
Copy link
Member

Choose a reason for hiding this comment

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

Hm, why remove this test? We should still check that globalThis cannot be used as a sneaky channel..

Copy link
Member Author

@kriskowal kriskowal Nov 18, 2020

Choose a reason for hiding this comment

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

The crux of the issue here is that freezing globalThis can be optional because freezing it only limits the vulnerability of programs in the same Compartment to one another. With the prior two bundle formats, there is only one compartment so it is necessary and sufficient to freeze a single globalThis to protect the application from its third-party dependencies. With this new bundle format, it is neither necessary nor sufficient to freeze the globalThis, and whether to freeze globalThis should be at the bundled application’s discretion, so that it can be informed by LavaMoat.

I could leave this test in place if I copied and modified the test for the new bundle format, but that seems like an unnecessary maintenance overhead. I could parameterize the test fixture so the constraint could vary. I could alternately go back into compartment mapper and thread a directive to freeze globalThis from package.json or a parallel policy JSON file. I had hoped to defer the last point until we had a better grasp of how LavaMoat will integrate.

@@ -18,3 +18,8 @@ lockdown({ errorTaming: 'unsafe' });
// Even on non-v8, we tame the start compartment's Error constructor so
// this assignment is not rejected, even if it does nothing.
Error.stackTraceLimit = Infinity;

harden(TextEncoder.prototype);
harden(TextEncoder);
Copy link
Member

Choose a reason for hiding this comment

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

Huh, why are these not already hardened? These two are non-ECMA names, right? So they should be removed from the Compartment globals by SES..

Copy link
Member

Choose a reason for hiding this comment

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

Ah, I see, we're changing the definition of the Compartment provided by import-bundle to include these two objects, and since they're endowments, they must be hardenable (thus .prototype must be hardened ahead of time).

We might want to update docs/vat-environment.md to reflect the availability of these names to vat code. OTOH we might want to prohibit their access (I can't think of any particularly good reason to withhold it, other than uniformity across platforms that might not provide it). (note: there are inbound changes to vat-environment.md from @tyg that I need to merge, so please make any changes to that file in a separate PR).

Is TextEncoder available in both Node.js and browser worlds? Just want to make sure this doesn't prevent swingset from working in a browser. (we haven't really tested that yet, apart from accidentally as part of the wallet, but I don't want to accidentally add a blocker)

Copy link
Member Author

Choose a reason for hiding this comment

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

TextEncoder and TextDecoder arrived in browsers before Node.js. They’re the more webby API, which is the reason I’m leaning on them instead of Buffer for Compartment Map’s Zip implementation.

const endowments = { ...optEndowments };
const { source, sourceMap, moduleFormat } = bundle;
const endowments = {
TextEncoder,
Copy link
Member

Choose a reason for hiding this comment

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

@michaelfig will exposing these enable a metering break? If they're wrapped like all the other globals, probably not, but it's a new ability being handed to all Compartments so I wanted to double-check.

Copy link
Member

Choose a reason for hiding this comment

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

@kriskowal I'm guessing that TextEncoder and TextDecoder will be available in the immediate Compartments produced by import-bundle, but they won't automatically be in any child compartments created therein. Is that correct? I guess that won't prohibit nested import-bundles, like the kernel does to load vats.

Copy link
Member Author

Choose a reason for hiding this comment

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

encode and decode are O(string.length), so we may need to meter them.

Copy link
Member Author

Choose a reason for hiding this comment

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

cc @michaelfig I think I need your reaction to the question “do we need metering to attenuate Text{En,De}coder?”, before I land this change.

Copy link
Member

Choose a reason for hiding this comment

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

cc @michaelfig I think I need your reaction to the question “do we need metering to attenuate Text{En,De}coder?”, before I land this change.

Ideally, the TextEncoder and TextDecoder sources would be evaluated in a metered compartment (not endowed as a vetted shim), so that the metering transform would be applied to them as they are to user code.

Copy link
Member Author

@kriskowal kriskowal Nov 18, 2020

Choose a reason for hiding this comment

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

TextEncoder and TextDecoder are platform code.

sigh… We could get metering for free by slurping a UTF-8 dependency, but I’d wanted to avoid that because it’ll be unnecessary bloat on the web. The Text* utilities are available in both Node.js and Web.

Copy link
Member

Choose a reason for hiding this comment

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

TextEncoder and TextDecoder are platform code.

Oh, in that case, they're covered by the blanket metering performed by @agoric/install-metering-and-ses. No need to special-case (I had thought they were shims written by you).

Copy link
Member

@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.

Just a quick reaction to a local issue for now. I don't yet understand the overall issue well enough to offer any more.

Comment on lines 24 to 23
harden(TextDecoder.prototype);
harden(TextDecoder);
Copy link
Member

Choose a reason for hiding this comment

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

Even with today's too-complicated harden lines 22 and 24 above are redundant. TextEncoder.prototype is reachable by own property traversal from TextEncoder and so will be included in the set hardened when starting with TextEncoder.

@kriskowal kriskowal merged commit 983681b into master Nov 19, 2020
@kriskowal kriskowal deleted the kris-endo-zip-hex branch November 19, 2020 16:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants