CA2138: Transparent methods must not call methods with the SuppressUnmanagedCodeSecurity attribute
TypeName |
TransparentMethodsMustNotCallSuppressUnmanagedCodeSecurityMethods |
CheckId |
CA2138 |
Category |
Microsoft.Security |
Breaking Change |
Breaking |
Cause
A security transparent method calls a method that is marked with the SuppressUnmanagedCodeSecurityAttribute attribute.
Rule Description
This rule fires on any transparent method that calls directly into native code, for example, by using a via a P/Invoke (platform invoke) call. P/Invoke and COM interop methods that are marked with the SuppressUnmanagedCodeSecurityAttribute attribute result in a LinkDemand being done against the calling method. Because security transparent code cannot satisfy LinkDemands, the code also cannot call methods that are marked with the SuppressUnmanagedCodeSecurity attribute, or methods of class that is marked with SuppressUnmanagedCodeSecurity attribute. The method will fail, or the demand will be converted to a full demand.
Violations of this rule lead to a MethodAccessException in the Level 2 security transparency model, and a full demand for UnmanagedCode in the Level 1 transparency model.
How to Fix Violations
To fix a violation of this rule, remove the SuppressUnmanagedCodeSecurityAttribute attribute and mark the method with the SecurityCriticalAttribute or the SecuritySafeCriticalAttribute attribute.
When to Suppress Warnings
Do not suppress a warning from this rule.
Example
using System;
using System.Runtime.InteropServices;
using System.Security;
namespace TransparencyWarningsDemo
{
public class CallSuppressUnmanagedCodeSecurityClass
{
[SuppressUnmanagedCodeSecurity]
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool Beep(uint dwFreq, uint dwDuration);
public void CallNativeMethod()
{
// CA2138 violation - transparent method calling a method marked with SuppressUnmanagedCodeSecurity
// (this is also a CA2149 violation as well, since this is a P/Invoke and not an interface call).
Beep(10000, 1);
}
}
}