Breaking Rust’s memory safety with 1 line of code

preview_player
Показать описание
Discover how Rust's memory safety guarantee was shattered with just one line of code! Dive into the story of a 10-year-old bug in the Rust compiler that allows undefined behavior in safe Rust. Learn how this discovery raises questions about Rust's promise of reliability and what it means for the future of the language.

Рекомендации по теме
Комментарии
Автор

📝Get your *FREE 4-day Rust training* :

letsgetrusty
Автор

0:30 "this defect is surprisingly easy to understand if we just unpack this code a bit"
2:53 "this code is using some very complicated rust features"

jacobamason
Автор

>one line
>looks inside
>multiple lines

Ganerrr
Автор

As a beginner I would have expected you to actually explain the trick Mr. Rust wizard used to trick the compiler. I understand that it tricks the compiler but how does the code do it?I think thats the most interesting part here. Do I also need to be a wizard to understand that trick?

itsmefrancois
Автор

This should be resolved with the new trait solver system

AbelShields
Автор

Absence of `unsafe` does not mean that a malicious dependency is safe (in the colloquial sense) to use. Safe Rust isn't sandboxed.

gamekiller
Автор

"and this defect is easy to understand"
- this guy, right before never explaining the defect

Stdvwr
Автор

If you can guarantee that this vulnerability cannot be accidentally enabled, then I wouldn't count it as a vulnerability. I feel like the backend dev must deliberately write the bad code to introduce the issue. And no, being included in malicious dependency doesn't count, because a malicious dependency can screw you over without triggering a memory corruption exploit.

parlor
Автор

Who have thought, the Rust compiler is not perfect. Need to test if clippy or clippy in pedantic form will notice this.

Yes, its a bug. A bug does not mean the promise is a lie. Rust 2024 is around the corner with a few big changes, including the internal changes. I wonder if that would resolve this bug and why they wasn't able to solve it yet. Maybe it requires some complete rewrites of the backend?

thingsiplay
Автор

If I ever get smart enough to understand this vulnerability, I'll be smart enough to avoid it.

richardbranson
Автор

My attempt to explain it in terms of high school algebra: In algebra, you must avoid dividing by zero or taking the square root of a negative number by adding restrictions, such as restricting "x != 2" when dealing with 1/(x-2). Instead of numbers, Rust have the concept of "lifetimes" to determine when resources are allocated or deallocated, and there can be "restrictions" placed on lifetimes. However, Rust failed to keep track of restrictions in that example and requires a very difficult bug fix.

ProjSHiNKiROU
Автор

"The compiler throws another error, this time yelling..."

You know, I've always thought of the compiler as a very soft spoken and patient teacher, I can really imagine it yelling.

perplexedon
Автор

It looks to me like the reasoning is: if _ &'a &'b is instantiated, then the 'b variables can't be dropped before the 'a variables are in the caller. So Rust assumes "where 'b : 'a" without being explicitly told. In fact you can just write:

fn check<'a, 'b>(x : &'b usize) -> &'a usize where 'b : 'a { x }

just fine. But that "where" assumption is only being added to helper because the compiler is assuming the _ variable is being instantiated.

But then someone showed how to call the function without instantiating the variable, because of the () class, the 0 bit class.

I suspect that if they fix the bug, some valid code will break because the compiler can't prove the supplied type isn't the () type. But that doesn't make sense because it should be a straight forward check after monomorphism. Maybe the compiler would have to be retooled to make post monomorphism checks. Or maybe they are afraid of runtime created types. Which never should have been a thing.

It reminds me of the \forall x P(x) \implies \exists x P(x) problem in first order logic. Holds always except in empty universes.

CarrotCakeMake
Автор

Is there anyone with good knowledge of how this works that can explain why the compiler accepted the helper function. I mean, it should have complained that the output of the function needed to live for at least 'a .

tijljappens
Автор

Amazing, I'm now going to use it everytime rust complains about lifetimes

blablablablablablblablabla
Автор

Look as like they're not back checking the lifetime in a generic when they make it concrete. Or if they are it's not recursive.

NFvidoJagg
Автор

I thought Rust borrow checker has been formally proven to be sound (free of bugs like this)?

rui-lianglyu
Автор

Seems to be fixed with 1.84.0 as the migration to the new trait solver has begun.

SeppJörger
Автор

is there a clippy check for code that exploits this ? Is it possible to check this via static analysis ?

koushikm
Автор

Version 1.83.0 seems to have fixed it.

emanuelbalaban
welcome to shbcf.ru