未验证 提交 82cfad54 编写于 作者: A Aleksey Kliger (λgeek) 提交者: GitHub

[interp] bounds check fallthru in conditional branches (#73580)

Throw if we ever take the fall thru on a conditional branch at the end
of a method.

Related to https://github.com/dotnet/runtime/issues/73474 but doesn't
fix it: this just makes the interpreter throw instead of falling off
the end of the transformed CFG
上级 aee90131
......@@ -295,6 +295,13 @@ interp_prev_ins (InterpInst *ins)
} \
} while (0)
#define CHECK_FALLTHRU() \
do { \
if (G_UNLIKELY (td->ip >= end)) { \
interp_generate_ipe_bad_fallthru (td); \
} \
} while (0)
#if NO_UNALIGNED_ACCESS
#define WRITE32(ip, v) \
do { \
......@@ -1305,6 +1312,18 @@ interp_generate_ipe_throw_with_msg (TransformData *td, MonoError *error_msg)
}
}
static void
interp_generate_ipe_bad_fallthru (TransformData *td)
{
ERROR_DECL (bad_fallthru_error);
char *method_code = mono_disasm_code_one (NULL, td->method, td->ip, NULL);
mono_error_set_invalid_program (bad_fallthru_error, "Invalid IL (conditional fallthru past end of method) due to: %s", method_code);
interp_generate_ipe_throw_with_msg (td, bad_fallthru_error);
g_free (method_code);
mono_error_cleanup (bad_fallthru_error);
}
static int
create_interp_local (TransformData *td, MonoType *type)
{
......@@ -4939,98 +4958,122 @@ generate_code (TransformData *td, MonoMethod *method, MonoMethodHeader *header,
case CEE_BRFALSE:
one_arg_branch (td, MINT_BRFALSE_I4, read32 (td->ip + 1), 5);
td->ip += 5;
CHECK_FALLTHRU ();
break;
case CEE_BRFALSE_S:
one_arg_branch (td, MINT_BRFALSE_I4, (gint8)td->ip [1], 2);
td->ip += 2;
CHECK_FALLTHRU ();
break;
case CEE_BRTRUE:
one_arg_branch (td, MINT_BRTRUE_I4, read32 (td->ip + 1), 5);
td->ip += 5;
CHECK_FALLTHRU ();
break;
case CEE_BRTRUE_S:
one_arg_branch (td, MINT_BRTRUE_I4, (gint8)td->ip [1], 2);
td->ip += 2;
CHECK_FALLTHRU ();
break;
case CEE_BEQ:
two_arg_branch (td, MINT_BEQ_I4, read32 (td->ip + 1), 5);
td->ip += 5;
CHECK_FALLTHRU ();
break;
case CEE_BEQ_S:
two_arg_branch (td, MINT_BEQ_I4, (gint8) td->ip [1], 2);
td->ip += 2;
CHECK_FALLTHRU ();
break;
case CEE_BGE:
two_arg_branch (td, MINT_BGE_I4, read32 (td->ip + 1), 5);
td->ip += 5;
CHECK_FALLTHRU ();
break;
case CEE_BGE_S:
two_arg_branch (td, MINT_BGE_I4, (gint8) td->ip [1], 2);
td->ip += 2;
CHECK_FALLTHRU ();
break;
case CEE_BGT:
two_arg_branch (td, MINT_BGT_I4, read32 (td->ip + 1), 5);
td->ip += 5;
CHECK_FALLTHRU ();
break;
case CEE_BGT_S:
two_arg_branch (td, MINT_BGT_I4, (gint8) td->ip [1], 2);
td->ip += 2;
CHECK_FALLTHRU ();
break;
case CEE_BLT:
two_arg_branch (td, MINT_BLT_I4, read32 (td->ip + 1), 5);
td->ip += 5;
CHECK_FALLTHRU ();
break;
case CEE_BLT_S:
two_arg_branch (td, MINT_BLT_I4, (gint8) td->ip [1], 2);
td->ip += 2;
CHECK_FALLTHRU ();
break;
case CEE_BLE:
two_arg_branch (td, MINT_BLE_I4, read32 (td->ip + 1), 5);
td->ip += 5;
CHECK_FALLTHRU ();
break;
case CEE_BLE_S:
two_arg_branch (td, MINT_BLE_I4, (gint8) td->ip [1], 2);
td->ip += 2;
CHECK_FALLTHRU ();
break;
case CEE_BNE_UN:
two_arg_branch (td, MINT_BNE_UN_I4, read32 (td->ip + 1), 5);
td->ip += 5;
CHECK_FALLTHRU ();
break;
case CEE_BNE_UN_S:
two_arg_branch (td, MINT_BNE_UN_I4, (gint8) td->ip [1], 2);
td->ip += 2;
CHECK_FALLTHRU ();
break;
case CEE_BGE_UN:
two_arg_branch (td, MINT_BGE_UN_I4, read32 (td->ip + 1), 5);
td->ip += 5;
CHECK_FALLTHRU ();
break;
case CEE_BGE_UN_S:
two_arg_branch (td, MINT_BGE_UN_I4, (gint8) td->ip [1], 2);
td->ip += 2;
CHECK_FALLTHRU ();
break;
case CEE_BGT_UN:
two_arg_branch (td, MINT_BGT_UN_I4, read32 (td->ip + 1), 5);
td->ip += 5;
CHECK_FALLTHRU ();
break;
case CEE_BGT_UN_S:
two_arg_branch (td, MINT_BGT_UN_I4, (gint8) td->ip [1], 2);
td->ip += 2;
CHECK_FALLTHRU ();
break;
case CEE_BLE_UN:
two_arg_branch (td, MINT_BLE_UN_I4, read32 (td->ip + 1), 5);
td->ip += 5;
CHECK_FALLTHRU ();
break;
case CEE_BLE_UN_S:
two_arg_branch (td, MINT_BLE_UN_I4, (gint8) td->ip [1], 2);
td->ip += 2;
CHECK_FALLTHRU ();
break;
case CEE_BLT_UN:
two_arg_branch (td, MINT_BLT_UN_I4, read32 (td->ip + 1), 5);
td->ip += 5;
CHECK_FALLTHRU ();
break;
case CEE_BLT_UN_S:
two_arg_branch (td, MINT_BLT_UN_I4, (gint8) td->ip [1], 2);
td->ip += 2;
CHECK_FALLTHRU ();
break;
case CEE_SWITCH: {
guint32 n;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册