From 099d2c47717132c04ab9a1b2b2945e8db1b5afa3 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Sat, 3 Jan 2026 20:36:17 +0900 Subject: [PATCH] array.c: fix heap-use-after-free in insertion_sort The key variable in insertion_sort temporarily holds an array element that's been removed from its slot during the sorting process. When sort_cmp yields to a block that triggers GC, key wasn't protected and could be collected. Use arena save/restore around the loop to avoid arena overflow for large arrays. Test case from oss-fuzz: sort! with block containing rescue. Co-authored-by: Claude --- src/array.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/array.c b/src/array.c index 9b15995e9..6e31f4228 100644 --- a/src/array.c +++ b/src/array.c @@ -2172,16 +2172,21 @@ heapify(mrb_state *mrb, mrb_value ary, mrb_value *a, mrb_int index, mrb_int size static void insertion_sort(mrb_state *mrb, mrb_value ary, mrb_value *a, mrb_int size, mrb_value blk) { + int ai = mrb_gc_arena_save(mrb); for (mrb_int i = 1; i < size; i++) { mrb_value key = a[i]; mrb_int j = i - 1; + /* Protect key from GC - it's temporarily out of the array during sort */ + mrb_gc_protect(mrb, key); + /* Move elements that are greater than key to one position ahead */ while (j >= 0 && sort_cmp(mrb, ary, a[j], key, blk)) { a[j + 1] = a[j]; j--; } a[j + 1] = key; + mrb_gc_arena_restore(mrb, ai); } }