mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
Fix possible use after free in mrb_class_find_path
`mrb_class_find_path` resolves a `char*` pointer to a class name string by calling `mrb_class_name`. It then allocates a new string with capacity 40 to copy that `char*` into. https://github.com/mruby/mruby/blob/e04184185ab43b94980550e850d8813a415fa438/src/variable.c#L1111-L1112 `mrb_class_name` resolves the class name via `class_name_str`, which returns an `mrb_value` with type tag `MRB_TT_STRING` and backed by an `RString*`. Then `mrb_class_name` extracts the `RSTRING_PTR`: https://github.com/mruby/mruby/blob/e04184185ab43b94980550e850d8813a415fa438/src/class.c#L2133-L2134 That `RString*`-backed `mrb_value` ultimately comes from `mrb_class_path` which resolves the string from the symbol table: https://github.com/mruby/mruby/blob/e04184185ab43b94980550e850d8813a415fa438/src/class.c#L2111 The allocation of the target `str` after resolving the class name `mrb_value` and extracting its pointer is fragile and assumes the `RString*` is "static". If the `RString*` is not static, the interleaving of extracting the `RSTRING_PTR` followed by a subsequent allocation might result in the class name `mrb_value` being garbage collected, which will leave the extracted pointer invalid. Fix this bad interleaving by allocating the destination string first before taking a raw pointer to an `RString*`.
This commit is contained in:
+1
-1
@@ -1108,8 +1108,8 @@ mrb_class_find_path(mrb_state *mrb, struct RClass *c)
|
||||
if (outer == NULL) return mrb_nil_value();
|
||||
name = find_class_sym(mrb, outer, c);
|
||||
if (name == 0) return mrb_nil_value();
|
||||
str = mrb_class_name(mrb, outer);
|
||||
path = mrb_str_new_capa(mrb, 40);
|
||||
str = mrb_class_name(mrb, outer);
|
||||
mrb_str_cat_cstr(mrb, path, str);
|
||||
mrb_str_cat_cstr(mrb, path, "::");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user