В Rust обнаружили ошибку, которая позволяет обходить ограничения времени жизни ссылок и получать доступ к памяти после того, как она перестала быть действительной.
Проблема затрагивает механизм, который должен защищать программы от подобных ошибок. Баг воспроизводится даже в стабильных версиях Rust и мог существовать минимум с 2015 года.
Читают прямо сейчас:
Обзор языка программирования Rust — как работает borrow checker и что значит гарантия «безопасный код не обращается к недействительной памяти» — именно её нарушает найденный баг
Кибербезопасность: какие бывают уязвимости и как от них защититься — что такое use-after-free и почему это один из самых опасных классов уязвимостей в системном программировании
Что такое сборщик мусора в программировании — как Rust управляет памятью через ownership без GC и почему механизм Drop стал точкой, где система дала сбой
Как работает уязвимость
Один из примеров в отчете использует структуру с обобщенным типом и реализацией Drop — механизма, который выполняет код при уничтожении объекта.
Поле структуры сначала получает пустое значение, а затем в него записывают ссылку на локальную переменную. Компилятор пропускает присваивание, хотя заявленные ограничения требуют, чтобы ссылка оставалась действительной все время жизни программы.
При уничтожении объекта, специально написанный Drop может сохранить такую ссылку и использовать ее позже. В демонстрационном примере программа вместо ожидаемой ошибки компиляции выводит содержимое другой области памяти.
При запуске с AddressSanitizer возникает ошибка stack-use-after-scope — обращение к стековой памяти после завершения времени ее использования.
Насколько серьезна проблема
Участник команды Rust Ларс Кленнер (Lars Klener) отметил, что ошибка получила высокий приоритет.
Изначально ее оценили как критическую, но затем понизили до высокой: за примерно 11 лет существования бага, не появилось свидетельств того, что он часто приводит к проблемам случайно. Для эксплуатации, вероятно, требуется намеренно вредоносная реализация Drop.
При этом редкость случайного срабатывания не делает ошибку безобидной. Она нарушает ключевую гарантию Rust: безопасный код не должен позволять обращаться к недействительной памяти.
Это может приводить к падениям программы, повреждению данных и потенциальным уязвимостям безопасности.
Что будет дальше
Отчет опубликован в официальном репозитории Rust и помечен как проблема безопасности типов и проверки заимствований. Автор одного из примеров сообщил, что его код компилировался еще в Rust 1.18.0, выпущенном в 2017 году.
В обсуждении также нашли другие варианты, способные приводить к чтению освобожденной памяти.
Команда Rust работает над исправлением и усилением системы проверки типов.
Скидка на все курсы Практикума
Раз вы дочитали эту новость до конца, с технологиями у вас всё в порядке. А если давно присматривались к разработке, аналитике, нейросетям, тестированию или кибербезопасности, сейчас туда можно зайти дешевле.
Промокод KOD (можно просто нажать) даст скидку на любой платный курс! А если пока не готовы покупать курс, у Практикума есть бесплатные вводные части.
