views:

35

answers:

1

I've got some code which pinvokes native win32. Since I upgraded to .NET 4, the code started throwing a MethodAccessException saying:

Attempt by security transparent method 'Tek.Audio.Midi.MidiDevice.GetDevices()' to call native code through method 'Tek.Native.Windows.Multimedia.midiInGetNumDevs()' failed. Methods must be security critical or security safe-critical to call native code.

Here's what's going on:

  • Executable assembly's Program.Main method calls library1 public static Tek.Audio.Midi.MidiDevice.GetDevices()
  • Library1's GetDevices() calls library2's public static pinvoke Tek.Native.Windows.Multimedia.midiInGetNumDevs() (yeah, bad practice, whatever)

The only security-related attributes on classes, methods and assemblies involved are AllowPartiallyTrustedCallers on library1, and I don't even know why.

It shames me to admit that I'm quite ignorant about security in .NET. What should I do to prevent this exception? And while I'm here, any good articles to get me started on .NET security?

+2  A: 

You have choices. The easiest thing to do would be to "opt-out" of the new security model.

<configuration>
  <runtime>
    <NetFx40_LegacySecurityPolicy enabled="true" />
  </runtime>
</configuration>

OR (bearing in mind I am no .Net 4 security expert)

You could mark your method:

[SecuritySafeCritical]

since you can use that with code designed for partially trusted callers.

Sadly I don't have a good article I can send you, I have had to figure this out like you have, by fixing my broken code. :)

Nick Daniels
The attribute did the trick. I'm accepting this answer until anyone can give me a more in-depth explanation or a link explaining why this is needed, how it works and what are the consequences.
Trillian
I can tell you why you need it. Interop is a "Full Trust" operation, meaning our app must be completely trusted to perform it. As such we need to signal the runtime that our code would like to be cleared to perform a full trust operation. By marking with SecuritySafeCritical we are indicating the method we're about to invoke will require full trust and is safe for partially trusted callers, that is code that has not met the conditions of being fully trusted or has simply been run in partial trust (ASP.NET web apps on shared hosting systems are generally run in partial trust).
Nick Daniels
No consequence, this will merely replicate the security conditions you were running under before .Net 4. However if you think later down the road allowing a partially trusted caller is not a good idea simply change SecuritySafeCritical to SecurityCritical and then all calling code will require full trust to invoke it.
Nick Daniels