I have never seen real Go code (i.e. not code written purposefully to be exploitable) that was exploitable due to a data race. This doesn’t prove a negative, but is probably a good hint that this risk is not something worth prioritizing for Go applications from a security point of view. Compare this with C/C++ where 60-75% of real world vulnerabilities are memory safety vulnerabilities. Memory safety is definitely a…
There is no memory safety without thread safety
171–180 of 517 posts
Re: There is no memory safety without thread safety
#172Earlier quoted context omitted.
The most common definition of memory safe is literally "cannot segfault" (unless invoking some explicitly unsafe operation - which is not the case here unless you think the "go" keyword should be unsafe).
The definition has to do with certain classes of spatial and temporal memory errors. Ie., the ability to access memory outside the bounds of an array would be an example of a spatial memory error. Use-after-free would be an example of a temporal one. The violation occurs if the program keeps running after having violated a memory safety property. If the program terminates, then it can still be memory safe in the defi…
Re: There is no memory safety without thread safety
#173Earlier quoted context omitted.
Crashing on shared access is the safe thing to do
An intentional exit by a runtime is a safe crash. A segfault is not, and is here a clear sign that memory safety has been violated.
Re: There is no memory safety without thread safety
#174Earlier quoted context omitted.
It took months to finally solve a data race in Go. No race detector would see anything. Nobody understood what was happening. It ultimately resulted in a loop counter overflowing, which recomputed the same thing a billion of time (but always the same!). So the visible effect was a request would randomly take 3 min instead of 100ms. I ended up using perf in production, which indirectly lead me to understand the data r…
Rust does have loop counter overflow.
[^1]: https://www.reddit.com/r/ProgrammerTIL/comments/4tspsn/c_it_...
[^2]: https://stackoverflow.com/questions/69375375/is-it-safe-to-a...
Re: There is no memory safety without thread safety
#175Earlier quoted context omitted.
https://github.com/golang/go/issues/34902 https://www.cloudfoundry.org/blog/cve-2020-15586/ I don’t see any evidence that anyone wrote an RCE exploit for this, but I also don’t see any evidence of anyone even trying to rule it out.
What about this particular bug do you think makes it likely to be exploitable? I'm not asking you to write an RCE POC, just to tell a story of the sequence of events involving this bug that results in attacker-controlled code. What does the attacker control here, and how do they use that control to divert execution?
On first glance, it looks like the bug can (at least) result in the server accessing a slice object where the various fields don’t all come from the same place. So the target server can end up accessing some object out of bounds (or as the wrong type or both), which can easily end up writing some data (possibly attacker controlled) to an inappropriate place. In standard attack, the attacker might try to modify the stack or a function pointer to set up a ROP chain or something similar, which is close enough to arbitrarily code to eventually either corrupt something to directly escalate privileges or to do appropriate syscalls to actually execute code.
Re: There is no memory safety without thread safety
#176Java got this right. Fil-C gets it right, too. So, there is memory safety without thread safety. And it’s really not that hard.
Memory safety is a separate property unless your language chooses to gate it on thread safety. Go (and some other languages) have such a gate. Not all memory safe languages have such a gate.
Re: There is no memory safety without thread safety
#177Earlier quoted context omitted.
Crashing on shared access is the safe thing to do
An intentional exit by a runtime is a safe crash. A segfault is not, and is here a clear sign that memory safety has been violated.
Re: There is no memory safety without thread safety
#178Earlier quoted context omitted.
What about this particular bug do you think makes it likely to be exploitable? I'm not asking you to write an RCE POC, just to tell a story of the sequence of events involving this bug that results in attacker-controlled code. What does the attacker control here, and how do they use that control to divert execution?
As a general heuristic, a corrupted data structure in a network server results in RCE. This is common in languages like C and C++. On first glance, it looks like the bug can (at least) result in the server accessing a slice object where the various fields don’t all come from the same place. So the target server can end up accessing some object out of bounds (or as the wrong type or both), which can easily end up writ…
Re: There is no memory safety without thread safety
#179False. Java got this right. Fil-C gets it right, too. So, there is memory safety without thread safety. And it’s really not that hard. Memory safety is a separate property unless your language chooses to gate it on thread safety. Go (and some other languages) have such a gate. Not all memory safe languages have such a gate.
> At this point you might be wondering, isn’t this a problem in many languages? Doesn’t Java also allow data races? And yes, Java does allow data races, but the Java developers spent a lot of effort to ensure that even programs with data races remain entirely well-defined. They even developed the first industrially deployed concurrency memory model for this purpose, many years before the C++11 memory model. The result of all of this work is that in a concurrent Java program, you might see unexpected outdated values for certain variables, such as a null pointer where you expected the reference to be properly initialized, but you will never be able to actually break the language and dereference an invalid dangling pointer and segfault at address 0x2a. In that sense, all Java programs are thread-safe.
And:
> Java programmers will sometimes use the terms “thread safe” and “memory safe” differently than C++ or Rust programmers would. From a Rust perspective, Java programs are memory- and thread-safe by construction. Java programmers take that so much for granted that they use the same term to refer to stronger properties, such as not having “unintended” data races or not having null pointer exceptions. However, such bugs cannot cause segfaults from invalid pointer uses, so these kinds of issues are qualitatively very different from the memory safety violation in my Go example. For the purpose of this blog post, I am using the low-level Rust and C++ meaning of these terms.
Java is in fact thread-safe in the sense of the term used in the article, unlike Go, so it is not a counterexample to the article's point at all.
Re: There is no memory safety without thread safety
#180Earlier quoted context omitted.
You’re a cryptography person. So you know that most theoretically interesting cryptography vulnerabilities, even the ones that are exploitable in PoCs, are too obscure and/or difficult to get used by actual attackers. Same goes for hardware vulnerabilities. Rowhammer and speculative execution attacks are often shown to be able to corrupt and leak memory, respectively, but AFAIK there are no famous cases of them actua…
There's lots of clientside Go, too!