Выполнение SQL Server среды CLR завершается сбоем с typeInitializationException

Эта статья поможет вам обойти проблему, из-за которой выполнение SQL Server объектов CLR завершается сбоем и возвращает исключение System.TypeInitializationException.

Применяется к: SQL Server
Исходный номер базы знаний: 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] Ошибка платформа .NET Framework произошла во время выполнения определяемой пользователем подпрограммы или агрегата "ваш объект CLR":
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 type)
в System.Data.TypeLimiter.Scope.IsAllowedType(Type type)
в System.Data.TypeLimiter.EnsureTypeIsAllowed(Type type, TypeLimiter capturedLimiter) в 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, boolean isBase)
в System.Data.XSDSchema.HandleParticle(XmlSchemaParticle pt, таблица DataTable, таблица ArrayListChildren, boolean isBase)
в System.Data.XSDSchema.HandleComplexType(XmlSchemaComplexType ct, таблица DataTable, таблица ArrayListChildren, Boolean isNillable)
в System.Data.XSDSchema.InstantiateTable(XmlSchemaElement node, XmlSchemaComplexType typeNode, Boolean isRef)
в System.Data.XSDSchema.HandleTable(Узел XmlSchemaElement)
в System.Data.XSDSchema.HandleParticle(XmlSchemaParticle pt, таблица DataTable, таблица ArrayListChildren, boolean isBase)
в System.Data.XSDSchema.HandleComplexType(XmlSchemaComplexType ct, таблица DataTable, таблица ArrayListChildren, Boolean isNillable)
в System.Data.XSDSchema.InstantiateTable(XmlSchemaElement node, XmlSchemaComplexType typeNode, Boolean isRef)
в System.Data.XSDSchema.HandleTable(Узел XmlSchemaElement)
в System.Data.XSDSchema.LoadSchema(XmlSchemaSet schemaSet, DataSet ds)
в System.Data.DataSet.InferSchema(XmlDocument xdoc, String[] excludedNamespaces, Режим XmlReadMode)
в System.Data.Data...

Разрешение

Эта проблема была исправлена при повторной публикации платформа .NET Framework июля 2020 г. Security-Only Обновления 13 октября 2020 г.

Дополнительные сведения, в том числе о том, как получить исправление, см. в разделе платформа .NET Framework повторной публикации за июль 2020 г. Только Обновления безопасности.

Обходной путь

Предупреждение

Это обходное решение повышает уязвимость компьютера или сети к атакам пользователей-злоумышленников или вредоносных программ, например вирусов. Мы не рекомендуем использовать это решение, но предоставляем эти сведения, чтобы вы могли реализовать это решение по своему усмотрению. Ответственность за использование этого обходного пути несет пользователь.

Для приложений, которые десериализируют ненадежные XML-данные в экземпляр DataSet объектов или DataTable , рекомендуется использовать альтернативный метод для доступа к данным. Для приложений, которые считывают только доверенные XML-данные, можно попробовать одно из следующих обходных решений.

Примечание.

Обходные пути 1 и 2 предпочтительнее, так как изменения вносятся локально. Обходной путь 3 — это общесистемное решение.

Предупреждение

Эти обходные пути устраняют ограничения типов для десериализации XML в экземпляры DataSet объектов и DataTable . Это может открыть дыру безопасности, если приложение считывает ненадежные входные данные.

Решение 1. Вызов AppContext.SetSwitch

Измените начало кода объекта SQL CLR, чтобы задать для параметра Switch.System.Data.AllowArbitraryDataSetTypeInstantiation значение true. Это необходимо сделать для всех применимых объектов СРЕДЫ CLR SQL. См. следующий пример.

Снимок экрана: пример изменения кода объекта СРЕДЫ CLR SQL.

Дополнительные сведения см. в разделе Руководство по безопасности 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.

    Снимок экрана: пример экземпляра SQL Server 2016.

Обходной путь 3. Создание сборки System.Drawing

Вручную создайте сборку System.Drawing в SQL Server из DLL-файла в глобальном кэше сборок (GAC), а затем повторно создайте сборки, использующие 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 объекты CLR, которые не считывают XML в экземпляры DataSet объектов или DataTable , не будут затронуты.