#define SECTION_HEADER_INVALID_FLAGS 0x3E
static gboolean
-is_valid_method_header (VerifyContext *ctx, guint32 rva)
+is_valid_method_header (VerifyContext *ctx, guint32 rva, guint32 *locals_token)
{
unsigned local_vars_tok, code_size, offset = mono_cli_rva_image_map (ctx->image, rva);
unsigned header = 0;
unsigned fat_header = 0, size = 0, max_stack;
const char *ptr = NULL, *end;
+ *locals_token = 0;
+
if (offset == INVALID_ADDRESS)
FAIL (ctx, g_strdup ("MethodHeader: Invalid RVA"));
FAIL (ctx, g_strdup_printf ("MethodHeader: Invalid local vars signature table 0x%x", ((local_vars_tok >> 24) & 0xFF)));
if ((local_vars_tok & 0xFFFFFF) > ctx->image->tables [MONO_TABLE_STANDALONESIG].rows)
FAIL (ctx, g_strdup_printf ("MethodHeader: Invalid local vars signature points to invalid row 0x%x", local_vars_tok & 0xFFFFFF));
+ *locals_token = local_vars_tok & 0xFFFFFF;
}
if (fat_header & FAT_HEADER_INVALID_FLAGS)
verify_method_table_full (VerifyContext *ctx)
{
MonoTableInfo *table = &ctx->image->tables [MONO_TABLE_METHOD];
- guint32 data [MONO_METHOD_SIZE], rva;
+ guint32 data [MONO_METHOD_SIZE], rva, locals_token;
int i;
for (i = 0; i < table->rows; ++i) {
if (!data [MONO_METHOD_SIGNATURE] || !is_valid_method_signature (ctx, data [MONO_METHOD_SIGNATURE]))
ADD_ERROR (ctx, g_strdup_printf ("Invalid method row %d invalid signature token 0x%08x", i, data [MONO_METHOD_SIGNATURE]));
- if (rva && !is_valid_method_header (ctx, rva))
+ if (rva && !is_valid_method_header (ctx, rva, &locals_token))
ADD_ERROR (ctx, g_strdup_printf ("Invalid method row %d RVA points to an invalid method header", i));
}
}
mono_verifier_verify_method_header (MonoImage *image, guint32 offset, GSList **error_list)
{
VerifyContext ctx;
+ guint32 locals_token;
if (!mono_verifier_is_enabled_for_image (image))
return TRUE;
init_verify_context (&ctx, image, error_list != NULL);
ctx.stage = STAGE_TABLES;
- is_valid_method_header (&ctx, offset);
+ is_valid_method_header (&ctx, offset, &locals_token);
+ if (locals_token) {
+ guint32 sig_offset = mono_metadata_decode_row_col (&image->tables [MONO_TABLE_STANDALONESIG], locals_token - 1, MONO_STAND_ALONE_SIGNATURE);
+ is_valid_standalonesig_blob (&ctx, sig_offset);
+ }
+
return cleanup_context (&ctx, error_list);
}