Skip to content

Commit b1b97d5

Browse files
NFC: Protect arena hash operations conservatively
1 parent 315be90 commit b1b97d5

File tree

1 file changed

+16
-5
lines changed

1 file changed

+16
-5
lines changed

ext/witapi/witapi-core.c

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
#include "ruby.h"
44

5+
#define TAG_NONE 0
6+
57
#include "bindgen/rb-abi-guest.h"
68

79
__attribute__((import_module("asyncify"), import_name("start_unwind"))) void
@@ -67,30 +69,39 @@ void *rb_wasm_handle_fiber_unwind(void (**new_fiber_entry)(void *, void *),
6769
}
6870

6971
static VALUE rb_abi_guest_arena_hash;
70-
static void rb_abi_lend_object_internal(VALUE obj) {
72+
static VALUE rb_abi_lend_object_internal(VALUE obj) {
7173
VALUE ref_count = rb_hash_lookup(rb_abi_guest_arena_hash, obj);
7274
if (NIL_P(ref_count)) {
7375
rb_hash_aset(rb_abi_guest_arena_hash, obj, INT2FIX(1));
7476
} else {
7577
rb_hash_aset(rb_abi_guest_arena_hash, obj, INT2FIX(FIX2INT(ref_count) + 1));
7678
}
79+
return Qundef;
7780
}
7881
static void rb_abi_lend_object(VALUE obj) {
79-
RB_WASM_LIB_RT(rb_abi_lend_object_internal(obj));
82+
int state;
83+
RB_WASM_LIB_RT(rb_protect(rb_abi_lend_object_internal, obj, &state));
84+
assert(state == TAG_NONE && "rb_abi_lend_object_internal failed");
8085
}
8186

82-
void rb_abi_guest_rb_abi_value_dtor(void *data) {
83-
VALUE obj = (VALUE)data;
87+
static VALUE rb_abi_guest_rb_abi_value_dtor_internal(VALUE obj) {
8488
VALUE ref_count = rb_hash_lookup(rb_abi_guest_arena_hash, obj);
8589
if (NIL_P(ref_count)) {
8690
rb_warning("rb_abi_guest_rb_abi_value_dtor: double free detected");
87-
return;
91+
return Qundef;
8892
}
8993
if (ref_count == INT2FIX(1)) {
9094
rb_hash_delete(rb_abi_guest_arena_hash, obj);
9195
} else {
9296
rb_hash_aset(rb_abi_guest_arena_hash, obj, INT2FIX(FIX2INT(ref_count) - 1));
9397
}
98+
return Qundef;
99+
}
100+
101+
void rb_abi_guest_rb_abi_value_dtor(void *data) {
102+
int state;
103+
RB_WASM_LIB_RT(rb_protect(rb_abi_guest_rb_abi_value_dtor_internal, (VALUE)data, &state));
104+
assert(state == TAG_NONE && "rb_abi_guest_rb_abi_value_dtor_internal failed");
94105
}
95106

96107
// MARK: - Exported functions

0 commit comments

Comments
 (0)