Extraneous imported promises cause memory growth #6074
Labels
bug
Something isn't working
liveslots
requires vat-upgrade to deploy changes
resource-exhaustion
Threats to availability from resource exhaustion attacks
SwingSet
package: SwingSet
vaults_triage
DO NOT USE
Description of the problem
One kind of memory consumption that can be inflicted upon an innocent vat is when the inbound
dispatch.deliver
ordispatch.notify
contains promise vrefs (vpids) in the arguments or resolution data. Liveslots creates actualPromise
objects for each of these, passes them to userspace, and remembers theirresolve
/reject
functions in theimportedVPIDs
table.Each promise incurs memory consumption within the vat worker, which cannot be shed until it receives a
dispatch.notify
and the Promise can be settled. At that point, the resolved promise loses its identity, and liveslots is allowed to stop tracking it. If userspace does not retain a reference, thePromise
can then be garbage-collected by the engine.The problem is that an attacker might send messages with spurious extra arguments, which contain vpids, to provoke this memory consumption. The victim vat is not looking for extra arguments (or extra properties on normal arguments): it could, but it would be pretty awkward (walking the whole argument object graph). And even if it did that, the memory consumption is triggered when liveslots deserializes the data, so by the time userspace gets them, it is too late.
The same is true for promises that appear in resolution data (when
syscall.notify
includes capdata with new vpids inslots
), but it's even more awkward for userspace to be on the lookout for these. It would have to subscribe to every promise it ever sees, just to learn about even more promises in the resolution.Root cause and solutions
This kind of leak is caused by a chain of limitations in liveslots of JS engines:
Promise.prototype
making it impossible to detect when these imported promise areawait
ed orthen
ed. If using a normal subclass ofPromise
, it would be possible to detect if/when these promises are awaited, and delay subscription until then. Issue Use thenables for promises as delivery arguments #8469.The text was updated successfully, but these errors were encountered: