Мы используем куки, чтобы пользоваться сайтом было удобно.
Хорошо
to the top
menu mobile close menu
Проверка проектов
Дополнительная информация
toggle menu Оглавление

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.

01 Дек 2023

Анализатор обнаружил, что для работы с объектом класса используются такие низкоуровневые функции, как '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.