From f29f301e6eaca9d91fbee3bdf6263cc92aa9933d Mon Sep 17 00:00:00 2001 From: adam-rhebo Date: Fri, 21 Jun 2019 11:03:58 +0200 Subject: [PATCH] Make clearing value stack between export invocations optional (#188) This avoids the main overhead of repeated export invocations by making it optional to clear the value stack after each interpreter run. This is especially useful if different exports of the same module are invoked repeated so that no unintended information leaks are possible. --- src/runner.rs | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/runner.rs b/src/runner.rs index a3e7277..b969116 100644 --- a/src/runner.rs +++ b/src/runner.rs @@ -1493,6 +1493,22 @@ impl StackRecycler { } } + /// Clears any values left on the stack to avoid + /// leaking them to future export invocations. + /// + /// This is a secondary defense to prevent modules from + /// exploiting faulty stack handling in the interpreter. + /// + /// Do note that there are additional channels that + /// can leak information into an untrusted module. + pub fn clear(&mut self) { + if let Some(buf) = &mut self.value_stack_buf { + for cell in buf.iter_mut() { + *cell = RuntimeValueInternal(0); + } + } + } + fn recreate_value_stack(this: &mut Option<&mut Self>) -> ValueStack { let limit = this .as_ref() @@ -1526,10 +1542,6 @@ impl StackRecycler { } pub(crate) fn recycle(&mut self, mut interpreter: Interpreter) { - for cell in interpreter.value_stack.buf.iter_mut() { - *cell = RuntimeValueInternal(0); - } - interpreter.call_stack.buf.clear(); self.value_stack_buf = Some(interpreter.value_stack.buf);