A Taste of WebGPU in Firefox
hacks.mozilla.org
hacks.mozilla.org
The one glaring exception is binding. It's the thing I hate most about OpenGL. I don't really have to think about it in Metal at all. The fragment shader just takes a texture or buffer as a function argument and I can use it just like I'd use any other C++ object or struct in the shader. From the calling side, I just say, here's the texture that goes with that argument (by name in the code, not by some random ID assigned at runtime). No figuring out which texture unit to use, or which texture target. No cases of accidentally forgetting to enable a texture unit or bind a texture to it, or using the wrong texture target. All of that fiddling around makes OpenGL such a pain in the ass to use. But it seems like WebGPU kept some of that nastiness. Why?
Metal binding model works well because each buffer can contain references to other resources (`MTLArgumentBuffer`). So you can change whole packs of resources at once with this. But argument buffers are not implementable on other APIs. We chose Vulkan's descriptor set-like model as the least common denominator.
https://news.ycombinator.com/item?id=16457791 , https://www.contextis.com/en/blog/webgl-a-new-dimension-for-... , https://www.contextis.com/en/blog/webgl-more-webgl-security-...
Edit I should have given a quote from one of the articles covering the issue, so here's one:
> anyone running Firefox 4 with WebGL support is vulnerable to having malicious web pages capture screenshots of any window on their system
I do share the concern that security of talking to the GPUs is hard. We'll do our best. I think it's important for the Web platform to reach this capability.
Interestingly, the implementations are more diverse, because there isn't a single Angle-like library that everyone is going to use. This may mean that it's easier to find a vulnerability in a concrete browser, but harder to make an exploit that works portably.
WebGPU is a great innovation, but we have both privacy and security concerns here. It should be available where and when the user wants it, not silently in the background.
Why do you care if someone can see your bank account number? In the end they're just numbers.
So we thought, then ROWHAMMER arrived..
Even when a module is well tested, I'd like non-essential modules to be opt-in too.
The web is not a static document viewing anymore. Now I agree, that sites should have a static fallback, as I also do not want to run a full webapp, when all I want is a static article for example. But this is because of a different problem - the financing of most of the web, through advertisment and not the fault of javascript.
My thoughts are along these lines:
┌────────────────────┬──────────────────────────┬──────────────────────────────┐
│ │ Secure implementation │ Insecure implementation │
├────────────────────┼──────────────────────────┼──────────────────────────────┤
│ Opt-in │ Minimal security impact │ Significant security impact │
│ Enabled by default │ Minimal security impact │ Security disaster │
└────────────────────┴──────────────────────────┴──────────────────────────────┘When WebGL was first implemented in Firefox - long ago - it shipped with serious security flaws. This struck many people as sadly predictable, as graphics APIs like OpenGL are not intended to be accessible from untrusted code. WebGPU seems awfully similar to WebGL in this respect: it's trying to wrap a low-level graphics API in a secure sandboxed API. This isn't the equivalent of a routine addition like a new feature in CSS.
But yes I am guilty of some whataboutism here, WebGL did have some unique problems and WebGPU devs hopefully learn from them.
Edit For clarity, I'm saying you may as well just disable WebGPU. A CPU-based simulated GPU would indeed improve security, but its performance would be so atrocious that there would be no point having it compared to the existing drawing APIs.
A CPU-based fake GPU is guaranteed to have performance so poor that it isn't worth doing. This is the reason modern graphics APIs don't make provisions for CPU-based implementations.
If we aren't confident in the security of the WebGPU implementation (and we're agreed that we aren't), the solution is simply to disable support for WebGPU in the browser. The browser can still offer facilities like the Canvas API.
That was my mistake - i was not clear. I'm talking about virtualized GPUs that can be passed to a VM running a minimum system needed to boot a browser.
I believe significant work has been done on the browser/graphics sandboxing problem. Whether browsers use techniques comparable to virtualisation, I don't know. I'm afraid I don't know much about how that's done, or how effectively virtualisation is able to contain the operations of VMs, or how high the performance penalty is.
Going with guesswork though, it seems to me virtualisation doesn't offer particularly solid guarantees here. If the host OS has a buggy graphics driver, it would presumably be possible for it to leak data back to the VM. Any facilities the GPU can offer to help contain semi-trusted graphics contexts, should presumably be available for use directly by the browsers, without running a guest OS in virtualisation.
I do not want my browser to be able to talk to Bluetooth devices that are connected to my desktop. I do not want want my browser to be able to access random files on my file system simply because it is accessible to me. I do not want a web browser have ability to have GPU access outside the specific virtualized section of it that can only access the part of the screen and off-screen buffers associated with the window of a browser.
I started localizing different web browsers into dedicated VMs that have just a minimal operating system and a web browser. It works well enough for my use case ( i can playback youtube video almost like I could do it on my 2015 laptop ) but it is definitely hacky.
This is true, and it's the reason Chromium goes to great lengths to sandbox itself to contain the damage regarding JavaScript engine exploits. Annoyingly Firefox is lagging behind in that regard.
> I do not want a web browser have ability to have GPU access outside the specific virtualized section of it that can only access the part of the screen and off-screen buffers associated with the window of a browser.
Virtualisation will improve your general security, but it's isn't a perfect abstraction especially when it comes to GPUs, and it's not a rock-solid guarantee of the isolation assurances you want. [0] I believe cloud-computing providers never split a GPU between customers, for instance. Disabling sharing of the GPU with the VM would further improve your security at the price of performance.
[0] https://www.hpcwire.com/2018/05/31/gpus-excellent-performanc...
This has not been true since quite a while. Firefox has employed sandboxing even before the multi-process work (which culminated in the Quantum branches of Fx releases that added more and more sandboxing with each release). Before that, Moz went a different way than OS level sandboxing by principal containerization (I forgot the correct term, sorry), which worked in terms of separation of execution contexts (of Web JS and other parts like the styling system, plus the browser internals). Elements of that implementation have been removed by now (iirc) since the multi-process split required different communication paths anyway (which also enabled per-origin/-tab/-window OS-Level sandboxing), so that code was no longer needed.
What could an attacker do if they were able to trick the JIT into emitting evil native code?
Moving applications that can do anything into sandboxed pages in a browser that can't do arbitrary things to the user's system is a win. The more capable the browser is, the more things that once would have been downloaded applications can become safely sandboxed pages.
I agree that it would be nice to see stronger hypervisor based sandboxes.
I have 2 projects using Three.js and pure WebGL: https://bad.city (multiplayer browser game engine + editor) and http://fonted.io (shader toy + fonts)
P.S. vange-rs [2] is written on wgpu-rs and uses ray-tracing in fragment shaders for the terrain. I hope to run it in the browser one day!
[1] https://github.com/gpuweb/gpuweb/issues/639
[2] https://github.com/kvark/vange-rsBeware the behaviour of writes will not be consistent between vendors or shader stages, and may be surprising.
And of course its another way to do unique profiling of users.
Would likely just make it faster as you wouldn't have to read the results out of a canvas, although I haven't checked what the pure data API for WebGPU looks like.
After a bit more searching: https://bitcointalk.org/index.php?topic=27056.0
Some Linux setups run Xorg, others run Wayland (with the world moving towards the latter). Yet, many times these new features (especially things related to rendering!) only work on older Xorg setups, but not on Wayland.
For anyone Linux users out there: these updates only work if you're still running Xorg.
Vulkan has another fun aspect to it: the application doesn't have full control over the layer loading mechanisms in the mandatory driver wrapper. A user's system can be configured to load arbitrary validation layers in various ways and the application cannot prevent any of that. It can only ask for more layers to be loaded. This is great for development, but it also means that browsers can't generally assume that the Vulkan API does what they think it does. There might be a little extra in there.
I need to check out a few things, but if WebGPU prevents access to a few hairy bits of Vulkan like explicit synchronization and memory management (the Vulkan app has to provide that), it might be securable. There are still some benefits over OpenGL left like the entire pipeline state being expressed in pipeline objects.
I don't know about DX12 or Metal in practice, so I will not comment on that.
WebGPU is higher level. High enough to hide the most nasty aspects of Vulkan, yet low enough to still extract the performance benefits of a proper API.
Implementing validation and proper input sanitation is undoubtedly a big challenge. Each browser engine(!) vendor is going to be tackling that separately. We are ready to learn on Vulkan mistakes and drive this story of validation and CTS to be better. One of the things that make a difference in comparison to Vulkan is that validation is not an afterthought, not a side developer assistance tooling. Validation is in the core of WebGPU, it's mandatory and always enabled, so chances are it will be more polished.
[1] https://github.com/kvark/WebGLNext-Proposals/blob/obsidian/O...
Vulkan is hard to validate because it was designed assuming it trusts the developers to follow the valid usage rules. For example it is the developer's responsibility to only destroy GPU resources after they are done being used. Validation layers have to track for each submission the link from vkCmdBindDescriptorSets to descriptor sets to texture views to textures just to validate there is no use after frees, and that's just one of the many many valid usage rules.
In contrast a guiding principle in the design of WebGPU is that it should be fully validated at a reasonable cost. Keeping the same example, calling texture.destroy() in WebGPU will make the browser destroy the texture after all previous execution completes, and prevents any further usage of that texture. The Web Platform Tests (WPT) is a test suite that ensures browsers are interoperable. WebGPU's tests in WPT will contain test cases for all validation rules and corner cases, including overflows like the one you mentioned (and check it produces an error that is handled gracefully).
I don't think any of the existing implementations just "passes through" any "request" to the underlying 3D APIs (which is not just Vulkan btw) without taking it apart, looking at each piece to make sure it checks out, and then reassembling it. The security implications shouldn't be much different than WebGL (for better or worse of course).
The philosophy of the modern 3D-APIs like Metal, Vulkan and D3D12 of doing all costly configuration operations upfront instead of during rendering should help a lot to improve rendering performance compared to WebGL, where those security validations literally happen at random times during rendering.
Also your last point makes no sense. That's been the state of desktop graphics programming for years and years. You really don't control much as IHVs are always free to intercept calls and control things at the driver level.