ISO/IEC TS 17961 [libptr]

Формирование недопустимых указателей библиотечной функцией

Описание

Управляйте определением

Формирование недопустимых указателей библиотечной функцией. [1]

Примеры

развернуть все

Описание

Использование функции манипуляции с путями без буферной проверки максимального размера происходит, когда целевой аргумент манипуляции с путями функционирует, такие как realpath или getwd имеет buffer size меньше, чем PATH_MAX байты.

Риск

Буфер, меньшего размера, чем PATH_MAX байты могут переполниться, но вы не можете протестировать функциональное возвращаемое значение, чтобы определить, произошло ли переполнение. Если переполнение происходит, после вызова функции, содержимое буфера не определено.

Например, char *getwd(char *buf) копирует абсолютный путь текущей папки к ее аргументу. Если длина абсолютного пути больше PATH_MAX байты, getwd возвращает NULL и содержимое *buf isundefined. Можно протестировать возвращаемое значение getwd для NULL видеть если вызов функции, за которым следуют.

Однако, если позволенный буфер для buf меньше PATH_MAX байты, отказ может произойти для меньшего абсолютного пути. В этом случае, getwd не возвращает NULL даже при том, что отказ произошел. Поэтому позволенный буфер для buf должен быть PATH_MAX байты долго.

Фиксация

Возможные меры:

  • Используйте buffer size PATH_MAX байты. Если вы получаете буфер из неизвестного источника, перед использованием буфера в качестве аргумента getwd или realpath функционируйте, убедитесь, что размер меньше PATH_MAX байты.

  • Используйте функцию манипуляции с путями, которая позволяет вам задавать buffer size.

    Например, если вы используете getwd чтобы получить абсолютный путь текущей папки, используйте char *getcwd(char *buf, size_t size); вместо этого. Дополнительный аргумент size позволяет вам задавать размер, больше, чем или равный PATH_MAX.

  • Позвольте функции выделять дополнительную память динамически, если это возможно.

    Например, char *realpath(const char *path, char *resolved_path); динамически выделяет память если resolved_path isNull. Однако необходимо освободить эту память позже с помощью free функция.

Пример - возможное переполнение буфера в использовании getwd Функция

#include <unistd.h>
#include <linux/limits.h>
#include <stdio.h>

void func(void) {
    char buf[PATH_MAX];
    if (getwd(buf+1)!= NULL)         {
        printf("cwd is %s\n", buf);
    }
}

В этом примере, несмотря на то, что массив buf имеет PATH_MAX байты, аргумент getwd buf + 1, чей позволенный буфер меньше PATH_MAX байты.

Коррекция — массив использования размера PATH_MAX Байты

Одна возможная коррекция должна использовать аргумент Array с размером, равным PATH_MAX байты.

#include <unistd.h>
#include <linux/limits.h>
#include <stdio.h>

void func(void) {
    char buf[PATH_MAX];
    if (getwd(buf)!= NULL)         {
        printf("cwd is %s\n", buf);
    }
}

Описание

Недопустимое использование стандартной стандартной программы библиотеки memory происходит, когда библиотечная функция памяти вызвана недействительными аргументами. Например, memcpy функционируйте копирует в массив, который не может разместить количество скопированных байтов.

Риск

Использование библиотечной функции памяти с недействительными аргументами может привести к проблемам, таким как переполнение буфера.

Фиксация

Фиксация зависит от первопричины дефекта. Часто детали результата показывают последовательность событий, которые привели к дефекту. Можно реализовать закрепление на любом событии в последовательности. Если детали результата не показывают историю события, можно проследить использование, щелкните правой кнопкой по опциям по исходному коду и смотрите предыдущие связанные события. См. также Интерпретируют Результаты Polyspace Bug Finder.

Смотрите примеры мер ниже.

Если вы не хотите устранять проблему, добавьте комментарии в свой результат или код, чтобы избежать другого анализа. Смотрите Результаты Polyspace Адреса Через Исправления ошибок или Выравнивания.

Пример - недопустимое использование стандартной ошибки стандартной программы библиотеки Memory

#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;
 }

Описание

Недопустимое использование стандартной стандартной программы строки библиотеки происходит, когда библиотечная функция строки вызвана недействительными аргументами.

Риск

Риск зависит от типа недействительных аргументов. Например, использование 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);
}

Проверяйте информацию

Разрешимость: неразрешимый

Введенный в R2019a


[1]  Выписки из стандарта "Техническая характеристика ISO/IEC TS 17961 - 2013-11-15" воспроизводятся с соглашением о AFNOR. Только исходный и полный текст стандарта, как опубликовано Выпусками AFNOR - доступный через веб-сайт www.boutique.afnor.org - имеет нормативное значение.