Skip to content

Conversation

@ViktorHofer
Copy link
Member

@ViktorHofer ViktorHofer commented Aug 20, 2021

Fixes #54341

This issue was discovered in dotnet/aspnetcore#33571 (comment) by @dougbu, @wtgodbe and @ericstj.
Note that this change won't be ported into main as the System.Security.AccessControl package won't ship after 6.0 anymore as the library is now part of the shared framework. The reason why this package needs to be brought back for 6.0 is that aspnetcore depends on S.S.Cryptography.Xml which either depends on S.S.AccessControl or S.S.Permissions. As the latter is undesirable to reference, the former is chosen as a dependency. Going forward, S.S.Cryptography.Xml will continue to reference the last shipped 6.0.* version of S.S.AccessControl and doesn't require it to be built live.

Customer Impact

Customers transitively reference System.Security.Permissions (Legacy) with its large closure of assemblies when consuming System.Security.Cryptography.Xml (non-legacy) or some of the AspNetCore packages which expose it. When referencing matching https://www.nuget.org/packages/Microsoft.AspNetCore.DataProtection/6.0.0-preview.7.21378.6 to what is in the shared framework, that assembly will be dropped, yet SSP and it’s closure will go app-local and increase the app's foot print.

Testing

Automated testing via a) the PackageTesting SDK component that checks if assets are compatible with each other and b) the repo local testPackages infrastructue that restore the generated packages on tfms and checks if the packages are consumable.
Manually tested as well by creating the package and validating its output.

Risk

Low - The package already existed before and the automated package testing covers the consumption of the package on the consumer's end.

@ghost
Copy link

ghost commented Aug 20, 2021

Tagging subscribers to this area: @Anipik, @safern, @ViktorHofer
See info in area-owners.md if you want to be subscribed.

Issue Details

Fixes #54341

@ericstj as we don't want this in main (7.0), I'm not back porting anything but directly targeting 6.0-rc1. What bar do we apply to this change? Is this something for Tactics or M2 approval?

Author: ViktorHofer
Assignees: -
Labels:

area-Infrastructure-libraries, new-api-needs-documentation

Milestone: -

@ViktorHofer ViktorHofer changed the title Bring back System.Threading.AccessControl package [release/6.0-rc1] Bring back System.Threading.AccessControl package Aug 20, 2021
@dotnet dotnet deleted a comment Aug 20, 2021
@ViktorHofer ViktorHofer changed the title [release/6.0-rc1] Bring back System.Threading.AccessControl package [release/6.0-rc1] Bring back System.Security.AccessControl package Aug 20, 2021
@ericstj
Copy link
Member

ericstj commented Aug 20, 2021

@ericstj as we don't want this in main (7.0)

You might want some of this in main. The parts that get System.Security.Permissions out of our references for the other crypto packages. Agreed that will look different and will require the final 6.0 packages, please file a follow up issue to do that.

What bar do we apply to this change?

For RC1 we need tactics approval, for RC2 it's M2 approval. Apply the bug bar from @jeffhandley's mail. Make sure to add the template to the PR.

@danmoseley
Copy link
Member

RC1 bar high now. Probably if you back port it would be to RC2. Would need template.

@ViktorHofer
Copy link
Member Author

RC1 bar high now. Probably if you back port it would be to RC2. Would need template.

Yes, absolutely. I plan to re-target to RC2 when the change is ready.

@ViktorHofer ViktorHofer force-pushed the AddBackSystemThreadingAccessControlPkg branch from 7197ed8 to c0d5e95 Compare August 27, 2021 07:59
@ViktorHofer ViktorHofer changed the base branch from release/6.0-rc1 to release/6.0 August 27, 2021 07:59
@ViktorHofer ViktorHofer changed the title [release/6.0-rc1] Bring back System.Security.AccessControl package [release/6.0] Bring back System.Security.AccessControl package Aug 27, 2021
@ViktorHofer ViktorHofer force-pushed the AddBackSystemThreadingAccessControlPkg branch from c0d5e95 to 18efc63 Compare August 27, 2021 08:42

<PropertyGroup>
<TargetFrameworks>$(NetCoreAppCurrent);net461</TargetFrameworks>
<TargetFrameworks>$(NetCoreAppCurrent);net461-windows</TargetFrameworks>
Copy link
Member

Choose a reason for hiding this comment

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

Can you explain the logic behind the changes on netfx configurations and why we are adding OS to some of them? Is the one here due to the package reference to a windows-only package?

Copy link
Member Author

Choose a reason for hiding this comment

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

Libraries which projectreference rid-specific libraries need to be rid-specific as well. In this case, all the libraries that I annotated incorrectly referenced the netstandard2.0 asset instead of the net461-windows asset. The technical reason behind that is that net461 can't reference net461-windows, so netstandard2.0 wins.

I discovered that when bringing back System.Security.AccessControl and had to make changes to use it as a live reference.

Copy link
Member

Choose a reason for hiding this comment

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

I see, this seems like a very fragile system when trying to get them correct. Should we instead do one of the following:

  • Transform all net461 configs to instead be net461-windows, that way all configurations are referencing the right live libs.
  • Add some build checks that check P2Ps when building netfx libs, and ensuring that we are not incorrectly getting a NS2.0 asset when the P2P also has a net461-windows asset.

Of course we don't have to fix it here, but I thought of bringing the suggestions here anyway

Copy link
Member Author

@ViktorHofer ViktorHofer Aug 31, 2021

Choose a reason for hiding this comment

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

I see, this seems like a very fragile system when trying to get them correct. Should we instead do one of the following:

Agree with this being a fragile design. It predates me, it existed for several years and apparently it worked just fine. Even though this is hard to get right without understanding RID compatibility rules, it's the closest / best implementation based on the rid graph.

Transform all net461 configs to instead be net461-windows, that way all configurations are referencing the right live libs.

Reason why we didn't do this yet is because of these two major downsides:

  • Making a tfm rid specific without also building a rid agnostic tfm of the same TargetFrameworkIdentifier results in packages having duplicated assets in the i.e. lib/net461/ and runtimes/win/lib/net461/ folders. For more information see
    <!-- Copy runtime specific assemblies into the rid agnostic 'lib' folder if the ridless tfm doesn't exist on .NETFramework.
    The assumption holds that a ridless tfm doesn't follow a '-' charater. This is necessary to avoid NU5128. -->
    <TfmSpecificPackageFile Include="@(TfmRuntimeSpecificPackageFile)"
    PackagePath="$([MSBuild]::ValueOrDefault('$(BuildOutputTargetFolder)', 'lib'))/$(TargetFrameworkWithoutSuffix)"
    Condition="'$(TargetFrameworkIdentifier)' == '.NETFramework' and !$([System.Text.RegularExpressions.Regex]::IsMatch('$(TargetFrameworks)', '$(TargetFrameworkWithoutSuffix)(?!-)'))" />
  • net461-windows is a tfm alias that nuget doesn't understand and the -windows part needs to be stripped from the target framework alias: https://github.com/dotnet/arcade/blob/761d2e6545a31d2ebf9cb60443ed2a9c2f8268b5/src/Microsoft.DotNet.Build.Tasks.TargetFramework.Sdk/src/build/Microsoft.DotNet.Build.Tasks.TargetFramework.Sdk.props#L21-L22. Adding the -windows rid to every .NETFramework tfm results in this hack being applied in many more places and more NuGet.config files being necessary to disable VS's restore which can't handle restoring them:
    <!-- This disables restore in VS for projects that target platform specific target frameworks older than net5.0. -->

Add some build checks that check P2Ps when building netfx libs, and ensuring that we are not incorrectly getting a NS2.0 asset when the P2P also has a net461-windows asset.

Correct me if I'm wrong but I believe the ProjectReference protocol doesn't expose the necessary information to implement such a check. Of course you could always implement custom targets and MSBuild calls but that won't work with static graph build which we want to leverage.

Copy link
Member

Choose a reason for hiding this comment

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

I see, this seems like a very fragile system when trying to get them correct.

I believe at one point package validation would catch any mistake here and would actually drive folks to do the right thing / teach them about the RID specific asset being preferred. Not sure if that's still the case.

Copy link
Member Author

Choose a reason for hiding this comment

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

I believe at one point package validation would catch any mistake here

@ericstj can you please elaborate on "at one point ... would catch any mistakes here"? Do you mean that the new PackageValidation infrastructure will eventually catch this in the future, did you refer the the old pkgproj system or to the runtime repo specific testPackages infra (which creates wrapper projects and restores the package)?

Copy link
Member Author

Choose a reason for hiding this comment

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

For the sake of this discussion, I filed #58495 to simplify .NETFramework tfms.

Copy link
Member

Choose a reason for hiding this comment

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

I'm talking about package testing that we run that consumes the nuget packages we build in a project. We would run that with RIDs on .NETFramework, so it would see duplicate runtime types in the case someone forgot to include a RID specific asset, and would see duplicate reference types if someone forgot the RID-less asset. I think we may still catch this today if we use the runtimeTargets on .NETFramework.

Previously we would also sometimes catch this in package build itself if the assembly versions differed (as is the case in servicing).

I added a comment to the issue about making sure we have test coverage of this scenario.

<?xml version="1.0" encoding="utf-8"?>
<Suppressions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
Copy link
Member

Choose a reason for hiding this comment

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

NIT: It might be good to test at least locally with the new PackageValidation logic how the diff looks like since this specific suppression will go away and instead you'll get the actual diffs after following type forwards.

@danmoseley
Copy link
Member

Approved for release/6.0: significant regression since 5.0 of footprint of aspnet shared framework. Per discussion offline, we've tested as best we can. Please address any feedback. also verify the result when it reaches aspnetcore repo (perhaps that will happen first in main)

@dougbu
Copy link
Contributor

dougbu commented Aug 31, 2021

@ViktorHofer with this, we'll be able to remove our previous workarounds for RC2❔ Should we eliminate our Microsoft.Win32.SystemEvents, System.Drawing.Common, System.Security.Permissions, or System.Windows.Extensions references going forward❔ We reference them mainly to ensure they do not end up in Microsoft.AspNetCore.App.* nor our targeting packs.

Separately, should we expect (and allow) System.Security.AccessControl to land in our targeting packs again❔ If yes, will we need Microsoft.Win32.Registry and System.Security.Principal.Windows again too❔ (We use 5.0.0 versions of the later two elsewhere and I expect that'll continue, right❔)

Copy link
Member

@ericstj ericstj left a comment

Choose a reason for hiding this comment

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

LGTM. It might make sense to review a package diff for any project touched here just to make sure you understand the changes and they are what you'd expect. You can also do a diff of S.S.ACL with the last version before the removal, so that it gets the same treatment as other pkgproj->csproj conversions.

@vitek-karas
Copy link
Member

For the linker issue: I think we should just not try to trim these generated not-supported assemblies. While we're probably going to fix this particular issue in the linker, there are other potential issues with these type of assemblies (as pointed out in dotnet/linker#2238 (comment)).

@ViktorHofer
Copy link
Member Author

LGTM. It might make sense to review a package diff for any project touched here just to make sure you understand the changes and they are what you'd expect.

If we are going to request nuspec / package diffs for any change that we might make in the future to packages we should invest in tooling that helps with that. At the moment this is a very manual process and takes time. I would imagine that PackageValidation could generate a nuspec diff based on the baseline version vs the just build package.

You can also do a diff of S.S.ACL with the last version before the removal, so that it gets the same treatment as other pkgproj->csproj conversions.

I compared the packages (including content and nuspec diffs) but didn't upload a diff (as mentioned, there's no automation available). Let me know if you want me to upload one, which I can most definitely do.

For the linker issue: I think we should just not try to trim these generated not-supported assemblies. While we're probably going to fix this particular issue in the linker, there are other potential issues with these type of assemblies (as pointed out in dotnet/linker#2238 (comment)).

Thanks Vitek. We have been trimming PNSEs for a quite a while now (as we don't differentiate between the "kind" of assembly) and we are close to shipping release/6.0. Do you think we should stop doing that even for 6.0?

@ericstj
Copy link
Member

ericstj commented Sep 1, 2021

I don’t need to see the diffs personally, just suggesting to test this as it can be helpful when making these types of changes and it was something we did in the past, especially when we wanted to communicate the risk level of a large change. The mechanism we used to use for this was to just rename the intermediate nuspec folder, apply the change, then build packages again, and diff the folders. It was a low cost check that only took ~5 minutes and often helped quickly illustrate the amount of change to the shipping product.

@ViktorHofer
Copy link
Member Author

It was a low cost check that only took ~5 minutes and often helped quickly illustrate the amount of change to the shipping product.

Let me share the process that I followed during the "pkgproj -> NuGet Pack task" migration. Let me say that generating and providing the diffs was actually what took the longest.

When I touch a package I usually verify packaging changes by doing the following:

  1. Generate the package and with it implicitly run PackageValidation.
  2. Open the baseline package (i.e. the last released preview / or the last nightly) in NuGet Package Explorer.
  3. Open the generated package in NuGet Package Explorer
  4. Diff the nuspec, especially the dependencies section and the package content.
  5. Optional: Generate and upload the nuspec diff

I personally use NuGet Package Explorer as it provides additional value i.e. checking for symbol files, sourcelink and compiler optimizations being present. The reason why I prefer a baseline package over a live build is that it lets me compare the applied change against the last shipped state.

@ViktorHofer ViktorHofer merged commit 56894f0 into dotnet:release/6.0 Sep 1, 2021
@ViktorHofer ViktorHofer deleted the AddBackSystemThreadingAccessControlPkg branch September 1, 2021 13:40
@vitek-karas
Copy link
Member

We have been trimming PNSEs for a quite a while now (as we don't differentiate between the "kind" of assembly) and we are close to shipping release/6.0. Do you think we should stop doing that even for 6.0?

I don't think this is something we should try to play with in 6 - as you said - too late...

dougbu added a commit to dotnet/aspnetcore that referenced this pull request Sep 3, 2021
@dougbu
Copy link
Contributor

dougbu commented Sep 3, 2021

You'll be able to do the same in main once main is able to pick up the System.Security.AccessControl package we're building 6.0.

Do you mean this change has not been merged into 'main' in this repo❔ I don't see it there but want to make sure this isn't about dependency flow into dotnet/aspnetcore.

@ericstj
Copy link
Member

ericstj commented Sep 3, 2021

For the effect of this change to occur in main we need to update our reference here

<ProjectReference Include="$(LibrariesProjectRoot)System.Security.Permissions\src\System.Security.Permissions.csproj" />

To use the 6.0.0 System.Security.AccessControl package. @ViktorHofer can you file an issue for that if you don't have one? Not sure that will happen naturally.

@ericstj
Copy link
Member

ericstj commented Sep 3, 2021

Actually, that makes me realize that this part might have been missed here. @ViktorHofer -- can you check that the crypto package that ASP.NET uses was updated to reference S.S.AcessControl instead of Permissions?

dougbu added a commit to dotnet/aspnetcore that referenced this pull request Sep 7, 2021
dougbu added a commit to dotnet/aspnetcore that referenced this pull request Sep 10, 2021
dougbu added a commit to dotnet/aspnetcore that referenced this pull request Sep 22, 2021
dougbu added a commit to dotnet/aspnetcore that referenced this pull request Sep 23, 2021
* [main] React to dotnet/runtime#57816 (#36155)
- `cherry-pick` e58a6c2
- see dotnet/runtime#57816 (comment)
- also reacting to dotnet/runtime#58731
- undo much of 18a61fb

* [main] Cleanup remaining SSP references (#36248)
- `cherry-pick` 888e03a
- remove references to System.Security.Permissions and its closure
  - only mentions are in eng/PackageOverrides.txt and eng/PlatformManifest.txt
  - those files will remain unused until we update them in the run-up to 6.0.1
  - may see some package refs for SSP and its closure elsewhere but this does not impact targeting pack content
- also remove duplication between `@(AspNetCoreReferenceAssemblyPath)` additions (for efficiency)

nit: Only need to exclude System.Net.Quic from `@(_AvailableRuntimeRefAssemblies)`
  - Crypto.Pkcs is **not** present in the transport package
  - other disallowed entries aren't present in the transport package or our dependency closure
@ghost ghost locked as resolved and limited conversation to collaborators Oct 3, 2021
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.

8 participants