2013-07-10 18 views
8

Ich kann nicht verstehen, wie CA2123 für ein C++/CLI-Projekt zu beheben. Hier ist ein Beispielprojekt, das Problem zu demonstrieren:Wie behebt man CA2123 (Override Link Anforderungen sollte identisch mit Base) in einem verwalteten C++/CLI Projekt

1) Erstellen Sie eine C# (.NET 4) Klassenbibliothek

ManagedClass.cs

Namespace CSharpLibrary {

public interface IManagedClass 
{ 
    void WriteSomething(); 
} 

public class ManagedClass : IManagedClass 
{ 
    public void WriteSomething() 
    { 
    } 
} 

}

2) Erstellen Sie eine C++/CLI-Konsolenanwendung (VS 2010):

AssemblyInfo.cpp

#include "stdafx.h" 

using namespace System; 
using namespace System::Reflection; 
using namespace System::Runtime::CompilerServices; 
using namespace System::Runtime::InteropServices; 
using namespace System::Security; 

[assembly:AssemblyTitleAttribute("CPlusPlusCLIConsoleApp")]; 
[assembly:AssemblyDescriptionAttribute("")]; 

[assembly:AssemblyVersionAttribute("1.0.*")]; 

[assembly:ComVisible(false)]; 

[assembly:CLSCompliantAttribute(false)]; 

[assembly:SecurityCritical]; 

CPlusPlusCLIConsoleApp.h

#pragma once 

using namespace CSharpLibrary; 
using namespace System::Security; 

typedef void* (__cdecl FACTORY_PROC)(); 

namespace CPlusPlusCLIConsoleApp 
{ 
    public ref class MainClass : public IManagedClass 
    { 
    public: 
     [SecurityCritical] 
     virtual void WriteSomething(); 
    }; 

}; 

CPlusPlusCLIConsoleApp.cpp

#include "stdafx.h" 
#include "CPlusPlusCLIConsoleApp.h" 

using namespace System; 

int main(){}; 

namespace CPlusPlusCLIConsoleApp 
{ 
    [SecurityCritical] 
    void MainClass::WriteSomething() 
    { 
    } 
}; 

Nach ENAB ling alle Microsoft Security Rules, erhalte ich diese Warnung:

CA2123 Anforderungen außer Kraft setzen Link sollte

Fügen Sie die folgende Sicherheitsattribut zu 'Mainclass :: WriteSomething (void)', um zu stützen identisch sein zu entsprechen a LinkDemand on Basismethode 'IManagedClass :: WriteSomething (void)': 'SecurityCriticalAttribute'.

CPlusPlusCLIConsoleApp cpluspluscliconsoleapp.cpp 13

Ich versuchte zu folgen, was diese StackOverflow answer vorgeschlagen, aber es hat nicht den Fehler zu beheben.

Ich verstehe, dass die verwaltete DLL standardmäßig SecurityCritical ist (ich möchte dies nicht in meinem ursprünglichen Projekt ändern), da ich keine SecurityAttribute angeben. Warum folgt die C++ CLI-DLL nicht demselben Standard?

Welche Schritte sollte ich befolgen, um diesen Fehler zu beheben?

EDIT 1 (Im Grunde genommen wie kann ich WriteSomething Methode sicherheitskritischen in C++ CLI machen): Ich habe die gleiche Frage gestellt auf MSDN.

EDIT 2: kontaktiert Microsoft und es ist ein wie entworfenes Verhalten. Das C++ \ CLI-Team hatte gerade keine Zeit, Level2 Security für C++ \ CLI zu implementieren. Daher bleibt C++ \ CLI immer bei Level1 Security hängen. Man kann die Codeanalysewarnung für dasselbe sicher unterdrücken.

+0

"Ich habe versucht zu folgen, was diese StackOverflow Antwort vorgeschlagen, aber es hat den Fehler nicht behoben." - aber der Code, den Sie gepostet haben, spiegelt das nicht wider - haben Sie [assembly: SecurityCritical] zu AssemblyInfo.cpp hinzugefügt? –

+0

Es ist einfach zu trivial, die Anforderung zu umgehen, der Aufrufer kann einfach die Objektreferenz auf den Schnittstellentyp umwandeln und den Aufruf tätigen. Das Attribut muss daher auch auf die Interface-Methode angewendet werden. –

+0

@SebastianRedl Ja. Ich habe nur vergessen, das Attribut hier zu kopieren. Behoben. –

Antwort

9

Das Grundproblem besteht darin, dass Ihre C# - und C++ - Assemblys zwei verschiedene Transparenzmodelle verwenden (Details zu den beiden Ebenen finden Sie unter http://blogs.msdn.com/b/shawnfa/archive/2009/11/11/transparency-models-a-tale-of-two-levels.aspx und http://blogs.msdn.com/b/shawnfa/archive/2009/11/12/differences-between-the-security-rule-sets.aspx). Das liegt daran, dass die C# -Assembly standardmäßig auf Ebene 2 kompiliert wird, aber die C++ - Assembly vom Compiler aus einem scheinbar undokumentierten Grund automatisch auf die Ebene 1 gezwungen wird. Leider scheint das letztere Verhalten nicht zu übersteuern. Um die Dinge noch schlimmer zu machen, scheint es sich in VS2012 und it doesn't look like the product team is considering changing it any time soon nicht geändert zu haben.

Vorausgesetzt, dass Sie nicht die C++ Montage auf Ebene bewegen kann 2, haben Sie ein paar potenziell lebensfähigen Möglichkeiten, wenn Sie die ausführbare Datei in C++ halten wollen, und es muss die Interface-Implementierung enthalten:

  1. verschieben die C# -Assembly auf Ebene 1 über die Verwendung des SecurityRulesAttribute . Dies wäre vermutlich nur akzeptabel, wenn die C++ - Konsolenanwendung der einzige Consumer der C# -Bibliothek ist.
  2. Reproduzieren Sie die "Eskalation" der Sicherheitskritischen Ebene 2 zu einer vollständigen Vertrauensverknüpfung/Vererbungsanforderung über die Verwendung von PermissionSetAttribute. zB:

    [SecurityCritical] 
    [PermissionSet(SecurityAction::LinkDemand, Unrestricted = true)] 
    [PermissionSet(SecurityAction::InheritanceDemand, Unrestricted = true)] 
    virtual void WriteSomething(); 
    

Es könnte auch sinnvoll sein, einen anderen Bug-Report auf Connect einreichen (Abstimmung für geschlossene, scheint nicht sehr nützlich zu sein) oder ein Feature-Request auf UserVoice dass der Compiler anfordern Verhalten geändert werden. (Locking in Level 1 ist ziemlich seltsam, da Level 2 der Standard für .NET 4.0 und höher ist.)

+0

+1 Danke für Ihre Antwort. Tolle Links. Ich denke, was Sie sagen, ist die Antwort. Ich warte nur darauf, dass Microsoft Support dies bestätigt. –