Live data from Hacker News

There is no memory safety without thread safety

ralfj.de

311–320 of 517 posts

Re: There is no memory safety without thread safety

#311

Earlier quoted context omitted.

Rust checks overflow by default in debug builds

I've often thought that I'd prefer it to check by default in release builds, too, but I understand that comes with a performance penalty that a lot of folks aren't happy with. I assume this implies that common processor architectures (x86_64, aarch64) lack trap-on-overflow variants of their integer arithmetic instructions? If the explanation really is that simple, it's pretty disappointing.

You can tell the compiler that you want your crate to perform the checks regardless.

https://doc.rust-lang.org/cargo/reference/profiles.html#over...

You can also either (in nightly Rust) use the strict APIs which make it explicit that you want the overflow panics, or, (stably) use the checked APIs and then do whatever makes sense, which could include explicitly panic when overflow would happen unexpectedly.

This would let you have e.g. code where most arithmetic is checked, but a tight inner loop you're pretty sure won't overflow only has checks in debug (in release it will wrap, but you should not rely on that for correctness, unintended overflow is a bug)

Re: There is no memory safety without thread safety

#312
post #305

Earlier quoted context omitted.

I believe your productivity drops as you say. I don't think it's inherent to the language though, at least not most of it. Rather it think it's a matter of familiarity and experience in each. When you're less practiced in a language, you're slower at it. I can write python fast, but im pretty slow at ruby. I've written a lot of python rust and go, and am about equally productive in them (although how that productivit…

Rust is objectively harder to write than Go (or any other GC-language) because it exposes more concerns for the programmer to take care of. With Rust, you must always ensure your program complies with the borrow checker's rules (which is what makes Rust memory-safe) which includes having to add lifetime annotations to your variables in many cases. Go just doesn't have any of that. You could argue Rust still has an ad…

> an experienced Go developer probably has internalized how to avoid those bugs and the cost of preventing them can be nearly negligible.

And an experienced Rust developer has internalized the patterns (such as cloning or ARC) that are needed to cope with the borrow checker while writing prototype-quality, quick-iteration code. What's easier, fixing hard-to-spot bugs in the code or getting that code to compile in the first place?

Re: There is no memory safety without thread safety

#313

Earlier quoted context omitted.

I am curious. Generally basic structures like map are not thread safe and care has to be taken while modifying it. This is pretty well documented in go spec. In your case in dropbox, what was essentially going on?

I think the surprise here is that failing to synchronize writes leads to a SEGFAULT, not a panic or an error. This is the point GP was making, that Go is not fully memory safe in the presence of unsynchronized concurrent writes. By contrast, in Java or C#, unsynchronized writes will either throw an exception (if you're lucky and they get detected) or let the program continue with some unexpected values (possibly ones…

Segfault sounds better than running with inconsistent data.

Re: There is no memory safety without thread safety

#314
post #243

Earlier quoted context omitted.

This is way outside my domain but isn’t the answer: yes, if the code is formally proven safe? Doesn’t NASA have an incredibly strict, specific set of standards for writing safety critical C that helps with writing programs that can be formalized?

There are safety recommendations / best practice standards like CERT. None of them will prevent you from making intentional looking but logically unsound memory unsafe operations with C and C++. The code can be very indistinguishable from safe code. The things that C and C++ allow you to do basically makes code written in those languages impossible to fully formally prove. Although there are subsets, the basic intege…

> impossible to formally prove

If you assume the entire lang, yes. If you use a large subset, no. Furthermore, compiler interpretation might actually be sane! There are more compilers out there than GCC, Clang or MSVC. I suspect many assumptions are being made on this claim.

Re: There is no memory safety without thread safety

#315
post #180

Earlier quoted context omitted.

Where? Within, as I said, “the type of consumer OS or client-side application that typically gets attacked”. It has to be a component of either a big application or a big OS, or something with comparable scope. Otherwise it would not likely be targeted by real-world memory corruption attacks (that we hear about) no matter the language. At least that’s my impression.

I'm sure I could come up with a bunch of examples but the first thing that jumps into my head is the Docker ecosystem.

Yeah, that’s not nearly the level of big I was thinking of. It’s not a browser or WhatsApp or Word.

Admittedly, Go is popular among developers. And there are some public examples of client-side attacks targeting developers and security researchers specifically. Such attacks could hypothetically go after something like Docker. But, searching now, every single example I can find seems to either exploit a non-developer-specific target (browser, iMessage, Acrobat), or else not exploit anything and just rely on convincing people to execute a Trojan (often by sending a codebase that executes the Trojan when you build it).

That bifurcation actually surprises me and I’m not sure what to conclude from it, other than “build systems are insecure by design”. But at any rate, the lack of Go exploits doesn’t say much if we don’t see exploits of developer tools written in C either.

Re: There is no memory safety without thread safety

#316

Earlier quoted context omitted.

I think the surprise here is that failing to synchronize writes leads to a SEGFAULT, not a panic or an error. This is the point GP was making, that Go is not fully memory safe in the presence of unsynchronized concurrent writes. By contrast, in Java or C#, unsynchronized writes will either throw an exception (if you're lucky and they get detected) or let the program continue with some unexpected values (possibly ones…

Segfault sounds better than running with inconsistent data.

Go/C programs that race can also run with inconsistent data. Nothing guarantees you a segfault under torn writes.

In practice, Java programs tend to pick up on data races very quickly because they mutate some collection and the collections framework has safety checks for this.

Re: There is no memory safety without thread safety

#317

Earlier quoted context omitted.

I think the surprise here is that failing to synchronize writes leads to a SEGFAULT, not a panic or an error. This is the point GP was making, that Go is not fully memory safe in the presence of unsynchronized concurrent writes. By contrast, in Java or C#, unsynchronized writes will either throw an exception (if you're lucky and they get detected) or let the program continue with some unexpected values (possibly ones…

Segfault sounds better than running with inconsistent data.

The inconsistent data thing could happen in Go too. A segfault is not guaranteed, it’s just one of the more likely possibilities.

Re: There is no memory safety without thread safety

#318
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.

I don't think that's the (only) reason Go became popular. The huge thing about Go is the runtime: it's the only language runtime available today, at least in any language with a large org behind it, that offers (a) GC, (b) fast start-up time, (c) static types, (d) fast execution, and (e) multi-threading. This is a killer combination for any team looking to write code for auto-scalable microservices, to run for exampl…

Kubernetes services are one of the places where you don't care about startup time. Likewise for Docker itself. These are the things that do the scaling, normally.

Go is not particularly fast. People often see that Java gets faster as it runs and thinks, oh, it must be slow at the start then. But when you compare like with like, Go ends up being stuck at the bottom of the curve that Java then sharply climbs. The difference in GC quality is big, or at least, used to be? The only place where you really notice the difference is command line tools, and Java has GraalVM for that.

Re: There is no memory safety without thread safety

#319
post #230

Earlier quoted context omitted.

Was it open source? Would be interested to know more.

Yeah, reading binary files in go with an mmap library and the whole file is based on offsets to point to other sections of the file. Damaged file or programming error and segfault.

How is that a data race? Also, you're using unsafe.

The post is about data races in safe Go leading to crashes or exploits, because things like "eface" (the tuple used to implement interfaces) and slices (again a tuple) are multi-word and thus impossible to update atomically.

This is not an issue in Java because such things always box behind a pointer.

Re: There is no memory safety without thread safety

#320

Earlier quoted context omitted.

I think the surprise here is that failing to synchronize writes leads to a SEGFAULT, not a panic or an error. This is the point GP was making, that Go is not fully memory safe in the presence of unsynchronized concurrent writes. By contrast, in Java or C#, unsynchronized writes will either throw an exception (if you're lucky and they get detected) or let the program continue with some unexpected values (possibly ones…

Segfault sounds better than running with inconsistent data.

No, SEGFAULT means you're lucky and your corrupted memory caused you to access something the OS knew you can't access. But every SEGFAULT means that you have a memory safety violation, and so if you get unlucky, the exact same code that SEGFAULTED once will read oe write random objects in your memory (which might include code areas, GC data structures, etc).

Inconsistent data is pretty bad, but it's not as bad as memory corruption.

Post reply on HN