Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ILVerify falsely reports a field being modified #102997

Closed
masonwheeler opened this issue Jun 3, 2024 · 8 comments
Closed

ILVerify falsely reports a field being modified #102997

masonwheeler opened this issue Jun 3, 2024 · 8 comments
Labels
area-Tools-ILVerification Issues related to ilverify tool and IL verification in general help wanted [up-for-grabs] Good issue for external contributors
Milestone

Comments

@masonwheeler
Copy link
Contributor

masonwheeler commented Jun 3, 2024

Description

ILVerify is usually pretty good at finding invalid IL in your code. But I've stumbled across something that's either a false positive or a bug in Roslyn's C# codgen, and I'm guessing it's the former, because the error message does not match what's in either the C# code or the decompiled CIL. (If this is actually a Roslyn problem, let me know and I'll refile this bug on the Roslyn repo.)

Reproduction Steps

Build the following, then examine the resulting DLL in ILVerify

using System.Reflection.Emit;

namespace CorruptRoslynCodegen
{
	internal class Program
	{
		static void Main(string[] args)
		{
			Console.WriteLine("Hello, World!");
		}

		protected static bool IsStobj(OpCode code)
		{
			return OpCodes.Stobj.Value == code.Value;
		}
	}
}

Expected behavior

As the flagship .NET language, it's expected that the official C# compiler does not produce invalid IL.

It is also expected that official IL verification tools do not report invalid IL where none exists.

Actual behavior

[IL]: Error [InitOnly]: [C:...\CorruptRoslynCodegen.dll : CorruptRoslynCodegen.Program::IsStobj([S.P.CoreLib]System.Reflection.Emit.OpCode)][offset 0x00000001] Cannot change initonly field outside its .ctor.

Regression?

No response

Known Workarounds

No response

Configuration

.NET 9, most recent daily build as of 6/3/2024
Windows 10, x64

Other information

No response

@dotnet-issue-labeler dotnet-issue-labeler bot added the needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners label Jun 3, 2024
@dotnet-policy-service dotnet-policy-service bot added the untriaged New issue has not been triaged by the area owner label Jun 3, 2024
@vcsjones vcsjones added area-Tools-ILVerification Issues related to ilverify tool and IL verification in general and removed needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners labels Jun 3, 2024
Copy link
Contributor

Tagging subscribers to this area: @JulieLeeMSFT
See info in area-owners.md if you want to be subscribed.

@MichalStrehovsky
Copy link
Member

The message could be better (it matches peverify.exe per dotnet/corert#4911 though), but the gist is that ILVerify checks whether the input is verifiable and ldsflda with an initonly field is documented as not verifiable in the ECMA-335 spec. We track adding a weaker mode to ILVerify that checks for valid IL in #37391.

Roslyn generates ldsflda because the OpCode struct is marked readonly and therefore this doesn't violate C# type safety rules. But the code is unverifiable and ILVerify will warn.

@masonwheeler
Copy link
Contributor Author

So basically, the ldsflda sets things up to that further down the line, something else could violate type safety, but nothing is actually doing so?

@jkotas
Copy link
Member

jkotas commented Jun 4, 2024

ILVerify implements .NET Framework 4.0 set of verification rules. These rules were not officially amended for the new constructs such as readonly structs and methods in this case. We would be happy to merge changes to amend the verification rules for the new constructs such as this one.

@jkotas jkotas added help wanted [up-for-grabs] Good issue for external contributors and removed untriaged New issue has not been triaged by the area owner labels Jun 4, 2024
@jkotas jkotas added this to the Future milestone Jun 4, 2024
@masonwheeler
Copy link
Contributor Author

These rules were not officially amended for the new constructs such as readonly structs and methods in this case.

Are those rules unofficially described anywhere besides compiler source code?

@jkotas
Copy link
Member

jkotas commented Jun 4, 2024

The theoretical verification rules are sometimes discussed in the C# design notes: https://github.com/search?q=repo%3Adotnet%2Fcsharplang%20verification . I do not see the discussion for this specific case.

I think the rules for this specific case would be:

  • Introduce concept of readonly managed pointer (different from the existing controlled-mutability managed pointer)
  • Reads from readonly managed pointer, calling readonly methods, conversion of regular managed pointer to readonly managed pointer are verifiable
  • Writes to readonly managed pointer, conversion of readonly managed pointer to regular managed pointer are non-verifiable

@reflectronic
Copy link
Contributor

reflectronic commented Jun 5, 2024

@jkotas
Copy link
Member

jkotas commented Jun 5, 2024

Resolving as duplicate of #57444

@jkotas jkotas closed this as completed Jun 5, 2024
@github-actions github-actions bot locked and limited conversation to collaborators Jul 6, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-Tools-ILVerification Issues related to ilverify tool and IL verification in general help wanted [up-for-grabs] Good issue for external contributors
Projects
None yet
Development

No branches or pull requests

5 participants