exponenta event banner

ISO/IEC TS 17961 [libptr]

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

Описание

Определение правила

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

Реализация Polyspace

Эта проверка проверяет на наличие следующих проблем:

  • Использование функции манипуляции путями без проверки буфера максимального размера.

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

  • Недопустимое использование стандартной стандартной программы строк библиотек.

  • Переполнение целевого буфера при манипуляции строками.

Примеры

расширить все

Проблема

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

Риск

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

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

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

Зафиксировать

Возможные исправления:

  • Используйте buffer size PATH_MAX байты. Если вы получаете буфер из неизвестного источника, прежде чем использовать буфер в качестве аргумента getwd или realpath function, убедитесь, что размер меньше 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 является NULL. Тем не менее, вы должны отселить эту память позже, используя 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 bytes, аргумент getwd является buf + 1, чей разрешенный буфер меньше PATH_MAX байты.

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

Одной из возможных коррекций является использование аргумента массива с размером, равным 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);
    }
}
Проблема

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

Риск

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

Зафиксировать

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

См. примеры исправлений ниже.

Если вы не хотите устранять проблему, добавьте комментарии к своему результату или коду, чтобы избежать другой проверки. Смотрите Адрес Результаты 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;
 }
Проблема

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

Риск

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

Зафиксировать

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

char * strcpy(char * destination, const char* source);
пытается скопировать слишком много байтов в целевой аргумент по сравнению с доступным буфером, ограничивает исходный аргумент перед вызовом strcpy. В некоторых случаях можно использовать альтернативную функцию, чтобы избежать ошибки. Для образца вместо strcpy, можно использовать strncpy для управления количеством скопированных байтов. Смотрите также Результаты интерпретации Bug Finder в интерфейсе пользователя Polyspace Desktop.

См. примеры исправлений ниже.

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

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

Решимость: Undecidable
Введенный в R2019a

[1] Выдержки из стандарта «Техническая спецификация ISO/IEC TS 17961 - 2013-11-15» воспроизводятся с согласия АФНОР. Только оригинальный и полный текст стандарта, опубликованный AFNOR Editions - доступный через веб-сайт www.boutique.afnor.org - имеет нормативное значение.