zlacker

[parent] [thread] 27 comments
1. tialar+(OP)[view] [source] 2021-07-20 23:11:14
Not just memory safety. Rust also prevents data races in concurrent programs. And there are a few more things too.

But these tricks have the same root: What if we used all this research academics have been writing about for decades, improvements to the State of the Art, ideas which exist in toy languages nobody uses -- but we actually industrialise them so we can use the resulting language for Firefox and Linux not just get a paper into a prestigious journal or conference?

If ten years from now everybody is writing their low-level code in a memory safe new C++ epoch, or in Zig, that wouldn't astonish me at all. Rust is nice, I like Rust, lots of people like Rust, but there are other people who noticed this was a good idea and are doing it. The idea is much better than Rust is. If you can't do Rust but you can do this idea, you should.

If ten years from now people are writing unsafe C and C++ like it's still somehow OK, that would be crazy.

Imagine it's 1995, you have just seen an Internet streaming radio station demonstrated, using RealAudio.

Is RealAudio the future? In 25 years will everybody be using RealAudio? No, it turns out they will not. But, is this all just stupid hype for nothing? Er no. In 25 years everybody will understand what an "Internet streaming radio station" would be, they just aren't using RealAudio, the actual technology they use might be MPEG audio layer III aka MP3 (which exists in 1995 but is little known) or it might be something else, they do not care.

replies(6): >>deckar+c4 >>pa7ch+K9 >>perryi+7a >>pcwalt+eh >>raxxor+oz1 >>SolarN+kD2
2. deckar+c4[view] [source] 2021-07-20 23:52:29
>>tialar+(OP)
> If ten years from now people are writing unsafe C and C++ like it's still somehow OK, that would be crazy.

It's 26 years after Java was released. Java has largely been the main competitor to C++. I don't see C++ going away nor do I see C going away. And it's almost always a mistake to lump C and C++ developers together. There is rarely an intersection between the two.

I think you do not understand how short 10 years is. There are tons of people still running computers on Sandy Bridge.

replies(1): >>tialar+Dc
3. pa7ch+K9[view] [source] 2021-07-21 00:48:41
>>tialar+(OP)
I remain unconvinced that race proof programs are nearly as big a deal as memory safety. Many classes of applications can tolerate panics and its not a safety or security issue. I don't worry about a parser or server in go like I would in C.

(I realize that racing threads can cause logic based security issues. I've never seen a traditional memory exploit from on racing goroutines though.)

replies(2): >>nyanpa+xc >>tialar+pe
4. perryi+7a[view] [source] 2021-07-21 00:52:37
>>tialar+(OP)
> also prevents data races in concurrent programs.

I have another neat trick to avoid races. Just write single threaded programs. Whenever you think you need another thread, you either don't need it, or you need another program.

replies(1): >>kaba0+QM
◧◩
5. nyanpa+xc[view] [source] [discussion] 2021-07-21 01:17:32
>>pa7ch+K9
I've seen Qt Creator segfault due to the CMake plugin doing some strange QStringList operations on an inconsistent "implicitly shared" collection, that I guess broke due to multithreading (though I'm not sure exactly what happened). In RSS Guard, performing two different "background sync" operations causes two different threads to touch the same list collections, producing a segfault. (These are due to multiple threads touching the same collection/pointers; racing on primitive values is probably less directly going to lead to memory unsafety.)

Apparently in Golang, you can achieve memory unsafety through data races: https://blog.stalkr.net/2015/04/golang-data-races-to-break-m... (though I'm not sure if a workaround has been added to prevent memory unsafety).

◧◩
6. tialar+Dc[view] [source] [discussion] 2021-07-21 01:18:48
>>deckar+c4
> I think you do not understand how short 10 years is. There are tons of people still running computers on Sandy Bridge.

Ten years is about the time since C++ 11. I may be wrong, but I do not regret my estimate.

◧◩
7. tialar+pe[view] [source] [discussion] 2021-07-21 01:36:32
>>pa7ch+K9
A Race in Go is Undefined Behaviour. All bets are off, whatever happens, no matter how strange, is OK.

If you have a race which definitely only touches some simple value like an int and nothing more complicated then Go may be able to promise your problem isn't more widespread - that value is ruined, you can't trust that it makes any sense (now, in the future, or previously), but everything else remains on the up-and-up. However, the moment something complicated is touched by a race, you lose, your program has no defined meaning whatsoever.

replies(1): >>gpdere+PW
8. pcwalt+eh[view] [source] 2021-07-21 02:01:20
>>tialar+(OP)
Well, Zig isn't memory safe (as implemented today; they could add a GC), so it's not a good example of a Rust alternative in this domain. But I agree with your overall point, and would add that you could replace Zig with any one of the dozens of popular memory safe language, even old standbys like Java. The point is not to migrate to one language in particular, but rather to migrate to languages in which memory errors are compiler bugs instead of application bugs.
replies(3): >>tialar+Dj >>dralle+Un >>pron+p41
◧◩
9. tialar+Dj[view] [source] [discussion] 2021-07-21 02:20:57
>>pcwalt+eh
I could have sworn I'd read that Zig's ambition was to be memory safe. Given ten years I don't find that impossible. Indeed I gave C++ the same benefit of the doubt on that timeline. But, when I just searched I couldn't find whatever I'd seen before on that topic.
replies(1): >>dralle+co
◧◩
10. dralle+Un[view] [source] [discussion] 2021-07-21 03:05:12
>>pcwalt+eh
Zig isn't memory safe but it's still leaps and bounds above C.

I have to admire the practicality of the approach they've been taking.

◧◩◪
11. dralle+co[view] [source] [discussion] 2021-07-21 03:08:57
>>tialar+Dj
The Zig approach is "memory safe in practice" vs "memory safe in theory". They don't have any aspirations to total memory safety like Rust, but they want to get most of the way there with a lot less overhead.

Basically they have a lot of runtime checks enabled in debug mode, where you do the majority of your testing, that are then disabled in the release binary.

Additionally the approach they've taken to allocators means that you can use special allocators for testing that can perform even more checks, including leak detection.

I think it's a great idea and a really interesting approach but it's definitely not as rigorous as what Rust provides.

replies(3): >>pcwalt+6u >>adwn+kC >>little+i91
◧◩◪◨
12. pcwalt+6u[view] [source] [discussion] 2021-07-21 04:21:37
>>dralle+co
I don't think Zig is going to be memory safe in practice, unless they add a GC or introduce a Rust-like system. All of the mitigations I've seen come from that language--for example, quarantine--are things that we've had for years in hardened memory allocators for C++ like Chromium PartitionAlloc [1] and GrapheneOS hardened_malloc [2]. These have been great mitigations, but have not been effective in achieving memory safety.

Put another way: Anything you could do in the malloc/free model that Zig uses right now is something you could do in C++, or C for that matter. Maybe there's some super-hardened malloc design yet to be found that achieves memory safety in practice for C++. But we've been looking for decades and haven't found such a thing--except for one family of techniques broadly known as garbage collection (which, IMO, should be on the table for systems programming; Chromium did it as part of the Oilpan project and it works well there).

There is always a temptation to think "mitigations will eliminate bugs this time around"! But, frankly, at this point I feel that pushing mitigations as a viable alternative to memory safety for new code is dangerous (as opposed to pushing mitigations for existing code, which is very valuable work). We've been developing mitigations for 40 years and they have not eliminated the vulnerabilities. There's little reason to think that if we just try harder we will succeed.

[1]: https://chromium.googlesource.com/chromium/src/+/HEAD/base/a...

[2]: https://github.com/GrapheneOS/hardened_malloc

replies(1): >>pron+R41
◧◩◪◨
13. adwn+kC[view] [source] [discussion] 2021-07-21 05:58:52
>>dralle+co
> Basically they have a lot of runtime checks enabled in debug mode, where you do the majority of your testing, that are then disabled in the release binary.

But there's the problem: Testing can't and won't cover all inputs that a malicious attacker will try [1]. Now you've tested all inputs you can think of with runtime checks enabled, you release your software without runtime checks, and you can be sure that some hacker will find a way to exploit a memory bug in your code.

[1] Except for very thorough fuzzing. Maybe. If you're lucky. But probably not.

◧◩
14. kaba0+QM[view] [source] [discussion] 2021-07-21 07:43:07
>>perryi+7a
You do realize that data races can happen between multiple programs as well, when shared resources are used? Which is pretty much a requirement for many things.
replies(1): >>perryi+jK1
◧◩◪
15. gpdere+PW[view] [source] [discussion] 2021-07-21 09:24:15
>>tialar+pe
Of course, but when talking about security, a race in Go would be very hard to exploit.

It is a different story in languages meant to run untrusted code of course.

◧◩
16. pron+p41[view] [source] [discussion] 2021-07-21 10:46:12
>>pcwalt+eh
> Well, Zig isn't memory safe (as implemented today; they could add a GC), so it's not a good example of a Rust alternative in this domain.

While the first part of the sentence is mostly true (although the intention is to make safe Zig memory safe, and unsafe Rust isn't safe either), the second isn't. The goal isn't to use a safe language, but to use a language that best reduces certain problems. The claim that the best way to reduce memory safety problems is by completely eliminating all of them regardless of type and regardless of cost is neither established nor sensical;. Zig completely eliminates overflows, and, in exchange for the cost of eliminating use-after-free, makes detecting and correcting it, and other problems, easier.

◧◩◪◨⬒
17. pron+R41[view] [source] [discussion] 2021-07-21 10:49:12
>>pcwalt+6u
You understand "memory safe in practice" as soundly eliminating all memory safety issues. This is not how I understand it. Zig can exceed Rust's memory safety in practice without soundly eliminating all issues. The reason is that many codebases rely on unsafe code, and finding problems in Zig can be cheaper than finding problems in Rust w/ unsafe. This is even more pronounced when we look at security overall because while many security issues are memory safety issues, many aren't (and most aren't use-after-free bugs); in other words, it's certainly possible that paying to eliminate all use-after-free harms security more than just catching much of it more cheaply. So there is no doubt that Rust programs that don't use unsafe will have fewer use-after-free bugs than Zig programs, but it is very doubtful that they will, on average, be more secure as a result of this tradeoff.
◧◩◪◨
18. little+i91[view] [source] [discussion] 2021-07-21 11:27:47
>>dralle+co
It's not “memory safe in practice”. It's “we provide tools to make our memory unsafe language with as little memory issue as possible”. Is it better than what C or C++ offer out of the box: yes. It's totally reasonable to think that it may be as good as C or C++ with state of the art tooling that most programmers aren't using today because they don't want to invest the effort, so this is a big progress over C.

But this shouldn't be called “memory safety”.

19. raxxor+oz1[view] [source] 2021-07-21 14:06:02
>>tialar+(OP)
I take that bet about C being pretty prominent in 10 years from now.

A language and a memory access model are no panacea. 10 years is like the day after tomorrow in many industries.

◧◩◪
20. perryi+jK1[view] [source] [discussion] 2021-07-21 14:55:29
>>kaba0+QM
Yes, and rust can't prevent those.
replies(1): >>adwn+iR1
◧◩◪◨
21. adwn+iR1[view] [source] [discussion] 2021-07-21 15:26:42
>>perryi+jK1
It can prevent data races in memory shared between processes in the same way it can prevent them in memory shared between threads. Data race prevention isn't built into the Rust language, it is constructed using a combination of the borrow checker and the type system.
replies(1): >>perryi+V12
◧◩◪◨⬒
22. perryi+V12[view] [source] [discussion] 2021-07-21 16:18:16
>>adwn+iR1
As I understand the borrow checker, it wouldn't detect races that result from the interaction of separate processes, since that would be out of the bounds of the compilation unit. But my knowledge is limited in this, so I maybe wrong.
replies(1): >>static+cX2
23. SolarN+kD2[view] [source] 2021-07-21 19:01:19
>>tialar+(OP)
> If ten years from now people are writing unsafe C and C++ like it's still somehow OK, that would be crazy.

I mean to be clear, modern C++ can be effectively as safe as rust is. It requires some discipline and code review, but I can construct a tool-chain and libraries that will tell me about memory violations just as well as rust will. Better even in some ways.

I think people don't realize just how much modern C++ has changed.

replies(1): >>static+tW2
◧◩
24. static+tW2[view] [source] [discussion] 2021-07-21 20:31:48
>>SolarN+kD2
It must have changed a shitload in the last 2-3 years if that's the case. What tools are you referring to? I'm pretty familiar with C++ tooling but I haven't paid attention for a little while.
replies(1): >>SolarN+aB5
◧◩◪◨⬒⬓
25. static+cX2[view] [source] [discussion] 2021-07-21 20:35:32
>>perryi+V12
Rust has no concept of a process, same as it has no concept of a thread. So you'd build a safe abstraction for sharing memory across processes the same way you do today with threads.
◧◩◪
26. SolarN+aB5[view] [source] [discussion] 2021-07-22 17:43:23
>>static+tW2
The modern standard library, plus some helpers is the big part of it. Compiler warnings as errors are very good at capturing bad situations if you follow the rules (e.g. don't allow people to just make raw pointers, follow a rule of 5). I never said it was as easy to do as in rust.

As for tooling, things like valgrind provide an excellent mechanism for ensuring that the program was memory safe, even in it's "unsafe" areas or when calling into external libraries (something that rust can't provide without similar tools anyway).

My broader point is that safety is more than just a compiler saying "ok you did it", though that certainly helps. I would trust well written safety focused C++ over Rust. On the other hand, I would trust randomly written Rust over C++. Rust is good for raising the lower end of the bar, but not really the top of it unless paired with a culture and ecosystem of safety focus around the language.

replies(1): >>tialar+OB7
◧◩◪◨
27. tialar+OB7[view] [source] [discussion] 2021-07-23 11:56:12
>>SolarN+aB5
Address sanitizers and valgrind tell you whether your program did something unsafe while you were analysing, but they can't tell you whether the program can do something unsafe.

Since we're in a thread about security this is a crucial difference. I'm sure Amy, Bob, Charlie and Deb were able to use the new version of Puppy Simulator successfully for hours without any sign of unsafety in the sanitizer. Good to go. Unfortunately, the program was unsafe and Evil Emma had no problem finding a way to attack it. Amy, Bob, Charlie and Deb had no reason to try naming a Puppy in Puppy Simulator with 256 NUL characters, so, they didn't, but Emma did and now she's got Administrator rights on your server. Oops.

In contrast safe Rust is actually safe. Not just "It was safe in my tests" but it's just safe.

Even though it might seem like this doesn't buy you anything when of course fundamental stuff must use unsafe somewhere, the safe/unsafe boundary does end up buying you something by clearly delineating responsibility.

For example, sometimes in the Rust community you will see developers saying they had to use unsafe because, alas, the stupid compiler won't optimise the safe version of their code properly. For example it has a stupid bounds check they don't need so they used "unsafe" to avoid that. But surprisingly often, another programmer looks at their "clever" use of unsafe, and actually they did need that bounds check they got rid of, their code is unsafe for some parameters.

For example just like the C++ standard vector, Rust's Vec is a wasteful solution for a dozen integers or whatever, it does a heap allocation, it has all this logic for growing and shrinking - I don't need that for a dozen integers. There are at least two Rust "small vector" replacements. One of them makes liberal use of "unsafe" arguing that it is needed to go a little faster. The other is entirely safe. Guess which one has had numerous safety bugs.... right.

Over in the C++ world, if you do this sort of thing, the developer comes back saying duh, of course my function will cause mayhem if you give it unreasonable parameters, that was your fault - and maybe they update the documentation or maybe they don't bother. But in Rust we've got this nice clean line in the sand, that function is unsafe, if you can't do better label it "unsafe" so that it can't be called from safe code.

This discipline doesn't exist in C++. The spirit is willing but the flesh (well, the language syntax in this case) is too weak. Everything is always potentially unsafe and you are never more than one mistake from disaster.

replies(1): >>SolarN+kP8
◧◩◪◨⬒
28. SolarN+kP8[view] [source] [discussion] 2021-07-23 18:58:52
>>tialar+OB7
> This discipline doesn't exist in C++.

And this is where the argument breaks down for me. The C++ vector class can be just as safe if people are disciplined. And as you even described, people in rust can write "unsafe" and do whatever they want anyway to introduce bugs.

The language doesn't really seem to matter at the end of the day from what you are telling me (and that's my main argument).

With the right template libraries (including many parts of the modern C++ STL) you can get the same warnings you can from Rust. One just makes you chant "unsafe" to get around it. But a code review should tell off any developer doing something unsafe in either language. C++ with only "safe" templates is just as "actually safe" as rust is (except for with a better recovery solution than panics!).

[go to top]