2013-07-10 10 views
8

Nie jestem w stanie zrozumieć, jak naprawić kod CA2123 dla projektu C++/CLI. Oto przykładowy projekt do wykazania problem:Jak naprawić kod CA2123 (Przesłania łącza żądania powinny być identyczne z bazą) w zarządzanym projekcie C++/CLI

1) Utwórz C# (.NET 4) Class Library

ManagedClass.cs

nazw CSharpLibrary {

public interface IManagedClass 
{ 
    void WriteSomething(); 
} 

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

}

2) Utwórz aplikację konsoli C++/CLI (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() 
    { 
    } 
}; 

Po enab ling wszystkich reguł zabezpieczeń firmy Microsoft, mam to ostrzeżenie:

żądania łącza CA2123 Zastąp powinny być identyczne oprzeć

Dodaj następujący atrybut zabezpieczeń 'MainClass :: WriteSomething (void)' w celu dopasowania LinkDemand na metoda podstawowa "IManagedClass :: WriteSomething (void)": "SecurityCriticalAttribute".

CPlusPlusCLIConsoleApp cpluspluscliconsoleapp.cpp 13

Starałem się śledzić, co to StackOverflow answer sugeruje, ale nie naprawić błąd.

Rozumiem, że zarządzana biblioteka dll jest domyślnie SecurityCritical (nie chcę tego zmieniać w moim oryginalnym projekcie), ponieważ nie określam żadnej SecurityAttribute. Dlaczego biblioteka CLI języka C++ nie jest zgodna z tym samym ustawieniem domyślnym?

Co należy zrobić, aby naprawić ten błąd? (W zasadzie, jak mogę uczynić metoda WriteSomething SecurityCritical w C++ CLI)

EDIT 1: Mam to samo pytanie na MSDN.

EDYCJA 2: Skontaktowano się z firmą Microsoft i jest ona zgodna z założeniami. Zespół C++ \ CLI po prostu nie miał czasu na wdrożenie Level2 Security for C++ \ CLI. Stąd C++ \ CLI zawsze utknął na poziomie 1 Security. Można bezpiecznie ukryć ostrzeżenie o analizie kodu dla tego samego.

+0

"Próbowałem zastosować się do sugestii StackOverflow, ale nie naprawiłem błędu." - ale kod, który wysłałeś, nie odzwierciedla tego - czy dodałeś [assembly: SecurityCritical] do AssemblyInfo.cpp? –

+0

Po prostu zbyt trywialne, aby ominąć żądanie, osoba dzwoniąca może po prostu rzucić referencję obiektu do typu interfejsu i wykonać połączenie. Dlatego atrybut musi być również zastosowany do metody interfejsu. –

+0

@SebastianRedl Tak. Właśnie zapomniałem skopiować ten atrybut tutaj. Naprawione. –

Odpowiedz

9

Problem korzeń tutaj jest to, że C# i C++ zespoły są za pomocą dwóch różnych modeli przejrzystości (zob http://blogs.msdn.com/b/shawnfa/archive/2009/11/11/transparency-models-a-tale-of-two-levels.aspx i http://blogs.msdn.com/b/shawnfa/archive/2009/11/12/differences-between-the-security-rule-sets.aspx szczegóły dwóch poziomach). Dzieje się tak dlatego, że domyślnie kompilator C# kompiluje się na poziom 2, ale kompilacja C++ jest automatycznie zmuszana przez kompilator do poziomu 1 z jakiegoś pozornie nieudokumentowanego powodu. Niestety, wydaje się, że to ostatnie zachowanie nie jest możliwe do zastąpienia. Co gorsza, wygląda na to, że nie zmieniło się w VS2012 i it doesn't look like the product team is considering changing it any time soon.

Biorąc pod uwagę, że nie można przenieść zespół C++ na poziomie 2, masz kilka potencjalnie zdolnych do wyborów, jeśli chcesz zachować pliku wykonywalnego w C++ i musi zawierać implementację interfejsu:

  1. Move zestaw C# do poziomu 1 za pomocą atrybutu SecurityRulesAttribute . Prawdopodobnie będzie to dopuszczalne, jeśli aplikacja konsolowa C++ jest jedynym użytkownikiem biblioteki C#.
  2. Powtórz poziom 2 "eskalacji" krytyczności zabezpieczeń do pełnego połączenia zaufania/żądania dziedziczenia za pomocą metody PermissionSetAttribute. np

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

Może być również warto przedstawić kolejny raport o błędzie na Connect (głosowanie na zamkniętych nie wydaje się być bardzo przydatne) lub na żądanie funkcja UserVoice do żądania kompilatora zachowanie zostać zmienione. (Zablokowanie na poziom 1 jest dość dziwne, biorąc pod uwagę, że poziom 2 powinien być domyślny dla .NET 4.0 i wyższych.)

+0

+1 Dziękuję za odpowiedź. Świetne linki. Myślę, że to, co mówisz, jest odpowiedzią. Właśnie czekam na wsparcie Microsoft, aby to potwierdzić. –

Powiązane problemy