I recently needed to use classes and methods from MSXML6.dll in Reporting Services reports (to make web service calls).
Tried to instantiate XMLHTTP and DOMDocument from MSXML6.dll with late binding like this:
Request = CreateObject("MSXML2.XMLHTTP.6.0") Doc = CreateObject("MSXML2.DOMDocument.6.0")
However it failed with a SecurityException, but the exact cause was unknown.
I decided to identify the cause by attaching WinDbg (x86) to RsReportHost.exe
On each report refresh I noticed a number of exceptions like:
(2a54.34d4): CLR exception - code e0434352 (first chance) (2a54.34d4): CLR exception - code e0434352 (first chance) (2a54.34d4): C++ EH exception - code e06d7363 (first chance) (2a54.34d4): C++ EH exception - code e06d7363 (first chance)
I configured WinDbg to break on first chance exceptions under: Debug -> Event Filters…
And loaded the SOS extension with:
.loadby sos clr
Typical (top part) of the call stack was:
0:007> !clrstack OS Thread Id: 0x55f4 (7) Child SP IP Call Site 00bbb28c 7652dae8 [HelperMethodFrame: 00bbb28c] 00bbb33c 72f25d5a System.Security.CodeAccessSecurityEngine.ThrowSecurityException(...) 00bbb36c 72f25cad System.Security.CodeAccessSecurityEngine.ThrowSecurityException(...) 00bbb394 72f2136c System.Security.CodeAccessSecurityEngine.CheckSetHelper(...) 00bbb3e4 73581acf System.Security.CodeAccessSecurityEngine.CheckSetHelper(...) 00bbb50c 73e41376 [GCFrame: 00bbb50c] 00bbbd08 73e41376 [GCFrame: 00bbbd08] 00bbbdc0 73e41376 [GCFrame: 00bbbdc0] 00bbbf58 73e41376 [DebuggerSecurityCodeMarkFrame: 00bbbf58] 00bbbee4 73e41376 [HelperMethodFrame: 00bbbee4] 00bbbf7c 09a16859 Microsoft.VisualBasic.Interaction.CreateObject(System.String, System.String) 00bbbfa4 09a180ba ReportExprHostImpl+CustomCodeProxy.CallServiceTest2() 00bbbfcc 09a1807b ReportExprHostImpl+Description_TextBoxExprHost+Paragraph00_ParagraphExprHost+TextRun00_TextRunExprHost.get_ValueExpr()
(parameters trimmed for readability)
I checked the mscorlib.dll code for System.Security.CodeAccessSecurityEngine.CheckSetHelper(…) in ILSpy.
Noticed something interesting: The local variable permThatFailed could show which permission was missing.
This was also used when calling System.Security.SecurityException.MakeSecurityException, so that was an ideal place to set a breakpoint.
Set a breakpoint with !bpmd:
0:015> !bpmd mscorlib.dll System.Security.SecurityException.MakeSecurityException Found 1 methods in module 72bf1000... MethodDesc = 72c88e84 Setting breakpoint: bp 72F33813 [System.Security.SecurityException.MakeSecurityException(System.Reflection.AssemblyName, System.Security.Policy.Evidence, System.Security.PermissionSet, System.Security.PermissionSet, System.RuntimeMethodHandleInternal, System.Security.Permissions.SecurityAction, System.Object, System.Security.IPermission)] Adding pending breakpoints...
Continued execution, refreshed the report and then checked the call stack with parameters:
0:014> !clrstack -p OS Thread Id: 0x54c0 (14) Child SP IP Call Site 0103bd88 72f33813 System.Security.SecurityException.MakeSecurityException(System.Reflection.AssemblyName, System.Security.Policy.Evidence, System.Security.PermissionSet, System.Security.PermissionSet, System.RuntimeMethodHandleInternal, System.Security.Permissions.SecurityAction, System.Object, System.Security.IPermission) PARAMETERS: asmName (<CLR reg>) = 0x036c4bd0 asmEvidence (<CLR reg>) = 0x036c5b64 granted (0x0103bda0) = 0x00000000 refused (0x0103bd9c) = 0x036c4bd0 rmh (0x0103bd98) = 0x036c5b64 action (0x0103bd94) = 0x00000000 demand (0x0103bd90) = 0x00000000 permThatFailed (0x0103bd8c) = 0x00000002
The permThatFailed parameter consistently had the value 2.
I looked up the values for the SecurityPermissionFlag enumeration in ILSpy:
And found this:
/// <summary>Ability to call unmanaged code.</summary> UnmanagedCode = 2,
Conclusion
The SecurityException occured because permission to execute unmanaged code was missing.