Hacker News new | ask | show | jobs
by websiteapi 177 days ago
is go not memory safe? other than unsafe and other contrived goroutine scenarios, isn't it? I'm actually really curious - I've been writing go for just a couple years now and my understanding is the only ways for it to be unsafe are the two scenarios I described earlier.
3 comments

Changes to multi-word pointers can cause UB due to race conditions in Go because only changes at the word level are atomic.

See: https://blog.stalkr.net/2015/04/golang-data-races-to-break-m...

Does Rust not have race conditions?
One of Rust's core guarantees is that a race condition in safe code will never cause UB. It might return a nondeterministic result, but that result will be safe and well-typed (for example, if it's a Vec, it will be a valid Vec that will behave as expected and, once you have a unique reference, is guaranteed not to change out from under you).
When talking about the kind that lead to torn memory writes, no it doesn't have those. To share between threads you need to go through atomics or mutexes or other protection methods.
Rust prevents data races, but not race conditions.
Rust has double free concurrency bugs

https://materialize.com/blog/rust-concurrency-bug-unbounded-...

Lockbud: project detailing memory, concurrency bugs and panics for Rust. https://github.com/BurtonQin/lockbud

USENIX paper on model checking for Rust OS kernels uncovered 20 concurrency bugs across 12 modules in projects like Redox OS and Tock, including data races, deadlocks, and livelocks

https://www.usenix.org/system/files/atc25-tang.pdf

You've linked to a bug that was unintentional and was fixed.

Go allowing torn writes for their slices and interfaces (their fat pointer types) is intentional behavior in the go implementation and has no sign of being fixed.

Some one getting unsafe code unintentionally wrong is not an indication that any language lacks memory safety.

I see, you wish to limit the domain. Do safety issues in the async runtime count ? Or is even "async Rust" out of your criteria ?

What about this one ? "Futurelock in Tokyo" ? https://rfd.shared.oxide.computer/rfd/0609

> What about this one ? "Futurelock in Tokyo" ?

Deadlocks are not memory safety issues by the definition used in the OP. Furthermore, safe Rust is only intended to guarantee protection against data races, not race conditions in general.

Usually people are talking about race conditions. When you say contrived you're thinking races conditions are difficult to win and unrealistic but attackers who have a lot of money on the line spend the time to win all sorts of wild race conditions consistently.
is there actually a programming language that makes race conditions impossible (I am not being facetious, I actually do not know)? if the existence of races makes a language unsafe, then aren't all languages unsafe?
It's not that race conditions are generally memory-unsafe. The same race conditions would not be memory-unsafe in, say, Java or Python.

Go has a memory model that basically guarantees that the language is memory-safe except with a few marked "unsafe" functions or in case of race conditions involving interfaces or arrays. It's pretty easy to come up with an example of such a race condition that will cause reads or writes from/to unpredictable memory addresses. I imagine it's quite feasible to turn this into reads or writes from/to crafted memory addresses, which would be a mean to defeat pretty much any security measure implemented in the language.

The Rust community caters to people who are a bit obsessive about safety (including myself) and Rust developers tend to consider this a bug in the design of the Go language (there are a few, albeit much harder to achieve, issues that are vaguely comparable in Rust and they are considered bugs in the current design of Rust). The Go community tends to attract people who are more interested in shipping than in guarantees, and Go developers who are aware of this issue tend not care and assume that this is never going to happen in practice (which may or may not be true, I haven't checked).

>is there actually a programming language that makes race conditions impossible

It'd be very hard to make something that offers that guarantee in the real world. One of the most common, IRL exploitable race conditions are ones that involve multiple services/databases, and even if your programming language would have such a feature, your production system would not.

> is there actually a programming language that makes race conditions impossible

To my knowledge, no.

> if the existence of races makes a language unsafe, then aren't all languages unsafe?

Are we talking about "data races" or "race conditions" One can lead to the other, but race conditions are a much bigger set.

AIUI It's impossible for any language level controls to prevent any and all race conditions, because some are happening outside of the binary/process/computer.

Data races, OTOH are almost trivial to protect against - a contestable thing must have a guard that ensures a writer has exclusive access to that thing for the duration of the write.

Some languages do this with mutually exclusive locks (mutex/semaphore/go channels), some languages/paradigms do this by never having shareable objects (Functional Programming/Pass by Value), and some (Rust) are doing this with the compile time checks and firm rules on a single writer.

Edit: Never having shareable objects should really be "never allowing an outside thread/coroutine/process/whatever mutate your copy of an object" meaning that an object is immutable to them, and they have to have a copy that they can mutate to their heart's content. They have to communicate any changes back, and then you choose whether to integrate those changes, or not

Python has that property when you don't bring C extensions into the conversation. Data races exist, but can never cause memory corruption due to the GIL.
GIL is on its way out already in 3.14 onwards.
isn’t that the point of languages that have first class actor models something something?
Even in those languages you can easily have the equivalent of race conditions simply due to the order messages are received.
Go is absolutely memory safe in the sense used by Prossimo and software security. It's not "safe" in an academic sense used by almost nobody except message board language warriors.
Usually it is Rust message board language warriors.

Which also overlook how Rust type system can be subverted to actually allow for data races, with some help of linker scripts and OS IPC primitives.