[Cryptech Tech] More ideas for improved code quality
Linus Nordberg
linus at nordberg.se
Wed Oct 10 09:48:05 UTC 2018
Hi,
Inspired by Joachims initiative to run Coverity on parts of the Cryptech
code base I've compiled a list of best practices in Tor Project which
Cryptech could consider adopting. Some of the procedures and tools
listed might already be in place or under way. The bullets regarding
tests are examples of that.
This is a starting point, with focus on C code. Some of it can be
applied on Python code and perhaps Verilog. More work is needed.
In no particular order:
- Code review
Have at least two maintainers for every git repo, enforcing a second
pair of eyes on code before it goes into any branch that ends up in a
release.
This can help with getting manual code review done but limiting review
to being performed by maintainers only should be avoided. A variant of
this is to require sign-off by at least N other developers
knowledgeable in the code base at hand.
Reviewing code can be hard. Guidelines for reviewing would be needed.
- Using the compiler(s)
Compiling C code with -Werror and other flags instructing the compiler
to be more strict makes it harder to ignore possibly less optimal code
constructs.
Compiling C code with -fstack-protector-all and other flags making the
compiler emit code for various types of "hardening" can help catching
some types of errors both at compile time and run time.
- More static code analysis
Run static code analysis beyond what the compiler usually
performs. Useful tools include Coverity, the clang static analyzer and
runtime sanitizers.
- Detecting memory leakage
Running code under valgrind to find out if and where a program leaks
memory can help in spotting memory handling errors.
- Unit tests
Write tests for functions (or sets of functions).
Making sure that all code is being run can help ensuring functionality
and also catch regressions. Using tools like gcov and lcov to measure
test coverage can help with knowing what code is not being tested.
- Integration tests
Write tests for external and device internal interfaces.
Testing the interfaces used for communicating with the device
(e.g. RPC, CLI), interfaces between components on the device
(e.g. ARM-FPGA, tamper MCU-MKM-FPGA, ATM-RTC) as well as command line
interfaces to programs executed on a computer used for interacting
with a device can help in similar ways as unit tests do. Fuzzing of
such interfaces could be considered falling into this category of
tests, see below for more on fuzzing.
- Fuzzing of interfaces
Make it easy to run fuzzers on those interfaces where it makes
sense. This includes compiling and maintaining corpora for those
interfaces.
Useful fuzzers include AFL [0], libFuzzer [1] and OSS-Fuzz.
[0] http://lcamtuf.coredump.cx/afl/
[1] http://llvm.org/docs/LibFuzzer.html
[2] https://github.com/google/oss-fuzz
- Document all interfaces
Pick a method and tools for documenting all interfaces and make sure
it gets done and being kept up to date. This goes for all kinds of
interfaces -- API:s (including functions, global variables, types,
structures), wire protocols, UI:s, more.
More information about the Tech
mailing list