Earlier quoted context omitted.
Why people with vastly more skill and experience programming and writing programming languages made the decisions they did.
I meant, which particular design decisions are you accusing people of having failed to comprehend the rationale for?
There is no memory safety without thread safety
211–220 of 517 posts
Re: There is no memory safety without thread safety
#212Earlier quoted context omitted.
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…
No, that doesn't work. Lots of (maybe even most) corrupted data structures aren't exploitable (past DOS). Where does the attacker-controlled data come from . What path does it take to get to where the attacker wants it to go . You have to be able to answer those two questions.
> Where does the attacker-controlled data come from.
The example I gave was an HTTP server. Attackers can shove in as much attacker-controlled data as they want. They can likely do something like a heap by using many requests or many headers. Unless the runtime zeroes freed memory (and frees it immediately, which GC languages like Go often don’t do), then lots of attacker controlled data will stick around. And, for all I know, the slice that gets mixed up in this bug is fully attacker controlled!
In any event, I think this whole line of reasoning is backwards. Developers should assume that a memory safety error is game over unless there is a very strong reason to believe otherwise — assume full RCE, ability to read and write all in-process data, the ability to issue any syscall, and the ability to try to exploit side channels. Maybe very strong mitigations like hardware-assisted CFI will change this, and maybe not.
Re: There is no memory safety without thread safety
#213Earlier quoted context omitted.
If you're stipulating deliberately inserted vulnerabilities then there are much easier ways, e.g., with a plausibly-deniable logic bug in code that calls os/exec or reflect (both of which can execute arbitrary code by design).
If you see `exec`, that's an obvious point where you want to pay extra attention. Compare to an innocent looking map operation, and it's not even in the same league.
Re: There is no memory safety without thread safety
#214Every time this conversation comes up, I'm reminded of my team at Dropbox, where it was a rite of passage for new engineers to introduce a segfault in our Go server by not synchronizing writes to a data structure. Swift has (had?) the same issue and I had to write a program to illustrate that Swift is (was?) perfectly happy to segfault under shared access to data structures. Go has never been memory-safe (in the Rust…
Crashing on shared access is the safe thing to do
Re: There is no memory safety without thread safety
#215Earlier 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…
> 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. This means that multiple goroutines were writing to the same local variable. I've never worked on a Go team where code that is structured in such a way would be considered normal or pass code review without goo…
It's not because people intentionally write this way. A function takes a parameter (a Go slice for example) and calls another function and so one. Deep down a function copies the pointer to the slice (via closure for example). And then a goroutine is spawned with this closure.
The most obvious mistakes are caught quickly. Buu sharing a memory address between two threads can happen very indirectly.
And somehow in Go, everybody feels incredibly comfortable spawning millions of coroutines/threads.
Re: There is no memory safety without thread safety
#216Every time this conversation comes up, I'm reminded of my team at Dropbox, where it was a rite of passage for new engineers to introduce a segfault in our Go server by not synchronizing writes to a data structure. Swift has (had?) the same issue and I had to write a program to illustrate that Swift is (was?) perfectly happy to segfault under shared access to data structures. Go has never been memory-safe (in the Rust…
Safety isn't binary, so your comment makes no sense.
Re: There is no memory safety without thread safety
#217Earlier quoted context omitted.
Where? Within, as I said, “the type of consumer OS or client-side application that typically gets attacked”. It has to be a component of either a big application or a big OS, or something with comparable scope. Otherwise it would not likely be targeted by real-world memory corruption attacks (that we hear about) no matter the language. At least that’s my impression.
I'm sure I could come up with a bunch of examples but the first thing that jumps into my head is the Docker ecosystem.
Re: There is no memory safety without thread safety
#218I 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…
I have! What do i win?
Re: There is no memory safety without thread safety
#219Earlier 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…
The line I'm not quite as sure about is https://go.googlesource.com/go/+/refs/tags/go1.13.1/src/bufi.... That assignment is to a variable of interface type, so in theory it could cause memory corruption if multiple goroutines executed it concurrently on the same receiver, which was possible until the bug was fixed. That said, I cannot immediately think of a way to exploit this; you can only write error values corresponding to errors that you can make occur while writing to the socket, and that's a much more constrained set of possible values than the arbitrary bytes that can occur in a buffer. And for that, you only get confusion among the types of those particular errors. It might be possible but it at least looks challenging.
Re: There is no memory safety without thread safety
#220Earlier quoted context omitted.
The situation with numbers in basically every widely used programming language is kind of an indictment of our industry. Silent overflow for incorrect results, no convenient facilities for units, lossy casts everywhere. It's one of those things where standing in 1975 you'd think surely we'll spend some of the next 40 years of performance gains to give ourselves nice, correct numbers to work with, but we never did.
"nice, correct numbers" end somewhere between 1/3 and sqrt(2) so in reality, it's just "pick your own poison" to various degrees...
The non computable reals are a huge problem because, as their name suggests, we can't compute them - and in the strict sense that's Almost All reals, but none of the ones you're thinking of are non-computable so you'll likely be fine.
For the merely rational numbers like a third, or sixteen hundred and five sevenths, it's even more so a matter of choosing not to address it rather than it being out of reach.