Breaking Rust’s memory safety with 1 line of code

แชร์
ฝัง
  • เผยแพร่เมื่อ 16 ม.ค. 2025

ความคิดเห็น • 88

  • @letsgetrusty
    @letsgetrusty  16 ชั่วโมงที่ผ่านมา +3

    📝Get your *FREE 4-day Rust training* :
    letsgetrusty.com/bootcamp

  • @Ganerrr
    @Ganerrr 6 ชั่วโมงที่ผ่านมา +25

    >one line
    >looks inside
    >multiple lines

    • @pearl911
      @pearl911 6 ชั่วโมงที่ผ่านมา +4

      my program is only one line! { second_main(); }

    • @dmdeemer
      @dmdeemer 4 ชั่วโมงที่ผ่านมา +4

      And he didn't explain it. It's some combination of implied lifetimes and variance. I feel uneducated

    • @letsgetrusty
      @letsgetrusty  4 ชั่วโมงที่ผ่านมา +1

      This library allows you do this in 1 line of code: crates.io/crates/fake-static

    • @pearl911
      @pearl911 4 ชั่วโมงที่ผ่านมา

      @ I have seen a very similar video on this exact thing maybe a year ago. I can't find the video. Is this a repost, or was it a different channel?

    • @jackraidenph5791
      @jackraidenph5791 ชั่วโมงที่ผ่านมา

      @@letsgetrusty lol. Those are the same multiple lines, just packed into a library

  • @jacobamason
    @jacobamason 16 ชั่วโมงที่ผ่านมา +116

    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"

    • @letsgetrusty
      @letsgetrusty  15 ชั่วโมงที่ผ่านมา +21

      You got me

    • @yondaime500
      @yondaime500 12 ชั่วโมงที่ผ่านมา +13

      Also "someone just figured out... 10 years ago".

    • @georgehelyar
      @georgehelyar 9 ชั่วโมงที่ผ่านมา +1

      Rest of the rusty owl

    • @daleryanaldover6545
      @daleryanaldover6545 9 ชั่วโมงที่ผ่านมา

      ​@@letsgetrustymy man is indeed rusty 😂

  • @itsmefrancois6825
    @itsmefrancois6825 16 ชั่วโมงที่ผ่านมา +68

    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?

    • @letsgetrusty
      @letsgetrusty  15 ชั่วโมงที่ผ่านมา +19

      You need to be at least a level 38 wizard to understand the trick. Jokes aside I agree with your point. Thank you for the feedback!

    • @samuelfalk8438
      @samuelfalk8438 15 ชั่วโมงที่ผ่านมา +15

      The helper function has an implicit constraint on the lifetimes from the signature, i.e. that 'b >= 'a.
      We then typecast the helper function to set the extra lifetime to static while keeping the implicit constraint. Finally we call helper with a double reference to a static value (&&()) which is valid.
      The compiler is not smart enough to follow the implicit constraint through these steps and misses the fact that 'a in make_static must be static.

    • @BlueishSapphire7
      @BlueishSapphire7 3 ชั่วโมงที่ผ่านมา

      this video I found did a pretty good job explaining it, it involves function parameter lifetime contravariance (a sentence dreamed up by the utterly deranged) th-cam.com/video/vfMpIsJwpjU/w-d-xo.html

  • @AbelShields
    @AbelShields 16 ชั่วโมงที่ผ่านมา +49

    This should be resolved with the new trait solver system

    • @letsgetrusty
      @letsgetrusty  15 ชั่วโมงที่ผ่านมา +8

      Can you provide a link to some info about it?

    • @fntr
      @fntr 15 ชั่วโมงที่ผ่านมา +1

      @@letsgetrusty hes capping

    • @thingsiplay
      @thingsiplay 14 ชั่วโมงที่ผ่านมา +20

      @@letsgetrusty Links most likely get deleted. In the Rust Compiler Development Guide there is a section 50.6. Next-gen trait solving.

    • @dark0sv
      @dark0sv 12 ชั่วโมงที่ผ่านมา

      @@letsgetrusty also check out issues in rust repo with label fixed-by-next-solver

    • @sunofabeach9424
      @sunofabeach9424 2 ชั่วโมงที่ผ่านมา

      which we will get approximately never

  • @gamekiller0123
    @gamekiller0123 14 ชั่วโมงที่ผ่านมา +29

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

    • @BartoszGrabias
      @BartoszGrabias 10 ชั่วโมงที่ผ่านมา +2

      True, but in rust safe and unsafe have very well defined meanings, which are far from the colloquial sense :)

    • @gamekiller0123
      @gamekiller0123 10 ชั่วโมงที่ผ่านมา +2

      @BartoszGrabias My comment is an objection to the notion that fixing soundness bugs has any significant impact on supply chain security, not the use of "safe" by the Rust ecosystem.

    • @BartoszGrabias
      @BartoszGrabias 8 ชั่วโมงที่ผ่านมา

      @@gamekiller0123 Oh, okay, sorry, I misunderstood then. Fully agree on that point.

  • @thingsiplay
    @thingsiplay 16 ชั่วโมงที่ผ่านมา +27

    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?

    • @chiffaonosu
      @chiffaonosu 16 ชั่วโมงที่ผ่านมา +8

      clippy doesn't but miri does

    • @NabekenProG87
      @NabekenProG87 9 ชั่วโมงที่ผ่านมา +1

      Yes, they are in the process of completely rewriting the trait solver. This will fix some long standing bugs

  • @parlor3115
    @parlor3115 9 ชั่วโมงที่ผ่านมา +5

    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.

  • @ilmuoui
    @ilmuoui 16 ชั่วโมงที่ผ่านมา +10

    Ah yes, the doohickey footgun

  • @mr.togrul--9383
    @mr.togrul--9383 16 ชั่วโมงที่ผ่านมา +7

    i think CVE-RS also mentioned this

  • @yuan.pingchen3056
    @yuan.pingchen3056 13 ชั่วโมงที่ผ่านมา +5

    As long as it is memory-safe in actual application scenarios, it is fine, and there is no need to care about the special cases that deliberately make it unsafe.

  • @tijljappens7953
    @tijljappens7953 9 ชั่วโมงที่ผ่านมา +3

    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 .

  • @sunofabeach9424
    @sunofabeach9424 11 ชั่วโมงที่ผ่านมา +3

    yeah I see *&static* I see a disaster

  • @rui-lianglyu7221
    @rui-lianglyu7221 12 ชั่วโมงที่ผ่านมา +2

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

    • @gamekiller0123
      @gamekiller0123 10 ชั่วโมงที่ผ่านมา +5

      @@rui-lianglyu7221 I believe the issue is with the trait solver, but even if it wasn't the formal proof works with a model which doesn't have to correspond to what's actually implemented.

    • @alexdaguy9626
      @alexdaguy9626 4 ชั่วโมงที่ผ่านมา

      i think the formal proof proved only a subset of the language was sound

  • @blablablablablablblablabla
    @blablablablablablblablabla 14 ชั่วโมงที่ผ่านมา +3

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

  • @NFvidoJagg2
    @NFvidoJagg2 14 ชั่วโมงที่ผ่านมา +1

    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.

  • @akashsonar6332
    @akashsonar6332 15 ชั่วโมงที่ผ่านมา +8

    Can you talk about some other topic, features or framework of Rust, move on from that memory safe thing, it's repetitive.
    Build an actual project, that would be more helpfull than always talking about memory.
    No offense !!

    • @letsgetrusty
      @letsgetrusty  14 ชั่วโมงที่ผ่านมา +1

      Sure! What topics would you like me to cover specifically?

    • @blablablablablablblablabla
      @blablablablablablblablabla 14 ชั่วโมงที่ผ่านมา +5

      @@letsgetrusty I would really like a very deep dive into tokio, not just simple stuff that is done in 7 minutes like the other video, but really meat content like how to limit the threads count, how to write your own futures, how to make more than 1 runtimes on dedicated threads, etc. This kind of control is needed to for example make a game that doesnt hiccup

    • @blablablablablablblablabla
      @blablablablablablblablabla 14 ชั่วโมงที่ผ่านมา +1

      @@letsgetrusty And another - lifetimes in structs, and the hell it brings, structs with 8 references and 8 lifetimes type of hell and how to manage it

    • @RainbowPigeon15
      @RainbowPigeon15 9 ชั่วโมงที่ผ่านมา +2

      ​@@letsgetrustysome sugestions:
      Async with tokio is super important to learn for some.
      The clap crate has lots of awesome features for building cli tools.
      Front end libraries like egui and iced would really benefit from more tutorials.

  • @proton46
    @proton46 ชั่วโมงที่ผ่านมา

    Why would a library(even a malicious one), one written by any competent developers ever use this way more complex ways to cast &'a to &'static instead of a actually unsafe code? And supply chain attacks? For what would you even use it for exactly? There are way easier way to do a supply chain attack then to use this bypass, like just writing unsafe code and by that matter you could just open a backdoor in safe-rust.

  • @Sypaka
    @Sypaka 8 ชั่วโมงที่ผ่านมา

    2:57 **sideeyes** What the...

  • @Singlton
    @Singlton ชั่วโมงที่ผ่านมา

    What kind of scenarios that requires you to write code like this?
    Where is your discord link? If not, just create one!!

  • @joefitahiana
    @joefitahiana 8 ชั่วโมงที่ผ่านมา

    it's not working on my end . I use v1.83.0

  • @lMINERl
    @lMINERl 13 ชั่วโมงที่ผ่านมา

    damn since 2015 ! what takes them too long to just fix the damn thing

    • @NabekenProG87
      @NabekenProG87 9 ชั่วโมงที่ผ่านมา

      The current rust solver took a whole PhD to write I think. They have been working on a new one for a while to fix some long standing issues, don't know when it will be released.

  • @kpopalitfonzelitaclide2147
    @kpopalitfonzelitaclide2147 7 ชั่วโมงที่ผ่านมา +1

    Cve-rs

  • @thisguy.-.
    @thisguy.-. 4 ชั่วโมงที่ผ่านมา

    and then theres Box::leak() :D

  • @NuflynMagister
    @NuflynMagister 16 ชั่วโมงที่ผ่านมา +1

    Дякую, Богдане!

  • @kalkidanyishak3455
    @kalkidanyishak3455 16 ชั่วโมงที่ผ่านมา

    Interesting

  • @adrian_sp6def
    @adrian_sp6def 13 ชั่วโมงที่ผ่านมา

    Great

  • @bartek38912051
    @bartek38912051 16 ชั่วโมงที่ผ่านมา +11

    The problem with Rust is that it is too complicated. If something is complicated there is higher probability of making stupid bugs in the code.

    • @zohnannor
      @zohnannor 16 ชั่วโมงที่ผ่านมา +19

      this same reason doesn't prevent a ton of people using c, c++ etc.

    • @thingsiplay
      @thingsiplay 16 ชั่วโมงที่ผ่านมา +32

      Wrong. Its the other way, its actually hard to make those kind of bugs in Rust. The complexity helps with that. In fact its much easier to make these kind of bugs in simple languages, because there are no safe guards in C in example. No, just because Rust is complex and a bit complicated does not mean people will make more stupid bugs in the code. People make less bugs in the code with Rust, thanks to the safe guards.

    • @MartinWoad
      @MartinWoad 16 ชั่วโมงที่ผ่านมา +14

      It is complicated, but not too complicated. It can be too complicated for a simple task. For me Rust is actually super elegant due to static typing and very explicit handling of all types and branches in code. The amount of weird bugs I've gotten in Python just because a function could return or receive many data types is insane.

    • @jboss1073
      @jboss1073 16 ชั่วโมงที่ผ่านมา +1

      I don't disagree but may I ask you what parts of Rust do you have in mind when you say that it is too complicated?
      I am personally waiting for Julia to compile. It is the closest to a simple and fast language. After that there's Crystal (already super fast, but has OOP which to me is a minus), Codon (with Python syntax), mind you I'm talking about high-level languages that target LLVM and become as fast as Rust (as it also targets LLVM) and Go (for a non-LLVM comparison), and of course C and C++ (both of which have both LLVM and non-LLVM targets).
      I like Rust but I would like it more if all the lifetime stuff would go away.

    • @what42pizza
      @what42pizza 16 ชั่วโมงที่ผ่านมา +1

      @@thingsiplay I think bartek was talking about language bugs, and that this language bug exists because of rust's extreme complexity

  • @anon_y_mousse
    @anon_y_mousse 9 ชั่วโมงที่ผ่านมา +1

    Rustaceans won't agree, but people with brains inside their skulls will, that this completely invalidates the promise of safety. Safety isn't just protection from accidents, it's also protection from intentions. Of course, that doesn't mean this can't still be triggered accidentally, and it likewise doesn't mean that it's not likely given that a complete newbie could bang something like this out trying to get around a weird warning or error that pops up in the compiler. The only possible caveat that a Rustacean has here is if it *always* causes a noticeable bug, and it doesn't.

    • @nicholas_obert
      @nicholas_obert 8 ชั่วโมงที่ผ่านมา +3

      I wouldn't say that it completely invalidates the promise of safety, as it's clearly not the case. The fact that the compiler is imperfect does, by the way, imply that developers should always be mindful of what they are doing, as it's always been and should always be. As for the promise of safety, I think we can still consider rust to be by far the best we have ever had despite it not being perfect.

    • @thingsiplay
      @thingsiplay 8 ชั่วโมงที่ผ่านมา +2

      This is an exploit of a bug. Likely being solved with the next big update, where they rewrote the entire trait solver for years. And no, the language safety features is one thing (what Rust promises) and the intentions are another thing. Rust lang designers are not developing the intentions of the end programmer.
      In fact, Rust allows for unsafe code and has the unsafe keyword to mark such intentions. But that does not invalidate the principles of Rust itself.

    • @anon_y_mousse
      @anon_y_mousse 4 ชั่วโมงที่ผ่านมา

      @ Talk about cope. It's a 10 year old bug that is likely never going to be fixed because the developers of the language are making it up as they go along instead of planning things out. By the way, principles can't be invalidated by bugs, and this isn't a principle being invalidated, it's a promise.

    • @thingsiplay
      @thingsiplay 4 ชั่วโมงที่ผ่านมา +1

      @ They could not fix the bug, because it was deeply rooted in the system they were using. And they were working on the a replacement system for the trait solver, which is finally after years of work finished and will be released in one month.

    • @anon_y_mousse
      @anon_y_mousse 2 ชั่วโมงที่ผ่านมา

      @ Even if you're right, that'll still only plug one hole. For starters, they don't think that leaks are unsafe, so they don't prevent any of them, even the obvious ones. And you still have many classes of logic errors that aren't prevented in the slightest. Not to mention FFI because the majority of the world's code is still not written in Rust.

  • @Person-who-exists
    @Person-who-exists 9 ชั่วโมงที่ผ่านมา

    This is why o don’t like rust, it looks absolutely overly convoluted, worse than lisp even

    • @anderdrache8504
      @anderdrache8504 7 ชั่วโมงที่ผ่านมา +5

      This code is convoluted on purpose and not something you would write.

    • @alexdaguy9626
      @alexdaguy9626 4 ชั่วโมงที่ผ่านมา

      oi stop with the lisp disrespect

  • @pankajbatham
    @pankajbatham 5 ชั่วโมงที่ผ่านมา +2

    I compiled your code but it didn't compiled successfully instead it gave me an error as follows:
    ```
    * Executing task: cargo run --package refcell --bin reference_cycles
    Compiling refcell v0.1.0 (/mnt/d/Pankaj Batham/Coding PlayGround/Rust Coding Practice/refcell)
    error: lifetime may not live long enough
    --> src/bin/reference_cycles.rs:86:12
    |
    85 | fn make_static &'static T {
    | -- lifetime `'a` defined here
    86 | let f: fn(_, &'a T) -> &'static T = helper;
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
    error: could not compile `refcell` (bin "reference_cycles") due to 1 previous error
    * The terminal process "cargo 'run', '--package', 'refcell', '--bin', 'reference_cycles'" terminated with exit code: 101.
    * Terminal will be reused by tasks, press any key to close it.
    ```

  • @sxlg_32
    @sxlg_32 10 ชั่วโมงที่ผ่านมา

    "Memory safe" languages make it harder for actual programmers to fully understand what the code is doing. There is a reason it has no place in kernel space.

    • @Madinko12
      @Madinko12 10 ชั่วโมงที่ผ่านมา +8

      Except that it has a place in kernel space.

    • @sxlg_32
      @sxlg_32 10 ชั่วโมงที่ผ่านมา

      ​@Madinko12 if your language panics on memory allocation failure, no it doesn't. Wannabe kernel programmers shouldn't be breaking shit just to use their favorite language. Write a stable kernel in Rust first then we can have that discussion.

    • @Madinko12
      @Madinko12 9 ชั่วโมงที่ผ่านมา +5

      @@sxlg_32 there are safe wrappers for kmalloc already being used in the current Linux kernel. The fact that some piece of software mandates "memory-unsafe" code in some specific places doesn't imply "memory-safe" languages "have no place" in said software. Your fallacy is called "false dilemma", you may want to look that up.

    • @NabekenProG87
      @NabekenProG87 8 ชั่วโมงที่ผ่านมา +2

      ​@@sxlg_32They already wrote a whole driver in Rust??? I agree, panicking is a no go, but actually useful people didn't cry about it and solved the issue. Rust without panicks, crazy what actual problem solving can accomplish

    • @alexdaguy9626
      @alexdaguy9626 4 ชั่วโมงที่ผ่านมา

      I think in terms of Rust, it's not too hard to fully understand what Rust code is doing, the thing that almost nobody understands however is how the compiler chooses to accept and not accept the code, which is what leads to this kind of mistake in the design of the language