-
Notifications
You must be signed in to change notification settings - Fork 212
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
slots in vatAdmin terminate/createVat are not translated correctly #4588
Comments
Chip's latest may make only one vat crash. |
warner
added a commit
that referenced
this issue
Mar 19, 2022
This allows `E(vatAdminService).createVat(bundleID, { vatParameters })` to include object references in `vatParameters`, which are then delivered through the `dispatch.startVat()` delivery and made available to `buildRootObject(vatPowers, vatParameters)`. From within a vat, `vatPowers.exitVat(completion)` and `.exitVatWithFailure(reason)` can include object references, and they will be delivered to the parent caller's `done` promise. From outside the vat, `E(adminNode).terminateWithFailure(reason)` can take object refs in `reason` and they will be delivered to the parent caller's `done` promise. `E(adminNode).upgrade(bundleID, vatParameters)` can take object refs in `vatParameters` just like `createVat` (although `upgrade` itself is still non-functional). The kernel will maintain a refcount on each object passed through this mechanism, to keep it from being collected while in transit. This is implemented with the new "kernel device hooks" feature, which allows a device to call into the kernel and have its drefs translated into krefs. This will help with ZCF/contract vat upgrade, to pass the new contract bundlecap into the new ZCF vat via vatParameters. closes #4588 closes #4381 refs #1848
warner
added a commit
that referenced
this issue
Mar 19, 2022
This allows `E(vatAdminService).createVat(bundleID, { vatParameters })` to include object references in `vatParameters`, which are then delivered through the `dispatch.startVat()` delivery and made available to `buildRootObject(vatPowers, vatParameters)`. In vat-vat-admin, the CreateVatOptions validation was rewritten to ensure that any existing slots are only in vatParameters. From within a vat, `vatPowers.exitVat(completion)` and `.exitVatWithFailure(reason)` can include object references, and they will be delivered to the parent caller's `done` promise. From outside the vat, `E(adminNode).terminateWithFailure(reason)` can take object refs in `reason` and they will be delivered to the parent caller's `done` promise. `E(adminNode).upgrade(bundleID, vatParameters)` can take object refs in `vatParameters` just like `createVat` (although `upgrade` itself is still non-functional). The kernel will maintain a refcount on each object passed through this mechanism, to keep it from being collected while in transit. This is implemented with the new "kernel device hooks" feature, which allows a device to call into the kernel and have its drefs translated into krefs. This will help with ZCF/contract vat upgrade, to pass the new contract bundlecap into the new ZCF vat via vatParameters. closes #4588 closes #4381 refs #1848
warner
added a commit
that referenced
this issue
Mar 22, 2022
This allows `E(vatAdminService).createVat(bundleID, { vatParameters })` to include object references in `vatParameters`, which are then delivered through the `dispatch.startVat()` delivery and made available to `buildRootObject(vatPowers, vatParameters)`. In vat-vat-admin, the CreateVatOptions validation was rewritten to ensure that any existing slots are only in vatParameters. From within a vat, `vatPowers.exitVat(completion)` and `.exitVatWithFailure(reason)` can include object references, and they will be delivered to the parent caller's `done` promise. From outside the vat, `E(adminNode).terminateWithFailure(reason)` can take object refs in `reason` and they will be delivered to the parent caller's `done` promise. `E(adminNode).upgrade(bundleID, vatParameters)` can take object refs in `vatParameters` just like `createVat` (although `upgrade` itself is still non-functional). The kernel will maintain a refcount on each object passed through this mechanism, to keep it from being collected while in transit. This is implemented with the new "kernel device hooks" feature, which allows a device to call into the kernel and have its drefs translated into krefs. This will help with ZCF/contract vat upgrade, to pass the new contract bundlecap into the new ZCF vat via vatParameters. closes #4588 closes #4381 refs #1848
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
While working on #4566 I realized that we're probably mishandling object references (slots) in the "terminate vat from the outside" case:
The object
obj
is assigned a vat-1 vref asterminateWithFailure
gets serialized forsyscall.send
, then assigned a kref as the syscall is translated. When the message is delivered tovat-admin
, the c-list allocates a vat-admin vref, which is what appears at thevatAdminWrapper.js
terminateWithFailure()
call:The
D(vatAdminNode)
does asyscall.callNow
, which translates the vref through the kref into adevices.vatAdmin
dref, which is what arrives at the device code.Previously (on current trunk), the device code was written with
deviceSlots
, which provided a copy of itsm.serialize
to the device code, sovatAdmin-src.js
could re-serialize thereason
object into capdata.vatAdmin-src.js
then passed thereason
capdata to its kernel endowment (terminate(vatID, serialize(reason))
).The problem is that
serialize(reason)
is device-side capdata, with "drefs" (the device equivalent of "vrefs" in a vat). But the kernelterminate
endowment is going to use thatreason
capdata to reject theadmin.done()
promise: the kernel enqueues avatTerminated
message to vat-admin, andqueueToKref
assumes that the arguments you give it use krefs.The consequence is that when we attempt to deliver the
vatTerminated
to vat-admin, the translator will encounter invalid slot types. This will either cause a kernel panic, or cause the failure of that message (andadmin.done()
will never fire), probably the former.In my #4566 rewrite, I encountered the same problem in a raw-device form of
vatAdmin-src.js
. I get dref capdata from thedispatch.invoke
, and I want to provide kref capdata to the kernel endowment.The same problem exists in
createVat
with theoptions
argument. This one is more pressing because #4381 will want to include bundlecaps inoptions.vatParameters
.For now, I'm adding an assertion that the
.slots
are empty, so we catch this in the calling vat. For most of these methods that's going to bevatAdminWrapper.js
, which will probably cause theterminateWithFailure()
orcreateVat()
to fail, which is a perfectly reasonable way to handle it. But to implement #4381 we'll need something better.It probably wants to be a syscall, because that provides an easy place to perform dref-to-kref translation. But after translation, we want to hit some kernel-provided API. The
terminate
case has no return value, but thecreateVat
cases want to return a vatID from that API.This might overlap with #720 (a kernel input queue). One thought is that the built-in device might be given an endowment which is a marker/handle object (one for
terminate
, another one or two forcreateVat
/createVatByBundle
). We add asyscall.triggerKernelSomething(handle, deviceCapdata)
, the syscall translatesdeviceCapdata
intokernelCapdata
, then invokes whatever function the kernel had previously registered withhandle
(possibly through a queue that protects the kernel from reentrancy).The way this interacts with #720 would be that external callers could invoke the device's exterior APIs any time they want, and
syscall.triggerKernelSomething
would know to queue the actual translation and invocation until the kernel was safely idle. I'm not sure that's sound.The text was updated successfully, but these errors were encountered: