> Go has lots of weird edge cases, like sharing a slice across threads can lead to memory corruption (in the C / assembly sense, not merely within that array)
Er, your summary does not at all describe what is going on there. Like, all of that code violates the memory model, so whatever it accomplishes is irrelevant.
> Like, all of that code violates the memory model,
and?
> so whatever it accomplishes is irrelevant.
I have no idea what point you are making. _Of course_ there has to be a bug in the code for there to be a buffer overflow vuln. Or are you objecting that they put contrived code to make the race work better (this is the concept of a PoC)? None of the patterns in that code are unlikely in practice.
> I have no idea what point you are making. _Of course_ there has to be a bug in the code for there to be a buffer overflow vuln. Or are you objecting that they put contrived code to make the race work better (this is the concept of a PoC)?
The original claim was that "Go has lots of weird edge cases, like sharing a slice across threads can lead to memory corruption." But that's not the whole picture, you have to violate the memory model, too. And that's not interesting, because if you violate the memory model, literally any consequence is fair game.
Maybe your point is (a) it's easy to violate the memory model, and/or (b) bugs that violate the memory model have surprising consequences? I don't agree with (a); the situation can always be improved, but it's easy to spot and fix data races, and Go provides plenty of tooling for that purpose. And I guess I agree with (b) in the basic sense, but that's just a truism, for the reasons stated above.
> because if you violate the memory model, literally any consequence is fair game.
Any consequence is _not_ fair game. "Memory Models" only involve stuff like tossing out sequential consistency [1]. They never say or imply something like "if you have a data race, anything can happen [including executing code on the stack]". Go slices exposing implementation details in a way that makes the language memory-unsafe is a completely different issue. If Go was sequentially consistent (so it had no "Memory Model" to violate), it would still not make the language memory-safe, because it would still write the array pointer and be pre-empted before writing the length.
> And that's not interesting
It matters because all programs have bugs (apparently), and so we'd like them to fail in a less harmful way than executing shellcode submitted by a client.
> it's easy to spot and fix data races, and Go provides plenty of tooling for that purpose.
Never used the data race detector but it probably can only identify low hanging fruit, and is not a substitute for the developer education problem.
Okay I think I see your confusion: You can actually avoid slices causing buffer overflows because the language requires you to have a happens-before relationship for all data shared across threads in the first place. That is, even if you share a boolean or across threads, you would be sure to establish a happens-before relationship if you are in the know. However, this does not rebuke my original argument, which assumes that most devs are not in the know. They do not know about slices being unsafe, nor do they know about happens-before. So they are not educated to prevent this mistake. Also, avoiding data races is hard.
Violating the memory model gets you undefined behavior.
> However, this does not rebuke my original argument, which assumes that most devs are not in the know. They do not know about slices being unsafe, nor do they know about happens-before
I just don't agree. Go programmers know that nothing is safe for concurrent access unless explicitly noted otherwise. They don't have any confusion about slices requiring synchronization.
Concurrent programming isn't trivial but neither is it impossible. And data races are critical bugs that can be subtle, but are straightforward to identify, and straightforward to fix.