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

Plan for SharedArrayBuffer #1435

Closed
annevk opened this issue Jan 31, 2019 · 29 comments · Fixed by #1903
Closed

Plan for SharedArrayBuffer #1435

annevk opened this issue Jan 31, 2019 · 29 comments · Fixed by #1903
Labels
layering affects the public spec interface and may require updates to integrating specs web reality

Comments

@annevk
Copy link
Member

annevk commented Jan 31, 2019

In whatwg/html#3740 and whatwg/html#4175 folks from Apple, Google, and Mozilla are designing a set of headers that coupled with a particular implementation strategy would make it safer to enable high-resolution timers in specific agent clusters, for the HTML host environment. The reason for the top-in approach is largely due to the web not enforcing CORS by default.

Effectively, if those headers are present we'd annotate the relevant agent clusters with a high-resolution timer bit.

Our proposed approach for SharedArrayBuffer is that it's enabled by default, but can only be messaged between agents in agent clusters that have the high-resolution timer bit set. This means you can always get hold of a SharedArrayBuffer, but you might not be able to use it to create a high-resolution timer. Or in other words, no changes to ECMAScript are required, it's effectively a host environment concern.

This approach does require every API that takes a SharedArrayBuffer to carefully consider whether it can be (ab)used to create a high-resolution timer, and if so, also check that bit on the agent cluster. That's the downside, but there should not be that many of those APIs. The upside is that we could allow APIs where someone else writing into the SharedArrayBuffer is safe, e.g., bytes coming from the network. And more general utility functions won't need to branch on the availability of SharedArrayBuffer.

We'd appreciate feedback on this approach from TC39.

Related: #1060 and tc39/security#3.

cc @arturjanc @cdumez @csreis @linclark @lukewagner @mystor @rniwa

@ljharb
Copy link
Member

ljharb commented Jan 31, 2019

cc @syg @erights @dtribble

@waldemarhorwat
Copy link

Can someone provide more context about how this would ensure security? Would everything outside a CORS-approved agent cluster be in a different process?

@annevk
Copy link
Member Author

annevk commented Jan 31, 2019

So the overall architecture is somewhat complex, but yes, that's what it comes down to. It allows for several agent clusters to be in the same process, but only if the resources that caused the creation of those agent clusters have all consented to being included into the same process through the new HTTP response headers. Anything that does not consent would end up being blocked (equivalent to "network error").

Any further resources fetched within these agent clusters are always fetched with CORS to ensure servers hosting those resources consent to those resources being readable by whoever is embedding them. This avoids cross-origin image data for instance from entering the process without consent.

(whatwg/html#4198 (comment) lays out some of the high-level architecture here. Effectively, this allows user agents to put the process boundary at the browsing context group level, but also at the individual agent cluster level if there are less resource constraints. Long term I would expect all user agents to converge on putting the process boundary at the agent cluster level, but this would not diminish the values of these headers as they have other utility too (e.g., getting rid of openers) and you still need the agent cluster wide CORS opt-in.)

@ajklein
Copy link
Contributor

ajklein commented Jan 31, 2019

@lars-t-hansen @binji

@ljharb
Copy link
Member

ljharb commented Apr 26, 2019

Is there any update here? What's the current status of SAB?

@annevk
Copy link
Member Author

annevk commented Apr 27, 2019

The plan hasn't substantially changed from OP, but we're still working out the details.

@annevk
Copy link
Member Author

annevk commented Jan 2, 2020

You can now play with this in Firefox Nightly: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer/Planned_changes.

@syg
Copy link
Contributor

syg commented Mar 12, 2020

Linking here for visibility to TC39 delegates: whatwg/html#4732 (comment)

tl;dr is I (and V8) would like to gate the SharedArrayBuffer constructor on COOP+COEP, instead of just usability of postMessage.

@ljharb
Copy link
Member

ljharb commented Mar 12, 2020

What are those acronyms?

@jridgewell
Copy link
Member

COOP and COEP explained

@annevk
Copy link
Member Author

annevk commented Mar 18, 2020

If @syg's proposal is adopted (seems likely at this point) the HTML Standard would most likely delete the SharedArrayBuffer constructor if the cross-origin isolated (COOP+COEP) environment variable is false. No changes to ECMAScript itself would be needed.

@ljharb
Copy link
Member

ljharb commented Mar 18, 2020

Wouldn't that constructor have to become normative-optional then? I believe the ECMAScript spec requires it to exist for user code in order for the engine to be compliant (that's why all the things SES deletes have to be in Annex B)

@erights
Copy link

erights commented Mar 18, 2020 via email

@syg
Copy link
Contributor

syg commented Mar 18, 2020

Wouldn't that constructor have to become normative-optional then?

I don't think normative optional captures what's going on here: there're more conditions to it than pure optionality. If we say anything at all, I'd prefer to document that hosts must delete the constructor if it does not allow concurrent access to SABs. With a non-normative note saying that this is for feature detection backwards compat and is considered legacy, and that users should migrate to feature detection using host-specific mechanisms.

I am strongly opposed to putting it into Annex B, however.

@erights
Copy link

erights commented Mar 18, 2020 via email

@ljharb
Copy link
Member

ljharb commented Mar 18, 2020

I think we should not create a precedent that omitting anything that the spec implies must be present is acceptable by not saying anything re SAB; stating something like @syg describes sounds fine to me.

@allenwb
Copy link
Member

allenwb commented Mar 18, 2020

I suggest that a better precedent to follow is how ECMA-402 is treated by ECMA-262. Support of ECMA-402 is optional, but a number of places in the specification specifically address what happens when it is or is not present.

ECMA-262 also mandates the use of ECMA-402 if an implementation provide certain functionality.:

A conforming implementation of ECMAScript that provides an application programming interface (API) that supports programs that need to adapt to the linguistic and cultural conventions used by different human languages and countries must implement the interface defined by the most recent edition of ECMA-402 that is compatible with this specification.

This is handle in Clause 2 Conformance which is the proper place to talk about such things.

SAB should probably be handled in an analogous manner.

BTW, I can imagine situations where it would be useful to have an SAB implementation that did not support actual sharing. That might be a reasonable fall back for situations where the web platform disallows such sharing.

@annevk
Copy link
Member Author

annevk commented Mar 18, 2020

If you want to capture this in ECMAScript, which seems totally reasonable, the way to do it would be to let the host configure whether the global will expose the SharedArrayBuffer constructor. That way whenever HTML creates a global it can simply pass along the cross-origin isolated boolean value for that and ECMAScript will take care of the rest.

I.e., make it host-defined.

Having said all that that, there's a hope that it will eventually be web-compatible to expose the SharedArrayBuffer constructor unconditionally, so I'm not sure how much work we want to put into this until that's certain. Having HTML delete it when cross-origin isolated is false for a couple of years until that's more certain doesn't seem like the end of the world.

@syg
Copy link
Contributor

syg commented Mar 18, 2020

+2 to what @annevk said.

I don't want to bake in too much host machinery to conditionally expose SABs precisely for the reason he stated: we'd like to have it be non-conditional eventually, after the migration period, even if it's long-ish. I see the conditional deletion as the price we pay for Spectre.

The pragmatist in me don't see any issue with compliance here. We'll have interop. So I'd prefer to document the state with as minimal a change as necessary to ecma262.

@bakkot
Copy link
Contributor

bakkot commented Mar 18, 2020

I think a sufficient change would be to modify the Conformance part of the spec to add "except where otherwise noted" in the first paragraph, and then in the SharedArrayBuffer constructor section add a new paragraph reading "Implementations are not required to provide the SharedArrayBuffer constructor if they are unable to provide concurrent access to SharedArrayBuffer objects." or something like that.

@annevk
Copy link
Member Author

annevk commented Mar 18, 2020

That seems less reliable than making it host-defined. I.e., that would mean implementations get to decide the conditions.

@ljharb
Copy link
Member

ljharb commented Mar 18, 2020

Isn’t that exactly what “host-defined” already means?

@annevk
Copy link
Member Author

annevk commented Mar 18, 2020

Let's not rehash #1524 here. There's a meaningful difference if you don't look at ECMAScript in vacuum.

@bakkot
Copy link
Contributor

bakkot commented Mar 18, 2020

I am fine with saying "hosts" rather than "implementations".

@allenwb
Copy link
Member

allenwb commented Mar 18, 2020

@bakkot

I think a sufficient change would be to modify the Conformance part of the spec to add "except where otherwise noted" in the first paragraph, and then in the SharedArrayBuffer constructor section add a new paragraph...

Clause 2 Conformance wasn't arbitrarily introduced into the structure of ECMA-262. It's a "standard" part of Ecma and ISO standards with a specific purpose. It consolidates these sorts of conformance requirements into a single, well known place. Saying "except where otherwise noted" would make Clause 2 pretty much meaningless as it would mean that a reader would have to search the entire document for other conformance requirements or exceptions. It would be fine to explicitly reference some other part of the specification from Clause 2 but putting in an open "there may be exceptions but you have to search for them" would not be normal or unhelpful.

@bakkot
Copy link
Contributor

bakkot commented Mar 18, 2020

I would also be fine with saying "except for SharedArrayBuffer as noted in 24.2.2" rather than "except as otherwise noted".

@erights
Copy link

erights commented Mar 18, 2020

JavaScript on blockchain must run deterministically, given an agreed order of incoming messages. Therefore, it is a host that will never implement SharedArrayBuffer. I am happy handling this either in the 402-like manner that @allenwb suggests or in the more conventional "normative optional" manner. But we need to make it non-mandatory anyway.

@annevk
Copy link
Member Author

annevk commented Mar 20, 2020

@erights I think it would be preferable for it to implement SharedArrayBuffer, but not allow that object to be shared with another agent. The way we approach this in browsers is that the threat is postMessage() (or inter-agent communication). That would allow more shared code between platforms.

The main reason for not exposing SharedArrayBuffer is sites thinking that if SharedArrayBuffer is exposed, postMessage() will work too. Sites don't expect that with the Wasm API, which is why that will continue to work as a way of getting at a SharedArrayBuffer object, even in situations where postMessage() throws.

And again, hopefully long term SharedArrayBuffer can be exposed anywhere and be useful as non-detachable ArrayBuffer or just for generic code. And sharing between agents depends on the environment.

@annevk annevk added the layering affects the public spec interface and may require updates to integrating specs label May 9, 2020
@annevk
Copy link
Member Author

annevk commented Jul 8, 2020

The HTML Standard now fully defines this (modulo #1903). Firefox 79 implements it (shipping later this month). Chrome will migrate to it. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer/Planned_changes is still a useful high-level summary.

Feel free to close this (or after #1903 lands).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
layering affects the public spec interface and may require updates to integrating specs web reality
Projects
None yet
Development

Successfully merging a pull request may close this issue.

9 participants