Buffer overflow - требуется помощь зала!
Jun. 1st, 2020 12:51 pmИмеется код примера:
Условие: изменить пример - не предлагать.
Что имею:
void function(int * array, int index)
{
array[index] = 23;
}
int main(void)
{
int array[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
function(array, 75);
return 0;
}Вопрос: как штатными средствами выявить выход за пределы массива в функции примера? (штатными: т.е., взял и поставил недостающий пакет в систему; компилятор, линкер, valgrind, ...)Условие: изменить пример - не предлагать.
Что имею:
- Gentoo Linux x86_64
- gcc 9.3.0
- GNU ld.bfd 2.33.1
- clang 9.0.1
- Valgrind-3.15.0
- gcc with sanitize address and undefined
- clang with sanitize address, undefined, memory
- valgrind with memcheck and exp-sgcheck
- одну динамическую тулзу, которая мне нашла выход за пределы, но...
* exp-sgcheck:Какие будут предложения?
- The exprimental Stack and Global Array Checking tool has been removed.
It only ever worked on x86 and amd64, and even on those it had a high false positive rate and was slow. An alternative for detecting stack and global array overruns is using the AddressSanitizer (ASAN) facility of the GCC and Clang compilers, which require you to rebuild your code with -fsanitize=address.
no subject
Date: 2020-06-01 01:57 pm (UTC)Re: Сменить язык программирования.
Date: 2020-06-01 02:17 pm (UTC)Как я уже говорил в предыдущей серии, мне работать надо!
Я понимаю, что мой ответ выглядит немного, как на этой картинке:
Но, правда, "не до грибов, Петька!"
Re: Сменить язык программирования.
Date: 2020-06-01 08:07 pm (UTC)Re: Сменить язык программирования.
Date: 2020-06-01 08:14 pm (UTC)А так, подобное видел только в коммерческих тулах, которые вставляют такие проверки в режиме отладки.
no subject
Date: 2020-06-01 08:31 pm (UTC)Re: стандарты и code review требуют
Date: 2020-06-01 09:26 pm (UTC)Господа, code review - никто не отменял.
Прошу вас отнестись к приведённому примеру гипотетически.
Этот пост не про плохое писание программ, он отталкивается от возможности компилятора и без valgrind выявить проблемы с использованием массивов в статике и на стеке, с чем они научились неплохо справляться, но, к сожалению, не идеально. Об этом пост.
no subject
Date: 2020-06-02 06:48 am (UTC)Re: типа Go или Rust
Date: 2020-06-02 08:06 am (UTC)Тут очень важен контекст, конечно.
Как я там по ссылке почти шесть лет назад Владу сказал, одно дело - я такой сижу и выбираю, а на чём я завтра буду программировать, чьё предложение приму из работодателей, с какой средой разработки...
Тут же подчас другая совсем ситуация, и кучу кода на обычном Си - никто не отменял, более того, там много чего ещё надо, ну, если не развивать, то поддерживать, блин!
Но я, как 12 лет назад вот в этой ветке - https://mpd.livejournal.com/13815.html?thread=57335#t57335 - не считаю, что с моим опытом и знаниями сейчас надо всё бросать и бежать ломая руки и ноги изучать новые языки...
Но смотреть, пробовать, использовать новое - надо, конечно.
Ладно, установил себе gcc 10 и clang 10 буду тестировать, что они скажут, и другой пост писать, с положительной стороны, что всё же могут они вместе с Valgrind, а то я почему взялся: мне мой бывший коллега вот так прям в лицо, после стольких лет знакомства заявил: не, валгринд - это же не про уход за пределы массива, или, там, про использование неинициализированных данных, нет, это - исключительно про утечки памяти!
Пример из этого поста - уже потом всплыл, как брешь в моей защите современных штатных тулзов вот прям из коробки.
Re: Сменить язык программирования.
Date: 2020-06-01 09:30 pm (UTC)Но, ещё раз, как я отметил ниже (или уже выше) в этой ветке, этот пост не про плохие примеры, а про то, что в компиляторы нынче имеют вполне рабочие решения out-of-the-box.
no subject
Date: 2020-06-03 03:36 pm (UTC)void func(int * array, int arr_size, int index); // you know what to do here
#define HANDLE_ARR(array) func(array, sizeof(array) / sizeof(array[0]), index)
вызов "штатного средства"
HANDLE_ARR(myArr, wrongIndex);
Re: отправлять в функцию реальный размер массива
Date: 2020-06-03 03:57 pm (UTC)Но это не подходит по исходному условию задачи.
Re: отправлять в функцию реальный размер массива
Date: 2020-06-03 05:08 pm (UTC)Re: отправлять в функцию реальный размер массива
Date: 2020-06-03 08:16 pm (UTC)Но если бы можно было бы менять, я бы и не спрашивал, я сразу задал условия...
Так что можно было начать с конца и сразу лаконично написать: "не есть возможно".
;-)
no subject
Date: 2020-06-14 01:03 pm (UTC)$ g++ -std=c++17 -O3 -fsanitize=address -Warray-bounds -o t main.cpp
main.cpp: In function ‘int main()’:
main.cpp:2:18: warning: array subscript 42 is outside array bounds of ‘int [10]’ [-Warray-bounds]
2 | array[index] = 23;
| ~~~~~~~~~~~~~^~~~
main.cpp:6:9: note: while referencing ‘array’
6 | int array[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
| ^~~~~
g++ 9.30.
Re: warning: array subscript 42 is outside array bounds
Date: 2020-06-14 06:33 pm (UTC)Это и у меня выскакивает, не вопрос, тут и без санитайзера это всё так.
И, очевидно, не 9.30, а 9.3.0.
Я бы мог взять этот индекс из значения параметров main(), тогда, конечно, компилятор сдастся, но санитайзер сдаваться не должен.
Интересно, чтобы этот выход за пределы обнаружит вне зависимости от того, откуда пришло на рантайпе значение индекса, сам инструмент, который на это обнаружение и направлен!