
Документация уязвимости отказа в обслуживании в ELF-парсере фреймворка обратного проектирования Rizin, вызванной поддельным значением DT_VERNEEDNUM, приводящим к бесконечному циклу.
Rizin — это фреймворк для обратной разработки, ответвлённый от radare2. В его коде анализа ELF-файлов была обнаружена ошибка, которая позволяет с помощью специально созданного файла выполнить отказ в обслуживании. Это не позволит пользователю загрузить файл в rizin, но не повлияет на выполнение самого файла.
Обычный ELF-файл полагается на динамическое связывание/загрузку и поэтому содержит обширную информацию, встроенную в файл. Одной из частей информации является запись DT_VERNEEDNUM в разделе .dynamic. Это поле указывает количество записей в таблице зависимостей версий символов. Следовательно, это значение должно использоваться при анализе каждой зависимости версий, но таблица была спроектирована так, что в последней записи verneed поле vn_next равно 0. Однако вместо того, чтобы проходить по каждой записи до обнаружения конца, rizin выполняет цикл по записям таблицы, используя значение, полученное из записи DT_VERNEEDNUM. Это создаёт ситуации, когда значение DT_VERNEEDNUM может быть подделано до очень большого числа, например 0xFFFFFFFFFFFFFFFF, что заставляет анализатор ELF постоянно обрабатывать последнюю запись, думая, что есть ещё записи для перебора, вычисляя смещение следующей записи с теперь нулевым полем vn_next. Хотя это влияет на анализатор ELF в rizin, это не повлияет на выполнение двоичного файла, поскольку загрузчик Linux обнаружит, что достигнут конец таблицы с ложным DT_VERNEEDNUM. Это даёт простое решение: просто обнаружить, когда vn_next равен нулю, и выйти из цикла.
Ошибка присутствует в версиях до v0.5.0 и была исправлена в коммите 4564986ef29f8872a95733416ce0a860ac2aa7e5, затрагивающем файл и функцию librz/bin/format/elf/elf_info.c:get_gnu_verneed(ELFOBJ *bin).
https://github.com/rizinorg/rizin/pull/3214
https://github.com/rizinorg/rizin/pull/3214/commits/4564986ef29f8872a95733416ce0a860ac2aa7e5