Skip to content

VerificationException due to read-only struct use #27382

Open

Description

Related issues:

These are all closed, and as this is a pretty nasty and hard-to-track-down issue (you only find out it's a problem when running from full framework, and it's not at all obvious what causes it) I thought it better to raise the issue than stay quiet...

Version Used: Visual Studio 15.7.3; from the command line, csc reports version 2.8.3.62923 (7aafab5)

Steps to Reproduce:

  1. Create a class library targeting just .NET Standard 2.0

Project:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
    <LangVersion>7.3</LangVersion>
    <!--<Features>peverify-compat</Features> -->
  </PropertyGroup>
</Project>

Code:

[assembly: System.Security.AllowPartiallyTrustedCallers]

namespace Library
{
    public readonly struct OuterStruct
    {
        private readonly ValueHolder implementation;

        public int Value => implementation.Value;

        public OuterStruct(int value) => implementation = new ValueHolder(value);
    }

    internal readonly struct ValueHolder
    {
        internal int Value { get; }

        internal ValueHolder(int value) => Value = value;
    }
}
  1. Create a console app targeting the full framework, with a reference:

Project file:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net461</TargetFramework>
  </PropertyGroup>
  <ItemGroup>
    <ProjectReference Include="..\Library\Library.csproj" />
  </ItemGroup>
</Project>

Code:

using Library;
using System;

namespace ConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            var outer = new OuterStruct(100);
            Console.WriteLine(outer.Value);
        }
    }
}
  1. Run!

Expected Behavior:

Prints 100.

Actual Behavior:

Unhandled Exception: System.Security.VerificationException: Operation could destabilize the runtime.
   at Library.OuterStruct.get_Value()
   at ConsoleApp.Program.Main(String[] args)

Workarounds:

  • Remove AllowPartiallyTrustedCallers
  • Use the peverify-compat feature

What I would like to see:

  • A warning when the compiler detects that it's emitting non-verifiable code that could easily break full frameworks calling it
  • A good docs page that gives guidance to library developers as to which of these workarounds to use

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions