> It's not the case that Golang in its natural environment gives attackers the ability to paint the heap with malicious addresses and then provide themselves with a statistically significant shot at corrupting memory to exploit those addresses.
What if a Go program allowed Go objects to be scripted by untrusted user code written in JavaScript? In browsers it is very possible to corrupt the Frame (Gecko)/RenderObject (WebKit) tree, which is in a C++ heap that is separate from the JavaScript heap.
The memory safety issues in C++ are a problem not because they mean that untrusted code written in C++ can't safely be executed (although it does mean that). It also means that safe languages become easily weaponizable. JavaScript (or Lua, or whatever) embedded in a Go program could paint the heap with malicious addresses.
This argument reduces to, "what if a Golang process exposed enough of its runtime to Javascript so that Javascript would be able to simulate an attacker just having access to Golang in the first place". In reality, if you were wacky enough to bolt Javascript onto Golang, you probably wouldn't do it in a way that would enable heap spray exploits, even if you had no idea what a heap spray exploit was.
The Javascript/C marriage problem isn't "heap spraying", it's that the interpreters themselves are full of exploitable C bugs, which is made much worse by the fact that the Javascript object lifecycle is expressed in an inherently unsafe language and so every tuple of [reference, event] has to be diligent checked. The same simply wouldn't be the case for any realistic marriage of Golang/Javascript, if only because the number of exploitable code conditions in Golang is miniscule compared to that of C.
All heap spraying does is make bugs that are very plausible to exploit easy to exploit reliably. You still have to start with "plausible".
> All heap spraying does is make bugs that are very plausible to exploit easy to exploit reliably. You still have to start with "plausible".
I'm not confident that race conditions in a shared-everything language are not "plausible". My experience is that race conditions are subtle and hard to find, even with a race detector. All you have to do is race on a map or a slice. And virtual calls are everywhere in Go.
Sure, we don't know that it's a problem so far, as nobody has created such a scenario. We're in violent agreement there. I grant that for server-side use cases, it doesn't matter—people use enormous C++ server codebases in production all the time and memory safety issues rarely bite them to the same degree that we see in browsers.
All I'm saying is that I don't have the same level of confidence that Go is free from memory safety exploits that I have for, say, Erlang or Java.
The use-after-free bugs that people are heap-spraying to exploit are plausible because the people who find them can tell you a simple story about how a program writes attacker-controlled data to attacker-controlled addresses. Unlike the Golang hypothetical you offer, they aren't plausible just because someone says they are.
You're wildly off the mark when you say that C++ serverside code tends to survive against attackers looking for memory corruption bugs. They do not. They fail with memory corruption flaws routinely. That was a cheap shot (you tried to create an equivalence class of unsafety between two totally unrelated languages and two totally unrelated sets of bug classes) and it won't work. You're going to have to try harder to make a case, if it's worth it to you.
Nothing is as bad as browser Javascript (it would be hard to conceive of a harder software security problem to design against), but C++ server software is pretty far towards the "unsafe" side of the security spectrum, and Golang and Erlang probably occupy virtually the same spot on that spectrum.
Unfortunately, I think we're basically at an impasse here.
I've described a scenario whereby a Go program that embedded untrusted safe code could fall to memory safety vulnerabilities. To be exact, it creates a slice of interfaces and accesses the slice in a racy way in such a way that it calls virtual functions at the same time it inserts, causing the slice to be reallocated. Then an attacker sprays the heap with addresses of shellcode. This results in arbitrary code execution when calling a virtual method.
You're saying that this is so unlikely as to be implausible, as it's never been observed in practice and might not even work. That's fine, I respect that position. We'll leave it there, and agree to disagree about whether this is a concern relative to languages like Erlang that are designed to be 100% free of memory safety problems. :)
What you've done in this comment is recapitulate the idea of a web browser executing content-controlled code, which is a problem that neither Erlang nor Golang could safely solve, and which no reasonable designer would ever use Erlang or Golang to solve, but layered on just enough abstraction to make that observation sound symptomatic of a problem with Golang.
I'm not trying to be pissy about it; I make bogus arguments all the time too, often without realizing it. You obviously know what you're talking about. I just think in this one subthread, you're wrong.
What if a Go program allowed Go objects to be scripted by untrusted user code written in JavaScript? In browsers it is very possible to corrupt the Frame (Gecko)/RenderObject (WebKit) tree, which is in a C++ heap that is separate from the JavaScript heap.
The memory safety issues in C++ are a problem not because they mean that untrusted code written in C++ can't safely be executed (although it does mean that). It also means that safe languages become easily weaponizable. JavaScript (or Lua, or whatever) embedded in a Go program could paint the heap with malicious addresses.