Выполнение SQL Server CLR не удается с помощью TypeInitializationException

В этой статье помогают решить проблему, при которой выполнение объектов CLR SQL Server и возвращает исключение 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] 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 type)
в System.Data.TypeLimiter.Scope.IsAllowedType(Type type)
в System.Data.TypeLimiter.EnsureTypeIsAllowed (тип, тип 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 table, Boolean isBase)
в System.Data.XSDSchema.HandleParticle (XmlSchemaParticle pt, DataTable table, ArrayList tableChildren, Boolean isBase)
в System.Data.XSDSchema.HandleComplexType(XmlSchemaComplexType ct, таблица DataTable, ArrayList tableChildren, Boolean isNillable)
в System.Data.XSDSchema.InstantiateTable (узел XmlSchemaElement, тип XmlSchemaComplexType, Boolean isRef)
на узле System.Data.XSDSchema.HandleTable (XmlSchemaElement)
в System.Data.XSDSchema.HandleParticle (XmlSchemaParticle pt, DataTable table, ArrayList tableChildren, Boolean isBase)
в System.Data.XSDSchema.HandleComplexType(XmlSchemaComplexType ct, таблица DataTable, ArrayList tableChildren, Boolean isNillable)
в System.Data.XSDSchema.InstantiateTable (узел XmlSchemaElement, тип XmlSchemaComplexType, Boolean isRef)
на узле System.Data.XSDSchema.HandleTable (XmlSchemaElement)
в System.Data.XSDSchema.LoadSchema(XmlSchemaSet schemaSet, DataSet ds)
в System.DataSet.InferSchema (XmlDocument xdoc, String[] excludedNamespaces, XmlReadMode mode)
в 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. Это необходимо сделать для каждого применимого SQL объекта CLR. См. следующий пример.

    Снимок экрана показывает пример изменения кода объекта CLR SQL CLR.

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