Fix duplicate Trusted Types policy creation when spawning workers - #27256
Conversation
allocateUnusedWorker() and _emscripten_create_wasm_worker() called trustedTypes.createPolicy() on every Worker creation. The Trusted Types spec forbids reusing a policy name unless CSP allows duplicates, so programs with 2+ pthreads (or wasm workers) failed under Trusted Types enforcement. Cache each policy once and pass the script URL through createScriptURL.
The EXPORT_ES6 and non-EXPORT_ES6 worker creation paths are mutually exclusive at compile time, so one policy cache is sufficient.
| $_wasmWorkers: {}, | ||
| #if TRUSTED_TYPES | ||
| // Cached Trusted Types policy for Wasm Worker creation. | ||
| $_emscriptenWasmWorkerPolicy: 'null', |
There was a problem hiding this comment.
Does null not work here? (without the quotes)?
There was a problem hiding this comment.
null works. I misunderstood the addFromLibrary function before.
Changed in new commits.
| ); | ||
| worker = _wasmWorkers[wwID] = new Worker(p.createScriptURL('ignored'), {{{ wasmWorkerOptions }}}); | ||
| _emscriptenWasmWorkerPolicy ??= trustedTypes.createPolicy( | ||
| 'emscripten#workerPolicy1', { createScriptURL: (url) => url }); |
There was a problem hiding this comment.
Put this all on one line. And maybe drop the 1?
There was a problem hiding this comment.
Dropped.
However, I found dropping the 1 may break existing CSP trusted-types allowlists that
list emscripten#workerPolicy1 (and pthread's emscripten#workerPolicy1/2). Is that acceptable?
There was a problem hiding this comment.
I have not idea who, if anyone, is using the TRUSTED_TYPES setting, or the implications of changing these strings. @aaronshim originally added this settting. Perhaps they have some insight here?
This change has no impact on the generated code.
…1` to `emscripten#workerPolicy`
This is an automatic change generated by tools/maint/rebaseline_tests.py. The following (10) test expectation files were updated by running the tests with `--rebaseline`: ``` codesize/test_codesize_cxx_ctors1.json: 151786 => 151739 [-47 bytes / -0.03%] codesize/test_codesize_cxx_ctors2.json: 151189 => 151142 [-47 bytes / -0.03%] codesize/test_codesize_cxx_except.json: 195681 => 195624 [-57 bytes / -0.03%] codesize/test_codesize_cxx_except_wasm.json: 166910 => 166863 [-47 bytes / -0.03%] codesize/test_codesize_cxx_except_wasm_legacy.json: 164794 => 164747 [-47 bytes / -0.03%] codesize/test_codesize_cxx_lto.json: 120616 => 120589 [-27 bytes / -0.02%] codesize/test_codesize_cxx_mangle.json: 262160 => 262103 [-57 bytes / -0.02%] codesize/test_codesize_cxx_noexcept.json: 153786 => 153739 [-47 bytes / -0.03%] codesize/test_codesize_cxx_wasmfs.json: 179507 => 179460 [-47 bytes / -0.03%] codesize/test_codesize_files_wasmfs.json: 63720 => 63720 [+0 bytes / +0.00%] Average change: -0.02% (-0.03% - +0.00%) ```
…uplicate-worker-policy # Conflicts: # test/codesize/test_codesize_cxx_wasmfs.json
|
The CI failure in |
allocateUnusedWorker() and _emscripten_create_wasm_worker() called trustedTypes.createPolicy() on every Worker creation. The Trusted Types spec forbids reusing a policy name unless CSP allows duplicates, so programs with 2+ pthreads (or wasm workers) failed under Trusted Types enforcement.
Cache each policy once and pass the script URL through createScriptURL.
Reproducer (spawn 3 pthreads):
Build:
Serve with Trusted Types CSP:
python3 serve.py # open http://localhost:8080 in Chromium, DevTools console (F12)Expected:
thread 0/1/2 running, thenall 3 threads completed.Actual (without this patch): During startup,
initMainThread()synchronously pre-creates the worker pool (PTHREAD_POOL_SIZE=3); the secondallocateUnusedWorker()throws on duplicatecreatePolicy, aborting module initialization. Console outputs:Most of this PR is finished with AI, but I've confirmed this bug exists and the fix works. Please feel free to reject if you find it unacceptable.
I haven't included a test case, as I am not familiar with the test suite. I would appreciate any guidance or help from maintainers to add a test.