Skip to content

Commit dde1bb3

Browse files
[metadata_update] Fix bounds check error
The issue is that the STANDALONESIG bounds check was using a 0-based index, and mono_metadata_bounds_check_slow was compensating by adding 1. But that made another call to the bounds check fail: in mono_class_from_typeref_checked we passed a 1-based index. So in the case where a TypeRef was using the last AssemblyRef in a delta, the bound check would fail. Fixes #49227 Co-authored-by: Ryan Lucia <[email protected]>
1 parent f7de865 commit dde1bb3

File tree

2 files changed

+7
-2
lines changed

2 files changed

+7
-2
lines changed

src/mono/mono/metadata/metadata-internals.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -973,6 +973,7 @@ mono_metadata_table_bounds_check (MonoImage *image, int table_index, int token_i
973973
gboolean
974974
mono_metadata_table_bounds_check_slow (MonoImage *image, int table_index, int token_index);
975975

976+
/* token_index is 1-based */
976977
static inline gboolean
977978
mono_metadata_table_bounds_check (MonoImage *image, int table_index, int token_index)
978979
{

src/mono/mono/metadata/metadata.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1000,8 +1000,11 @@ mono_metadata_table_bounds_check_slow (MonoImage *image, int table_index, int to
10001000
GList *list = image->delta_image;
10011001
MonoImage *dmeta;
10021002
MonoTableInfo *table;
1003+
/* result row, 0-based */
10031004
int ridx;
10041005

1006+
int original_token = mono_metadata_make_token (table_index, token_index);
1007+
10051008
uint32_t exposed_gen = mono_metadata_update_get_thread_generation ();
10061009
do {
10071010
if (!list)
@@ -1011,7 +1014,8 @@ mono_metadata_table_bounds_check_slow (MonoImage *image, int table_index, int to
10111014
return TRUE;
10121015
list = list->next;
10131016
table = &dmeta->tables [table_index];
1014-
ridx = mono_image_relative_delta_index (dmeta, mono_metadata_make_token (table_index, token_index + 1)) - 1;
1017+
/* mono_image_relative_delta_index returns a 1-based index */
1018+
ridx = mono_image_relative_delta_index (dmeta, original_token) - 1;
10151019
} while (ridx < 0 || ridx >= table->rows);
10161020

10171021
return FALSE;
@@ -4779,7 +4783,7 @@ mono_metadata_parse_mh_full (MonoImage *m, MonoGenericContainer *container, cons
47794783

47804784
if (local_var_sig_tok) {
47814785
int idx = mono_metadata_token_index (local_var_sig_tok) - 1;
4782-
if (mono_metadata_table_bounds_check (m, MONO_TABLE_STANDALONESIG, idx)) {
4786+
if (mono_metadata_table_bounds_check (m, MONO_TABLE_STANDALONESIG, idx + 1)) {
47834787
mono_error_set_bad_image (error, m, "Invalid method header local vars signature token 0x%08x", idx);
47844788
goto fail;
47854789
}

0 commit comments

Comments
 (0)