Huon Wilson, a Rust contributor, writes about Rust internals, integer overflow, SIMD, QR codes and small projects like 2048 in 4D.
HN commenters like his 2048 4D game and engage closely with his Rust posts on integer overflow and mmap blocking IO.
> I’d love to see a survey talking about what bugs get actually solved by using one of these modern languages like Rust or Swift, since i personally never once in my career had a bug that wouldn’t have happened if i used const, let alone any of the many other annoying Rust features.
A quick analysis I did showed that half of the critical security vulnerabilities in Gecko would have been prevented by writing content and layout code in Rust. The other half were mostly JS issues, often having to do with built-in APIs that would also be safe if appropriately written in Rust (or self-hosted).
> For a “systems programming language”, Rust doesn’t let you do anything i’d expect, like let you specify whether a signed integer is 2s compliment, and how it behaves when it wraps.
Well, this definition of a systems programming language excludes C.
> Instead the programmer is at the whim of the compiler writer, same as in C, and its “undefined behaviour” which is a source of real, hard to track bugs.
Nope. Rust defines signed overflow. http://huonw.github.io/blog/2016/04/myths-and-legends-about-integer-overflow-in-rust/
> Rust doesn’t even have support for modern features like wide registers
What is a "wide register"? Do you mean SIMD? If so, it sure does [1].
> or any features that help you deal with raw memory, it just marks it as “unsafe”.
Sure it does. Rust helps you deal with raw memory by freeing you from the need to deal with raw memory in the vast majority of occasions.…
> You're conflating undefined behavior with spatial/temporal memory safety,
You are correct; I should have written "memory safety".
> Zig treats memory safety not as an extreme-at-all-costs but as a spectrum
Zig needs to be more forthright about this.
When I first heard about Zig, I googled "zig vs rust" and found an article on the Ziglang website addressing that very topic:
https://ziglang.org/learn/why_zig_rust_d_cpp/
It completely fails to mention memory safety at all. That seems extremely dishonest, since memory safety is basically the "headline feature" of Rust (well, one of two or three at most). I wasted a lot of time digging through the Zig language manual ("so then how do they...") before concluding that something didn't add up. It definitely left a bad taste in my mouth.
> Rust won't protect you from all undefined behavior ... Rust has checked arithmetic off by default in safe builds
That didn't surprise me at all, nor will it surprise anybody who knows Java. Modular arithmetic is perfectly well-defined.
It's only C/C++ that picked the crazysauce option of decreeing that signed overflow is totally equivalent to scribbling all over random pieces of memory. It isn't overflow that's a security risk; it's languages that define overflow to be undefined in order to squeeze out a few piddly loop micro-optimizations. This becomes increasingly less beneficial in languages with iterators and no backward-compatible-with-C burden. Details (scroll to "Myth:…
>As for disabling asserts in the code you ship: That is such a quaint 1980'ies thing to do, and people should have stopped doing it long time ago.
Sqlite makes all its asserts noop in release mode[1].
Chrome disables DCHECK() in release mode[2], and it's used many times[3].
RE2 has debug only checking[4].
In Rust debug mode, signed integer overflow panics, in release mode it wraps[5].
Firefox disables MOZ_ASSERT() in release mode[6], and it's used many times[7].
I doubt Huawei is more modern and less 1980s than all these other projects.
>My money is on Huaweis function doing the check with an assert which was compiled out for deliverable code.
Are you saying it was compiled out because asserts were disabled, or because the compiler could reason about the arguments at every callsite? It seems unlikely to me that the compiler could reason about the arguments at every callsite.
[1] https://www.sqlite.org/assert.html
[2] https://chromium.googlesource.com/chromium/src/+/master/styleguide/c++/c++.md#check_dcheck_and-notreached
[3] https://cs.chromium.org/search/?q=DCHECK%5C(+case:yes&sq=package:chromium&type=cs
[4] https://github.com/google/re2/blob/master/util/logging.h
[5] http://huonw.github.io/blog/2016/04/myths-and-legends-about-integer-overflow-in-rust/
[6] https://dxr.mozilla.org/mozilla-central/source/mfbt/Assertions.h#378
[7] https://dxr.mozilla.org/mozilla-central/search?q=MOZ_ASSERT(&redirect=true
> we get continuing bugs and vulnerabilities as a result
Background reading: https://huonw.github.io/blog/2016/04/myths-and-legends-about-integer-overflow-in-rust/
If you only want safety, then trapping or not, signalling or not does not matter at all. It is UB that causes safety problems, not the overflow itself. And RISC-V mandates the overflow handling manner. No UBs.
Throw on arithmetic overflow is a language choice. And at least Rust thinks that arithmetic exception everywhere is not necessary for security.
The only related problem with no overflow trapping is that dynamically typed languages needs numerical type conversion on overflow. But TBH, if a numerical javascript program often generates 1.7E308, then it's a terrible program that no one should care.
The problem with memory management is a problem with lifetime management, which Rust reasons about in terms of ownership management, which it attempts to reason about statically, with help from the programmer. GC attempts to do the same thing, dynamically, with less help from the programmer.
Both of those methods still allow leaks, which is why Rust encourages RAII. [1] Are there other structured lifetimes we can get compilers to enforce for us, like they enforce certain invariants about flow control using control structures?
[1] https://users.rust-lang.org/t/memory-leaks-in-rust/18187/2
http://huonw.github.io/blog/2016/04/memory-leaks-are-memory-safe/
https://doc.rust-lang.org/nomicon/leaking.html
The full write up shows that the exploit is based on a integer underflow that would be easily caught by Zig and any other programming language with sane runtime checks.
Ironically enough this is the one class of bugs that Rust would not have prevented out of the box since the language defines integers to be wrapping and you need to manually opt into runtime checks.
The exploit:
https://secret.club/2021/04/20/source-engine-rce-invite.html
Wrapping in Rust:
https://huonw.github.io/blog/2016/04/myths-and-legends-about-integer-overflow-in-rust/
https://scattered-thoughts.net/writing/how-safe-is-zig/
I hope that explains how inappropriate is the tone of your comment.