Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.

Enable ILLinkClearInitLocals across corefx #34406

Merged
merged 5 commits into from Jan 9, 2019

Conversation

stephentoub
Copy link
Member

@stephentoub stephentoub commented Jan 7, 2019

Enabled for all projects except tests and VB (where we can't use spans anyway).

There's a chance there's still something uninitialized that needs to be that's slipped through, but I've done a bunch of outerloop test runs on both Windows and Linux and so hopefully have caught the vast majority (there were just a few, which I knew about as well from when looking at this previously).

cc: @ViktorHofer, @jkotas, @danmosemsft, @bartonjs, @safern
Fixes https://github.com/dotnet/corefx/issues/26939

Directory.Build.props Outdated Show resolved Hide resolved
@@ -85,6 +85,7 @@ public static void DecodeObject(this byte[] encoded, CryptDecodeObjectStructType
throw Marshal.GetLastWin32Error().ToCryptographicException();

byte* decoded = stackalloc byte[cb];
new Span<byte>(decoded, cb).Clear();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this actually needed for CryptDecodeObjectPointer here, or is this just a "defense in depth"?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Strangely it was actually needed and I didn't invest heavily in figuring out why.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Which case was it needed? (I am worried that there is a bug that this is masking.)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Which case was it needed? (I am worried that there is a bug that this is masking.)

This one, L88. Without this Clear call, this test fails:

      System.Security.Cryptography.X509Certificates.Tests.ExtensionsTests.KeyUsageExtension_BER [FAIL]
        Assert.Equal() Failure
        Expected: DigitalSignature
        Actual:   69402752
        Stack Trace:
          d:\repos\corefx\src\System.Security.Cryptography.X509Certificates\tests\ExtensionsTests.cs(199,0): at System.Security.Cryptography.X509Certificates.Tests.ExtensionsTests.KeyUsageExtension_BER()

(Of course, the other two Clear calls I added might also be working around some issue, but removing them doesn't cause any test failures.)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bartonjs Is it intentional that the X509_KEY_USAGE is set as 16-bit int, but read as 32-bit int?

vs.

We are reading a memory that is not getting set by the decode API. It just happens when we clear the memory ourselves upfront, everything works fine.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably not. Desktop introduced the asymmetry (https://referencesource.microsoft.com/#System/security/system/security/cryptography/x509/x509extension.cs,124), probably back in net20; but it copied into a local buffer. During the port to core the code must have gotten "simplified" and since it worked it has been running since.

I don't know if the Windows implementation will always report cbData as 2 (making reading as a ushort* fine), or if they report 0/1 when the data is smaller.

Since DigitalSignature is in the low byte this could be easily validated with reading via ushort* and adding in a stopgap of span.Fill(0xFF) instead of span.Clear()

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since DigitalSignature is in the low byte this could be easily validated with reading via ushort* and adding in a stopgap of span.Fill(0xFF) instead of span.Clear()

Since this is pre-existing and since you're in the best position Jeremy to figure out the right fix here, I'm going to open an issue and go ahead with this change including the Clears, which can then hopefully be removed subsequently.

Enable it for all C# src projects.
Simplifies BitHelper, basing it on span instead of having to accomodate both pointers and arrays, and avoids allocating the BitHelper instance.  We now also clear the input optionally.
@stephentoub
Copy link
Member Author

@dotnet-bot test Windows x64 Debug Build please

@stephentoub
Copy link
Member Author

@dotnet-bot test Outerloop Linux x64 Release Build please

1 similar comment
@stephentoub
Copy link
Member Author

@dotnet-bot test Outerloop Linux x64 Release Build please

@stephentoub stephentoub merged commit b26339b into dotnet:master Jan 9, 2019
@stephentoub stephentoub deleted the clearlocals branch January 9, 2019 01:22
@karelz karelz added this to the 3.0 milestone Mar 18, 2019
picenka21 pushed a commit to picenka21/runtime that referenced this pull request Feb 18, 2022
Enable ILLinkClearInitLocals across corefx

Commit migrated from dotnet/corefx@b26339b
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
6 participants