tgoop.com/paniccode/33
Create:
Last Update:
Last Update:
Blazingly 🔥 fast 🚀 memory vulnerabilities, written in 100% safe Rust. 🦀
https://github.com/Speykious/cve-rsНашли багу Красиво оформили старую багу в проверке лайфтаймов в компиляторе раста
TL;DR: в этом месте вся магия
https://github.com/Speykious/cve-rs/blob/main/src/lifetime_expansion.rs
Для незнающих: лайфтайм в расте это как бы время жизни переменной. Он существует только во время компиляции, и если очень грубо, то лайфтаймы можно описать на интуитивном уровне как "множество строчек между моментом, где переменная создалась, и где она закончила существовать".
И происходит там что-то такое:
Пусть есть два лайфтайма
'a, 'b
. Если в функцию передавать двойную ссылку &'a &'b
, то из этого следует, что 'b: 'a
, т.е. 'b
должен жить дольше, чем 'a
(иначе, существует момент, в котором верхняя ссылка жива, а внутренняя - нет). Это похоже на множественные операции: 'a
является подмножеством 'b
.Из этого следует, что в таком контексте конвертация
&'b -> &'a
является безопасной: как на множествах, 'a' является частью множества
'b`, и в расте (очевидно) можно конвертировать лайфтаймы в их "подмножества".Это делает первая функция:
// val_a тут только для создания ограничений на лайфтаймы
pub const fn lifetime_translator<'a, 'b, T>(_val_a: &'a &'b (), val_b: &'b T) -> &'a T {
val_b
}
И, как написано в комментариях, сама по себе она ничего не нарушает.
А дальше мы просто засовываем вместо
val_a
переменную с &'static &'static
лайфтаймами ('static
по сути значит, что переменная живет все время выполнения программы, например, такой лайфтайм у констант). И тут компилятор ломается, и почему-то не проверяет, что вызов функции lifetime_translator
невалидный. Это довольно важное замечение: сама функция валидна, но этот конкретный вызов - нет. У функции есть ограничения на лайфтаймы, и мы их по факту не прошли, но компилятор при этом не поругался.Компилятор должен сделать две вещи:
Подставить вместо
'b
минимальный лайфтайм из val_a
и val_b
, а потом проверить, что 'b: 'a
. Но из-за того, что ограничение на лайфтаймы написано не явно, а через двойную ссылку, то компилятор делает эти две вещи отдельно: сначала проверяет, что двойная ссылка валидна (условие 'b: 'a
), а потом подставляет лайфтайм, и на этом как раз и ломаетсяВсе, раст сломали, возвращаемся в плюсы?
Конечно же нет, с точки зрения математической модели тут очевидно есть ошибка, и по сути тут просто обычный баг в компиляторе, что он что-то не проверил/проверил неправильно.
P.S. а еще там очень забавная лицензия
BY Panic! At the 0xC0D3
Share with your friend now:
tgoop.com/paniccode/33