Hacker News new | ask | show | jobs
by _wldu 2339 days ago
I really wish the OpenBSD team would consider rewriting some of these internet facing services in Go. It would be much safer than C.
2 comments

This isn't memory corruption, and you could easily end up with the same bug in Go (or Rust) code; the problem is that it's shelling out to subcommands to perform mail delivery and not screening addresses for metacharacters due to a logic bug.
In a better language than C, you could encode valid addresses in a proper type whose constructor would fail. But yes, you can treat everything as a string in any language.
You can also use type safety to enforce input validation in C. Just return an error code from the initializer, and annotate it must check. (Or, if you want to couple memory allocation with the checks, write a factory that returns null on input validation errors).

Various parts of the stdlib do this, though often without the compiler annotation. They often hide the struct members inside a compilation unit to prevent callers from bypassing the check (as much as is possible in a language with unsafe primitives).

It's not idiomatic C, and is pretty rare in practice. And the ergonomics are vastly better in other languages, starting with C++.
C have types too. Put your string into a struct, do not expose struct fields directly but make an API to access/modify those fields and it won't be any different.
But you still have to decide what is invalid in order to do that. You could just as easily not think of an invalid input case.
I did not say it was related to memory corruption. I said Go would be much safer than C (and it would be). When you remove an entire class of bugs, you can focus on other things... such as sound logic.

I love OpenBSD and use it a lot. But this notion of C everywhere for everything is wrong.

You also lose a lot of tooling that has been built up over the decades to help with C development, such as model checkers. Simply replacing one language for another doesn't help. It's silver bullet thinking.

This isn't an issue of language or platform, but an issue of process. The OpenBSD team has one of the best overall software development processes out there, but it is still very much a manual process. The class of exploits that are currently being discovered are often discovered via tool-assisted analysis. Such tools can also be used during the software development process to find errors that can be exploited. There are a dozen or so of such tools available for C currently ranging from OSS to commercial. Typically, these tools rely on model checking or bounded model checking, and they are quite effective at reducing attack surfaces or entire classes of errors beyond what most languages can provide on their own.

To take full advantage of model-guided development, however, requires a different software development process that is more difficult to adapt to older code bases overnight. Still, this adaptation is significantly less effort than, say, porting a C code base to Go or Rust. Model-guided development and other types of formal methods aren't silver bullets, and they aren't perfect. But, they are much more effective tools for building better systems than a language or compiler on its own.

I suspect that the OpenBSD developers will adapt to using a model-guided approach. They make use of some static analysis tools already. I find this much more likely than the OpenBSD team switching to Go or Rust, as it is a much more pragmatic solution and a more powerful solution.

Can you elaborate as to what "model-guided approach" OpenBSD is going to use?

I am skeptical of the claim that it is more "pragmatic" to adopt formal methods to achieve memory safety, as the number of projects that achieve memory safety through formal methods is multiple orders of magnitude smaller than the number of projects that achieve memory safety through just writing in a memory-safe language.

If you read the article, this RCE had nothing to do with memory safety. But, a model checker does a great job of finding memory issues as well as logic errors, if you use it correctly.

OpenBSD, AFAIC, has not announced any plans. But, there are plenty of tools out there that work. CBMC is a solid example and it is one I have used to great success with both systems programming and firmware development. As noted, this requires both a process change and a use of this tooling. Properly using assertions is a skill, but it can typically be cross-checked using existing manual processes with the added benefit of catching logic issues like the one that caused this RCE.

Many things, including Rust's type system, could theoretically prevent bugs like this if used properly too. The question comes down to compatibility of these tools with normal development practices. Formal methods are not known for their wide use in software like OpenSMTPD for many reasons, despite being around for decades. Until that changes, I have a hard time believing they are a "pragmatic" solution.
>The class of exploits that are currently being discovered are often discovered via tool-assisted analysis

Which tools would I start googling if I wanted to learn more about this?

Clang's static analyzer and libfuzzer are fantastic, and the former has saved my bacon more than once. It also has lots of sanitizers (more than gcc) for run-time instrumentation, not that that would have helped in this case, but still.
That's great and all, but you'd create a host of new bugs unrelated to safety with a pile of new code in a largely unfamiliar language (for the openbsd devs, anyways).

Rewriting the world in some safe language isn't a panacea, this meme is getting very old.

The fact that memory-safe languages don't prevent every bug ever is not an argument against their use, any more than the fact that some people die in car accidents even when wearing a seatbelt is an argument that you shouldn't wear seatbelts.
I'm not arguing against their use.
Presumably, you could also build your C code with Address Sanitizer and use that in production, then most memory corruption would segfault. You'd have a performance hit of course, but could be worth it.
If it's in base, that would mean dragging Go itself into the OpenBSD tree. Which you can argue is good, but that's a major change.
nice, then someone would just port rust and go and whatever to all the obsd arches, and not just to the main 2-3 platforms. Breaths not being held.
At least it's BSD-licensed.