почему вызов free () после переполнения кучи приводит к cra sh - какова точная причина? - PullRequest
0 голосов
/ 04 мая 2020

Я написал простую программу для переполнения кучи (предоставляющую больший ввод, чем выделенная память), и когда я пытаюсь распечатать этот ввод, я получаю полную строку (потому что поиск выполняется до тех пор, пока мы не встретим '\ 0' в памяти ), до этой части все ясно.

Но когда я позвонил free(), система потерпела крах и получила сообщение об ошибке, подобное этому

free() invalid next size (fast) aborted (core dumped): some_address

, здесь адрес указывает на базовый адрес память, выделенная через malloc.

Ниже мой код

#include <stdio.h>
#include <stdlib.h>
int main()
{
    char *string = (char*)malloc(sizeof(char)*10);
    scanf("%s", string);     //intentionally i am providing input much longer than 10 bytes
    printf("\n string input given by user is %s\n", string);
    free(string);

    return 0;
}

на пути к точному пониманию причины этого крэ sh, я узнал, какие метаданные живут одновременно и свободные чанки содержат, и немного о «бинах», управляемых GLIB C.

Я узнал, метаданные, которыми является живое хранилище чанков: размер (указывает, сколько я запросил, и это будет выровнен либо по 8, либо по 16), а также по нескольким битам, которые говорят об арене, предыдущем чанке, вне кучи, и в конце будет указатель на предыдущий чанк (если предыдущий чанк свободен).

Первоначально Я думал, что предыдущий чанк может быть пустым, и когда GLIB C попытался извлечь предыдущий адрес чанка и объединить его с чаном, который я передаю в free (), он обнаружил некоторые значения спама в предыдущем поле указателя чанка из-за переполнения I сделал, но позже, когда я увидел определение функции free() и сообщение об ошибке, более четко, я понял, что это как-то связано с fastbins , и быстрые корзины не объединяют фрагменты с предыдущими фрагментами, поэтому мое предположение неверно.

Может кто-нибудь из вас объяснить точную причину крэ sh? Я пытался читать код и потерял время, когда они делают "chunk_at_offset"

Объяснение из кода и некоторое графическое представление было бы очень полезно

This это ссылка на исходный код, на который я ссылаюсь.

edit: я использую для этого компилятор onlinegdb c, я попробовал то же самое на своем персональном компьютере, где у меня была Ubuntu GLIB C 2.27-3ubuntu1 и моя система довольно стабильна даже для огромного ввода

1 Ответ

0 голосов
/ 05 мая 2020

Может кто-нибудь из вас объяснить точную причину для cra sh?

точная причина для cra sh - реализация кучи внутри GLIB C удалось обнаружить повреждение кучи в данном конкретном случае и вызвать abort().

Как уже говорили другие, вы ведете неопределенное поведение, поэтому что угодно может произойти.

В другой системе, или с другой версией GLIB C, или для другого пользователя, или при установке других переменных окружения этот cra sh может больше не происходить (и это не ошибка ).

Я чувствую, что это неопределенное поведение является просто "неопределенным поведением", что означает, что мы не приложили усилий для анализа того, как система ведет себя.

бессмысленно анализировать поведение системы: вы играете в русскую рулетку. Вам может повезти, и в вашем конкретном окружении оружие либо полностью разряжено, либо полностью заполнено, поэтому вы получаете предсказуемое поведение. Но вы не можете сделать какие-либо выводы из этого - в другой системе, или завтра система может вести себя по-другому.

...