CA2101: Specify marshaling for P/Invoke string arguments

Note

This article applies to Visual Studio 2015. If you're looking for the latest Visual Studio documentation, see Visual Studio documentation. We recommend upgrading to the latest version of Visual Studio. Download it here

Item Value
TypeName SpecifyMarshalingForPInvokeStringArguments
CheckId CA2101
Category Microsoft.Globalization
Breaking Change Non-breaking

Cause

A platform invoke member allows for partially trusted callers, has a string parameter, and does not explicitly marshal the string.

Rule Description

When you convert from Unicode to ANSI, it is possible that not all Unicode characters can be represented in a specific ANSI code page. Best-fit mapping tries to solve this problem by substituting a character for the character that cannot be represented. The use of this feature can cause a potential security vulnerability because you cannot control the character that is chosen. For example, malicious code could intentionally create a Unicode string that contains characters that are not found in a particular code page, which are converted to file system special characters such as '..' or '/'. Note also that security checks for special characters frequently occur before the string is converted to ANSI.

Best-fit mapping is the default for the unmanaged conversion, WChar to MByte. Unless you explicitly disable best-fit mapping, your code might contain an exploitable security vulnerability because of this issue.

How to Fix Violations

To fix a violation of this rule, explicitly marshal string data types.

When to Suppress Warnings

Do not suppress a warning from this rule.

Example

The following example shows a method that violates this rule, and then shows how to fix the violation.

using System;
using System.Runtime.InteropServices;
[assembly: System.Security.AllowPartiallyTrustedCallers()]

namespace SecurityLibrary
{
    class NativeMethods
    {
        // Violates rule: SpecifyMarshalingForPInvokeStringArguments.
        [DllImport("advapi32.dll", CharSet=CharSet.Auto)]
        internal static extern int RegCreateKey(IntPtr key, String subKey, out IntPtr result);

        // Satisfies rule: SpecifyMarshalingForPInvokeStringArguments.
        [DllImport("advapi32.dll", CharSet = CharSet.Unicode)]
        internal static extern int RegCreateKey2(IntPtr key, String subKey, out IntPtr result);
    }
}