Validate invalid base type declarations in ILVerify#129118
Conversation
|
Tagging subscribers to this area: @JulieLeeMSFT, @dotnet/jit-contrib |
|
@dotnet-policy-service agree |
| TypeSpecification typeSpecification = _module.MetadataReader.GetTypeSpecification(typeSpecificationHandle); | ||
| BlobReader signatureReader = _module.MetadataReader.GetBlobReader(typeSpecification.Signature); | ||
|
|
||
| if (signatureReader.ReadSignatureTypeCode() != SignatureTypeCode.GenericTypeInstance) | ||
| { | ||
| return false; | ||
| } | ||
|
|
||
| int genericTypeKind = signatureReader.ReadCompressedInteger(); | ||
| if (genericTypeKind != (int)SignatureTypeKind.Class) | ||
| { | ||
| return false; | ||
| } | ||
|
|
||
| EntityHandle genericTypeHandle = signatureReader.ReadTypeHandle(); | ||
| if (genericTypeHandle.Kind != HandleKind.TypeDefinition && | ||
| genericTypeHandle.Kind != HandleKind.TypeReference) | ||
| { | ||
| return false; | ||
| } |
There was a problem hiding this comment.
Is this any better than just calling _module.GetType(typeHandle)?
There was a problem hiding this comment.
I tried that locally again, using only _module.GetType(typeHandle) does not catch the #119536 repro. (ObjectTypeSpecBase_InvalidType_InvalidBaseType)
In the extends object case, _module.GetType(typeHandle) resolves the TypeSpec to System.Object, which loses the issue that the base type was encoded as an invalid TypeSpec in the extends clause.
There was a problem hiding this comment.
If you would like to check for invalid type specs, it should be done in the central location where typespecs are decoded so that it applies to all of them. The problem is not specific to base type.
There was a problem hiding this comment.
Thanks, I tried moving this into EcmaModule.GetType, but I don't think this check can be global.
EcmaModule.GetType is context-independent. A top-level built-in TypeSpec like ELEMENT_TYPE_OBJECT is invalid in a TypeDef extends clause, but it is not invalid in every context. For example, CoreCLR accepts stobj with a TypeSpec object token, and ILVerification already has a similar existing test case using stobj string ( [LoadStoreIndirectTests] StoreObject.ValidTypeToken).
Rejecting these TypeSpecs in EcmaModule.GetType would therefore make ILVerify reject IL that is accepted outside of base type declarations. I think this validation should stay in the base type verification path, where we know the token is being used as a class base type.
There was a problem hiding this comment.
TypeSpec with object token is invalid in every context according to the spec. Look for TypeSpecBlob grammar in ECMA-335.
ILVerify is meant to check for speced behavior. It is not meant to check for what CoreCLR happens to accept. The runtime often accepts more than what's allowed by the spec.
a03f2df to
87dc394
Compare
Fixes #119536
This adds ILVerify validation for invalid class base type declarations.
The original issue reports a case where ILAsm accepts a type declared with
extends object, but the resulting type cannot be loaded by the runtime.ILVerify previously accepted that assembly without reporting an error.
This change reports
InvalidBaseTypefor invalid base type declarations ratherthan special-casing only the exact
extends objectspelling.Tests added in
BaseTypeTests.il:ObjectTypeSpecBase_InvalidType_InvalidBaseTypeextends object.InvalidBaseType.NilBaseInterface_ValidType_ValidGenericClassTypeSpecBase_ValidType_ValidValueTypeBase_InvalidType_InvalidBaseTypeGenericValueTypeSpecBase_InvalidType_InvalidBaseType