11 year old unsoundness bugs found in Rust borrow checker
В Rust обнаружена ошибка типа P-high, позволяющая обойти требования времени жизни полей структуры через ковариантное присваивание. Суть в том, что компилятор некорректно проверяет владение ссылками, помещёнными в обёртку, которая затем хранится в статическом контейнере.
В примере структура Q<T> хранит опциональную ссылку и при уничтожении переносит её в глобальный Mutex<Vec<Box<dyn Any + Send>>>. В main ссылка на локальную строку l присваивается полю q.0, область видимости l завершается, но q уничтожается позже — в момент выхода из блока. Поскольку Q объявлен как Send и 'static, компилятор считает ссылку валидной всё время жизни программы. В результате в статическом векторе оказывается ссылка на уже уничтоженную строку, которую можно безопасно привести к &'static String и распечатать.
Ошибка существует уже 11 лет и не имеет статуса P-critical исключительно из-за её давности — за это время она не была найдена в реальной практике. Для эксплуатации требуется намеренно вредоносная реализация Drop, поэтому случайная утечка памяти маловероятна. При включённом AddressSanitizer программа завершается с ошибкой stack-use-after-scope. Исправление входит в приоритетную программу Types Team по устранению некорректности системы типов.