exponenta event banner

Запятнанная строка со значением NULL или строка с отличным от NULL окончанием

Аргумент получен из небезопасного источника и может иметь значение NULL или не заканчиваться NULL

Описание

Этот дефект возникает, когда строки из небезопасных источников используются в подпрограммах обработки строк, которые неявно отменяют назначение буфера строк, например, strcpy или sprintf. Чтобы считать все входные данные вне текущего периметра анализа небезопасными, используйте -consider-analysis-perimeter-as-trust-boundary.

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

Риск

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

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

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

Проверьте строку перед ее использованием. Проверьте, что:

  • Строка не имеет значение NULL.

  • Строка имеет нулевое окончание

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

Примеры

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

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define SIZE128 128
#define MAX 40
extern void print_str(const char*);
void warningMsg(void)
{
	char userstr[MAX];
	read(0,userstr,MAX);
	char str[SIZE128] = "Warning: ";
	strncat(str, userstr, SIZE128-(strlen(str)+1));
	print_str(str);
}


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

Исправление - проверка данных

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

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define SIZE128 128
#define MAX 40
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(void)
{
	char userstr[MAX];
	read(0,userstr,MAX);
	char str[SIZE128] = "Warning: ";
	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;
}

Информация о результатах

Группа: Запятнанные данные
Язык: C | C++
По умолчанию: Откл.
Синтаксис командной строки: TAINTED_STRING
Воздействие: Низкий
CWE ID: 120, 170, 476, 690, 822
Представлен в R2015b