2013-07-10 4 views
8

C++/CLI 프로젝트에서 CA2123을 수정하는 방법을 이해할 수 없습니다. 여기에 문제가 설명하는 샘플 프로젝트입니다 :관리되는 C++/CLI 프로젝트에서 CA2123 (오버라이드 링크 요구가 기본과 동일해야 함)을 수정하는 방법

1) C#을 만들기 (.NET 4) 클래스 라이브러리

ManagedClass.cs는

네임 스페이스 CSharpLibrary {

public interface IManagedClass 
{ 
    void WriteSomething(); 
} 

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

}

2) C++/CLI 콘솔 응용 프로그램 만들기 (VS 2010) :

ENAB 후

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() 
    { 
    } 
}; 

일치하기 위해

CA2123 재정의 링크 요구가 에 다음과 같은 보안 속성을 추가

의 기준이 동일해야 'MainClass :: WriteSomething (무효)'링 모든 Microsoft 보안 규칙,이 경고를 LinkDemand on 기본 메서드 'IManagedClass :: WriteSomething (void)': 'SecurityCriticalAttribute'.

CPlusPlusCLIConsoleApp의 cpluspluscliconsoleapp.cpp 13

나는이 StackOverflow answer 제안하지만 오류가 해결되지 팔로우 했어요.

관리 대상 dll은 기본적으로 SecurityCritical입니다. SecurityAutribute를 지정하지 않았으므로 원래 프로젝트에서 변경하지 않으려합니다. C++ CLI dll이 같은 기본값을 따르지 않는 이유는 무엇입니까?

이 오류를 해결하기 위해 수행해야 할 단계는 무엇입니까? (기본적으로 C++ CLI에서 WriteSomething 메서드 SecurityCritical 메서드를 만들 수 있습니다)

EDIT 1 : 나는 MSDN에서 같은 질문을했습니다.

편집 2 : Microsoft에 문의했으며 이는 설계된 동작입니다. C++ \ CLI 팀은 C++ \ CLI 용 Level2 Security를 ​​구현할 시간이 없었습니다. 따라서 C++ \ CLI는 항상 Level1 Security에 고정되어 있습니다. 코드 분석 경고를 안전하게 억제 할 수 있습니다.

+0

"이 StackOverflow 답변의 제안에 따르려고했지만 오류를 수정하지 않았습니다." -하지만 당신이 올린 코드는 이것을 반영하지 않습니다 - AssemblyInfo.cpp에 [assembly : SecurityCritical]을 추가 했습니까? –

+0

요청을 우회하는 것은 너무 간단합니다. 호출자는 객체 참조를 인터페이스 유형으로 단순히 캐스팅하고 호출 할 수 있습니다. 따라서 속성은 인터페이스 메소드에도 적용되어야합니다. –

+0

@SebastianRedl 예. 방금 속성을 여기에 복사하는 것을 잊었습니다. 고쳤다. –

답변

9

근본적인 문제는 C# 및 C++ 어셈블리가 두 개의 다른 투명도 모델을 사용한다는 것입니다 (두 수준에 대한 자세한 내용은 http://blogs.msdn.com/b/shawnfa/archive/2009/11/11/transparency-models-a-tale-of-two-levels.aspxhttp://blogs.msdn.com/b/shawnfa/archive/2009/11/12/differences-between-the-security-rule-sets.aspx 참조). 이것은 C# 어셈블리가 기본적으로 레벨 2로 컴파일되기 때문입니다. 그러나 C++ 어셈블리는 문서화되지 않은 이유로 인해 컴파일러에서 자동으로 레벨 1로 내려갑니다. 불행히도, 후자의 행동은 무시할 수없는 것 같습니다. 상황을 악화 시키려면 VS2012 및 it doesn't look like the product team is considering changing it any time soon에서 변경된 것으로 보이지 않습니다.

  1. 이동 :

    은 레벨 2에 C++ 어셈블리를 이동할 수 없습니다, 당신은 잠재적으로 가능한 선택의 몇 가지있다 당신이 C에서 ++을 실행을 유지하려는 경우와는 인터페이스의 구현을 포함해야한다는 것을 감안할 때 SecurityRulesAttribute를 사용하여 C# 어셈블리를 수준 1로 만듭니다. 이는 아마도 C++ 콘솔 앱이 C# 라이브러리의 유일한 소비자 인 경우에만 허용 될 수 있습니다.

  2. PermissionSetAttribute를 사용하여 보안 중요도의 수준 2 "에스컬레이션"을 전체 신뢰도/상속 요청 에 재현합니다. 예 :

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

는 또한 Connect에 또 다른 버그 리포트를 제출 가치가있을 수도 있습니다 (폐쇄 것들에 대한 투표를하는 것은 매우 유용 할 것 같지 않습니다) 또는 컴파일러 요청할 UserVoice에 기능 요청 행동이 변경됩니다. (Level 1은 Level 2가 .NET 4.0 이상에서 기본으로 제공된다는 점을 감안할 때 수준 1에 고정되어 있습니다.)

+0

+1 답장을 보내 주셔서 감사합니다. 훌륭한 링크. 나는 네가 말하는 것은 대답이라고 생각한다. 이 문제를 확인하기 위해 Microsoft 지원을 기다리는 중입니다. –