Уязвимость в GCC, позволяющая обойти защиту от переполнения стека

В наборе компиляторов GCC выявлена уязвимость (CVE-2023-4039), позволяющая обойти режим “-fstack-protector”, обеспечивающий защиту от атак, направленных на переполнение стека. Уязвимость проявляется только для приложений, собранных для архитектуры AArch64 и использующих динамическое выделение памяти для переменных. Проблема позволяет атакующему эксплуатировать уязвимости, приводящие к переполнению буфера при работе с динамически выделяемыми структурами, несмотря на включение защиты.

Например, защиту можно обойти при выделения памяти при помощи функции alloca() или использовании в коде массивов переменной длины (VLA, Variable-Length Arrays), предоставляющих возможность указания переменной в качестве размера при создании массива (“void foo(int n){ int m[n];”). Уязвимость не затрагивает ядро Linux, так как использование в коде ядра массивов переменной длины было прекращено в выпуске 4.20 (2018 год).

Защита “-fstack-protector” основана на добавлении в стек после указателей и объектов канареечных меток – случайных последовательностей, неизменность которых проверяется. В случае переполнения буфера в процессе эксплуатации уязвимости канареечная метка оказывается перезаписана другими данными, что приводит к срабатыванию последующей проверки неизменности метки и инициированию аварийного завершения приложения. Суть уязвимости в том, что динамически выделяемые локальные переменные размещаются на системах AArch64 в памяти не до, а после канареечной метки и переполнение динамических переменных не приводит к повреждению метки, т.е. переполнение остаётся необнаруженным.

Release. Ссылка here.