4 ms·
Somewhat related, I learned a surprising fact recently: Go is not actually memory safe. In particular because atomicity is only guaranteed for word size values,
by K0nserv 2y ago
Somewhat related, I learned a surprising fact recently: Go is not actually memory safe. In particular because atomicity is only guaranteed for word size values, double word values(interface pointers, slices) can introduce memory unsafety in the presence of concurrency[0].
It's one of those things that feels obvious when you see it.
0: https://blog.stalkr.net/2015/04/golang-data-races-to-break-memory-safety.html https://blog.stalkr.net/2015/04/golang-data-races-to-break-m...
- tptacek 2y agoIt's easy to demonstrate contrived abuses of Go concurrency that break memory safety, but despite the enormous popularity of the language, actual shipping vulnerabilities --- mistakes in concurrency, not deliberately-engineered pathological cases, that yield attacker-controlled control over memory --- are basically nonexistent (I can't think of a single one; there must be one somewhere!). Basically this is about as credible an argument as claiming that Rust isn't memory safe because its libraries have so much `unsafe` code. And that claim: not super credible. Basically, the takeaway in both cases is that it's not safe to allow an attacker to write code for you in the language. But everybody assumes that's the case anyways, because it's the case with virtually every other language (with one very notable, fraught, and well-understood exception), too.
- shitter 2y agoWhat is that exception?
- ViewTrick1002 2y agoInstead there’s a whole host of subtle footguns which while not leading to true memory unsafety will lead to complete junk data. https://www.uber.com/en-SE/blog/data-race-patterns-in-go/ https://www.uber.com/en-SE/blog/data-race-patterns-in-go/
- tptacek 2y agoI don't care to litigate program correctness and ergonomics. Those are extremely subjective, and I don't feel like I ever get anywhere useful in those kinds of conversations. The most popular backend programming language in the industry is almost certainly Python, and it barely even has types. I still wouldn't dunk on it. This thread is about a much narrower question, which is code security. There, I feel like I'm on much firmer ground drawing and defending conclusions, and my conclusion is that there isn't a mainstream general-purpose modern language that is meaningfully more secure than Go (or than Rust, or than Python, etc).
- atomic128 2y agoHere is code to circumvent Go's memory safety without importing unsafe. get() reads a byte at an arbitrary address and set() writes a byte at an arbitrary address. This is excerpted from BUGFIX 66 ("Hack This Site"): func racer() { var ( ptr1 *uintptr ptr2 *byte race any done = make(chan struct{}) ) put := func(x any) { for { select { case <-done: return default: race = x } } } go put(ptr1) go put(&ptr2) for { var ok bool ptr1, ok = race.(*uintptr) if ok && ptr1 != nil { close(done) break } } get := func(addr uintptr) byte { *ptr1 = addr return *ptr2 } set := func(addr uintptr, to byte) { *ptr1 = addr *ptr2 = to } if get(0xdeadbeef) == 111 { set(0xbaaaaaad, 222) } }
- tptacek 2y ago"Without importing unsafe" is doing a lot of work for examples like this.
- atomic128 2y agoThis comes from a webpage where the challenge is to compromise the site, despite the fact that Go imports are disallowed (including unsafe). It's a puzzle game. To clarify, I think Go is magnificent and I use it for everything. The racer() code is just a curiosity.
- ronsor 2y agoYou shouldn't be modifying any variable concurrently without a mutex. The only exception to this is if the variable is (1) less than or equal to the CPU word size; (2) is at a CPU word size aligned address; and (3) atomic memory access functions are used to read and write the variable.
- saghm 2y agoMemory safety as long as you don't violate certain rules is what C and C++ also have. The problem is that programmers make mistakes because we're all human.
- tptacek 2y agoNo, the "mistakes" we talk about with C/C++ are so common that it's hard to think of a major C/C++ project not to have them, and the "mistakes" we're talking about with Go or "unsafe" Rust are contrivances built to demonstrate things an actively malicious programmer could do. Equating the two is, obviously, a sleight of hand.
- klabb3 2y agoTo add to this: the built in go race detector is very good at catching data races. It’s a runtime, but I’ve never had a race that couldn’t be reproduced in the race detector trivially. But yes, in theory Go has a memory safety problem because of it. In practice though, it’s that people don’t use the race detector, which is ridiculously easy to do.
- tptacek 2y agoOrdinary non-race-checked Go code is memory-safe in the sense that we mean it in the field of software security.
- oasisaimlessly 2y ago"We"? Do you have a mouse in your pocket?
- icholy 2y ago[dead]
- Thaxll 2y agoGo is memory safe by modern standard. If I show you a UB in Rust without the use of unsafe does it means Rust is unsafe?
- Yoric 2y agoWhat does that mean? If I follow correctly, assuming that there are no bugs in the compilers/interpreters, Go is less memory-safe than Java, C#, Python (with GIL), JavaScript or Rust. The only languages that are less memory safe would be C, C++ or Zig.
- K0nserv 2y agoI believe UB without unsafe is considered a bug by the Rust language team. I should’ve said in my original comment, but I don’t mean to dunk on Go. In practice the issues illustrated in the blog post I linked seem unlikely to cause problems in practice, they are interesting nevertheless.
- kaba0 2y agoThat would mean it, yes. And yeah there is a bug in rust's borrow checker which can trigger something like that for some very special, "no human will ever write code like that" case. But this is an implementation detail for a semantically memory safe language, while in go's case having UB is a language primitive here.
- Thaxll 2y agoThe trigger for Go is exactly "no human will ever write code like that".
- pclmulqdq 2y agoThis is also true of most other "safe" languages.
- deleted 2y ago[deleted]
- deleted 2y ago[deleted]
- JyB 2y agoThat's like... the first thing you learn about the language and the primitives the language was built upon. Yes mutex are a thing.
- K0nserv 2y agoSure race conditions in general, but the subtlety that it can cause memory unsafety, not something I recall being mentioned.