ПроблемаTainted NULL или не-null-termined string ищет строки из небезопасных источников, которые используются в стандартных программах манипуляции строками, которые неявно передают буфер строк. Для примера, strcpy
или sprintf
.
Испорченная строка NULL или строка без обрыв NULL не вызывает дефекта для строки, возвращенной из вызова в scanf
-семейные вариадные функции. Точно так же никакой дефект не поднимается, когда вы передаете строку с %s
спецификатор для printf
-семейные вариадные функции.
Примечание
Если вы ссылаетесь на строку с помощью формы ptr[i]
, *ptr
, или арифметика указателя, Bug Finder поднимает Использование испорченного дефекта указателя вместо этого. Тонированный NULL или не-null-termined строковый дефект повышается только, когда указатель используется в качестве строки.
РискЕсли строка из небезопасного источника, возможно, что атакующий манипулировал строкой или указывал строковый указатель на другое место памяти.
Если строка имеет значение NULL, строковая стандартная программа не может разлучить строку, что приводит к аварийному завершению работы программы. Если строка не оконечна 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
и убедитесь, что строка имеет нулевое значение, прежде чем использовать ее в 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;
}