PANICCODE Telegram 33
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), а потом подставляет лайфтайм, и на этом как раз и ломается

Все, раст сломали, возвращаемся в плюсы?
Конечно же нет, с точки зрения математической модели тут очевидно есть ошибка, и по сути тут просто обычный баг в компиляторе, что он что-то не проверил/проверил неправильно.
Думаю, скоро пофиксят. UPD: Проблема эта старая и давно известная. К сожалению, комплиятор внутри довольно сложно устроен, и просто "закостылять" такую ошибку довольно сложно. Поэтому коммьюнити ждет, когда некоторые большие изменения во внутренней работе компилятора будут вмержены (основная - новый trait solver), и либо эти изменения сразу пофиксят эту проблему, либо на основе них будет намного проще

P.S. а еще там очень забавная лицензия
👍5🤡1



tgoop.com/paniccode/33
Create:
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), а потом подставляет лайфтайм, и на этом как раз и ломается

Все, раст сломали, возвращаемся в плюсы?
Конечно же нет, с точки зрения математической модели тут очевидно есть ошибка, и по сути тут просто обычный баг в компиляторе, что он что-то не проверил/проверил неправильно.
Думаю, скоро пофиксят. UPD: Проблема эта старая и давно известная. К сожалению, комплиятор внутри довольно сложно устроен, и просто "закостылять" такую ошибку довольно сложно. Поэтому коммьюнити ждет, когда некоторые большие изменения во внутренней работе компилятора будут вмержены (основная - новый trait solver), и либо эти изменения сразу пофиксят эту проблему, либо на основе них будет намного проще

P.S. а еще там очень забавная лицензия

BY Panic! At the 0xC0D3


Share with your friend now:
tgoop.com/paniccode/33

View MORE
Open in Telegram


Telegram News

Date: |

While the character limit is 255, try to fit into 200 characters. This way, users will be able to take in your text fast and efficiently. Reveal the essence of your channel and provide contact information. For example, you can add a bot name, link to your pricing plans, etc. With the sharp downturn in the crypto market, yelling has become a coping mechanism for many crypto traders. This screaming therapy became popular after the surge of Goblintown Ethereum NFTs at the end of May or early June. Here, holders made incoherent groaning sounds in late-night Twitter spaces. They also role-played as urine-loving Goblin creatures. Telegram users themselves will be able to flag and report potentially false content. Developing social channels based on exchanging a single message isn’t exactly new, of course. Back in 2014, the “Yo” app was launched with the sole purpose of enabling users to send each other the greeting “Yo.” Read now
from us


Telegram Panic! At the 0xC0D3
FROM American