执行 CLR SQL Server TypeInitializationException 失败

本文帮助您解决 CLR 对象的执行失败SQL Server并返回 System.TypeInitializationException 异常的问题。

适用于:  SQL Server
原始 KB 编号:   4576575

症状

重要

本文包含的信息演示如何帮助降低安全设置或如何关闭计算机上安全功能。 您可以进行这些更改以解决特定问题。 在进行更改之前,建议您评估与在你的特定环境中实施此解决方法相关的风险。 如果实现此解决方法,请执行任何适当的附加步骤来帮助保护计算机。

安装适用的 .NET Framework 更新以修复CVE-2020-1147中描述的漏洞后,执行使用公共语言运行时 (CLR) 生成数据库对象,该集成将 XML 读取到 DataSet 和DataTable安全指南对象中会失败。 这是因为 System.TypeInitializationException 异常具有嵌套 的 FileNotFoundException 异常。 此问题指示无法加载 System.Drawing 程序集。

有关参考,请参阅以下示例:

Msg 6522, Level 16, State 1, Procedure [your CLR object], Line 0 [Batch Start Line 0] A .NET Framework error occurred during execution of user-defined routine or aggregate "your CLR object":
System.TypeInitializationException:"Scope"的类型初始化程序引发了异常。 ---> System.IO.FileNotFoundException:无法加载文件或程序集"System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken= "或它的依赖项之一。 <Token> 系统找不到指定的文件。
System.TypeInitializationException:
位于 System.Data.TypeLimiter.Scope.IsTypeUnconditionallyAllowed (Type)
位于 System.Data.TypeLimiter.Scope.IsAllowedType (Type 类型)
At System.Data.TypeLimiter.EnsureTypeIsAllowed (Type, TypeLimiter capturedLimiter) at System.Data.DataColumn.UpdateColumnType (Type type, StorageType typeCode)
位于 System.Data.DataColumn。ctor (String columnName, Type dataType, String expr, MappingType type)
位于 System.Data.XSDSchema.HandleElementColumn (XmlSchemaElement elem, DataTable table, Boolean isBase)
at System.Data.XSDSchema.HandleParticle (XmlSchemaParticle pt, DataTable table, ArrayList tableChildren, Boolean isBase)
at System.Data.XSDSchema.HandleComplexType (XmlSchemaComplexType ct, DataTable table, ArrayList tableChildren, Boolean isNillable)
位于 System.Data.XSDSchema.InstantiateTable (XmlSchemaElement 节点,XmlSchemaComplexType typeNode,Boolean isRef)
位于 System.Data.XSDSchema.HandleTable (XmlSchemaElement 节点)
at System.Data.XSDSchema.HandleParticle (XmlSchemaParticle pt, DataTable table, ArrayList tableChildren, Boolean isBase)
at System.Data.XSDSchema.HandleComplexType (XmlSchemaComplexType ct, DataTable table, ArrayList tableChildren, Boolean isNillable)
位于 System.Data.XSDSchema.InstantiateTable (XmlSchemaElement 节点,XmlSchemaComplexType typeNode,Boolean isRef)
位于 System.Data.XSDSchema.HandleTable (XmlSchemaElement 节点)
位于 System.Data.XSDSchema.LoadSchema (XmlSchemaSet schemaSet,DataSet ds)
at System.Data.DataSet.InferSchema (XmlDocument xdoc, String[] excludedNamespaces, XmlReadMode mode)
位于 System.Data.Data...

解决方案

This issue has been fixed in the October 13, 2020 republishing of the .NET Framework July 2020 Security-Only Updates.

有关详细信息,包括如何获取修补程序,请参阅 .NET Framework 2020 年 7 月仅安全更新程序

解决方法

警告

此解决方法可能会使计算机或网络更容易受到恶意用户或恶意软件(如病毒)的攻击。 我们不建议采用此解决方法,但会提供此信息,以便你可以自行决定实现此解决方法。 如果使用此解决方法,需自行承担风险。

对于将不受信任的 XML 数据反作用于任一实例或对象的应用程序,建议您使用替代方法 DataSet DataTable 来访问数据。 对于仅读取受信任 XML 数据的应用程序,可以尝试以下解决方法之一。

备注

首选解决方法 1 和 2,因为更改是在本地进行。 解决方法 3 为系统范围。

警告

这些解决方法可删除用于将 XML 反列表化为 和 对象的实例的类型 DataSet DataTable 限制。 如果应用程序读取不受信任的输入,这可能会打开一个安全漏洞。

  • 解决方法 1:调用 AppContext.SetSwitch

    更改 CLR 对象代码SQL将 Switch.System.Data.AllowArbitraryDataSetTypeInstantiation 开关设置为 true。 您必须针对每个适用的 CLR 对象SQL此操作。 请参阅以下示例。

    Screenshot shows an example of the SQL CLR object code change.

    有关详细信息,请参阅 DataSet 和 DataTable 安全指南

  • 解决方法 2:为每个适用实例 Sqlservr.exe.config 文件

    此解决方法仅适用于实例本身。

    重要

    我们不能保证此更改不会被更新或实例SQL Server覆盖。 建议您确定在实例更新或升级后更改是否仍然存在。

    1. Sqlservr.exe.config实例的默认和命名实例的文件位置中查找SQL Server:

      %ProgramFiles%\Microsoft SQL Server\<Instance_ID>.<Instance Name>\MSSQL\Binn\

    2. <runtime> 节点内,但在任何嵌套节点外部,添加以下行:

      <AppContextSwitchOverrides value="Switch.System.Data. AllowArbitraryDataSetTypeInstantiation=true"/>
      
    3. 保存文件,然后重新启动实例。

      请参阅以下示例的 SQL Server 2016 实例。

      Screenshot shows an example of SQL Server 2016 instance.

  • 解决方法 3:创建 System.Drawing 程序集

    从全局程序集缓存 (GAC) 中的 DLL 文件在 SQL Server 中手动创建 System.Drawing 程序集,然后重新创建使用 DataSet.ReadXML 或 DataTable.ReadXML 的程序集。 例如:

    CREATE ASSEMBLY [Drawing] FROM 'C:\Windows\Microsoft.NET\assembly\GAC_MSIL\System.Drawing\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Drawing.dll' WITH PERMISSION_SET = UNSAFE GO
    
  • 解决方法 4:创建注册表子项

    重要

    请仔细按照此解决方法中的步骤操作。 对注册表修改不当可能会导致严重问题。 修改之前,备份注册表以便在发生问题时进行还原

    此解决方法将影响服务器上的所有 .NET 应用程序。 因此,如果您无法使用其他解决方法,则只应使用此方法作为最后手段。

    1. 打开注册表编辑器。

    2. 找到以下子项:

      KEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\AppContext

    3. 创建REG_SZ值,如下所示。

      名称 Switch.System.Data.AllowArbitraryDataSetTypeInstantiation
      true
    4. 重新启动所有SQL Server实例。

      请参阅以下示例。

      注册表编辑器中 AppContext 注册表项的屏幕截图。

更多信息

此问题由最近一次更新的 .NET Framework 操作导致,.NET Framework XML 内容标记验证。 SQL Server将 XML 读取到或 对象的实例中的 CLR DataSet DataTable 对象不会受到影响。