|
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System.Linq;
using Mono.Cecil;
namespace Mono.Linker.Steps
{
public static class RemoveSecurity
{
public static void ProcessAssembly (AssemblyDefinition assembly, LinkContext context)
{
if (context.Annotations.GetAction (assembly) == AssemblyAction.Link) {
ClearSecurityDeclarations (assembly);
RemoveCustomAttributesThatAreForSecurity (assembly);
RemoveCustomAttributesThatAreForSecurity (assembly.MainModule);
foreach (var type in assembly.MainModule.Types)
ProcessType (type);
}
}
static void ProcessType (TypeDefinition type)
{
ClearSecurityDeclarations (type);
RemoveCustomAttributesThatAreForSecurity (type);
type.HasSecurity = false;
foreach (var field in type.Fields)
RemoveCustomAttributesThatAreForSecurity (field);
foreach (var method in type.Methods) {
ClearSecurityDeclarations (method);
RemoveCustomAttributesThatAreForSecurity (method);
method.HasSecurity = false;
}
foreach (var nested in type.NestedTypes)
ProcessType (nested);
}
static void ClearSecurityDeclarations (ISecurityDeclarationProvider provider)
{
if (provider.HasSecurityDeclarations)
provider.SecurityDeclarations.Clear ();
}
/// <summary>
/// We have to remove some security attributes, otherwise pe verify will complain that a type has HasSecurity = false
/// </summary>
/// <param name="provider"></param>
static void RemoveCustomAttributesThatAreForSecurity (ICustomAttributeProvider provider)
{
if (!provider.HasCustomAttributes)
return;
var attrsToRemove = provider.CustomAttributes.Where (IsCustomAttributeForSecurity).ToArray ();
foreach (var remove in attrsToRemove)
provider.CustomAttributes.Remove (remove);
}
static bool IsCustomAttributeForSecurity (CustomAttribute attr)
{
var attr_type = attr.AttributeType;
if (attr_type.Namespace == "System.Security") {
switch (attr_type.Name) {
case "SecurityCriticalAttribute":
case "SecuritySafeCriticalAttribute":
case "SuppressUnmanagedCodeSecurityAttribute":
case "DynamicSecurityMethodAttribute":
case "UnverifiableCodeAttribute":
case "AllowPartiallyTrustedCallersAttribute":
case "SecurityTransparentAttribute":
case "SecurityRulesAttribute":
return true;
}
}
return false;
}
}
}
|