That's a fantastic endorsement for Dovecot. It's interesting that security is not highlighted on the homepage[0], just mentioned in passing. Also interesting is the "special C variant that makes it much more difficult to write security holes"[1]
>Don't rely on input validation. Maybe you missed something. Maybe someone
calls your function somewhere else where you didn't originally intend it.
Maybe someone makes the input validation less restrictive for some reason.
Point is, it's not an excuse to cause a security hole just because input
wasn't what you expected it to be.
This point makes me mad because we have both ways to statically verify that calling conditions are "correct" through the right kind of design, and it should be a zero-cost abstraction but you can't do it in C.
Plus this advice is messy when it comes to things like string escaping. This could easily lead to issues like double encoding. Issues that don't exist if you could set up "proper" type checking in C without having to use things like wrapper structs that incur performance penalties.
Defensive programming is always a bit weird because it always feels un-necessary, but in C it's really necessary because you have so few assurances. Pretty scary
I wonder if there's a tool out there that lets you use Rust-style linear types over C code, and other things that would make some of this advice redundant (because the CI server would check the code). You could still write C, but wrong C would error in the checking step.
> Plus this advice is messy when it comes to things like string escaping. This could easily lead to issues like double encoding.
That's escaping - it's not the same as validation. What they mean is that you shouldn't expect that the invariants you see right now to hold in the future. It still means that you should only escape right before the data sink that requires it. But on the other hand it means: escape it right before the data sink, even if you see that the caller only passes in 2 different static strings - it may change. Or escape even if the current filter before rejects anything apart from digits.
Their advice seems to be "do not assume invariants on inputs". In which case you can only assume that your input is unescaped, right?
If you could assume escaping, that means you're limiting your input, which seems to go against the advice from my reading.
I gave escaping as an example, but one of the primary ways to reduce bugs is to reduce the scope of possible inputs as much as possible (thus reducing the scope of output to manage).
The requirements are different depending on the use case, but for application-internal code, not relying on that means that so much more global knowledge about the project is necessary to work on it. And, of course, a greater possibility of mistakes (because your requirements are more vast)
> it looks to be some sensible guidelines/practices
But more notably I think, a whole bunch of custom functions and data types to be used in place of more typical C coding practices. The document references a number of (presumably custom) header files (lib/buffer.h, lib/str.h, lib/strfuncs.h, lib/array.h, lib/data-stack.h, lib/mempool.h), the Boehm GC, and use of "GCC Extensions".
Also, there seems to be one person contributing an overwhelming proportion of commits (just going by the "contributors" page). Hmm, this seems to be an example of largely a single person implementing a program in C with a priority on code safety. Impressively successfully. But with substantial effort and individual discipline employed to avoid the pitfalls of C.
I'm not sure how scalable/transferable this kind of approach is. Perhaps the takeaway here is
i) This is an impressive (mostly) individual achievement.
ii) Dovecot may have some useful libraries for improving code safety if you're forced to or are committed to using C.
iii) The effort and discipline required to achieve code safety in C in this case, might also be interpreted as a validation of the effort and time required to achieve code safety by adopting newer alternatives like Rust and SaferCPlusPlus[1] when those choices are available.
If you hack on the source (as I have for both fun and profit) then the secure coding style and defensive internal infrastructure quickly become obvious and natural to work with.
One could argue that in 2017 software that is safety-critical and/or handles potentially untrusted input should be written in memory-safe languages. Rust is one such choice, but there are certainly other valid choices too.
But, given that dovecot just got a glowing security audit, perhaps there are other software projects that should be prioritized higher in the "rewrite everything in rust" list..
ESR claims: But you guys have competition out there: Go, Nim, Swift, D, and maybe other languages that aren’t on anyone’s radar yet.
All those languages are garbage collected or use automatic reference counting. Rust is unique in using its type system to automatically allocate and free memory. For the use cases where the overhead of GC is too high - Wich are the same use cases that generally call for C or C++ these days - Rust has no competition. I think this explains why Rust is still in the explore phase.
That claim gets even stronger if one considers real-time GC's or ref counting. Like how they do with Java for embedded systems. The places where Rust is uniquely advantageous gets smaller.
It's hard to take Eric S. Raymond seriously. He starts by claiming to be responsible for the open source development model, continues to make some generic remarks about library quality that applies equally to many other established languages (including C), then has the gall to offer advice to the designers of a language that he is openly struggling with [1].
His arguments aren't all wrong, but it's weirdly presumptious to level them so unequivocally at a new language/community that is still finding its feet and whose adoption rate hasn't even reached the point where you can talk about library curation/fragmentation being a huge problem. One has to give Rust some slack just for being young and immature.
You also have to give Rust some slack for just being more different and complicated than the languages you are used to. If you read his previous post about Rust, it's clear that he's blaming Rust for his inability to grapple with its fairly advanced concepts, and his complaints mostly amount to knee-jerk reactions, not carefully reasoned criticisms.
While it's true that Rust doesn't offer a learning experience that's as friendly as Go, by far, Go has the benefit of having a head start of several years, a larger organization funding its development, and of being a much, much simpler language. Based on his skill level, it sounds like Go would be a better fit for him. (I use Go myself and see a huge benefit being that it's easy to learn for any developer, not just highly experienced ones.)
"Discussion" isn't the word I'd use to describe that mess.
Criticizing a low-level language that makes it cheap and easy to directly call C APIs directly for not providing special syntax for select/kqueue/epoll when he could just call epoll if that's what he wants makes it clear that he wants to be writing some other, higher level language entirely.
It tells us nothing interesting about whether or not Dovecot, a project that wants low-level direct binding to POSIX APIs, is not suited for Rust.
On the one hand, the audit is a bit of a counter to "writing C is the same as writing unsafe code". On the other hand, there are a number of potential efficiency (as in, time-to-develop, maintenance effort required) gains for using a language, such as Rust, which provides the abstractions used in the C code out of the box and "for free" (in terms of implementation time--not necessarily execution performance). For a mature and stable project, especially one that has already built-in the effort to set up and maintain the appropriate abstractions, the effort to re-write is probably not worth it.
"Rewrite all the things in Rust" is asinine in general, but in this particular case it's especially bad. It would be much better to focus on C and C++ projects with actual problems.
[0]: https://www.dovecot.org [1]: https://www.dovecot.org/security.html