[release/9.0-staging] JIT: fix bug in loop cloning with down-counting loops by github-actions[bot] · Pull Request #126913 · dotnet/runtime (original) (raw)

Backport of #126770 to release/9.0-staging

/cc @AndyAyersMS

Customer Impact

JIT optimizations can cause certain down-counting loops to bypass a bounds check. Code that normally would throw index out of bounds exceptions on an array store might instead corrupt the heap.

In particular the loop must have unknown upper bound and have a shape like:

for (int i = N; i > 0; i--) { a[i] = ...; }

and then be invoked in a context where N is exactly a.Length. The loop exiting predicate must be > and not >=.

In such cases the code will write to a[N] which is beyond the extent of a.

Customer impact is likely low. Correct behavior here is to throw an exception.

Regression

Introduced in .NET 7 with #67930.

Testing

Verified fix on repro case. SPMI had 132 method contexts with diffs from the fix change. Inspected a few and most either had redundant guards beforehand or else were only reading from the arrays.

Risk

Low, changes the code that decides at runtime if execution can use a "cloned" loop that omits bounds checks; now we are correctly cautious about running the fully checked loop.