C++/CLI C++ Interop and FxCop/Code-Analysis warning CA2122

G

Guest

I've purposely been ignoring a CA2122 warning in some C++ interop code I've
been working on for quite some time. I've just recently had the cycles to
investigate the warning. The warning message is as follows

Warning CA2122 : Microsoft.Security : MyClass.Method():Void calls into
Marshal.GetExceptionPointers():IntPtr which has a LinkDemand. By making this
call, Marshal.GetExceptionPointers():IntPtr is indirectly exposed to user
code. Review the following call stack that might expose a way to circumvent
security protection:
->System.Runtime.InteropServices.Marshal.GetExceptionPointers : IntPtr
->MyClass.Method : Void
....

MyClass is a managed class where Method calls a native static (for readable
illustration purposes only) function; where the code is as follows:

static void MethodImplementation() throw(std::runtime_error &)
{
//...
throw std::runtime_error("a message");
//...
}

//...
void MyClass::Method()
{
try
{
return MethodImplementation();
}
catch(std::runtime_error &)
{
//...
}
}

My concern isn't that FxCop/Code-Analysis is pumping out this message, it's
the LinkDemand that catch(std::runtime_error) is forcing upon this method.

Assume for a moment that the method MethodImplementation is not within my
control (cannot modify it) and it can obviously throw an std::runtime_error
reference. While I can add a LinkDemand attribute to the Method method,
strong-name its assembly, and either throw that assenbly in the GAC or
manually give it FullTrust and the implications of this LinkDemand go away;
but I don't think I should need to. There's are some architectural and
policy issues to simply going FullTrust to swallow the "inherited" security
demands of the Method method (like APTC); but this should all be an
implementation detail, and the abstraction of C++ interop has leaked through
to my implementation.

Any thoughts?
 
G

Gary Chang[MSFT]

Hi Peter,
There's are some architectural and policy issues to simply
going FullTrust to swallow the "inherited" security demands
of the Method method (like APTC); but this should all be an
implementation detail, and the abstraction of C++ interop
has leaked through to my implementation.

I will forward your opinion to our corresponding VC product team for
review.

Meantime, I suggest you can also submit this feedback to to our product
feedback center, our development team may communicate with you directly on
the issue there:

http://connect.microsoft.com/site/sitehome.aspx?SiteID=210

Thanks!

Best regards,

Gary Chang
Microsoft Online Community Support
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 
H

Holger Grund

Peter Ritchie said:
I've purposely been ignoring a CA2122 warning in some C++ interop code
I've
been working on for quite some time. I've just recently had the cycles to
investigate the warning. The warning message is as follows

Warning CA2122 : Microsoft.Security : MyClass.Method():Void calls into
Marshal.GetExceptionPointers():IntPtr which has a LinkDemand. By making
this
call, Marshal.GetExceptionPointers():IntPtr is indirectly exposed to user
code. Review the following call stack that might expose a way to
circumvent
security protection:
->System.Runtime.InteropServices.Marshal.GetExceptionPointers : IntPtr
->MyClass.Method : Void
...
I must admit the diagnostic message is a bit odd. I think it is trying to
tell you that you should make sure that you do not expose the effects
or results of calling GetExceptionPointers to untrusted callers in the
chain.
void MyClass::Method()
{
try
{
return MethodImplementation();
}
catch(std::runtime_error &)
{
//...
}
}

My concern isn't that FxCop/Code-Analysis is pumping out this message,
it's
the LinkDemand that catch(std::runtime_error) is forcing upon this method.
What's the problem? You'll need unmanaged code, anyway.
GetExceptionPointers is not directly exposed -- even though you'd
effectively
have to trap all exceptions (including C++ and async exceptions), which is
hardly a good idea.
Assume for a moment that the method MethodImplementation is not within my
control (cannot modify it) and it can obviously throw an
std::runtime_error
reference. While I can add a LinkDemand attribute to the Method method,
Adding the LinkDemand would just shut up FxCop. What's the problem
if MethodImplementation throws a std::runtime_error? I don't see how
a caller of Method could possibly do anything to exploit that.
Any thoughts?
How about just ignoring the message? I don't see any problem.

-hg
 
G

Guest

Hi Holger. In this particular example, yes, I must have UnmanagedCode to
even call my method. I would have expected that the compiler generate code
that doesn't needlessly leak demands. If I must have UnmanagedCode to use
"catch(std::exception)" the implementation detail of using
GetExceptionPointers (and its LinkDemand for UnmanagedCode) should be hidden.
Reliably hiding this in generated code would be awfully difficult while
directly calling GetExceptionPointers because there's no guarantee this
assembly won't be partially trusted. The only way to reliably hide this
would be to push the call to GetExceptionPointers into a system assembly
(which would then do a Demand/Assert pair so it no longer leaks the
LinkDemand) since system assemblies are guaranteed to have FullTrust.

Yes, *I* can simply add an Demand/Assert pair to get rid of the FxCop
warning. But, I know that's a correct way of getting rid of the message for
partially trusted callers. But, this then means my assembly must not be
denied Assert and usually means this assembly must been installed with
elevated permissions compared to its callers.

The FxCop documentation for CA2122 suggests mirroring the LinkDemand on the
method that calls GetExceptionPointers which pushes an new LinkDemand one
level up the stack, which could have huge ramifications if the next caller up
the stack is a method not in this assembly and does not need UnmanagedCode
and is either refusing it or ClickOnce security has filtered it out in it's
manifest previously.

It would appear the best course of action would normally be to ignore this
warning; but, that's not what normally happens when encountering an FxCop
warning. Users usually either do what the warning suggest (which, in this
case, would effectively make a LinkDemand into a Demand by continuously
cascading the LinkDemand up the graph--adding the LinkDemand to this method
would mean the warning shifts to methods that call this method, ad nauseam)
or they fiddle around with attributes/code until the warning goes away.
Doing this usually defeats the purpose of the original warning and often
makes the application more susceptible to attack, not less.

--
Browse http://connect.microsoft.com/VisualStudio/feedback/ and vote.
http://www.peterRitchie.com/blog/
Microsoft MVP, Visual Developer - Visual C#
 
H

Holger Grund

Peter Ritchie said:
Hi Holger. In this particular example, yes, I must have UnmanagedCode to
even call my method. I would have expected that the compiler generate
code
that doesn't needlessly leak demands. If I must have UnmanagedCode to use
"catch(std::exception)" the implementation detail of using
GetExceptionPointers (and its LinkDemand for UnmanagedCode) should be
hidden.

In which way is it observable from the outside?
Reliably hiding this in generated code would be awfully difficult while
directly calling GetExceptionPointers because there's no guarantee this
assembly won't be partially trusted. The only way to reliably hide this
would be to push the call to GetExceptionPointers into a system assembly
(which would then do a Demand/Assert pair so it no longer leaks the
LinkDemand) since system assemblies are guaranteed to have FullTrust.
I'm afraid I don't understand your problem. I don't understand what
you mean which "leaks the LinkDemand". GetExceptionPointers has
a LinkDemand, the MyClass::Method() has not.

Do you say that the generated code has a security weakness?
I don't see it.
Yes, *I* can simply add an Demand/Assert pair to get rid of the FxCop
warning. But, I know that's a correct way of getting rid of the message
for
partially trusted callers. But, this then means my assembly must not be
denied Assert and usually means this assembly must been installed with
elevated permissions compared to its callers.
I simply suggest to completely ignore FxCop because its warning is bogus.
No Demand/Assert pair -- nothing.
The FxCop documentation for CA2122 suggests mirroring the LinkDemand on
the
method that calls GetExceptionPointers which pushes an new LinkDemand one
level up the stack, which could have huge ramifications if the next caller
up
the stack is a method not in this assembly and does not need UnmanagedCode
and is either refusing it or ClickOnce security has filtered it out in
it's
manifest previously.
That's just the typical Microsoft security paranoia. It seems that there are
many smart folks at Microsoft who just got religious about all this security
thing. Once again, I don't see any security weakness in the code.
It would appear the best course of action would normally be to ignore this
warning; but, that's not what normally happens when encountering an FxCop
warning. Users usually either do what the warning suggest (which, in this
case, would effectively make a LinkDemand into a Demand by continuously
cascading the LinkDemand up the graph--adding the LinkDemand to this
method
would mean the warning shifts to methods that call this method, ad
nauseam)
or they fiddle around with attributes/code until the warning goes away.
Doing this usually defeats the purpose of the original warning and often
makes the application more susceptible to attack, not less.

So is your issue with the documentation of CA2122? Then you should
probably report it somewhere with the VSTS folks.

-hg
 
G

Guest

Peter Ritchie said:
In which way is it observable from the outside?

What FxCop is warning about is that the LinkDemand on GetExceptionPointers
means one call previous in the call stack will demand that permission--the
method with the catch. Ignoring the fact that the code simply cannot run
without having UnmanagedCode permission, that LinkDemand means callers to the
containing method must grant that method that permission.

Since the assembly must have UnmanagedCode permission, ideally the runtime
will simply optimize that out and not perform and stack crawl upon execution
of GetExceptionPointers because the containing method does have UnmanagedCode
permissions.

But, I think the compiler should not generate code that makes calls to
methods with LinkDemands. Despite being benign in this context.
I'm afraid I don't understand your problem. I don't understand what
you mean which "leaks the LinkDemand". GetExceptionPointers has
a LinkDemand, the MyClass::Method() has not.

Do you say that the generated code has a security weakness?
I don't see it.

I simply suggest to completely ignore FxCop because its warning is bogus.
No Demand/Assert pair -- nothing.

I agree.
That's just the typical Microsoft security paranoia. It seems that there are
many smart folks at Microsoft who just got religious about all this security
thing. Once again, I don't see any security weakness in the code.


So is your issue with the documentation of CA2122? Then you should
probably report it somewhere with the VSTS folks.

Worst case, this is an issue with FxCop/CA--it should be smart enough not to
warn about a LinkDemand for a permission in code that already has that
permission. Best case, it's also a problem with the compiler generating code
that makes calls to methods with LinkDemands.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top