mirror of
https://github.com/janet-lang/janet
synced 2026-10-29 18:34:27 +00:00
validate captured env before reading locals in debug/stack (#1928)
This commit is contained in:
1 parent
dc0f243bb9
commit
4475a3d51c
2 files changed
+29
No files matched your search
@@ -23,6 +23,7 @@
|
||||
#ifndef JANET_AMALG
|
||||
#include "features.h"
|
||||
#include <janet.h>
|
||||
#include "fiber.h"
|
||||
#include "gc.h"
|
||||
#include "state.h"
|
||||
#include "util.h"
|
||||
@@ -347,6 +348,7 @@ static Janet doframe(JanetStackFrame *frame) {
|
||||
if (jsm.death_pc < (uint32_t) def->environments_length) {
|
||||
/* death_pc is in valid range */
|
||||
JanetFuncEnv *env = frame->func->envs[jsm.death_pc];
|
||||
janet_env_valid(env);
|
||||
if (jsm.slot_index < (uint32_t) env->length) {
|
||||
/* slot_index range good */
|
||||
if (env->offset > 0) {
|
||||
|
||||
@@ -30,5 +30,32 @@
|
||||
(debug/unfbreak map 1)
|
||||
(map inc [1 2 3])
|
||||
|
||||
# Reading locals of an unmarshalled closure that captures an on-stack
|
||||
# environment must validate the env first. The on-stack variant stores a
|
||||
# negative, unvalidated offset after unmarshal; without validation debug/stack
|
||||
# read the fiber pointer as a value array (out-of-bounds / type confusion).
|
||||
(def outer
|
||||
(fiber/new
|
||||
(fn []
|
||||
(def secret 0xBEEF)
|
||||
(def capt (fn [] (yield :paused) secret))
|
||||
(yield capt)
|
||||
:done)
|
||||
:y))
|
||||
(def capt (resume outer))
|
||||
(def inner (fiber/new capt :y))
|
||||
(resume inner)
|
||||
(def image (marshal inner))
|
||||
# Disable collection so the unmarshalled env keeps its unvalidated offset until
|
||||
# debug/stack touches it.
|
||||
(def old-interval (gcinterval))
|
||||
(gcsetinterval 0)
|
||||
(def inner2 (unmarshal image))
|
||||
(var locals nil)
|
||||
(each fr (debug/stack inner2)
|
||||
(when (fr :locals) (set locals (fr :locals))))
|
||||
(gcsetinterval old-interval)
|
||||
(assert (= 0xBEEF (get locals 'secret)) "unmarshalled on-stack env validated in debug/stack")
|
||||
|
||||
(end-suite)
|
||||
|
||||
Reference in new issue
Block a user