X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Fmetadata-verify.c;h=ba794c6b3de32c8a307dcb0913a0192a41a30a37;hb=12c99202fa08e7b128ba234d7b3bac722eb3aab8;hp=97712fa73c1ec1c1cfdb95a61e9cded51946c976;hpb=bc21b3eafaf465002446ef9c5419590f0d3558b7;p=mono.git diff --git a/mono/metadata/metadata-verify.c b/mono/metadata/metadata-verify.c index 97712fa73c1..ba794c6b3de 100644 --- a/mono/metadata/metadata-verify.c +++ b/mono/metadata/metadata-verify.c @@ -1230,7 +1230,7 @@ parse_custom_mods (VerifyContext *ctx, const char **_ptr, const char *end) if (!safe_read_cint (token, ptr, end)) FAIL (ctx, g_strdup ("CustomMod: Not enough room for the token")); - if (!is_valid_coded_index (ctx, TYPEDEF_OR_REF_DESC, token)) + if (!is_valid_coded_index (ctx, TYPEDEF_OR_REF_DESC, token) || !get_coded_index_token (TYPEDEF_OR_REF_DESC, token)) FAIL (ctx, g_strdup_printf ("CustomMod: invalid TypeDefOrRef token %x", token)); } @@ -1287,7 +1287,7 @@ parse_generic_inst (VerifyContext *ctx, const char **_ptr, const char *end) if (!safe_read_cint (token, ptr, end)) FAIL (ctx, g_strdup ("GenericInst: Not enough room for type token")); - if (!is_valid_coded_index (ctx, TYPEDEF_OR_REF_DESC, token)) + if (!is_valid_coded_index (ctx, TYPEDEF_OR_REF_DESC, token) || !get_coded_index_token (TYPEDEF_OR_REF_DESC, token)) FAIL (ctx, g_strdup_printf ("GenericInst: invalid TypeDefOrRef token %x", token)); if (ctx->token) { @@ -1303,6 +1303,9 @@ parse_generic_inst (VerifyContext *ctx, const char **_ptr, const char *end) FAIL (ctx, g_strdup ("GenericInst: Zero arguments generic instance")); for (i = 0; i < count; ++i) { + if (!parse_custom_mods (ctx, &ptr, end)) + FAIL (ctx, g_strdup ("Type: Failed to parse pointer custom attr")); + if (!parse_type (ctx, &ptr, end)) FAIL (ctx, g_strdup_printf ("GenericInst: invalid generic argument %d", i + 1)); } @@ -1346,7 +1349,7 @@ parse_type (VerifyContext *ctx, const char **_ptr, const char *end) if (!safe_read_cint (token, ptr, end)) FAIL (ctx, g_strdup ("Type: Not enough room for the type token")); - if (!is_valid_coded_index (ctx, TYPEDEF_OR_REF_DESC, token)) + if (!is_valid_coded_index (ctx, TYPEDEF_OR_REF_DESC, token) || !get_coded_index_token (TYPEDEF_OR_REF_DESC, token)) FAIL (ctx, g_strdup_printf ("Type: invalid TypeDefOrRef token %x", token)); if (!get_coded_index_token (TYPEDEF_OR_REF_DESC, token)) @@ -1436,8 +1439,11 @@ parse_param (VerifyContext *ctx, const char **_ptr, const char *end) } //it's a byref, update the cursor ptr - if (type == MONO_TYPE_BYREF) + if (type == MONO_TYPE_BYREF) { *_ptr = ptr; + if (!parse_custom_mods (ctx, _ptr, end)) + return FALSE; + } return parse_type (ctx, _ptr, end); } @@ -1526,6 +1532,8 @@ parse_property_signature (VerifyContext *ctx, const char **_ptr, const char *end FAIL (ctx, g_strdup ("PropertySig: Could not parse property type")); for (i = 0; i < param_count; ++i) { + if (!parse_custom_mods (ctx, &ptr, end)) + FAIL (ctx, g_strdup ("Type: Failed to parse pointer custom attr")); if (!parse_type (ctx, &ptr, end)) FAIL (ctx, g_strdup_printf ("PropertySig: Error parsing arg %d", i)); } @@ -1644,6 +1652,20 @@ is_valid_method_signature (VerifyContext *ctx, guint32 offset) return parse_method_signature (ctx, &ptr, end, FALSE, FALSE); } +static gboolean +is_valid_memberref_method_signature (VerifyContext *ctx, guint32 offset) +{ + guint32 size = 0; + const char *ptr = NULL, *end; + + if (!decode_signature_header (ctx, offset, &size, &ptr)) + FAIL (ctx, g_strdup ("MemberRefSig: Could not decode signature header")); + end = ptr + size; + + return parse_method_signature (ctx, &ptr, end, TRUE, FALSE); +} + + static gboolean is_valid_method_or_field_signature (VerifyContext *ctx, guint32 offset) { @@ -1856,6 +1878,8 @@ handle_enum: klass = get_enum_by_encoded_name (ctx, &ptr, end); if (!klass) return FALSE; + } else if (etype == 0x50 || etype == MONO_TYPE_CLASS) { + klass = mono_defaults.systemtype_class; } else if ((etype >= MONO_TYPE_BOOLEAN && etype <= MONO_TYPE_STRING) || etype == 0x51) { simple_type.type = etype == 0x51 ? MONO_TYPE_OBJECT : etype; klass = mono_class_from_mono_type (&simple_type); @@ -1983,6 +2007,8 @@ is_valid_cattr_content (VerifyContext *ctx, MonoMethod *ctor, const char *ptr, g klass = get_enum_by_encoded_name (ctx, &ptr, end); if (!klass) return FALSE; + } else if (etype == 0x50 || etype == MONO_TYPE_CLASS) { + klass = mono_defaults.systemtype_class; } else if ((etype >= MONO_TYPE_BOOLEAN && etype <= MONO_TYPE_STRING) || etype == 0x51) { simple_type.type = etype == 0x51 ? MONO_TYPE_OBJECT : etype; klass = mono_class_from_mono_type (&simple_type); @@ -2115,6 +2141,8 @@ is_valid_methodspec_blob (VerifyContext *ctx, guint32 offset) FAIL (ctx, g_strdup ("MethodSpec: Zero generic argument count")); for (i = 0; i < count; ++i) { + if (!parse_custom_mods (ctx, &ptr, end)) + return FALSE; if (!parse_type (ctx, &ptr, end)) FAIL (ctx, g_strdup_printf ("MethodSpec: Could not parse parameter %d", i + 1)); } @@ -2406,6 +2434,9 @@ verify_typedef_table (VerifyContext *ctx) if (data [MONO_TYPEDEF_EXTENDS] && !is_valid_coded_index (ctx, TYPEDEF_OR_REF_DESC, data [MONO_TYPEDEF_EXTENDS])) ADD_ERROR (ctx, g_strdup_printf ("Invalid typedef row %d extend field coded index 0x%08x", i, data [MONO_TYPEDEF_EXTENDS])); + if (data [MONO_TYPEDEF_EXTENDS] && !get_coded_index_token (TYPEDEF_OR_REF_DESC, data [MONO_TYPEDEF_EXTENDS])) + ADD_ERROR (ctx, g_strdup_printf ("Invalid typedef row %d zero coded extend field coded index 0x%08x", i, data [MONO_TYPEDEF_EXTENDS])); + visibility = data [MONO_TYPEDEF_FLAGS] & TYPE_ATTRIBUTE_VISIBILITY_MASK; if ((visibility >= TYPE_ATTRIBUTE_NESTED_PUBLIC && visibility <= TYPE_ATTRIBUTE_NESTED_FAM_OR_ASSEM) && search_sorted_table (ctx, MONO_TABLE_NESTEDCLASS, MONO_NESTED_CLASS_NESTED, i + 1) == -1) @@ -2558,7 +2589,7 @@ verify_field_table_full (VerifyContext *ctx) } /*bits 8,9,10,11,13,14,15*/ -#define INVALID_METHOD_IMPLFLAG_BITS ((1 << 8) | (1 << 9) | (1 << 10) | (1 << 11) | (1 << 13) | (1 << 14) | (1 << 15)) +#define INVALID_METHOD_IMPLFLAG_BITS ((1 << 9) | (1 << 10) | (1 << 11) | (1 << 13) | (1 << 14) | (1 << 15)) static void verify_method_table (VerifyContext *ctx) { @@ -2654,8 +2685,8 @@ verify_method_table (VerifyContext *ctx) //TODO check signature contents if (rva) { - if (flags & METHOD_ATTRIBUTE_ABSTRACT) - ADD_ERROR (ctx, g_strdup_printf ("Invalid method row %d has RVA != 0 but is Abstract", i)); + if ((flags & (METHOD_ATTRIBUTE_ABSTRACT | METHOD_ATTRIBUTE_PINVOKE_IMPL)) || (implflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL)) + ADD_ERROR (ctx, g_strdup_printf ("Invalid method row %d has RVA != 0 but is either Abstract, InternalCall or PinvokeImpl", i)); if (code_type == METHOD_IMPL_ATTRIBUTE_OPTIL) ADD_ERROR (ctx, g_strdup_printf ("Invalid method row %d has RVA != 0 but is CodeTypeMask is neither Native, CIL or Runtime", i)); } else { @@ -2795,7 +2826,7 @@ verify_interfaceimpl_table (VerifyContext *ctx) for (i = 0; i < table->rows; ++i) { mono_metadata_decode_row (table, i, data, MONO_INTERFACEIMPL_SIZE); if (data [MONO_INTERFACEIMPL_CLASS] && data [MONO_INTERFACEIMPL_CLASS] > ctx->image->tables [MONO_TABLE_TYPEDEF].rows) - ADD_ERROR (ctx, g_strdup_printf ("Invalid InterfaceImpl row %d Class field 0x%08x", i, data [MONO_TABLE_TYPEDEF])); + ADD_ERROR (ctx, g_strdup_printf ("Invalid InterfaceImpl row %d Class field 0x%08x", i, data [MONO_INTERFACEIMPL_CLASS])); if (!is_valid_coded_index (ctx, TYPEDEF_OR_REF_DESC, data [MONO_INTERFACEIMPL_INTERFACE])) ADD_ERROR (ctx, g_strdup_printf ("Invalid InterfaceImpl row %d Inteface field coded index 0x%08x", i, data [MONO_INTERFACEIMPL_INTERFACE])); @@ -2883,8 +2914,8 @@ verify_cattr_table (VerifyContext *ctx) if (!is_valid_coded_index (ctx, HAS_CATTR_DESC, data [MONO_CUSTOM_ATTR_PARENT])) ADD_ERROR (ctx, g_strdup_printf ("Invalid CustomAttribute row %d Parent field 0x%08x", i, data [MONO_CUSTOM_ATTR_PARENT])); - if (!is_valid_coded_index (ctx, CATTR_TYPE_DESC, data [MONO_CUSTOM_ATTR_TYPE])) - ADD_ERROR (ctx, g_strdup_printf ("Invalid CustomAttribute row %d Parent field 0x%08x", i, data [MONO_CUSTOM_ATTR_PARENT])); + if (!is_valid_coded_index (ctx, CATTR_TYPE_DESC, data [MONO_CUSTOM_ATTR_TYPE]) || !get_coded_index_token (CATTR_TYPE_DESC, data [MONO_CUSTOM_ATTR_TYPE])) + ADD_ERROR (ctx, g_strdup_printf ("Invalid CustomAttribute row %d Type field 0x%08x", i, data [MONO_CUSTOM_ATTR_TYPE])); if (data [MONO_CUSTOM_ATTR_VALUE] && !is_valid_blob_object (ctx, data [MONO_CUSTOM_ATTR_VALUE], 0)) ADD_ERROR (ctx, g_strdup_printf ("Invalid CustomAttribute row %d invalid value blob 0x%x", i, data [MONO_CUSTOM_ATTR_VALUE])); @@ -3250,7 +3281,7 @@ verify_moduleref_table (VerifyContext *ctx) mono_metadata_decode_row (table, i, data, MONO_MODULEREF_SIZE); if (!is_valid_non_empty_string (ctx, data[MONO_MODULEREF_NAME])) - ADD_ERROR (ctx, g_strdup_printf ("Invalid MethodImpl row %d Class field %08x", i, data [MONO_TABLE_TYPEDEF])); + ADD_ERROR (ctx, g_strdup_printf ("Invalid ModuleRef row %d name field %08x", i, data [MONO_MODULEREF_NAME])); } } @@ -3338,7 +3369,7 @@ verify_fieldrva_table (VerifyContext *ctx) } } -#define INVALID_ASSEMBLY_FLAGS_BITS ~((1 << 0) | (1 << 4) | (1 << 8) | (1 << 14) | (1 << 15)) +#define INVALID_ASSEMBLY_FLAGS_BITS ~((1 << 0) | (1 << 4) | (1 << 5) | (1 << 6) | (1 << 7) | (1 << 8) | (1 << 14) | (1 << 15)) static void verify_assembly_table (VerifyContext *ctx) { @@ -3370,7 +3401,7 @@ verify_assembly_table (VerifyContext *ctx) } } -#define INVALID_ASSEMBLYREF_FLAGS_BITS ~(1) +#define INVALID_ASSEMBLYREF_FLAGS_BITS ~((1 << 0) | (1 << 8) | (1 << 14) | (1 << 15)) static void verify_assemblyref_table (VerifyContext *ctx) { @@ -3599,7 +3630,7 @@ verify_generic_param_constraint_table (VerifyContext *ctx) mono_metadata_decode_row (table, i, data, MONO_GENPARCONSTRAINT_SIZE); if (!data [MONO_GENPARCONSTRAINT_GENERICPAR] || data [MONO_GENPARCONSTRAINT_GENERICPAR] > ctx->image->tables [MONO_TABLE_GENERICPARAM].rows) - ADD_ERROR (ctx, g_strdup_printf ("GenericParamConstraint table row %d has invalid Owner token %08x", i, data [MONO_TABLE_GENERICPARAM])); + ADD_ERROR (ctx, g_strdup_printf ("GenericParamConstraint table row %d has invalid Owner token %08x", i, data [MONO_GENPARCONSTRAINT_GENERICPAR])); if (!is_valid_coded_index (ctx, TYPEDEF_OR_REF_DESC, data [MONO_GENPARCONSTRAINT_CONSTRAINT])) ADD_ERROR (ctx, g_strdup_printf ("GenericParamConstraint table row %d has invalid Constraint token %08x", i, data [MONO_GENPARCONSTRAINT_CONSTRAINT])); @@ -4019,7 +4050,22 @@ mono_verifier_verify_method_signature (MonoImage *image, guint32 offset, MonoErr } gboolean -mono_verifier_verify_memberref_signature (MonoImage *image, guint32 offset, GSList **error_list) +mono_verifier_verify_memberref_method_signature (MonoImage *image, guint32 offset, GSList **error_list) +{ + VerifyContext ctx; + + if (!mono_verifier_is_enabled_for_image (image)) + return TRUE; + + init_verify_context (&ctx, image, error_list != NULL); + ctx.stage = STAGE_TABLES; + + is_valid_memberref_method_signature (&ctx, offset); + return cleanup_context (&ctx, error_list); +} + +gboolean +mono_verifier_verify_memberref_field_signature (MonoImage *image, guint32 offset, GSList **error_list) { VerifyContext ctx; @@ -4029,7 +4075,7 @@ mono_verifier_verify_memberref_signature (MonoImage *image, guint32 offset, GSLi init_verify_context (&ctx, image, error_list != NULL); ctx.stage = STAGE_TABLES; - is_valid_method_or_field_signature (&ctx, offset); + is_valid_field_signature (&ctx, offset); return cleanup_context (&ctx, error_list); } @@ -4238,14 +4284,14 @@ mono_verifier_verify_methodimpl_row (MonoImage *image, guint32 row, MonoError *e mono_metadata_decode_row (table, row, data, MONO_METHODIMPL_SIZE); body = method_from_method_def_or_ref (image, data [MONO_METHODIMPL_BODY], NULL); - if (mono_loader_get_last_error ()) { + if (!body || mono_loader_get_last_error ()) { mono_loader_clear_error (); mono_error_set_bad_image (error, image, "Invalid methodimpl body for row %x", row); return FALSE; } declaration = method_from_method_def_or_ref (image, data [MONO_METHODIMPL_DECLARATION], NULL); - if (mono_loader_get_last_error ()) { + if (!declaration || mono_loader_get_last_error ()) { mono_loader_clear_error (); mono_error_set_bad_image (error, image, "Invalid methodimpl declaration for row %x", row); return FALSE; @@ -4318,12 +4364,6 @@ mono_verifier_verify_method_signature (MonoImage *image, guint32 offset, MonoErr return TRUE; } -gboolean -mono_verifier_verify_memberref_signature (MonoImage *image, guint32 offset, GSList **error_list) -{ - return TRUE; -} - gboolean mono_verifier_verify_standalone_signature (MonoImage *image, guint32 offset, GSList **error_list) { @@ -4381,4 +4421,16 @@ mono_verifier_verify_methodimpl_row (MonoImage *image, guint32 row, MonoError *e return TRUE; } +gboolean +mono_verifier_verify_memberref_method_signature (MonoImage *image, guint32 offset, GSList **error_list) +{ + return TRUE; +} + +gboolean +mono_verifier_verify_memberref_field_signature (MonoImage *image, guint32 offset, GSList **error_list) +{ + return TRUE; +} + #endif /* DISABLE_VERIFIER */