From 794b9a28b562121426b3b1a19d2e465616af3ac0 Mon Sep 17 00:00:00 2001 From: Alan Wu Date: Mon, 6 Dec 2021 19:14:34 -0500 Subject: [PATCH] YJIT: Add integrity checks for blockid Verify that the iseq idx pair for the block is valid in invalidate_block_version(). While we are at it, bound loop iterating over instructions to `iseq_body->iseq_size`. --- yjit_codegen.c | 4 +++- yjit_core.c | 11 +++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/yjit_codegen.c b/yjit_codegen.c index 8c888fd53a..9c603e240b 100644 --- a/yjit_codegen.c +++ b/yjit_codegen.c @@ -639,6 +639,7 @@ static block_t * gen_single_block(blockid_t blockid, const ctx_t *start_ctx, rb_execution_context_t *ec) { RUBY_ASSERT(cb != NULL); + verify_blockid(blockid); // Allocate the new block block_t *block = calloc(1, sizeof(block_t)); @@ -660,6 +661,7 @@ gen_single_block(blockid_t blockid, const ctx_t *start_ctx, rb_execution_context RUBY_ASSERT(!(blockid.idx == 0 && start_ctx->stack_size > 0)); const rb_iseq_t *iseq = block->blockid.iseq; + const unsigned int iseq_size = iseq->body->iseq_size; uint32_t insn_idx = block->blockid.idx; const uint32_t starting_insn_idx = insn_idx; @@ -676,7 +678,7 @@ gen_single_block(blockid_t blockid, const ctx_t *start_ctx, rb_execution_context block->start_addr = cb_get_write_ptr(cb); // For each instruction to compile - for (;;) { + while (insn_idx < iseq_size) { // Get the current pc and opcode VALUE *pc = yjit_iseq_pc_at_idx(iseq, insn_idx); int opcode = yjit_opcode_at_pc(iseq, pc); diff --git a/yjit_core.c b/yjit_core.c index 00905e7f24..d420f0fcab 100644 --- a/yjit_core.c +++ b/yjit_core.c @@ -1205,6 +1205,15 @@ block_array_remove(rb_yjit_block_array_t block_array, block_t *block) RUBY_ASSERT(false); } +// Some runtime checks for integrity of a program location +static void +verify_blockid(const blockid_t blockid) +{ + const rb_iseq_t *const iseq = blockid.iseq; + RUBY_ASSERT_ALWAYS(IMEMO_TYPE_P(iseq, imemo_iseq)); + RUBY_ASSERT_ALWAYS(blockid.idx < iseq->body->iseq_size); +} + // Invalidate one specific block version static void invalidate_block_version(block_t *block) @@ -1214,6 +1223,8 @@ invalidate_block_version(block_t *block) // TODO: want to assert that all other ractors are stopped here. Can't patch // machine code that some other thread is running. + verify_blockid(block->blockid); + const rb_iseq_t *iseq = block->blockid.iseq; //fprintf(stderr, "invalidating block (%p, %d)\n", block->blockid.iseq, block->blockid.idx);