Fix IndexOutOfRangeException in ILVerify for invalid exception handler offsets#122056
Fix IndexOutOfRangeException in ILVerify for invalid exception handler offsets#122056
Conversation
Added specific error types with appropriate messages in commit 56fd7e9. Regarding tests: Creating tests for invalid exception region offsets that exceed code size is not feasible with IL assembly since ilasm validates offsets at assembly time. These scenarios would require crafting invalid binary data outside the assembler, which is beyond what the existing |
|
@copilot Please use -ERR command line option for ilasm to compile these tests. The command line option suppresses IL validation done by ilasm tool and allows it to produce invalid IL like the one required to test this code. |
|
@copilot The issue that this PR is trying to fix mentions a few more cases where similar checks are missing:
Please make sure that these are covered as well |
Added tests using the
|
Moved the
The fix in PR #63239 only modified ILImporter.Verify.cs and didn't address the shared ILImporter.cs code. This PR makes the fix in the shared |
|
@copilot Merge from main and resolve the conflicts |
I'm unable to pull branches from GitHub or resolve merge conflicts in my environment. Could you please merge from main and resolve the conflicts, or provide guidance on what specific conflicts need to be addressed? |
25b6322 to
ad6fd4f
Compare
|
Blocked by #122270 |
…r offsets Co-authored-by: agocke <515774+agocke@users.noreply.github.com> Co-authored-by: jkotas <6668460+jkotas@users.noreply.github.com>
ba4bb12 to
300c999
Compare
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Pull request overview
Fixes ILVerify/ILImporter robustness when encountering malformed IL exception handling (EH) metadata so the verifier reports a diagnostic instead of throwing IndexOutOfRangeException.
Changes:
- Added bounds validation for EH region offsets/lengths in shared
ILImporter.FindEHTargets(). - Introduced a new verifier error
EHClauseOutOfRangewith a corresponding resource string. - Updated ILVerification tests to emit malformed EH clauses (via
ilasm -ERR) to validate the new behavior.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| src/coreclr/tools/Common/TypeSystem/IL/ILImporter.cs | Adds EH bounds checks before creating basic blocks for try/filter/handler starts. |
| src/coreclr/tools/ILVerification/ILImporter.Verify.cs | Moves CodeSizeZero check earlier; adds ReportInvalidExceptionRegion() mapping to the new error. |
| src/coreclr/tools/ILVerification/VerifierError.cs | Adds EHClauseOutOfRange verifier error. |
| src/coreclr/tools/ILVerification/Strings.resx | Adds message string for EHClauseOutOfRange. |
| src/coreclr/tools/aot/ILCompiler.Compiler/IL/ILImporter.Scanner.cs | Adds scanner-side ReportInvalidExceptionRegion() implementation (throws InvalidProgramException). |
| src/coreclr/tools/ILVerification.Tests/ILTests/ExceptionRegionTests.ilproj | Adds -ERR to ilasm flags to allow numeric EH offsets for malformed cases. |
| src/coreclr/tools/ILVerification.Tests/ILTests/ExceptionRegionTests.il | Adds new malformed EH test methods expecting EHClauseOutOfRange. |
|
|
||
| void ReportInvalidExceptionRegion() | ||
| { | ||
| VerificationError(VerifierError.EHClauseOutOfRange); |
There was a problem hiding this comment.
ReportInvalidExceptionRegion() only reports an error and then allows verification to continue. With malformed EH clauses, later code still indexes _basicBlocks using the invalid FilterOffset/HandlerOffset (e.g., in StartImportingBasicBlock), which can still throw IndexOutOfRangeException. Consider making this path fatal for the method (e.g., abort method verification after reporting), or otherwise guarantee all later EH-related _basicBlocks[...] accesses are bounds-checked.
| VerificationError(VerifierError.EHClauseOutOfRange); | |
| VerificationError(VerifierError.EHClauseOutOfRange); | |
| AbortMethodVerification(); |
| //E_FIL_CONT_HND "Filter contains handler." | ||
| //E_FIL_CONT_FIL "Nested filters." | ||
| //E_FIL_GTEQ_CS "filter >= code size." | ||
| EHClauseOutOfRange, // Exception handling clause bounds outside code size. | ||
| FallthroughException, // Fallthrough the end of an exception block. |
There was a problem hiding this comment.
VerifierError is a public enum, and inserting EHClauseOutOfRange in the middle changes the numeric values of all subsequent members, which is a potential breaking change for any external consumers persisting/serializing these values. Prefer appending the new member at the end, or assign an explicit numeric value that preserves existing values.
🤖 Copilot Code Review — PR #122056Note This review was generated by Copilot and validated across multiple model families (Claude, GPT). Holistic AssessmentMotivation: The PR addresses a real, long-standing issue (#63227) — ILVerify crashes with Approach: Adding bounds validation in the shared Summary: Detailed Findings❌ Incomplete fix — crash path remains in
|
Fixes an issue where ILVerify throws
IndexOutOfRangeExceptionwhen processing malformed IL with invalid exception handler offsets. A diagnostic tool should provide helpful diagnostic information about the nature of errors encountered, not crash with boneheaded exceptions.Changes Made
FindEHTargets()in the sharedILImporter.cscode so all consumers benefitEHClauseOutOfRangeverifier error with message "Exception handling clause bounds outside code size."CodeSizeZerocheck to beginning ofVerify()method beforeFindBasicBlocks()to detect zero code size before any array accessesFixes #63227
Original prompt
This section details on the original issue you should resolve
<issue_title>Bad data can cause ILVerify to throw IndexOutOfRangeException</issue_title>
<issue_description>### Description
While attempting to use ILVerify to diagnose a compiler output problem, it instead blew up in my face, dumping an
IndexOutOfRangeExceptionstack trace on me.Reproduction Steps
ilverify .\testcase.dll -r "C:\Program Files\dotnet\shared\Microsoft.NETCore.App\5.0.13\*.dll" -r "Boo.Lang.dll"(Adjust .NET 5 path as needed)Expected behavior
A correct program should not throw "boneheaded exceptions."
A diagnostic tool should provide helpful diagnostic information about the nature of errors encountered.
Actual behavior
Details
Configuration
.NET 5, Windows 10, x64</issue_description>
Comments on the Issue (you are @copilot in this section)
@ Tagging subscribers to this area: @JulieLeeMSFT See info in [area-owners.md](https://github.com/dotnet/runtime/blob/main/docs/area-owners.md) if you want to be subscribed.Issue Details
Description
While attempting to use ILVerify to diagnose a compiler output problem, it instead blew up in my face, dumping an
IndexOutOfRangeExceptionstack trace on me.Reproduction Steps
ilverify .\testcase.dll -r "C:\Program Files\dotnet\shared\Microsoft.NETCore.App\5.0.13\*.dll" -r "Boo.Lang.dll"(Adjust .NET 5 path as needed)Expected behavior
A correct program should not throw "boneheaded exceptions."
A diagnostic tool should provide helpful diagnostic information about the nature of errors encountered.
Actual behavior
Details
Configuration
.NET 5, Windows 10, x64
untriaged,area-ILVerification💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.