Description
In the process of developing signature parsing facilities for System.Reflection.Metadata, I came across some discrepancies in the CLI specification vs. various signature parsing implementations.
My notes on that are here: dotnet/corefx#5435
One such discrepancy is that the specification states that the encoded token following CMOD_OPT/CMOD_REQ is a TypeDef or TypeRef, but it can be TypeSpec in practice.
This opens up a loophole to cycles as TypeSpecs can contain modifiers, and modifiers can contain TypeSpecs. I put together some quick code to create such bad TypeSpecs here in https://github.com/nguerrera/signature-repros and experimented with ilasm, peverify, and running the resulting programs.
Repro steps
- git clone https://github.com/nguerrera/signature-repros
- cd signature-repros
- build.bat
- ildasm SignatureCycle1.exe
- peverify SignatureCycle1.exe
- SignatureCycle1.exe
- repeat steps 4-6 for SignatureCycle2.exe and SignatureCycle3.exe
Expected results
For all 3 programs:
- ildasm succeeds, but indicates a bad signature as it does in other cases.
- peverify reports the signature as invalid
If the particular program causes the runtime to have to inspect the bad modifiers contents rather than just skip the bad typespec token:
- An appropriate BadImageFormat/InvalidProgram/TypeLoadException is raised.
Actual results
- ildasm crashes in all 3 cases
- peverify sometimes succeeds without error, sometimes crashes
- program sometimes crashes with stack overflow rather than a meaningful BadImageFormat/InvalidProgram/TypeLoadException.