Гарантируйте, что библиотечные функции не формируют недопустимые указатели
Гарантируйте, что библиотечные функции не формируют недопустимые указатели. [1]
Это средство проверки проверяет на эти проблемы:
Не сочетайтесь между длиной данных и размером.
Недопустимое использование стандартной стандартной программы библиотеки memory.
Возможное неправильное употребление sizeof.
Переполнение буфера от неправильного спецификатора формата строки.
Недопустимое использование стандартной библиотеки представляет стандартную программу в виде строки.
Целевое переполнение буфера в обработке строк.
Целевое недостаточное наполнение буфера в обработке строк.
Не сочетайтесь между длиной данных, и размер ищет функции копирования памяти, такие как memcpy
, memset
, или memmove
. Если вы не управляете аргументом аргумента длины и буфера данных правильно, Средство поиска Ошибки повышает дефект.
Если атакующий может управлять буфером данных или аргументом длины, атакующий может вызвать переполнение буфера путем создания фактического размера данных меньшим, чем длина.
Это несоответствие в длине позволяет атакующему копировать память мимо буфера данных к новому местоположению. Если дополнительная память содержит уязвимую информацию, атакующий может теперь получить доступ к тем данным.
Этот дефект похож на SSL ошибка Heartbleed.
При копировании или управлении памятью, вычислите аргумент длины непосредственно из данных так, чтобы размеры соответствовали.
#include <stdlib.h>
#include <string.h>
typedef struct buf_mem_st {
char *data;
size_t max; /* size of buffer */
} BUF_MEM;
extern BUF_MEM beta;
int cpy_data(BUF_MEM *alpha)
{
BUF_MEM *os = alpha;
int num, length;
if (alpha == 0x0) return 0;
num = 0;
length = *(unsigned short *)os->data;
memcpy(&(beta.data[num]), os->data + 2, length);
return(1);
}
Эта функция копирует буферный alpha
в буферный beta
. Однако length
переменная не связана с data+2
.
Одна возможная коррекция должна проверять длину вашего буфера против максимального значения минус 2. Эта проверка гарантирует, что у вас есть достаточно пробела, чтобы скопировать данные в beta
структура.
#include <stdlib.h> #include <string.h> typedef struct buf_mem_st { char *data; size_t max; /* size of buffer */ } BUF_MEM; extern BUF_MEM beta; int cpy_data(BUF_MEM *alpha) { BUF_MEM *os = alpha; int num, length; if (alpha == 0x0) return 0; num = 0; length = *(unsigned short *)os->data; if (length<(os->max -2)) { memcpy(&(beta.data[num]), os->data + 2, length); } return(1); }
Недопустимое использование стандартной стандартной программы библиотеки memory происходит, когда библиотечная функция памяти вызвана недействительными аргументами. Например, memcpy
функционируйте копирует в массив, который не может разместить количество скопированных байтов.
Использование библиотечной функции памяти с недействительными аргументами может привести к проблемам, таким как переполнение буфера.
Фиксация зависит от первопричины дефекта. Часто детали результата показывают последовательность событий, которые привели к дефекту. Можно реализовать закрепление на любом событии в последовательности. Если детали результата не показывают историю события, можно проследить использование, щелкните правой кнопкой по опциям по исходному коду и смотрите предыдущие связанные события. См. также Интерпретируют Результаты Polyspace Bug Finder.
Смотрите примеры мер ниже.
Если вы не хотите устранять проблему, добавьте комментарии в свой результат или код, чтобы избежать другого анализа. Смотрите Результаты Polyspace Адреса Через Исправления ошибок или Выравнивания.
#include <string.h>
#include <stdio.h>
char* Copy_First_Six_Letters(void)
{
char str1[10],str2[5];
printf("Enter string:\n");
scanf("%s",str1);
memcpy(str2,str1,6);
/* Defect: Arguments of memcpy invalid: str2 has size < 6 */
return str2;
}
Размер строки str2
5, но шесть символов строки str1
копируются в str2
использование memcpy
функция.
Одна возможная коррекция должна настроить размер str2
так, чтобы это разместило символы, скопированные с memcpy
функция.
#include <string.h> #include <stdio.h> char* Copy_First_Six_Letters(void) { /* Fix: Declare str2 with size 6 */ char str1[10],str2[6]; printf("Enter string:\n"); scanf("%s",str1); memcpy(str2,str1,6); return str2; }
Возможное неправильное употребление sizeof происходит, когда Polyspace® Bug Finder™ обнаруживает возможно непреднамеренные результаты использования sizeof
оператор. Например:
Вы используете sizeof
оператор на имени параметра массива, ожидая размер массивов. Однако имя параметра массива отдельно является указателем. sizeof
оператор возвращает размер того указателя.
Вы используете sizeof
оператор на элементе массива, ожидая размер массивов. Однако оператор возвращает размер элемента массива.
Аргумент размера определенных функций, таких как strncmp
или wcsncpy
является неправильным, потому что вы использовали sizeof
оператор ранее с возможно неправильными ожиданиями. Например:
В вызове функции strncmp(string1, string2, num)
, num
получен из неправильного использования sizeof
оператор на указателе.
В вызове функции wcsncpy(destination, source, num)
, num
не количество широких символов, но размера в байтах, полученных при помощи sizeof
оператор. Например, вы используете wcsncpy(destination, source, sizeof(destination) - 1)
вместо wcsncpy(destination, source, (sizeof(desintation)/sizeof(wchar_t)) - 1)
.
Неправильное использование sizeof
оператор может вызвать следующие проблемы:
Если вы ожидаете sizeof
оператор к размеру возвращаемого массива и используют возвращаемое значение, чтобы ограничить цикл, количество запусков цикла меньше, чем, что вы ожидаете.
Если вы используете возвращаемое значение sizeof
оператор, чтобы выделить буфер, buffer size меньше, чем, чего вы требуете. Недостаточный буфер может привести к результирующим слабым местам, таким как переполнение буфера.
Если вы используете возвращаемое значение sizeof
оператор неправильно в вызове функции, функция не ведет себя, как вы ожидаете.
Возможные меры:
Не используйте sizeof
оператор на имени параметра массива или элементе массива, чтобы определить размер массивов.
Лучшая практика состоит в том, чтобы передать размер массивов как параметр отдельной функции и использовать тот параметр в теле функции.
Используйте sizeof
оператор тщательно, чтобы определить аргумент номера функций, таких как strncmp
или wcsncpy
. Например, для широких строковых функций, таких как wcsncpy
, используйте количество широких символов в качестве аргумента вместо количества байтов.
sizeof
Используемый неправильно, чтобы определить размер массивов#define MAX_SIZE 1024
void func(int a[MAX_SIZE]) {
int i;
for (i = 0; i < sizeof(a)/sizeof(int); i++) {
a[i] = i + 1;
}
}
В этом примере, sizeof(a)
возвращает размер указателя a
а не размер массивов.
Одна возможная коррекция должна использовать, другой означает определять размер массивов.
#define MAX_SIZE 1024 void func(int a[MAX_SIZE]) { int i; for (i = 0; i < MAX_SIZE; i++) { a[i] = i + 1; } }
Переполнение буфера от неправильного спецификатора формата строки происходит когда аргумент спецификатора формата для функций, таких как sscanf
приводит к переполнению или потере значимости в аргументе буфера памяти.
Если спецификатор формата задает точность, которая больше размера буфера памяти, переполнение происходит. Переполнение может вызвать неожиданное поведение, такое как повреждение памяти.
Используйте спецификатор формата, который совместим с размером буфера памяти.
#include <stdio.h>
void func (char *str[]) {
char buf[32];
sscanf(str[1], "%33c", buf);
}
В этом примере, buf
может содержать 32 char
элементы. Поэтому спецификатор формата %33c
вызывает переполнение буфера.
Одна возможная коррекция должна использовать меньшую точность в спецификаторе формата.
#include <stdio.h> void func (char *str[]) { char buf[32]; sscanf(str[1], "%32c", buf); }
Недопустимое использование стандартной стандартной программы строки библиотеки происходит, когда библиотечная функция строки вызвана недействительными аргументами.
Риск зависит от типа недействительных аргументов. Например, использование strcpy
функция с исходным аргументом, больше, чем целевой аргумент, может привести к переполнению буфера.
Фиксация зависит от стандартной библиотечной функции, вовлеченной в дефект. В некоторых случаях можно ограничить аргументы функции перед вызовом функции. Например, если strcpy
функция:
char * strcpy(char * destination, const char* source)
strcpy
. В некоторых случаях можно использовать альтернативную функцию, чтобы избежать ошибки. Например, вместо strcpy
, можно использовать strncpy
управлять количеством скопированных байтов. См. также Интерпретируют Результаты Polyspace Bug Finder.Смотрите примеры мер ниже.
Если вы не хотите устранять проблему, добавьте комментарии в свой результат или код, чтобы избежать другого анализа. Смотрите Результаты Polyspace Адреса Через Исправления ошибок или Выравнивания.
#include <string.h>
#include <stdio.h>
char* Copy_String(void)
{
char *res;
char gbuffer[5],text[20]="ABCDEFGHIJKL";
res=strcpy(gbuffer,text);
/* Error: Size of text is less than gbuffer */
return(res);
}
Строка text
больше в размере, чем gbuffer
. Поэтому функциональный strcpy
не может скопировать text
в gbuffer
.
Одна возможная коррекция должна объявить целевую строку gbuffer
с равным или большим размером, чем исходная строка text
.
#include <string.h> #include <stdio.h> char* Copy_String(void) { char *res; /*Fix: gbuffer has equal or larger size than text */ char gbuffer[20],text[20]="ABCDEFGHIJKL"; res=strcpy(gbuffer,text); return(res); }
Целевое переполнение буфера в обработке строк происходит, когда определенные функции обработки строк пишут в свой целевой буферный аргумент при смещении, больше, чем buffer size.
Например, при вызове функционального sprintf(char* buffer, const char* format)
, вы используете постоянную строку format
из большего размера, чем buffer
.
Переполнение буфера может вызвать неожиданное поведение, такое как повреждение памяти или остановка вашей системы. Переполнение буфера также вводит риск инжекции кода.
Одно возможное решение состоит в том, чтобы использовать альтернативные функции, чтобы ограничить количество записанных символов. Например:
Если вы используете sprintf
чтобы записать отформатированные данные в строку, используйте snprintf
, _snprintf
или sprintf_s
вместо этого осуществлять управление длиной. В качестве альтернативы используйте asprintf
автоматически выделить память, требуемую для целевого буфера.
Если вы используете vsprintf
чтобы записать отформатированные данные от списка аргументов переменной до строки, используйте vsnprintf
или vsprintf_s
вместо этого осуществлять управление длиной.
Если вы используете wcscpy
чтобы скопировать широкую строку, используйте wcsncpy
, wcslcpy
, или wcscpy_s
вместо этого осуществлять управление длиной.
Другое возможное решение состоит в том, чтобы увеличить buffer size.
sprintf
Использование#include <stdio.h>
void func(void) {
char buffer[20];
char *fmt_string = "This is a very long string, it does not fit in the buffer";
sprintf(buffer, fmt_string);
}
В этом примере, buffer
может содержать 20 char
элементы, но fmt_string
имеет больший размер.
snprintf
Вместо sprintf
Одна возможная коррекция должна использовать snprintf
функция, чтобы осуществить управление длиной.
#include <stdio.h> void func(void) { char buffer[20]; char *fmt_string = "This is a very long string, it does not fit in the buffer"; snprintf(buffer, 20, fmt_string); }
Целевое недостаточное наполнение буфера в обработке строк происходит, когда определенные функции обработки строк пишут в свой целевой буферный аргумент при отрицательном смещении с начала буфера.
Например, для функционального sprintf(char* buffer, const char* format)
, вы получаете buffer
от операции buffer = (char*)arr; ... buffer += offset;
. arr
массив и offset
отрицательная величина.
Недостаточное наполнение буфера может вызвать неожиданное поведение, такое как повреждение памяти или остановка вашей системы. Недостаточное наполнение буфера также вводит риск инжекции кода.
Если целевой буферный аргумент следует из адресной арифметики с указателями, смотрите, постепенно уменьшаете ли вы указатель. Зафиксируйте декремент указателя путем изменения или исходного значения перед декрементом или декрементного значения.
sprintf
Использование#include <stdio.h>
#define offset -2
void func(void) {
char buffer[20];
char *fmt_string ="Text";
sprintf(&buffer[offset], fmt_string);
}
В этом примере, &buffer[offset]
при отрицательном смещении из памяти, выделенной buffer
.
Одна возможная коррекция должна изменить значение offset
.
#include <stdio.h> #define offset 2 void func(void) { char buffer[20]; char *fmt_string ="Text"; sprintf(&buffer[offset], fmt_string); }
Группа: правило 06. Массивы (ARR) |
[1] Это программное обеспечение было создано MathWorks, включающим фрагменты: “Веб-сайт SEI CERT-C”, © 2017 Carnegie Mellon University, веб-сайт SEI CERT-C © 2017 Carnegie Mellon University”, CERT SEI C Кодирование Стандарта – Правил для Разработки безопасных, Надежных и Защищенных систем – 2 016 Выпусков”, © 2016 Carnegie Mellon University, and “CERT SEI Стандарт Кодирования C++ – Правил для Разработки безопасных, Надежных и Защищенных систем на C++ – 2 016 Выпусков” © 2016 Carnegie Mellon University, со специальным разрешением от его Института программной инженерии.
ЛЮБОЙ МАТЕРИАЛ УНИВЕРСИТЕТА КАРНЕГИ-МЕЛЛОН И/ИЛИ ЕГО ИНСТИТУТА ПРОГРАММНОЙ ИНЖЕНЕРИИ СОДЕРЖАЛ, ЗДЕСЬ ПРЕДОСТАВЛЯЕТСЯ НА ОСНОВЕ "ASIS". УНИВЕРСИТЕТ КАРНЕГИ-МЕЛЛОН НЕ ДАЕТ ГАРАНТИЙ НИКАКОГО ВИДА, ИЛИ ВЫРАЗИЛ ИЛИ ПОДРАЗУМЕВАЛ, ОТНОСИТЕЛЬНО ЛЮБОГО ВОПРОСА ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИЛ, ГАРАНТИЯ ПРИГОДНОСТИ ДЛЯ ЦЕЛИ ИЛИ ВЫСОКОГО СПРОСА, ИСКЛЮЧИТЕЛЬНОСТИ, ИЛИ ЗАКАНЧИВАЕТСЯ ПОЛУЧЕННЫЙ ИЗ ИСПОЛЬЗОВАНИЯ МАТЕРИАЛА. УНИВЕРСИТЕТ КАРНЕГИ-МЕЛЛОН НЕ ДАЕТ ГАРАНТИИ НИКАКОГО ВИДА ОТНОСИТЕЛЬНО СВОБОДЫ ОТ ПАТЕНТА, ТОВАРНОГО ЗНАКА ИЛИ НАРУШЕНИЯ АВТОРСКОГО ПРАВА.
Это программное обеспечение и сопоставленная документация не были рассмотрены, ни являются подтвержденным Университетом Карнеги-Меллон или его Институтом программной инженерии.
1. Если смысл перевода понятен, то лучше оставьте как есть и не придирайтесь к словам, синонимам и тому подобному. О вкусах не спорим.
2. Не дополняйте перевод комментариями “от себя”. В исправлении не должно появляться дополнительных смыслов и комментариев, отсутствующих в оригинале. Такие правки не получится интегрировать в алгоритме автоматического перевода.
3. Сохраняйте структуру оригинального текста - например, не разбивайте одно предложение на два.
4. Не имеет смысла однотипное исправление перевода какого-то термина во всех предложениях. Исправляйте только в одном месте. Когда Вашу правку одобрят, это исправление будет алгоритмически распространено и на другие части документации.
5. По иным вопросам, например если надо исправить заблокированное для перевода слово, обратитесь к редакторам через форму технической поддержки.