4

I have a small C# class with a few unsafe methods. Is there a way to specify "/unsafe" option declaratively in C# source code (with #pragma or anyhow else) just for the context of the class' source file? I'd hate to create a separate assembly for such a small class, but I also really don't want the rest of the assembly (the class is currently a part of) to be enabled for unsafe code.

2
  • 4
    It is not the way it works. Using the /unsafe option only suppresses a compile-time error on classes/methods that explicitly use the unsafe keyword. It doesn't make code that's not declared that way unsafe in any way. Commented Sep 24, 2013 at 16:00
  • So is there or not a special flag in the generated assembly, as @StriplingWarrior suggests? Commented Sep 24, 2013 at 16:03

2 Answers 2

7

No, this is (currently) not possible, as the entire assembly is affected by having unsafe code in it.

By including unsafe code in your assembly, you are telling the CLR that the assembly could do something, well, unsafe, which changes how the runtime acts when it loads the assembly. The biggest change here is that the CLR will simply not try to verify your unsafe code, but it also will refuse to load your assembly unless it has full-trust (e.g. you couldn't load an unsafe assembly as a normal user over click-once.)

From a technical perspective, when you use the /unsafe option, it causes the compiler to emit the IL equivalent of the following module-level attributes into your assembly:

[assembly:SecurityPermission(SkipVerification = true)]
[assembly:UnverifiableCode]

Your best option is, as you said, to isolate the unsafe code into its own separate assembly as much as possible. The fact that the assembly has only one class in it is much less of a code-smell than tainting an entire assembly full of safe code due to one unsafe class.

Sign up to request clarification or add additional context in comments.

5 Comments

My understanding is that unsafe is per-method. Not per assembly. It also is not declared AFAIK. A method becomes unsafe when unverifiable IL is put intoit.
@usr to C#, unsafe code is per-code-block and the compiler permits you to do things in unsafe code blocks that are normally illegal. To the runtime, unsafe code occurs in assemblies that are marked as having unsafe code in them. Although the safe-code is still safe, there's no way to tell the runtime "half of this assembly is safe and the other half isn't." For example, the entire assembly requires full-trust to load, even if you never call the unsafe block.
Are you sure that assemblies are marked? That's what I was putting into question. I think not even methods are marked in the binaries.
@usr my answer was probably oversimplified, I will fix it.
In C#, as well as you can mark a code block as unsafe, you can also mark an entire class as unsafe. But it might be equivalent to marking all "blocks" in that class unsafe.
5

C# has an unsafe keyword that you have to use around unsafe code, just to avoid having people using unsafe code by accident. This is as good an approach as any I can think of: If someone can introduce the unsafe keyword in a file, they could just as easily add or remove a #pragma tag or some such.

The /unsafe compiler tag tells the compiler that you're okay with people using the unsafe keyword in this assembly, and you recognize that the assembly it generates will be marked "unsafe," which may prevent it from running in less-than-Full-Trust environments. There's no way to have the compiler mark only individual classes as unsafe: people can either trust your assembly or they can't.

4 Comments

you need the use the /unsafe compiler switch for the unsafe keyword to compile.
That makes sense, although I'm surprised about how interop code (both WinAPI and COM) is considered more secure than unsafe code, given the fact interop doesn't require "/unsafe" option.
interop is probably "safe" as it's been hand-verified. The developer writing the assembly isn't allowed to do anything with it beyond what MS explicitly allowed (which is also why the Marshal class can do unsafe things "safely")
@MichaelEdenfield, I'd say, calling RtlZeroMemory alone with a malicious IntPtr argument can do a lot more damage than my innocent pointer operations, for which I have to use "/unsafe".

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.