Question about "formal soundness"

I learnt this from various AI. They all told me stuff like the following:

  • The goal of the Rust "Types Team" is to achieve Formal Soundness.
  • Rust is approaching formal sound, though it's not there yet.

Yet I can't really get any search results from Google.
Is AI hallucinating? Or does it know some insider information I can't find?

I am asking the question because it's really important to understand the expectations we can set for type safety and borrow check security.

Will known exploition in cve-rs be finally fixed?
Is a-mir-formality a goal that is currently being pursued?

I would appreciate some insights from the types team.

1 Like

Formal soundness of the type system refers to bugs like these in the type system:


I don't know your expectations, but I've never worried about soundness holes in the type system. I find them to be quite esoteric and unlikely to trigger accidentally, unless you are doing real type gymnastics, in which case you probably are aware of them in the first place.


I'm sure very clever people are working on it.


Yes.


I've never seen a member of t-types post here. You might reach them on IRLO though, or Zulip.

1 Like

cve-rs is not really a formal soundness issue, rather it's a bug in the compiler.

1 Like

They are there to catch bugs that developers make. They are not there to be used as a security boundary. They are too convoluted and complicated for that.

There are few very limited and primitive languages that have achieved in-language sandbox (e.g. SafeTCL is belived to be, well… safe), but cost is extremely high: both your verifier and compiler should be bug-free. That implies language that is both primitive and the one that's [almost] never changes. Rust is not willing to pay that price.

That's unfeasible to expect from a program as complex as Rust compiler.

1 Like

One of the best things that a formal specification allows you to do is “differential fuzz testing”.

You generate some random input (a Rust program), and then pass it through both the slow formal reference compiler, and the fast normal compiler. If they ever give a different output, then you know that something is wrong.

Thanks for your quick responses, guys.

Nevertheless, there are contradictions in your messages. The uncertainty worries me the most.

I understand that you shouldn't mind those soundness holes. After all, even if they are all fixed, there are still hardware-related memory vulnerabilities, such as Spectre and RawHammer, that the CPU vendors can't fix. And software can never truly be secure.

But it means a lot to me in a certain area. For example, Microcontrollers (MCU) hardware don't provide hardware protection like big CPUs. If soundness can be guaranteed, software can be easily verified automatically to provide the same protection as big CPUs. That will be a game-changer. We still don't have it now. But the concept of expectation matters the most.

Why? What do you plan to achieve?

No, it wouldn't. “Hardware protection like big CPUs” is needed if you want to run untrusted code on your CPU. If you run untrusted code then people can (and would) produce ridiculous code that may not even be malicious, but would simply consume all available resources and you would have to deal with that, somehow.

Having MCU is not overkill, in that case, and you would have to spend a lot of ongoing efforts to keep your system usable. Perhaps more then you would spend on keeping it safe.

If you don't plan to run untrusted code, on the other hand, then you don't need security boundary because there are nothing to protect you from.

Confining a process within a sandbox vs. letting a process to hijack your entire system.

The level of risk is quite different. Imagine your smartphone App, what level of security is acceptable? what is risk too high? The boundary has already been set.

What's the difference between a compiler bug and a soundness issue? Rust doesn't have a spec; valid Rust programs are "what rustc compiles." That being said I think at least some of the issues in cve-rs are genuine soundness issues.

I believe that there is a sound language similar to Rust and that most Rust programs would be valid "sound Rust" programs. But we don't have it yet.

Easy: something that's really shouldn't be hijacked, something that actually talks to network is on entirely different piece of silicone.

Separate code, separate memory, access via AT commands, the whole nine yards.

Yes. You do that at hardware level if you want to ensure it'll work. Simple.

Or you do something like WASM sandbox. Less simple, but still possible.

You don't try to do that at language level. It's entirely wrong abstraction for that.

We wouldn't have it in the foreseeable future. Period.

We would need to freeze both language and implementation to even approach some semblance of security. Not feasible, no one would accept that.

Why not if we can? If soundness can be guaranteed, only a few trusted crates are allowed to have unsafe code. It is an easy check.

If that's an authoritative answer, then I will appreciate the clarity. It's much better than uncertainty. How authoritative is it?

Because we can't.

It can not be guaranteed. End of story. Sun tried to do that, spent billions, it simply doesn't work.

No one offered to pour few billions into Rust to make it an explicit goal, so far.

You want to check few millions lines of C++ and Rust code explicitly never designed for such use? Good luck doing that.

What do you mean by “authoritative” here? We couldn't guarantee that there doesn't exist some hidden beneficiary who sits in the “top-sikrit military lab” and develops an alternate Rust implementation designed for security, after all. Stranger things happened.

Rust is open-source, after all

There are dozens of developers who are contributing to the Rust compiler. And I don't know a single one who even contemplates bringing Rust to the level needed to enable such use[1].

We couldn't be sure that such developers don't exist, mind you, just no one was able to find one.

Even if you would, surprisingly, find few such developers it would still require funding that would ensure that others wouldn't break their attempts to create and support secure Rust.

Does it sound realistic to you?


  1. There are few who may contemplate such goal, as purely theoretical possibility, but none who would call it realistic. ↩︎

1 Like

I said "if soundness can be guaranteed ...", then it's an easy check. I don't want to cause any confusion here.

I am no expert. Are type safety and borrow security checks part of compiler developers' responsibility? Rust is a fairly complex system; figuring out who is doing what is valuable information.

Obviously. There are quite a few soundness bugs. Currently there are 103 of them, with different severity.

Some are over 10 years old.

Note that you need to add bugs in Rust to bugs in LLVM. That's more such bugs on top of these: if Rust accepts program that should be, theoretically, safe but then LLVM miscompiles it then this is another attack vector.

You would have to become one, obviously. Doing security boundary (means: opposing hostile adversary) is very different kettle of fish from doing language development (mean: assuming bugs, but no ill intent).

These things are radically different and while knowing that Rust have solid theoretical foundation is interesting research (and yes Rust types are, theoretically, guarantee safety), but doing something that is practically usable is entirely different thing.

Many soundness holes are not closed, because they are very obscure and the only known means of closing them would break existing, safe, programs — and doing “proper” fix is not a priority because, once again, Rust compiler protects against bugs and not against hostile intent.

That's what have done Java, in the end, too: they couldn't find a way to both keep old programs working and to stop breakouts by applet writers (at the end of Java era the majority of applets available on the open web were malware), thus they simply stopped caring and started demanding signatures, instead (and signed applets were always allowed to bypass security, because they were supposed to be “trusted”).

IOW: Rust developers, obviously, care about soundness bugs and want to fix them… but for them it's a balancing act between number of potential program these soundness issues are creating and usability of existing crates.

Turning Rust into a security boundary wasn't contemplated by anyone (well… people with such “bring” ideas arrive on URLO regularly, but there was no one who was willing to spend resources needed to do the job… everyone assumes that Rust developers would do that job for free, out of goodness of their hearts).

2 Likes

103 left doesn't really sound like a lot. I checked out a few. Never thought that they would be so hilarious. Like this will push the stack below the boundary.

#[repr(align(0x10000))]
struct Aligned(u8);

But I am afraid that there would be many more.

I get the impression that Rust is never afraid to break old things. Like they have done that many times.

I believe no one should work for free. Very few languages have safety guarantees. Rust is the only one with C-level efficiency. That gift shouldn't be wasted.

On the contrary: Rust is extremely proud of being extremely backward-compatible. And while formal promise explicitly reserves the right to break compatibility “to patch safety holes”… that's not something that's done lightly.

Rust is not Haskell and not D, that's why you even hear about it today.

Languages that “never afraid to break old things” very rarely become used by industry players.

Care to name these times? There were less than half-dozen incidents where Rust broke things intentionally and only after doing crater run and helping people to upgrade. And even these are not something developers are willing to repeat.

Don't you want to say “very few languages don't have safety guarantees”?

The majority of widely used languages are memory safe, after all, from Java and JavaScript to the Tcl and PHP. Only three languages in the top 20 are not memory safe: C, C++ and Objective-C. I think you see the pattern, no?

C and C++ are rare exceptions.

Yes, but first you need to understand what is actually promised. Again: out of these same Top20 languages only JavaScript and TypeScript provide in-language sandbox (as in: something that is supposed to not just catch bugs, but also stop a hostile adversary)… and they probably have many times more software developers working on them right now than ever touched Rust compiler in its lifetime.

1 Like

I am pretty new to Rust. The one I can recall now is that all of a sudden, it forced unsafe on no_mangle.

Rust and TypeScript are the two languages I chose for my Apps.

That's not a breaking change: unless you explicitly opt-in into Rust 2024 you wouldn't have any problems with the use of no_mangle without unsafe.

But only one of them was literally born to process untrusted code (well, JavaScript was made for that, TypeScript inherited its safety from JavaScript… every single “extra” safety that it promises is more of lint than a gurantee).

1 Like

AFAIK this was an edition-related change, so it didn't break any code unless developers bumped the edition they use.

3 Likes

This back and forth seems a bit strange—the type system being 100% provably sound has very little to do with safely running untrusted code.

After all, a fully type safe application would be delighted to recursively remove all of the files on your filesystem…

6 Likes