From 6076f634c03a0c15b90b46661f2b412cc216d87c Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Sun, 10 May 2026 07:06:52 +0300 Subject: [PATCH] context: avoid use-after-free in propagate_cancel spawn --- vlib/context/cancel.v | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/vlib/context/cancel.v b/vlib/context/cancel.v index 21d33019f..4d2b4f248 100644 --- a/vlib/context/cancel.v +++ b/vlib/context/cancel.v @@ -136,14 +136,19 @@ fn propagate_cancel(mut parent Context, mut child Canceler) { else {} } mut p := parent_cancel_context(mut parent) or { - spawn fn (mut parent Context, mut child Canceler) { - pdone := parent.done() + // Pre-extract the parent done channel and pass it by value into the + // spawn. The goroutine may outlive the caller's stack frame, so + // dereferencing `parent` inside the spawn (e.g. via parent.done()) + // reads freed stack memory once the caller returns and reuses that + // region — observed as a consistent segfault in vlib/context/cause_test.v + // on Linux x86_64. Mirrors the fix in onecontext.run_two_contexts. + spawn fn (pdone chan int, mut parent Context, mut child Canceler) { select { _ := <-pdone { child.cancel(false, parent.err()) } } - }(mut parent, mut child) + }(done, mut parent, mut child) return } -- 2.39.5