From 819156e67854a3501567a2f7e06fc958d89e9666 Mon Sep 17 00:00:00 2001 From: 0x1eef <0x1eef@hardenedbsd.org> Date: Wed, 27 May 2026 23:00:45 -0300 Subject: [PATCH] task: return `nil` when given a nested call to `Task.run` When you try to start an event loop inside an event loop, the mruby process will SIGSEGV: ```ruby Task.new { Task.run } Task.run ``` This change turns the second call to `Task.run` into a noop that returns nil instead. Fix #6865 --- include/mruby.h | 1 + mrbgems/mruby-task/src/task.c | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/include/mruby.h b/include/mruby.h index db89b6236..7bbfb9634 100644 --- a/include/mruby.h +++ b/include/mruby.h @@ -274,6 +274,7 @@ typedef struct mrb_task_state { volatile mrb_bool switching; /* Context switch pending flag */ struct mrb_task *main_task; /* Main task wrapper for root context */ uint8_t scheduler_lock; /* Lock counter for synchronous execution */ + mrb_bool loop_running; /* Active mrb_task_run loop flag */ } mrb_task_state; #endif diff --git a/mrbgems/mruby-task/src/task.c b/mrbgems/mruby-task/src/task.c index 70f9e6233..9662ffdfc 100644 --- a/mrbgems/mruby-task/src/task.c +++ b/mrbgems/mruby-task/src/task.c @@ -445,6 +445,11 @@ mrb_task_run(mrb_state *mrb) { mrb_task *t; + if (mrb->task.loop_running) { + return mrb_nil_value(); + } + mrb->task.loop_running = TRUE; + while (1) { t = q_ready_; @@ -481,6 +486,7 @@ mrb_task_run(mrb_state *mrb) } } + mrb->task.loop_running = FALSE; return mrb_nil_value(); } @@ -1505,6 +1511,7 @@ mrb_mruby_task_gem_init(mrb_state *mrb) /* Initialize main task to NULL and scheduler_lock to 0 */ mrb->task.main_task = NULL; mrb->task.scheduler_lock = 0; + mrb->task.loop_running = FALSE; task_class = mrb_define_class_id(mrb, MRB_SYM(Task), mrb->object_class); MRB_SET_INSTANCE_TT(task_class, MRB_TT_DATA);