CERT C: Rule STR32-C

Не передавайте не пустую отключенную последовательность символов библиотечной функции, которая ожидает строку

Описание

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

Не передавайте не пустую отключенную последовательность символов библиотечной функции, которая ожидает string.[1]

Реализация Polyspace

Это средство проверки проверяет на эти проблемы:

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

  • Испорченный NULL или не пустая отключенная строка.

Примеры

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

Проблема

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

Риск

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

Фиксация

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

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

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

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

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

Испорченный NULL или не пустая отключенная строка не повышает дефекта для строки, возвращенной от вызова до scanf- семейство variadic функции. Точно так же никакой дефект не повышен, когда вы передаете строку с %s спецификатор к printf- семейство variadic функции.

Примечание

Если вы ссылаетесь на строку с помощью формы ptr[i], *ptr, или адресная арифметика с указателями, Средство поиска Ошибки повышает Использование испорченного дефекта указателя вместо этого. Испорченный NULL или не пустой отключенный дефект строки повышен только, когда указатель используется в качестве строки.

Риск

Если строка из небезопасного источника, возможно, что атакующий управлял строкой или указал указатель строки на различную ячейку памяти.

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

Фиксация

Подтвердите строку, прежде чем вы будете использовать ее. Проверяйте что:

  • Строка не является ПУСТОЙ.

  • Строка отключена пустым указателем

  • Размер строки совпадает с ожидаемым размером.

Пример - получение строки от входного параметра
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define SIZE128 128

extern void print_str(const char*);

void warningMsg(char* userstr)
{
    char str[SIZE128] = "Warning: ";
    strncat(str, userstr, SIZE128-(strlen(str)+1));
    print_str(str);
}

void errorMsg(char* userstr)
{
  char str[SIZE128] = "Error: ";
  strncat(str, userstr, SIZE128-(strlen(str)+1));
  print_str(str);
}

В этом примере, строка str конкатенирован с аргументом userstr. Значение userstr неизвестно. Если размер userstr больше доступного пробела, переполнение конкатенации.

Коррекция — подтверждает данные

Одна возможная коррекция должна проверять размер userstr и убедитесь, что строка отключена пустым указателем перед использованием его в strncat. Этот пример использует функцию помощника, sansitize_str, подтверждать строку. Дефекты сконцентрированы в этой функции.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define SIZE128 128

extern void print_str(const char*);

int sanitize_str(char* s) {
  int res = 0; 
  if (s && (strlen(s) > 0)) { // TAINTED_STRING only flagged here
    // - string is not null
    // - string has a positive and limited size
    // - TAINTED_STRING on strlen used as a firewall
    res = 1;
  }
  return res; 
} 

void warningMsg(char* userstr)
{
    char str[SIZE128] = "Warning: ";
    if (sanitize_str(userstr)) 
      strncat(str, userstr, SIZE128-(strlen(str)+1));
    print_str(str);
}

void errorMsg(char* userstr)
{
  char str[SIZE128] = "Error: ";
  if (sanitize_str(userstr))
    strncat(str, userstr, SIZE128-(strlen(str)+1));
  print_str(str);
}
Коррекция — подтверждает данные

Другая возможная коррекция должна вызвать функциональный errorMsg и warningMsg с определенными строками.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define SIZE128 128

extern void print_str(const char*);

void warningMsg(char* userstr)
{
    char str[SIZE128] = "Warning: ";
    strncat(str, userstr, SIZE128-(strlen(str)+1));
    print_str(str);
}

void errorMsg(char* userstr)
{
  char str[SIZE128] = "Error: ";
  strncat(str, userstr, SIZE128-(strlen(str)+1));
  print_str(str);
}

int manageSensorValue(int sensorValue) {
  int ret = sensorValue;
  if ( sensorValue < 0 ) {
    errorMsg("sensor value should be positive");
    exit(1);
  } else if ( sensorValue > 50 ) {
    warningMsg("sensor value greater than 50 (applying threshold)...");
    sensorValue = 50;
  }
  
  return sensorValue;
}

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

Группа: правило 07. Символы и строки (STR)
Введенный в R2019a

[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". УНИВЕРСИТЕТ КАРНЕГИ-МЕЛЛОН НЕ ДАЕТ ГАРАНТИЙ НИКАКОГО ВИДА, ИЛИ ОПИСАЛ ИЛИ ПОДРАЗУМЕВАЛ, ОТНОСИТЕЛЬНО ЛЮБОГО ВОПРОСА ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИЛ, ГАРАНТИЯ ПРИГОДНОСТИ ДЛЯ ЦЕЛИ ИЛИ ВЫСОКОГО СПРОСА, ИСКЛЮЧИТЕЛЬНОСТИ, ИЛИ ЗАКАНЧИВАЕТСЯ ПОЛУЧЕННЫЙ ИЗ ИСПОЛЬЗОВАНИЯ МАТЕРИАЛА. УНИВЕРСИТЕТ КАРНЕГИ-МЕЛЛОН НЕ ДАЕТ ГАРАНТИИ НИКАКОГО ВИДА ОТНОСИТЕЛЬНО СВОБОДЫ ОТ ПАТЕНТА, ТОВАРНОГО ЗНАКА ИЛИ НАРУШЕНИЯ АВТОРСКОГО ПРАВА.

Это программное обеспечение и сопоставленная документация не были рассмотрены, ни являются подтвержденным Университетом Карнеги-Меллон или его Институтом программной инженерии.