[Cryptography] Ada vs Rust vs safer C

John Gilmore gnu at toad.com
Tue Sep 20 03:08:26 EDT 2016


> In such cases, there are two options. The lazy one is to add pragmas
> asking Prefast to "ignore warning such and such in this part of the
> code". The correct option is to refactor the code, e.g. splitting the
> long function in a small set of easier-to-evaluate functions.

There is usually a reason that long, complicated functions are long
and complicated!  And it's not stupidity.  It's the complicated nature
of the job that that function is trying to do.

Inserting pragmas that are basically comments is unlikely to produce
any NEW bugs in the code.

Refactoring a long, complex function is very likely to introduce new
bugs.

So what makes refactoring the "correct" option?  Suppose there is
*not* a complete test suite that gets 100% test coverage of the code
in question?  (That's extremely common.)  If so, then you don't just
have to rewrite the function; you also have to write test cases from
scratch, and validate them on the old code before trying them on the
new code.  Just doing that is a major project, and when you're done
you haven't started the refactoring yet.

Or you could just refactor, introduce bugs, and not really try very
hard to detect them before shipping the buggy code.  But I thought the
point of the exercise was to REDUCE vulnerabilities in the code, not
increase them.

	John

PS: There is/was a long, complicated function in GDB
("wait_for_inferior") that figures out what to do when the program
being debugged stops running and the kernel reports back its status.
It was 600 lines long (including many comments) when I became the GDB
maintainer.  It was very hard to modify it without introducing new
bugs, but modifications were needed to fix bugs and support new
machine architectures and new object file formats and such (even
though such things were heavily paramaterized, some new capabilities
needed to be created in this function).  Over the three or four years
that I maintained GDB, I did gradually split things out of it to make
it more maintainable.  But only toward the end of that period was I
able to make even small changes without introducing subtle bugs.  This
is the kind of code where you hesitate to fix Bug X because you know
you'll introduce Bug Y and Bug Z in the process.  These were not the
sort of bugs that our test suite would find.  These were the sort that
only the thousands of people running GDB in the field, on unusual
architectures and in unique circumstances, would find.  Only after
several years of this, did I have enough understanding *in detail* of
what that function did, to be able to modify it without invalidating
some assumption that was depended upon 300 lines away.

PPS: It's one kind of job for an academic or researcher, whose main
objective is to write a paper or get a degree, to build
non-production-quality tools for analyzing programs.  It's another
kind to keep a large, complex, production program running reliably
while evolving it.  In the real world you can't just say "rewrite your
production 600 line function so my flaky research tool won't fail on
it".  If you do, the customers/users of your tool just go away,
quietly or with parting insults.


More information about the cryptography mailing list