mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
Making splat argument objects invisible from Ruby side
The `mrb_get_argv()` function and the `*` specifier of `mrb_get_args()` get the address of the argument. At this time, if it is passed in the form of a splat argument, it will be an address to an element of an array object. After getting the pointer to the array object, the caller may call `mrb_vm_exec()` directly or indirectly. At this time, a splat argument with the class set can be retrieved as an array object by searching with `ObjectSpace.each_object`. If changes are made as array objects, addresses on the heap as arrays may become invalid, or objects in the array may be recycled by the GC. When the caller references the changed address in a subsequent operation, use-after-free is established. This patch assigns `NULL` as the class of the array object so that it cannot be detected by `ObjectSpace.each_object` from the Ruby side.
This commit is contained in:
@@ -834,6 +834,7 @@ mrb_get_argc(mrb_state *mrb)
|
||||
if (argc == 15) {
|
||||
struct RArray *a = mrb_ary_ptr(mrb->c->ci->stack[1]);
|
||||
|
||||
a->c = NULL; /* hide from ObjectSpace.each_object */
|
||||
argc = ARY_LEN(a);
|
||||
}
|
||||
return argc;
|
||||
@@ -847,6 +848,7 @@ mrb_get_argv(mrb_state *mrb)
|
||||
if (argc == 15) {
|
||||
struct RArray *a = mrb_ary_ptr(*array_argv);
|
||||
|
||||
a->c = NULL; /* hide from ObjectSpace.each_object */
|
||||
array_argv = ARY_PTR(a);
|
||||
}
|
||||
return array_argv;
|
||||
@@ -965,6 +967,7 @@ get_args_v(mrb_state *mrb, mrb_args_format format, void** ptr, va_list *ap)
|
||||
struct RArray *a = mrb_ary_ptr(*argv);
|
||||
argv = ARY_PTR(a);
|
||||
argc = ARY_LEN(a);
|
||||
a->c = NULL; /* hide from ObjectSpace.each_object */
|
||||
}
|
||||
|
||||
opt = FALSE;
|
||||
|
||||
Reference in New Issue
Block a user