Live data from Hacker News

There is no memory safety without thread safety

ralfj.de

121–130 of 517 posts

Re: There is no memory safety without thread safety

#121

Earlier quoted context omitted.

It's literally how the term "UB" is defined, and understood by experts. Why would anyone want to say "undefined" when they really mean "unspecified"? That's just confusing.

No, it's how one very specific community of experts understands it. It is not some kind of universal law of definition that it must mean that always and everywhere. As far as what is confusing, that is a matter of perspective. I think it is confusing (to put it mildly) that the C community has chosen to use "undefined behavior" to mean "it must never happen, and anything goes if it does". That is extremely counterint…

I agree that the term "undefined behavior", when used as in C/C++/Rust/Swift/.NET, isn't very good at communicating to non-experts what's at stake, not least because it doesn't sound scary enough (the security community remains indebted to whoever coined the term "nasal demons"). That said, is there a specific other community of practice where there's a shared understanding that the term "undefined behavior" means something different?

Re: There is no memory safety without thread safety

#122
post #102
post #95

Earlier quoted context omitted.

On the flip side, what would be the point? There are already a million other languages that have everything and the kitchen sink. Not going down the same road is the only reason it didn't end up on the pile of obscure languages nobody uses.

The only reason it didn't end on pile of obscure languages nobody uses, it called Google, followed by luck with Docker and Kubernetes adoption on the market, after they decided to rewrite from Python and Java respectively into Go, after Go heads joined their teams. Case in point, Limbo and Oberon-2, the languages that influenced its design, and authors were involved with.

The strength of Go is not the language. It's that the libraries you need for web back-end stuff are written, maintained, and used in production by Google. All the obscure cases get exercised in production due to sheer volume of internal usage.

At one time, Go maps were not thread-safe. Was that fixed?

Re: There is no memory safety without thread safety

#123
post #88

Earlier quoted context omitted.

Yes, but that's just a subset of expressions where unspecified sequencing applied. For instance, the example with two `print()` as parameters would have a sequence point (in pre-C++11 terminology) separating any reads/writes inside the `print` due to the function calls. It would never be UB even though the order in which the prints are called is still unspecified.

IIRC the point was that there was no sequence point between argument evaluation, so for example f(++i, ++i) was UB. Or maybe it was only for builtin operators? Cppreference is not authoritative[1], but seems to support my recollection. In fact it states that the f(++i, ++i) was UB till C++17. [1] https://en.cppreference.com/w/cpp/language/eval_order.html , Pre C++11 Ordering Rules, point (2).

`f(++i, ++i)` is/was indeed UB, but the example in munificent's comment was `foo(print(1), print(2))` which as far as I know is not even if both `print` calls read/write the same memory.

Re: There is no memory safety without thread safety

#124
post #104
post #95

Earlier quoted context omitted.

On the flip side, what would be the point? There are already a million other languages that have everything and the kitchen sink. Not going down the same road is the only reason it didn't end up on the pile of obscure languages nobody uses.

Well, that and the slight fact that it bears Google's brand name. I personally appreciate Go as a research experiment. Plenty of very interesting ideas, just as, for instance, Haskell. I don't particularly like it as a development language, but I can understand why some people do.

> Plenty of very interesting ideas

Is there? When you get down to it, it is really just a faster Python. Which is exactly what it was said to be when it was released. Their goal was to create a "dynamically-typed" language that was more performant. It is likely that it wouldn't have had a static type system at all if they figured out how to achieve on the performance end without needing types.

You can tell who is clueless when you hear someone say its type system is lacking. I mean, technically it is, but it is supposed to be. Like saying Javascript or Ruby's type system is lacking.

Re: There is no memory safety without thread safety

#125

Earlier quoted context omitted.

It's literally how the term "UB" is defined, and understood by experts. Why would anyone want to say "undefined" when they really mean "unspecified"? That's just confusing.

No, it's how one very specific community of experts understands it. It is not some kind of universal law of definition that it must mean that always and everywhere. As far as what is confusing, that is a matter of perspective. I think it is confusing (to put it mildly) that the C community has chosen to use "undefined behavior" to mean "it must never happen, and anything goes if it does". That is extremely counterint…

It is also not what the C community has chosen. It is what was imposed on us by certain optimizing compilers that used the interpretation that gave them maximum freedom to excel in benchmarks, and it was then endorsed by C++. The C definition is that "undefined behavior" can have arbitrary concrete behavior, not that a compiler can assume it does not happen. (that form semantic people prefer the former because it makes their life easier did not help)

Re: There is no memory safety without thread safety

#126

Every 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…

Swift is in the process of fixing this, but it’s a slow and painful transition; there’s an awful lot of unsafe code in the wild that wasn’t unsafe until recently.

One of the biggest hurdles is just getting all the iOS/macOS/etc APIs up to speed with the thread safety improvements. It won’t make refactoring all that application code any easier, but as things stand even if you’ve done that, you’re going to run into problems anywhere your code makes contact with UI code because there’s a lot of AppKit and UIKit that have yet to make the transition.

Re: There is no memory safety without thread safety

#127
post #102

Earlier quoted context omitted.

The only reason it didn't end on pile of obscure languages nobody uses, it called Google, followed by luck with Docker and Kubernetes adoption on the market, after they decided to rewrite from Python and Java respectively into Go, after Go heads joined their teams. Case in point, Limbo and Oberon-2, the languages that influenced its design, and authors were involved with.

The strength of Go is not the language. It's that the libraries you need for web back-end stuff are written, maintained, and used in production by Google. All the obscure cases get exercised in production due to sheer volume of internal usage. At one time, Go maps were not thread-safe. Was that fixed?

I'd be surprised if the JSON module was used within Google, though. It's neither particularly fast nor particularly convenient nor particularly suited to properly handle edge cases. But it's still in the stdlib for compatibility reasons.

Re: There is no memory safety without thread safety

#128
post #81

Go is memory safe by the most common definition, does not matter if you have segfault in some scenario. How many exploits or security issues have there been related to data race on dual word values? I work with Go for the last 10 years and I never heard of such issues. Not a single time.

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).

I've never heard anyone define memory safety that way. You can segfault by overflowing stack space and hitting the guard page or dereferencing a null pointer. Those are possible in languages that don't even expose their underlying pointers like Java. You can make Python segfault if you set the recursion limit too high. Meanwhile a memory access bug or exploit that does not result in a segfault would still be a memory safety issue.

Memory safe languages make it harder to segfault but that's a consequence, not the primary goal. Segfaults are just another memory protection. If memory bugs only ever resulted in segfaults the instant constraints are violated, the hardware protections would be "good enough" and we wouldn't care the same way about language design.

Re: There is no memory safety without thread safety

#129

Earlier quoted context omitted.

I'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.

I 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?

https://blog.stalkr.net/2022/01/universal-go-exploit-using-d...

This example hardcodes the payload, but (unless I've badly misunderstood how the exploit works) that's not necessary, it could instead be input from the network (and you wouldn't have to pass that input to any APIs that are marked unsafe). The payload is just hardcoded so that the example could be reproduced on the public Go Playground, which sandboxes the code it runs and so can't accept network input.

Note that what tptacek is asking for is more stringent than this; he wants a proof-of-concept exploitation of a memory safety vulnerability caused by the data-race loopholes in the Go memory model, in a real program that someone is running in production. I do think it's interesting that nobody has demonstrated that yet, but I'm not sure what it tells us about how sure we can be that those vulnerabilities don't exist.

Re: There is no memory safety without thread safety

#130
post #95
post #90

Earlier quoted context omitted.

It is kind of wild that for a 21st century programming language, the amount of stuff in Go that should have been but never was, but hey Docker and Kubernetes.

On the flip side, what would be the point? There are already a million other languages that have everything and the kitchen sink. Not going down the same road is the only reason it didn't end up on the pile of obscure languages nobody uses.

Having the weight of Google behind it is the primary reason it didn't end up on the pile of obscure languages nobody uses.
Post reply on HN