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

fix: reject promises in the arguments to syscall.callNow() #1766

Merged
merged 2 commits into from
Sep 15, 2020

Conversation

warner
Copy link
Member

@warner warner commented Sep 15, 2020

Vats which hold device nodes (d-NN references) can use syscall.callNow()
on them, to make a synchronous invocation (which can return data). The
outbound arguments and return data are capdata, which is translated through
c-lists just like regular syscall.send() and promise resolution.

However devices do not (currently) handle Promises at all. The
kernel-to-device c-list translation will panic the kernel if asked to
translate a promise reference (kpNN).

Vats should not be able to panic the kernel, even if we give them access to a
device node. This changes the vat-to-kernel translator to reject promise
references in the arguments of callNow, making it a vat-fatal error. This
will terminate the vat, but leave the kernel running.

In the long run (#1346), devices should accept Promises, but it will take
more work (and probably require devices to operate on a much lower level than
vats do). But this should fix the immediate kernel panic.

Note that killing a vat is not exactly friendly either. The bug described in
issue #1358 was triggered by user REPL input causing the HTTP vat to try
sending a Promise into the Command device, killing the kernel. With this
change, this will instead kill the HTTP vat, which breaks the REPL, rendering
the system mostly unusable. But at least the attribution is correct.

We have another fix in the works that will change liveslots.js to catch this
situation during the call to D(devnode).methname(args), which should reduce
the blast radius to merely throw an exception in D(), rather than killing
the whole vat.

refs #1358

@warner warner added the SwingSet package: SwingSet label Sep 15, 2020
@warner warner requested a review from FUDCo September 15, 2020 20:51
@warner warner self-assigned this Sep 15, 2020
Copy link
Contributor

@FUDCo FUDCo left a comment

Choose a reason for hiding this comment

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

LGTM

We use the same bootstrap vat files multiple times in this test file, so this
amortizes the bundling cost up front. We were previously doing this for the
kernel bundles, but this adds the vat bundles too.

I also changed the tests to run serially (using `test.serial()` instead of
`test()`), because we aren't speeding anything up by thrashing around among a
dozen simultaneous tests. JS remains single-threaded (and threads remain
evil).
Vats which hold device nodes (`d-NN` references) can use `syscall.callNow()`
on them, to make a synchronous invocation (which can return data). The
outbound arguments and return data are capdata, which is translated through
c-lists just like regular `syscall.send()` and promise resolution.

However devices do not (currently) handle Promises at all. The
kernel-to-device c-list translation will panic the kernel if asked to
translate a promise reference (`kpNN`).

Vats should not be able to panic the kernel, even if we give them access to a
device node. This changes the vat-to-kernel translator to reject promise
references in the arguments of `callNow`, making it a vat-fatal error. This
will terminate the vat, but leave the kernel running.

In the long run (#1346), devices should accept Promises, but it will take
more work (and probably require devices to operate on a much lower level than
vats do). But this should fix the immediate kernel panic.

Note that killing a vat is not exactly friendly either. The bug described in
issue #1358 was triggered by user REPL input causing the HTTP vat to try
sending a Promise into the Command device, killing the kernel. With this
change, this will instead kill the HTTP vat, which breaks the REPL, rendering
the system mostly unusable. But at least the attribution is correct.

We have another fix in the works that will change liveslots.js to catch this
situation during the call to `D(devnode).methname(args)`, which should reduce
the blast radius to merely throw an exception in `D()`, rather than killing
the whole vat.

refs #1358
@warner warner force-pushed the 1358-cleanup-device-tests branch from 3a45930 to 2e4c10c Compare September 15, 2020 21:23
@warner warner force-pushed the 1358-callnow-promises branch from 4d5b059 to 3ca1700 Compare September 15, 2020 21:23
Base automatically changed from 1358-cleanup-device-tests to master September 15, 2020 21:33
@warner warner merged commit 7472661 into master Sep 15, 2020
@warner warner deleted the 1358-callnow-promises branch September 15, 2020 21:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
SwingSet package: SwingSet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants