问题
How do i mark as assembly as "safe"?
Alternatively, how do i have Visual Studio tell me when something in my assembly is not "safe"?
Sometimes you cannot use an assembly unless it is "safe" (e.g. from SQL Server).
i would like my assembly to be marked as safe. If my assembly cannot be marked as safe because it's not safe, i'd like to know how i can know that my assembly is not safe.
There are some concepts in Visual Studio that seem to relate to safe-ness, that may or may not have anything to do with an assembly being "safe":
Allow unsafe code assembly option:
- What is allowed if i check the allow unsafe code option?
- What is not allowed if i uncheck the allow unsafe code option?
What relation, if any, does "unsafe code" have to do with an assembly being "safe"?
(i ask because my assembly doesn't "allow unsafe code", but allows P/Invoke calls - which i thought was the definition of "unsafe")
ClsCompliant assembly option:
[assembly: CLSCompliant(true)] namespace MyApplication
- What is the relation, if any, does "cls compliant" code have to do with an assembly being "safe"?
unsafe code block:
int error; unsafe { error = 0x80004005; }
The code inside the
unsafe
block is "unsafe"UnsafeNativeMathods
Microsoft recommends creating a class called
UnsafeNativeMethods
that contain unsafe managed code:[SuppressUnmanagedCodeSecurity] internal static class UnsafeNativeMethods { ... }
This contrasts with
SafeNativeMethods
:[SuppressUnmanagedCodeSecurity] internal static class SafeNativeMethods { ... }
that contains safe native methods, and
NativeMethods
:internal static class SafeNativeMethods { ... }
that contain native methods.
How do i mark as assembly as "safe"?
How does SQL know that as assembly is "not safe"?
回答1:
- Reading from this, the "Safe" for SQL Server is a:
SAFE is the most restrictive permission set. Code executed by an assembly with SAFE permissions cannot access external system resources such as files, the network, environment variables, or the registry
so its about code execution permission set inside SQL Server code domain
Unsafe
flag from VS has nothing to do, basically, with code execution security, but enables non managed code execution. So this about non managed code integration into managed code baseCLS Compilant
attribute as defined here is about defining the code of the assembly marked with that attribute like a code that follows CSL (Common Language Specification) guideline. So this about compilation and code architecture.
How do i mark as assembly as "safe"?
It defined in the first link in this answer and has relation with SQL Server integration.
How does SQL know that as assembly is "not safe"?
Considering description provided: "Creates a managed application module that contains class metadata and managed code as an object in an instance of SQL Server", SQL Server relays on metadata
, that in some fields provides an information about the fact if it is "safe" or not.
回答2:
How do i mark as assembly as "safe"?
You're thinking about this the wrong way.
Someone who you think maybe wants to kill you hands you a bottle and says "drink this". You say "is it safe to drink?" The guy says "read the bottle". You do. It says "SAFE TO DRINK" on it.
Do you drink it?
Whether the liquid is safe to drink or not has nothing whatsoever to do with what the label on the bottle says! It is perfectly possible to put gasoline in a bottle marked "SAFE TO DRINK".
You're the guy handing out the bottle full of suspicious liquid to SQL server, and SQL Server says "I don't trust any label you're going to put on this assembly". Rather, it is going to make the assembly "safe" by restricting what the assembly can do. It locks down the permissions on that thing so that any attempt by your assembly to take advantage of SQL server will result in its termination via an exception.
How do I know when something in my assembly is not "safe"?
Try running it in low trust. Did it crash and die with a security exception? If the answer is yes, then it wasn't safe according to that trust level. Different trust levels grant different levels of permissions. Code you install on your own machine is typically fully trusted, code you run from your corporate network is less trusted, code you run from the internet is hardly trusted at all. Code you run in SQL server gets the least level of trust of all; it thinks almost everything is unsafe.
What is allowed if i check the allow unsafe code option?
You can then write code that directly manipulates raw pointers to memory in a manner of its choosing. That requires full trust; there must be no restrictions placed upon your assembly if you wish to use unsafe code. Unsafe code can change every bit of user-mode memory in the process.
What is the relation, if any, does "cls compliant" code have to do with an assembly being "safe"?
None whatsoever, other than the fact that CLS compliant code does not allow for APIs that take raw pointer types.
CLS is the Common Language Subset -- the set of features that are required to be present in all compliant .NET languages. That way you don't have to ask yourself "hey, if I write this method that takes an int and returns a string in C#, can I call it from F#?" If you restrict yourself to follow the rules of the CLS then you know that any CLS language can use your library, and you can use CLS-compliant libraries no matter what language they were written in. It has nothing whatsoever to do with safety.
The code inside the unsafe block is "unsafe"
The code inside the unsafe block can arbitrarily corrupt memory throughout the process if it is written badly. We make you mark code like that "unsafe" so that you know where to concentrate your code reviewing efforts. In an unsafe block you, not the C# language, are responsible for ensuring type and memory safety.
A question you did not ask:
What does marking an assembly as "safe for partially trusted caller" mean?
This is a situation where you do mark an assembly as "safe". By marking an assembly with the AllowPartiallyTrustedCallerAttribute (APTCA) you, the author of the assembly, are asserting that if the code in the assembly is called by low-trust hostile code that is attempting to attack the user, then there is nothing in your assembly which the low-trust hostile code can use against the user. In short, you are saying "even if fully trusted by the user, my code is not a weapon that evil code can use against the user".
We invented APTCA because back in the day, Peter Torr and I discovered that there was a way for hostile callers who had low trust to trick the JScript.NET code -- which was high trust by default -- in such a way that the low trust code could cause the JScript.NET code to attack the user on its behalf. (This is usually called the "luring attack" because the low-trust code "lures" the high-trust code into doing its dirty work for it.)
As just one small part of a large effort to ensure that this sort of mistake did not happen again, the CLR team introduced APTCA. By putting APTCA on an assembly, you are telling your users that you are making the claim that their trust of your work is not abusable by hostile third party code. Do not put APTCA on an assembly unless (1) you intend for the assembly to be called by code the user believes may be hostile, and (2) you have actually done a thorough security review.
The new transparency based security model obviates much of the need for APTCA, fortunately.
If APTCA is not present on an assembly then a "link demand" will ensure that the code which invokes your assembly is fully trusted. Note that it is a link demand, not a full demand.
回答3:
SQL in this case is looking for code that you've wrapped in an "unsafe" block. Here's an MSDN pointer to the unsafe keyword
http://msdn.microsoft.com/en-us/library/chfa2zb8.aspx
回答4:
Depends on what you mean, but if you import an assembly (i.e a .dll) there is a "unblock" option in the properties of that .dll file. This will allow you to use the dll as a reference.
来源:https://stackoverflow.com/questions/8795498/how-to-mark-a-net-assembly-as-safe