Инструменты и методы для выявления / предотвращения статического переполнения буфера - PullRequest
3 голосов
/ 27 января 2012

Существуют ли какие-либо инструменты или методы, которые могут определять переполнение буфера в статически определенных массивах (т. Е. char[1234] вместо malloc(1234))?

Большую часть вчерашнего дня я потратил на отслеживание сбоев и странного поведения, которое в итоге оказалось вызвано следующей строкой:

// ensure string is nul terminated due to stupid snprintf
error_msg[error_msg_len] = '\0';

Этот индекс явно вызывал запись за пределы массива. Это приводит к засорению переменной-указателя, что впоследствии приводит к неожиданному поведению с этим указателем.

Три вещи, которые приходят на ум, которые могут помочь облегчить такие проблемы:

  1. Отзыв по коду

    Это не было сделано, но я работаю над этим.

  2. valgrind

    Я часто использую valgrind во время разработки для выявления проблем с памятью, но он не работает со статическими массивами. В приведенном выше примере он только показал мне симптомы, такие как недействительный free() из-за засоренного указателя.

  3. -fstack-protector-all

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

Так может ли кто-нибудь предложить какие-либо идеи о том, как я мог бы определить такие перерасходы? Либо путем улучшения в приведенном выше списке или что-то совершенно новое.

РЕДАКТИРОВАТЬ : В некоторых ответах упоминались коммерческие продукты, которые довольно дороги. На данном этапе я не думаю, что смогу убедить власть в том, чтобы купить такой инструмент, поэтому я бы хотел ограничить использование инструментов дешевым / бесплатным. Да, вы получаете то, за что платите, но некоторые улучшения лучше, чем ничего.

Ответы [ 3 ]

3 голосов
/ 27 января 2012

Инструменты статического анализатора способны обнаруживать некоторые переполнения буфера.

Например, с этим кодом:

char bla[1024];
int i;

for (i = 0; i <= 1024; i++)
    bla[i] = 0;

Вот что сообщает PC-Lint / flexelint:

tst.c 9 Предупреждение 661: возможный доступ за пределами границ указателя (1 за концом данных) оператором '[' [Ссылка: файл tst.c: строки 8, 9]

1 голос
/ 27 января 2012

Пробовали ли вы экспериментальный инструмент Valgrind "SGCheck: экспериментальный стек и детектор переполнения глобального массива" в отличие от стандартного инструмента "memcheck"?

http://valgrind.org/docs/manual/sg-manual.html

Я сам не пробовал, но, похоже, он охватывает некоторые типы ошибок, которые вас интересуют.

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

0 голосов
/ 27 января 2012

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

CheckPointer ловит многие вещи, которые Valgrind не может, например, ссылать за пределы какого-либо поля struct или struct, независимо от того, где оно выделено, включая статические массивы, как в проблеме, показанной OP. Valgrind не может обнаружить такие переполнения, потому что он не имеет ни малейшего представления о фактической форме данных, которыми манипулируют; это требует понимания языка программирования, например, C. Valgrind может обнаруживать ссылки только за пределами выделенной памяти. Checkpointer может сделать это, потому что он хорошо понимает C; для сбора информации о типе и критических размерах используется полноценный интерфейс C в стиле компилятора.

В настоящее время он доступен для C, но еще не для C ++.

...