5 ms·
Golang does have an excellent built-in data race detector, which shows exactly which threads (and functions) are colliding. https://go.dev/doc/articles/race_de
by gunapologist99 4y ago
Golang does have an excellent built-in data race detector, which shows exactly which threads (and functions) are colliding.
https://go.dev/doc/articles/race_detector https://go.dev/doc/articles/race_detector
Caveats are that it requires cgo, and it might have lower performance, so enable it during development but not during production. Also detection requires actually triggering the data race, so you need good tests to try to exercise those areas of code.
Although Rust prevents them outright, that does seem to come at the expense at some flexibility, and the actual security risk of a data race in Golang seems to be moot. For example, if you know that a shared object will only be used when the program is starting up and in single-threaded mode, then you can safely use it then without a mutex.
Even when Golang does have a data race, the race causes the program (or at least the thread) to panic and thus is probably not directly exploitable, unlike older languages.
In other words, golang changes the risk of a data race from being a vulnerability to just a program-crashing bug. [EDIT: please see comments below which indicates that this may not be true in all cases, especially if you're trying to sandbox untrusted code!]
Beyond that, Go provides special capabilities (channels) to allow communications across goroutines (which are analogous to threads but can also automatically use different cores, unlike regular threads). Channels are like a vastly improved version of Erlang's mailboxes, and are the best way to pass information between goroutines.
So, rather than use mutexes, channels are Golang's idiomatic way to eliminate data races entirely. You can pass any complex object through a channel to another listener (blocking or non-blocking) on the other side. This excellent video is actually what convinced me to switch to Go for concurrent coding (which is the only place where you run into data races anyway):
https://go.dev/blog/waza-talk https://go.dev/blog/waza-talk
- mirashii 4y ago> In other words, golang changes the risk of a data race from being a vulnerability to just a program-crashing bug. I don't believe this is true, people have demonstrated using data races to build arbitrary code execution primitives. See for example https://blog.stalkr.net/2022/01/universal-go-exploit-using-data-races.html https://blog.stalkr.net/2022/01/universal-go-exploit-using-d...
- gunapologist99 4y agoVery interesting, thank you! Looking at the attack vector (https://blog.stalkr.net/2019/11/the-gomium-browser-google-ctf-2019.html https://blog.stalkr.net/2019/11/the-gomium-browser-google-ct...), this is a pretty tightly constrained circumstance where you are permitting an attacker to execute unknown Golang code within the context of your process. (perhaps like the Go Playground, if that's not starting a new process for each user.) I don't personally think that's really that applicable to regular golang users, unless they're trying to sandbox Golang code somehow within the language itself. (And if you are allowing untrusted code, then it's basically game over anyway). But it's still interesting and I added a note to my comment above about your point.