Недавно наша система обнаружения уязвимостей выявила критическую проблему в rBPF Solana (т.е. в виртуальной машине, на которой работают все dApps Solana: https://github.com/solana-labs/rbpf). После тщательного расследования мы обнаружили, что это ошибка переполнения целого числа, которую можно использовать для вывода из строя всей сети Solana. Мы сообщили об этой ошибке команде безопасности Solana, и они немедленно приняли меры для подтверждения и исправления проблемы. На момент написания статьи почти все узлы валидаторов получили исправление и обновились до последней версии, что означает, что публикация информации об уязвимости безопасна.
eBPF и rBPF
Extended Berkeley Packet Filter (eBPF[1]) изначально был разработан для фильтрации пакетов в ядре. Благодаря безопасности, эффективности и масштабируемости eBPF, он теперь используется в различных областях, таких как сетевые технологии, трассировка, профилирование ит.д.[2]. Учитывая широкие возможности eBPF, Solana также выбрала его в качестве движка выполнения для смарт-контрактов. Чтобы создавать dApps на Solana, разработчикам необходимо писать свои смарт-контракты на Rust, которые будут компилироваться в байт-код eBPF.
Для хостинга dApps Solana требуется точная виртуальная машина для eBPF. В данном случае Solana использует rBPF — виртуальную машину для eBPF, написанную на языке Rust. Однако вопрос о том, является ли предложенная виртуальная машина (т.е. rBPF) надежной, безопасной и точной, остается открытым. Как только внутри rBPF возникают проблемы безопасности, это влияет на все валидаторы, использующие rBPF, что приводит к огромным потерям (например, DDoS-атака) для всей сети Solana.
Первопричина ошибки
Мы разработали инструмент для поиска ошибок в rBPF. Этот инструмент все еще находится в стадии активной разработки. В процессе работы в rBPF (версия 0.2.16) была выявлена одна серьезная проблема, которая может вывести из строя всю сеть.
В частности, функция «load» в файле «elf.rs» используется для синтаксического анализа и проверки ELF-файла (смарт-контракта). Сначала функция «load» считывает структуру ELF и вызывает функцию «relocate» для установки смещения вызываемого объекта. Однако в функции «relocate» атрибут «sym.st_value» извлекается напрямую из ELF-файла. Если значение «st_value» достаточно велико, при вычислении «addr» (которое является суммой «sym.st_value» и «refd_pa») может возникнуть переполнение целого числа.

В этом случае злоумышленник может создать вредоносный ELF-файл в качестве смарт-контракта, который вызовет переполнение целого числа. После этого каждый валидатор запустит целевой ELF-файл, и rBPF выдаст ошибку «add with overflow» (переполнение при сложении).

В этот момент rBPF зависнет, и поступающие транзакции не будут выполняться, что приведет к DoS-атаке. Мы можем наблюдать, как узел зависает на этапе «Finalizing transaction» (завершение транзакции), как показано ниже, из-за переполнения целого числа при загрузке ELF-файла.

Эта проблема была внесена в https://github.com/solana-labs/rbpf/pull/200, что означает, что rBPF был уязвим начиная с версии 0.2.14. Мы выявили проблему и сообщили о ней команде безопасности Solana 6 декабря 2021 года. Solana исправила проблему за несколько часов после нашего отчета, применив механизм safemath. Исправление доступно по ссылке: https://github.com/solana-labs/rbpf/pull/236. На момент написания статьи (30.12.2021) более 86% валидаторов обновились до самой новой версии.
[1] https://en.wikipedia.org/wiki/Berkeley_Packet_Filter
[2] https://ebpf.io/
Хронология
- 06.12.2021: проблема была сообщена команде безопасности Solana
- 06.12.2021: уязвимость была исправлена.
- 30.12.2021: информация об этой уязвимости была опубликована
- 28.01.2022: был присвоен номер CVE-2021–46102



