From ef5ae084d759fb829a9b19432d3348f652a09bfa Mon Sep 17 00:00:00 2001 From: dearblue Date: Sun, 10 Apr 2022 21:36:59 +0900 Subject: [PATCH] Must the `mrb_sys_fail()` function raise an exception Normal return of control from the `mrb_sys_fail()` function has unexpected results. Example: double free, malloc with huge size used as error integer The following is an example of an actual crash: ```console % cat crash.rb def SystemCallError._sys_fail(*a) nil end File.readlink("/404") % bin/mruby crash.rb zsh: segmentation fault (core dumped) bin/mruby crash.rb ``` --- include/mruby/error.h | 2 +- src/error.c | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/include/mruby/error.h b/include/mruby/error.h index 752baae84..225234a77 100644 --- a/include/mruby/error.h +++ b/include/mruby/error.h @@ -23,7 +23,7 @@ struct RException { #define mrb_exc_ptr(v) ((struct RException*)mrb_ptr(v)) #define MRB_EXC_MESG_STRING_FLAG 0x100 -MRB_API void mrb_sys_fail(mrb_state *mrb, const char *mesg); +MRB_API mrb_noreturn void mrb_sys_fail(mrb_state *mrb, const char *mesg); MRB_API mrb_value mrb_exc_new_str(mrb_state *mrb, struct RClass* c, mrb_value str); #define mrb_exc_new_lit(mrb, c, lit) mrb_exc_new_str(mrb, c, mrb_str_new_lit(mrb, lit)) MRB_API mrb_value mrb_make_exception(mrb_state *mrb, mrb_int argc, const mrb_value *argv); diff --git a/src/error.c b/src/error.c index 2c2f709b1..643279bd4 100644 --- a/src/error.c +++ b/src/error.c @@ -521,7 +521,7 @@ exception_call: return mesg; } -MRB_API void +MRB_API mrb_noreturn void mrb_sys_fail(mrb_state *mrb, const char *mesg) { struct RClass *sce; @@ -537,9 +537,8 @@ mrb_sys_fail(mrb_state *mrb, const char *mesg) mrb_funcall_id(mrb, mrb_obj_value(sce), MRB_SYM(_sys_fail), 1, mrb_fixnum_value(no)); } } - else { - mrb_raise(mrb, E_RUNTIME_ERROR, mesg); - } + + mrb_raise(mrb, E_RUNTIME_ERROR, mesg); } MRB_API mrb_noreturn void