>
>
>
V598. Memory manipulation function is u…


V598. Memory manipulation function is used to work with a class object containing a virtual table pointer. The result of such an operation may be unexpected.

Анализатор обнаружил, что для работы с объектом класса используются такие низкоуровневые функции, как 'memset', 'memcpy', 'memmove', 'memcmp', 'memchr'. Это недопустимо, если класс содержит указатель на таблицу виртуальных функций (vtable).

Если указатель на объект передается в качестве целевого функциям 'memset', 'memcpy' или 'memmove', то они могут испортить vtable. Если указатель передается в качестве источника функциям 'memcpy' или 'memmove', то результат такого копирования может быть непредсказуемым. В случае с функциями 'memcmp' и 'memchr' сравнение или поиск при наличии vtable также может привести к нежелательному результату.

Рассмотрим пример кода:

class MyClass
{
public:
  MyClass();
  virtual ~MyClass();

private:
  int A, B, C;
  char buf[100];
};

MyClass::MyClass()
{
  memset(this, 0, sizeof(*this));
}

Обратите внимание, что в классе есть виртуальный деструктор. Это значит, что в классе присутствует vtable. Программист поленился очищать члены класса по отдельности. Для очистки он использовал функцию 'memset'. Это привет к порче vtable, так как функция 'memset' ничего про него не знает.

Корректный код:

MyClass::MyClass() : A(0), B(0), C(0)
{
  memset(buf, 0, sizeof(buf));
}

Начиная с C++11, можно переписать этот код следующим образом, если требуется инициализировать поля нулями:

class MyClass
{
public:
  MyClass() = default;
  virtual ~MyClass() = default;

private:
  int A = {}, B = {}, C = {};
  char buf[100] = {};
};

Данная диагностика классифицируется как:

  • CWE-665
  • CERT-EXP62-CPP
  • CERT-OOP57-CPP

Взгляните на примеры ошибок, обнаруженных с помощью диагностики V598.