Conclusions
Writing secure code in C is difficult, but not impossible. The security record of systems like OpenBSD show that it can be done. The language doesn't go out of its way to make writing secure code easy, but in some ways this fact is helpful. The programmer must rely on good code, rather than language features, to avoid problems.
As with all languages, the best way of writing secure code is to write very little code. Factoring out commonly used patterns into functions or macros means that if you find a bug, you don't have to search through the entire code base looking for instances of the pattern.
Beyond that solution, the best general points are to validate input in every case, even from sources you might trust (you don't know if they've been compromised and are attempting a privilege-escalation attack), and prefer to crash rather than abort and attempt to proceed in an undefined state.