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

Make parts of ResourceManager trimming safe #38432

Merged
merged 2 commits into from
Jul 6, 2020

Conversation

MichalStrehovsky
Copy link
Member

We'll need a feature switch to turn off support for the parts that read text strings out of resources to make this fully safe.

I got rid of the LazyInitializer because it's just extra overhead that is not buying anything, except making things impossible to statically analyze. There won't be races when it comes to reflection object...

We'll need a feature switch to turn off support for the parts that read text strings out of resources to make this fully safe.

I got rid of the LazyInitializer because it's just extra overhead that is not buying anything, except making things impossible to statically analyze. There won't be races when it comes to reflection object...
@Dotnet-GitSync-Bot
Copy link
Collaborator

I couldn't figure out the best area label to add to this PR. If you have write-permissions please help me learn by adding exactly one area label.

public ResourceManager(string baseName, Assembly assembly, Type? usingResourceSet)
public ResourceManager(string baseName, Assembly assembly,
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)]
Type? usingResourceSet)
Copy link
Member

Choose a reason for hiding this comment

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

Nit: indentation

Type.GetType("System.Runtime.Serialization.Formatters.Binary.BinaryFormatter, System.Runtime.Serialization.Formatters, Version=0.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a",
throwOnError: true)!;

if (s_binaryFormatterType == null)
Copy link
Member

Choose a reason for hiding this comment

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

Either delete the null check; or change this to Interlocked.CompareExchange to make sure the first one wins in thread-safe way.

Copy link
Member

Choose a reason for hiding this comment

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

Type.GetType with the same string always returns the same instance, right? So deleting the null check should be fine.

Copy link
Member Author

Choose a reason for hiding this comment

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

What is the thread safety concern? I got rid of the LazyInitializer because it looked like unnecessary ceremony for something that is inherently thread safe, but I would like to understand what it was trying to solve.

Copy link
Member

Choose a reason for hiding this comment

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

Here was past discussion around this: dotnet/coreclr#20907 (comment)

Copy link
Member

Choose a reason for hiding this comment

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

Type.GetType with the same string always returns the same instance, right?

Unless you manage to load multiple copies of the framework. We generally do not handle such situation well, so ignoring its existence should be ok.

What is the thread safety concern?

My concern was that the null check as it is written right now provides false sense of thread-safety. It is either unnecessary or a thread safety bug.

I agree that LazyInitializer is way too expensive for that it does in 99% cases.

@ghost
Copy link

ghost commented Jun 26, 2020

Tagging subscribers to this area: @tarekgh, @buyaa-n, @krwq
Notify danmosemsft if you want to be subscribed.

@eerhardt eerhardt requested a review from ericstj June 26, 2020 15:31
@@ -65,24 +67,47 @@ private object DeserializeObject(int typeIndex)
return graph;
}

// TODO: Remove this DynamicDependencyAttributes when https://github.com/mono/linker/issues/943 is fixed.
[DynamicDependency("Deserialize", "System.Runtime.Serialization.Formatters.Binary.BinaryFormatter", "System.Runtime.Serialization.Formatters")]
Copy link
Member

Choose a reason for hiding this comment

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

Note that today the BinaryFormatter type exists, and is empty in a default Blazor app. So this is going to make the app size larger.

We should implement a way to turn this behavior off. There are probably 2 levels that both could be done.

  1. Completely removing BinaryFormatter from an app, no matter where it is used. This was discussed in the feature-switch.md#security section of the design doc.
  2. Disallow deserialization in ResourceReader. The boolean is already there, we would just need to add a feature switch for it:
    if (!_permitDeserialization)
    {
    throw new NotSupportedException(SR.NotSupported_ResourceObjectSerialization);
    }

See the discussion here #32862 (comment)

cc @joperezr since he is already working in the Resources area for linking.

Copy link
Member Author

Choose a reason for hiding this comment

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

On a second thought, I should probably just remove this part of the change - if the BinarySerializer indeed gets used for something, after trimming, chances are pretty low that we would end up in a happy place. I'll instead tag this and a couple other places as RequiresUnreferencedCode to get rid of some of the warning noise and leave this for the feature switches to take care of.

Copy link
Member

@eerhardt eerhardt left a comment

Choose a reason for hiding this comment

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

LGTM

@MichalStrehovsky MichalStrehovsky merged commit c8a9942 into dotnet:master Jul 6, 2020
@MichalStrehovsky MichalStrehovsky deleted the res branch July 6, 2020 12:48
@ghost ghost locked as resolved and limited conversation to collaborators Dec 8, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants