-
Notifications
You must be signed in to change notification settings - Fork 4.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix SSP restoring in edge cases (#104820)
* Fix SSP restoring in edge cases There are edge cases when the SSP restoring for continuation after a catch handler completes doesn't work correctly. The problem is caused by the fact that we scan for the Rip of the frame handling the exception on the shadow stack to find where to restore it, and in those edge cases, the same address can be there multiple times and the first occurence is not the right one. For example, when an exception is thrown from a catch handler, it escapes the handler and the handler for the escaped exception is in the same method as the one that invoked the handler. This change fixes it by finding the SSP of the first managed frame where we search for the handler and then updating the SSP with every unwind. The SSP is stored in the REGDISPLAY. So when we reach the CallCatchFunclet, the REGDISPLAY contains the SSP to restore. There was also one more issue with restoring the SSP. I turned out that the incsspq instruction uses only the lowest 8 bits of the argument to increment the SSP, so the ClrRestoreNonVolatileContextWorker needs to have a loop that repeats that instruction in case we need to move it by more than 255 slots. * Fix linux x64 build * Fix release build REGDISPLAY size constant * Add regression test * Update src/tests/Regressions/coreclr/GitHub_104820/test104820.cs --------- Co-authored-by: Jan Vorlicek <jan.vorlicek@volny,cz> Co-authored-by: Jan Kotas <[email protected]>
- Loading branch information
1 parent
5677d92
commit 4f38f92
Showing
9 changed files
with
125 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
using System; | ||
using System.Runtime.CompilerServices; | ||
using Xunit; | ||
|
||
public class Test104820 | ||
{ | ||
// Test that SSP is updated properly when resuming after catch when the shadow stack | ||
// contains the instruction pointer of the resume frame multiple times and the SSP needs | ||
// to be restored to the location of one that's not the first one found on the shadow | ||
// stack. | ||
// This test fails with stack overflow of the shadow stack if the SSP is updated incorrectly. | ||
static void ShadowStackPointerUpdateTest(int depth) | ||
{ | ||
if (depth == 0) | ||
{ | ||
throw new Exception(); | ||
} | ||
|
||
for (int i = 0; i < 1000; i++) | ||
{ | ||
try | ||
{ | ||
try | ||
{ | ||
ShadowStackPointerUpdateTest(depth - 1); | ||
} | ||
catch (Exception) | ||
{ | ||
throw new Exception(); | ||
} | ||
} | ||
catch (Exception) when (depth == 100) | ||
{ | ||
} | ||
} | ||
} | ||
|
||
[Fact] | ||
public static void TestEntryPoint() | ||
{ | ||
ShadowStackPointerUpdateTest(100); | ||
} | ||
} |
11 changes: 11 additions & 0 deletions
11
src/tests/Regressions/coreclr/GitHub_104820/test104820.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
<PropertyGroup> | ||
<CLRTestPriority>1</CLRTestPriority> | ||
</PropertyGroup> | ||
<ItemGroup> | ||
<Compile Include="test104820.cs" /> | ||
</ItemGroup> | ||
<ItemGroup> | ||
<ProjectReference Include="$(TestSourceDir)Common/CoreCLRTestLibrary/CoreCLRTestLibrary.csproj" /> | ||
</ItemGroup> | ||
</Project> |