Почему электрический забор / Valgrind не может уловить проблему переполнения буфера?

Я создал программу с ошибками — buggy.c — это сценарий переполнения буфера для буфера t.
Вы можете видеть, что я пишу более 5 индексов. Работает нормально. Это никогда не бросает мне ошибку. Мне было интересно, почему это так? Я пробовал даже Valgrind, это также не может найти эту проблему. Подскажите, пожалуйста, в чем здесь проблема?

void buffer_overflow(void)
{
int t[5];
int i = 0;

for(i = 0; i<=7; i++)
{
t[i] = i;

}/** this will cause buffer overflow **/
printf("Memory_overflow_completed\r\n");

}int main(int argc, char **argv)
{

buffer_overflow();

return 0;
}

$gcc -g buggy.c -o buggy.out -lefence

$./buggy.out

Тем не менее, я не получаю никакого сбоя. Здесь нет эффекта электрического забора.
Что мне не хватает?
Я видел аналогичный вопрос, размещенный здесь GCC с библиотекой электрического забора не вступает в силу, но, похоже, ответа пока нет.
Я запускаю этот пример на FC19. У кого-нибудь есть ответ на это? Даже Valgrind не может обнаружить проблему? Есть ли другой инструмент для обнаружения этих проблем?

Основываясь на дальнейших комментариях, я пересмотрел функцию переполнения буфера, чтобы она была обнаружена Electric Fence. Однако Electric Fence не может обнаружить проблему. Вот модифицированная функция.

void buffer_overflow(void)
{

#if 0
int t[5];
int i = 0;

for(i = 0; i<=7; i++)
{
t[i] = i;

}
#endif

char *t = malloc(sizeof(char)*7);
strcpy(t,"SHREYAS_JOSHI");/** this will cause buffer overflow **/
printf("Memory_overflow_completed\r\n");
free(t);

}

[joshis1@localhost blogs-tune2wizard]$ gcc -g buggy.c  -o buggy.out -lefence

[joshis1@localhost blogs-tune2wizard]$ ./buggy.out

Electric Fence 2.2.2 Copyright (C) 1987-1999 Bruce Perens <[email protected]>
Memory_overflow_completed

Electric Fence не обнаружил никаких ошибок, но Valgrind по крайней мере показал это.

4

Решение

Valgrind ограничен наличием только двоичного файла. Если вы не возражаете против того, чтобы в ваш код был вставлен какой-либо инструментарий (компилятором), вы можете попробовать дезинфицирующее средство для адресов. Он отравляет память вокруг выделенных областей (даже в стеке), а затем проверяет каждое чтение / запись, поэтому у него больше шансов обнаружить эти проблемы.

Он интегрирован в текущий gcc (4.8+) и clang (3.2+)
Просто скомпилируйте ваш код так:

gcc -g buggy.c  -o buggy.out -fsanitize=address

После выполнения он печатает что-то вроде:

==26247== ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7fff9fa0be54 at pc 0x4008df bp 0x7fff9fa0be00 sp 0x7fff9fa0bdf8
WRITE of size 4 at 0x7fff9fa0be54 thread T0

и трассировка стека.

Чендлер Каррут говорил об этом в этот разговор на GN13

Примечание: поддерживается даже в clang 3.1, но коммутатор называется -faddress-sanitizer вместо -fsanitize=address,

11

Другие решения

Бег valgrind --tool=exp-sgcheck ./buggy.out и он должен быть в состоянии обнаружить, что у вас переполнение буфера в локальной переменной t[5]

2

Valgrind и EF обнаруживают ошибки в динамически выделяется объем памяти. Ваш массив не распределяется динамически.

0

Цитирование из Вальгринда Инструкция по началу работы: «Например, он не может обнаружить чтение или запись вне диапазона для массивов, которые размещены статически или в стеке».

0

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

Тот, который мы только начали использовать на работе Klocwork

Как уже упоминалось на Valgrind вики-страница (в рамках ограничений memcheck), он не может обнаружить доступ из-за ограничений на статически выделенную память.
Цитата из вики:

Экспериментальный инструмент valgrind exp-sgcheck был написан для устранения этого ограничения в Memcheck. Он обнаружит ошибки переполнения массива при условии, что первый доступ к массиву находится в границах массива.

0
По вопросам рекламы [email protected]