Repository navigation
Allow passing FileHandle objects via postMessage #33772
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
Closed
Closed
Changes from 1 commit
Commits
Show all changes
11 commits
Select commit
Hold shift + click to select a range
cbc35c3
src: introduce BaseObject base FunctionTemplate
addaleax 915b90e
worker: allow transferring/cloning generic BaseObjects
addaleax 5f25ff9
fixup! worker: allow transferring/cloning generic BaseObjects
addaleax b1aad92
src: add equality operators for BaseObjectPtr
addaleax 877d631
worker: allow passing JS wrapper objects via postMessage
addaleax 758fe1a
worker,fs: make FileHandle transferable
addaleax 82a2220
fixup! worker: allow passing JS wrapper objects via postMessage
addaleax 22e70e2
fixup! worker,fs: make FileHandle transferable
addaleax c74eeb2
fixup! fixup! worker: allow passing JS wrapper objects via postMessage
addaleax a94759a
fixup! worker,fs: make FileHandle transferable
addaleax 9f487ab
worker: emit `'messagerror'` events for failed deserialization
addaleax File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
worker: allow passing JS wrapper objects via postMessage
Enable JS wrapper objects to be used as transferable or cloneable objects in `postMessage()` calls, by having them extend a C++-backed class. This requires a few internal changes: - This commit adds the possibility for transferred objects to read/write JS values at the end of the serialization/deserialization phases. - This commit adds the possibility for transferred objects to list sub-transferables, e.g. typically the public JS wrapper class would list its C++ handle in there. - This commit adds usage of `BaseObject` in a few more places, because now during deserialization weakly held objects can also be involved, in addition to `MessagePort`s.
- Loading branch information
commit 877d631c56e6b99d9af176a2287edab850ab6e55
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| 'use strict'; | ||
| const { | ||
| messaging_deserialize_symbol, | ||
| messaging_transfer_symbol, | ||
| messaging_clone_symbol, | ||
| messaging_transfer_list_symbol | ||
| } = internalBinding('symbols'); | ||
| const { | ||
| JSTransferable, | ||
| setDeserializerCreateObjectFunction | ||
| } = internalBinding('messaging'); | ||
|
|
||
| function setup() { | ||
| // Register the handler that will be used when deserializing JS-based objects | ||
| // from .postMessage() calls. The format of `deserializeInfo` is generally | ||
| // 'module:Constructor', e.g. 'internal/fs/promises:FileHandle'. | ||
| setDeserializerCreateObjectFunction((deserializeInfo) => { | ||
| const [ module, ctor ] = deserializeInfo.split(':'); | ||
| const Ctor = require(module)[ctor]; | ||
| return new Ctor(); | ||
| }); | ||
| } | ||
|
|
||
| module.exports = { | ||
| setup, | ||
| JSTransferable, | ||
| kClone: messaging_clone_symbol, | ||
| kDeserialize: messaging_deserialize_symbol, | ||
| kTransfer: messaging_transfer_symbol, | ||
| kTransferList: messaging_transfer_list_symbol | ||
| }; | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should the module name be guarded with a whitelist here?
I don't think it should since worker threads don't provide a sandbox but I just want to make sure that this isn't exposing a new attack surface somehow.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@benjamingr Hm yeah … this isn’t extending capabilities of the calling code in any way, but I agree that it might be good to be careful here. I’ll think about this a bit more.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@benjamingr I’ve updated this PR so that this function now verifies that the target constructor is a subclass of
JSTransferable, and added tests that verify that fact + the fact that this will only load internal modules (which was already the case before).I think that’s as “locked down” as this can get. If user code makes other internal classes inherit from
JSTransferableon the receiving side, and override thekTransfermethod on the sending side – which is totally doable in most situations – then that means that you can already make arbitrary changes to Node.js internals and won’t even need to do this.The one thing I could see happen would be side effects from
require()ing the internal module itself, which the sending code can still trigger on the receiving side (and which would still typically result in an uncaught exception).What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Better :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fwiw that's the part that initially bugged me, but like we both said it doesn't increase the attack surface at all from what I can tell.