V512. A call of the 'Foo' function will lead to a buffer overflow or underflow.


Анализатор обнаружил потенциально возможную ошибку, связанную с заполнением, копированием или сравнением буферов памяти. Ошибка может приводить к переполнению буфера (buffer overflow) или, наоборот, к его неполной обработке (buffer underflow).

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

Приведем два примера, взятых из реальных приложений.

Пример N1.

MD5Context *ctx;
...
memset(ctx, 0, sizeof(ctx));

Здесь из-за опечатки нулями заполняется не вся структура, а только её часть. Ошибка в том, что вычисляется размер указателя, а не структуры MD5Context. Корректный вариант кода:

MD5Context *ctx;
...
memset(ctx, 0, sizeof(*ctx));

Пример N2.

#define CONT_MAP_MAX 50
int _iContMap[CONT_MAP_MAX];
memset(_iContMap, -1, CONT_MAP_MAX);

В данном примере также неверно указан размер заполняемого буфера. Корректный вариант:

#define CONT_MAP_MAX 50
int _iContMap[CONT_MAP_MAX];
memset(_iContMap, -1, CONT_MAP_MAX * sizeof(int));

Пример N3.

struct MyTime
{
  ....
  int time;
};
MyTime s;
time((time_t*)&s.time);

В данном примере также неверно указан тип 's.time'. В случае, когда используется 64-битный time_t, произойдёт переполнение. Корректный вариант:

struct MyTime
{
  ....
  time_t time;
};
MyTime s;
time(&s.time);

Примечание касательно функции strncpy.

Некоторых программистов удивляет, что анализатор выдает предупреждение V512 на подобный код:

char buf[5];
strncpy(buf, "X", 100);

На первый взгляд может показаться, что функция должна скопировать только 2 байта (символ 'X' и терминальный ноль). Но на самом деле, здесь действительно произойдет выход за пределы массива. Здесь забыто одно свойство функции 'strncpy'. Цитата из описания этой функции на сайте MSDN: If count is greater than the length of strSource, the destination string is padded with null characters up to length count.

Примечание касательно ложных срабатываний.

Так сложилось, что для некоторых проектов, анализатор выдает много ложных срабатываний, предупреждая об использовании, только части массива (buffer underflow). А иногда наоборот, все предупреждения о переполнении буфера являются ложными. В этом случае, вы можете воспользоваться тонкой настройкой диагностического правила.

Для этого можно вписать где-то в текст программы следующие комментарии:

//-V512_UNDERFLOW_OFF
//-V512_OVERFLOW_OFF

Первый комментарий отключает предупреждения в данной единице трансляции о неполном использовании массива, а второй о переполнении. Если написать оба комментария, то это будет аналогично полному отключению диагностического правила V512.

Эти комментарии следует вписать в заголовочный файл, который включается во все другие файлы. Например, таким файлом может быть "stdafx.h". Если вписать этот комментарий в "*.cpp" файл, то он будет действовать только для этого файла.

Согласно Common Weakness Enumeration, потенциальные ошибки, найденные с помощью этой диагностики, классифицируются как CWE-119, CWE-125, CWE-193, CWE-467, CWE-682, CWE-787, CWE-806.

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


Найденные ошибки

Проверено проектов
344
Собрано ошибок
12 970

А ты совершаешь ошибки в коде?

Проверь с помощью
PVS-Studio

Статический анализ
кода для C, C++, C#
и Java

goto PVS-Studio;