From 4475a3d51cc7e07d2d4fcaa8588f5b6a4561cfc3 Mon Sep 17 00:00:00 2001 From: nabeel-dev21 Date: Sat, 24 Oct 2026 19:43:19 +0530 Subject: [PATCH] validate captured env before reading locals in debug/stack (#1928) --- src/core/debug.c | 2 ++ test/suite-debug.janet | 27 +++++++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/src/core/debug.c b/src/core/debug.c index f74d8bcf..76e7c9fb 100644 --- a/src/core/debug.c +++ b/src/core/debug.c @@ -23,6 +23,7 @@ #ifndef JANET_AMALG #include "features.h" #include +#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) { diff --git a/test/suite-debug.janet b/test/suite-debug.janet index 95514710..22472f57 100644 --- a/test/suite-debug.janet +++ b/test/suite-debug.janet @@ -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)