5 ms·
Go is not memory safe (though is certainly safer than C++). Various Go constructs like interfaces and slices are implemented via non-atomic multiword structs, a
by millstone 9y ago
Go is not memory safe (though is certainly safer than C++). Various Go constructs like interfaces and slices are implemented via non-atomic multiword structs, and data races may result in invalid values leading to memory corruption, etc. See https://blog.stalkr.net/2015/04/golang-data-races-to-break-memory-safety.html https://blog.stalkr.net/2015/04/golang-data-races-to-break-m...
- hoosieree 9y agoIs there any language not safer than C++?
- viraptor 9y agoMany. I like bashing C++ as much as the next dev, but modern C++ has nice type checks, interesting types/wrappers which help with common patterns (shared, unique ptrs, etc), and the compilers learned some great tricks which allow you to run memory safety checks yourself. (Asan and others) Also multithreading gets some improvements which will take more of the manual sync details away from the business logic. (http://www.modernescpp.com/index.php/multithreading-in-c-17-and-c-20 http://www.modernescpp.com/index.php/multithreading-in-c-17-...) It's still delivered attached to a foot-gun, but you could do worse.
- sagichmal 9y agoYours is a stricter and not-commonly-used definition of "memory safe", which typically means "in the C sense" i.e. pointer arithmetic and bounds checking. Go is certainly memory safe by the typical definition.
- panic 9y agoWhat's the typical definition? With data races, you can access array values out-of-bounds, which seems like the most fundamental thing you'd want protection from in a memory safe language.
- pjmlp 9y agoThe typical definition is memory corruption caused by out of bounds writes, stack corruption, use after free. On safe languages an out-of-bounds will cause a crash on the access point, while on unsafe languages it will silently corrupt memory.
- zaarn 9y agoYou can't access data out of bounds. Go will panic with a runtime exceptions if you do. Memory safety doesn't mean "memory IO errors never happen" it means "if a memory IO error happens, you'll know" If you have an out of bound in C, your program keeps running in 9/10 cases. In Go you'll cause a panic in 10/10 cases which you can either handle and propagate as error or let the program crash entirely, the memory will be in a defined state if you choose to recover (your array might be garbage but you won't have written data into random memory belonging to other threads)
- millstone 9y agoBut with Go you CAN access data out of bounds. See the "Exploiting the slice type" section where writing to a slice modifies a function pointer which happens to be stored after the slice. It's an OoB write which does not panic.
- zaarn 9y agoan OoB write under a data race in a program that won't occur like this in the wild. The conclusion section of the post you mean contains that statement too. The %p formatting used to gain access to the pointer of a variable uses the unsafe package, the formatting itself is incredibly rarely use to begin with. I don't see anybody doing any security-related exploits doing that unless you explicitly write for it. Go won't do out of bounds, edges cases do happen. You can find the same stuff on Java and Rust (yes, I had OoB in Rust, though on a baremetal environment without OS, even Rust ain't safe.)
- int_19h 9y agoI don't see why it's a different definition, though. What's he's saying is that it's very easy to break Go's bounds checking with race conditions, and produce memory corruption. This isn't true of languages traditionally considered as memory safe - e.g. Java or Python.
- pjmlp 9y agoA crash on out of bounds will always happen, unless unsafe package is being used to subvert memory accesses.
- burntsushi 9y agoThis is only true if you can prove that data races will never cause any bounds checks to be wrong. The blog post linked upthread suggests otherwise, and even appears to provide a counter-example to your claim.
- pjmlp 9y agoAs mentioned in that blog post > You'll notice my address() trick to get the address of a function or variable that I used in my previous exploit. We're relying on package fmt and its %p format specifier which is implemented by using the unsafe package, so we don't need to use it ourselves.
- millstone 9y agounsafe code is not required or used. The exploit constructs a confused interface value, whose vtable refers to a different type than is what is stored. The result is that Go treats an integer as a function and jumps to it. The unsafe address() is used to get the address of a function to store in the int, to demonstrate the potential for shellcode injection. But you could just as easily assign pp := 12345 and produce a SIGSEGV or SIGILL, which would not be possible if Go were memory safe.
- deleted 9y ago