﻿# Дефекты безопасности, которые устранила команда PVS\-Studio на этой неделе: выпуск N1

Мы решили в меру своих сил регулярно искать и устранять потенциальные уязвимости и баги в различных проектах\. Можно назвать это помощью open\-source проектам\. Можно \- разновидностью рекламы или тестированием анализатора\. Еще вариант \- очередной способ привлечения внимания к вопросам качества и надёжности кода\. На самом деле, не важно название, просто нам нравится это делать\. Назовём это необычным хобби\. Давайте посмотрим, что интересного было обнаружено в коде различных проектов на этой неделе\. Мы нашли время сделать исправления и предлагаем вам ознакомиться с ними\.

![0484_vulnerabilities_N1_ru/image1.png](https://import.viva64.com/docx/blog/0484_vulnerabilities_N1_ru/image1.png)

## Для тех, кто ещё не знаком с инструментом PVS\-Studio

[PVS\-Studio](https://pvs-studio.ru/ru/pvs-studio/) \- это инструмент, который выявляет в коде многие разновидности ошибок и уязвимостей\. PVS\-Studio выполняет статический анализ кода и рекомендует программисту обратить внимание на участки программы, в которых с большой вероятностью содержатся ошибки\. Наилучший эффект достигается тогда, когда статический анализ выполняется регулярно\. Идеологически предупреждения анализатора подобны предупреждениям компилятора\. Но в отличии от компиляторов, PVS\-Studio выполняет более глубокий и разносторонний анализ кода\. Это позволяет ему находить ошибки в том числе и в компиляторах: [GCC](https://pvs-studio.ru/ru/blog/posts/cpp/0425/); LLVM [1](https://pvs-studio.ru/ru/blog/posts/0108/), [2](https://pvs-studio.ru/ru/blog/posts/cpp/0155/), [3](https://pvs-studio.ru/ru/blog/posts/cpp/0446/); [Roslyn](https://pvs-studio.ru/ru/blog/posts/csharp/0363/)\.

Поддерживается анализ кода на языках C, C\+\+ и C\#\. Анализатор работает под управлением Windows и Linux\. В Windows анализатор может интегрироваться как плагин в Visual Studio\.

Для дальнейшего знакомства с анализатором, предлагаем изучить следующие материалы:

* Подробная [презентация](https://www.slideshare.net/Andrey_Karpov/pvsstudio-static-code-analyzer-windowslinux-ccc-2017) на сайте SlideShare\. В формате [видео](https://www.youtube.com/watch?v=kmqF130pQW8&feature=youtu.be) она доступна на YouTube \(47 минут\)\. 
* [Статьи](https://pvs-studio.ru/ru/blog/inspections/) о проверенных открытых проектах\.
* [PVS\-Studio: поиск дефектов безопасности](https://pvs-studio.ru/ru/blog/posts/cpp/0486/)\.

## Потенциальные уязвимости \(weaknesses\)

В этом разделе приведены дефекты, которые попадают под классификацию CWE и, по сути, являются потенциальными уязвимостями\. Конечно, не в каждом проекте дефекты безопасности создают какую\-то практическую угрозу, но хочется продемонстрировать, что мы умеем находить подобные ситуации\.

**1\. CoreFX\. CWE\-476 \(NULL Pointer Dereference\)**

[V3080](https://pvs-studio.ru/ru/docs/warnings/v3080/) Possible null dereference\. Consider inspecting '\_swtFirst'\. MemberLookup\.cs 109

```cpp
if (_swtFirst == null)
{
  _swtFirst.Set(sym, type); // <= 
  ....
}
```

Pull Request: [https://github\.com/dotnet/corefx/pull/16807](https://github.com/dotnet/corefx/pull/16807)

**2\. CoreFX\. CWE\-476 \(NULL Pointer Dereference\)**

[V3080](https://pvs-studio.ru/ru/docs/warnings/v3080/) Possible null dereference\. Consider inspecting 'tabClasses'\. PropertyTabAttribute\.cs 225

```cpp
if (tabClasses != null)                        // <=
{
  if (tabScopes != null && tabClasses.Length != tabScopes.Length)
  {
    ....
  }
  _tabClasses = (Type[])tabClasses.Clone();
}
else if (tabClassNames != null)
{
  if (tabScopes != null &&
      tabClasses.Length != tabScopes.Length)    // <=
  {
    ....
  }
  _tabClassNames = (string[])tabClassNames.Clone();
  _tabClasses = null;
}
```

Pull Request: [https://github\.com/dotnet/corefx/pull/16807](https://github.com/dotnet/corefx/pull/16807)

**3\. CoreFX\. CWE\-476 \(NULL Pointer Dereference\)**

[V3080](https://pvs-studio.ru/ru/docs/warnings/v3080/) Possible null dereference\. Consider inspecting 'BaseSimpleType'\. SimpleType\.cs 368

```cpp
if ((BaseSimpleType == null && otherSimpleType.BaseSimpleType != null)
    &&
    (BaseSimpleType.HasConflictingDefinition(...)).Length != 0) // <=
    return ("BaseSimpleType");
```

Pull Request: [https://github\.com/dotnet/corefx/pull/16807](https://github.com/dotnet/corefx/pull/16807)

**4\. CoreFX\. CWE\-476 \(NULL Pointer Dereference\)**

[V3019](https://pvs-studio.ru/ru/docs/warnings/v3019/) Possibly an incorrect variable is compared to null after type conversion using 'as' keyword\. Check variables 'o', 'other'\. CompilerInfo\.cs 106

```cpp
CompilerInfo other = o as CompilerInfo;
if (o == null)
{
    return false;
}
return CodeDomProviderType == other.CodeDomProviderType && ... // <=
```

Pull Request: [https://github\.com/dotnet/corefx/pull/16807](https://github.com/dotnet/corefx/pull/16807)

**5\. CoreFX\. CWE\-476 \(NULL Pointer Dereference\)**

[V3019](https://pvs-studio.ru/ru/docs/warnings/v3019/) Possibly an incorrect variable is compared to null after type conversion using 'as' keyword\. Check variables 'myObject', 'myString'\. CaseInsensitiveAscii\.cs 46

```cpp
string myString = myObject as string;
if (myObject == null)
{
    return 0;
}
int myHashCode = myString.Length;      // <=
```

PVS\-Studio: fixed vulnerability CWE\-476 \(NULL Pointer Dereference\)

Pull Request: [https://github\.com/dotnet/corefx/pull/16807](https://github.com/dotnet/corefx/pull/16807)

**6\. CoreFX\. CWE\-476 \(NULL Pointer Dereference\)**

[V3019](https://pvs-studio.ru/ru/docs/warnings/v3019/) Possibly an incorrect variable is compared to null after type conversion using 'as' keyword\. Check variables 'a', 'nodeA'\. AttributeSortOrder\.cs 22

[V3019](https://pvs-studio.ru/ru/docs/warnings/v3019/) Possibly an incorrect variable is compared to null after type conversion using 'as' keyword\. Check variables 'b', 'nodeB'\. AttributeSortOrder\.cs 22

```cpp
XmlNode nodeA = a as XmlNode;
XmlNode nodeB = b as XmlNode;
if ((a == null) || (b == null))
    throw new ArgumentException();
int namespaceCompare =
  string.CompareOrdinal(nodeA.NamespaceURI, nodeB.NamespaceURI); // <=
```

Pull Request: [https://github\.com/dotnet/corefx/pull/16807](https://github.com/dotnet/corefx/pull/16807)

**7\. CoreFX\. CWE\-476 \(NULL Pointer Dereference\)**

[V3019](https://pvs-studio.ru/ru/docs/warnings/v3019/) Possibly an incorrect variable is compared to null after type conversion using 'as' keyword\. Check variables 'a', 'nodeA'\. NamespaceSortOrder\.cs 21

[V3019](https://pvs-studio.ru/ru/docs/warnings/v3019/) Possibly an incorrect variable is compared to null after type conversion using 'as' keyword\. Check variables 'b', 'nodeB'\. NamespaceSortOrder\.cs 21

```cpp
XmlNode nodeA = a as XmlNode;
XmlNode nodeB = b as XmlNode;
if ((a == null) || (b == null))
    throw new ArgumentException();
bool nodeAdefault = Utils.IsDefaultNamespaceNode(nodeA); 
bool nodeBdefault = Utils.IsDefaultNamespaceNode(nodeB);
```

Pull Request: [https://github\.com/dotnet/corefx/pull/16807](https://github.com/dotnet/corefx/pull/16807)

**8\. MSBuild\. CWE\-476 \(NULL Pointer Dereference\)**

[V3095](https://pvs-studio.ru/ru/docs/warnings/v3095/) The 'name' object was used before it was verified against null\. Check lines: 229, 235\. Microsoft\.Build\.Tasks GenerateBindingRedirects\.cs 229

[V3095](https://pvs-studio.ru/ru/docs/warnings/v3095/) The 'publicKeyToken' object was used before it was verified against null\. Check lines: 231, 235\. Microsoft\.Build\.Tasks GenerateBindingRedirects\.cs 231

```cpp
private void UpdateExistingBindingRedirects(....)
{
  ....
  var name = assemblyIdentity.Attribute("name");
  var nameValue = name.Value;  // <=
  var publicKeyToken = assemblyIdentity.
                       Attribute("publicKeyToken");
  var publicKeyTokenValue = publicKeyToken.Value;  // <=
  var culture = assemblyIdentity.Attribute("culture");
  var cultureValue = culture == null ? 
                     String.Empty : culture.Value;
  
  if (name == null || publicKeyToken == null)
  {
      continue;
  }  
  ....
}
```

Pull Request: [https://github\.com/Microsoft/msbuild/pull/1829](https://github.com/dotnet/msbuild/pull/1829)

## Прочие ошибки

**1\. MSBuild**

[V3041](https://pvs-studio.ru/ru/docs/warnings/v3041/) The expression was implicitly cast from 'long' type to 'float' type\. Consider utilizing an explicit type cast to avoid the loss of a fractional part\. An example: double A \= \(double\)\(X\) / Y;\. Microsoft\.Build CommunicationsUtilities\.cs 615

```cpp
private static long s_lastLoggedTicks = DateTime.UtcNow.Ticks;
internal static void Trace(....)
{
  ....
  long now = DateTime.UtcNow.Ticks;
  float millisecondsSinceLastLog = 
    (float)((now - s_lastLoggedTicks) / 10000L);
  ....
}
```

Pull Request: [https://github\.com/Microsoft/msbuild/pull/1829](https://github.com/dotnet/msbuild/pull/1829)

**2\. MSBuild**

[V3118](https://pvs-studio.ru/ru/docs/warnings/v3118/) Milliseconds component of TimeSpan is used, which does not represent full time interval\. Possibly 'TotalMilliseconds' value was intended instead\. MSBuild XMake\.cs 629

```cpp
public static ExitType Execute(string commandLine)
{
  ....
  if (!String.IsNullOrEmpty(timerOutputFilename))
  {
      AppendOutputFile(timerOutputFilename, 
                        elapsedTime.Milliseconds);
  }
  ....
}
```

Pull Request: [https://github\.com/Microsoft/msbuild/pull/1829](https://github.com/dotnet/msbuild/pull/1829)

## Заключение

Предлагаем скачать анализатор PVS\-Studio и попробовать проверить ваш проект:

* Скачать [PVS\-Studio для Windows](https://pvs-studio.ru/ru/pvs-studio/download/)
* Скачать [PVS\-Studio для Linux](https://pvs-studio.ru/ru/pvs-studio/download/)

Для снятия [ограничения](https://pvs-studio.ru/ru/docs/manual/0009/) демонстрационной версии, вы можете [написать](https://pvs-studio.ru/ru/about-feedback/) нам, и мы отправим вам временный ключ\.

Для быстрого знакомства с анализатором, вы можете воспользоваться утилитами, отслеживающими запуски компилятора и собирающие для проверки всю необходимую информацию\. См\. описание утилиты [CLMonitoring](https://pvs-studio.ru/ru/docs/manual/0031/) и [pvs\-studio\-analyzer](https://pvs-studio.ru/ru/docs/manual/0036/)\. Если вы работаете с классическим типом проекта в Visual Studio, то всё ещё проще: достаточно выбрать в меню PVS\-Studio команду "Check Solution"\.