5 ms·
> to describe the property of programming languages that don't admit to memory corruption vulnerabilities, such as stack and heap overflows, use-after-frees, an
by Sharlin 1y ago
> to describe the property of programming languages that don't admit to memory corruption vulnerabilities, such as stack and heap overflows, use-after-frees, and type confusions.
And data races allow all of that. There cannot be memory-safe languages supporting multi-threading that admit data races that lead to UB. If Go does admit data races it is not memory-safe. If a program can end up in a state that the language specification does not recognize (such as termination by SIGSEGV), it’s not memory safe. This is the only reasonable definition of memory safety.
- tptacek 1y agoIf that were the case, you'd be able to support the argument with evidence.
- chowells 1y agoYou mean like the program in the article where code that never dereferences a non-pointer causes the runtime to dereference a non-pointer? That seems like evidence to me.
- tptacek 1y agoAn exploit against a real Go program that relies on memory corruption.
- afdbcreid 1y agoIt should be possible to construct an exploit for such programs. But even for truly unsafe languages, vulnerabilities just from data races are very rare, because they are much harder to exploit. You could argue Go is safe from memory vulnerabilities, and that'll be 99% correct (we can't know what will happen if some very strong organization (e.g. a nation-state actor) will heavily invest in exploiting some Go program), but it still isn't memory safe, as per the definition in Wikipedia: > Memory safety is the state of being protected from various software bugs and security vulnerabilities when dealing with memory access, such as buffer overflows and dangling pointers.
- tptacek 1y agoThere's enormous incentive to construct those exploits. Why don't they exist?
- qualeed 1y agoThis seems to be operating on the premise that everyone knows of every exploit that exists. There's also an enormous incentive to hide working exploits.
- tptacek 1y agoAny. Not every.
- qcnguy 1y agoGo programs are normally running on the server side and are often proprietary, so you can't see the bugs exist to exploit them. It's not something like Chrome where someone can spend weeks finding a race and exploiting it to get a bug bounty, with full visibility of the source code and ability to develop an exploit in the lab.
- afdbcreid 1y agoI'm not sure that's correct. Yes, this is an enormous effort to construct exploits, but constructing exploits for C/C++ code is much much easier and gives not less, or even more, benefit. Therefore it makes sense the efforts are focused on that. If/when most C/C++ code in the world will be gone, I assume we'll see more exploits of Go code.
- lossolo 1y agoI can show you a trivial POC in C/C++ where someone opens a socket and ends up with a buffer overflow or UAF, both cases leading to memory corruption due to sloppy programming, and both easily exploitable for RCE. Can you show me any reasonable proof of concept (without using unsafe etc.) in Go that leads to similar memory corruption and is exploitable for RCE?
- amluto 1y agohttps://github.com/golang/go/issues/34902 https://github.com/golang/go/issues/34902 https://www.cloudfoundry.org/blog/cve-2020-15586/ 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.
- tptacek 1y agoWhat 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?
- amluto 1y agoAs 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 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.
- tptacek 1y agoNo, 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.
- amluto 1y ago
- gf000 1y agoHide the same program into some dependency of a dependency and you have a nice little security vulnerability in your prod app. It's actually very easy to hide such a vulnerability as an innocent bug.
- ameliaquining 1y agoIf 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).
- gf000 1y agoIf 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.
- ameliaquining 1y agoWhat's the least suspicious-looking code that you think could facilitate remote code execution via data-race memory corruption?
- Sharlin 1y agoThat’s called "moving the goal posts". A definition of memory safety that permits unsoundness as long as nobody has exploited said unsoundness is not a definition that anyone serious about security is going to accept. Unsoundness is unsoundness, undefined behavior is undefined behavior. The conservative stance is that once execution hits UB, anything can happen.
- tialaramex 1y agoIt's just a little airborne, it's still good https://www.youtube.com/watch?v=1XIcS63jA3w https://www.youtube.com/watch?v=1XIcS63jA3w
- sophacles 1y agoI think your security background is coloring your perception of the term memory safety. Specifically the requirement that the various issues lead to exploitation. These issues can lead to many other issues that are not vulnerability in the security sense, e.g. data corruption, incorrect (but not insecure) behavior, performance issues, and more. I don't think any of those were ever dismissed or excluded from memory safety discussion. Infosec circles tend to evaluate most ideas in the context of (anti)exploitation, and the rest of programming tends to focus on what the cool kids argue (that is they often weigh security concerns higher than other issues as well), so the other problems caused by double-free or buffer overruns (etc) just may not have been given as much weight in your mind.
- tptacek 1y ago"Memory safety" is a security term, not a PLT term.
- SkiFire13 1y agoThat's a statement without source and even if it was widely accepted as true it doesn't imply the fact that something needs to be exploitable to be considered a security issue. We are full of CVEs without a known way to be exploited.
- tptacek 1y agoNon-falsifiable statement is non-falsifiable.
- Sharlin 1y agoFirst off, in any and every engineering discipline it would be absurd to claim that "safety" only means security against intentional malice. Second, the burden of proof goes the other way. It’s absurd to claim that UB is safe unless proven otherwise. Unsafety must obviously be the default assumption.
- nemothekid 1y agoThis is no true Scotsman for programming languages. I could also argue C is memory safe and all the exploits that have been made weren’t real C programs