I have, for a number of years now, found the 2008 Winning entry by John Meacham to be an important reminder. The trick isn't any preprocessor abuse, pointer-math problem, or any of the usual places in C where the complexity can easily obscure what is really going on. The program uses several idiomatic construct like
for(c = buf;*c;c++) { ... }
to walk the PPM data. It does exactly what it is supposed to do. (output black (zeros) for pixes in a given region.
To find the problem, you have to understand the entire problem and the written algorithm, as this isn't a "bug" - it doesn't implement the spec properly. It walks char by char - which looks fine at first - but that means it zeros "1 12 123" into "0 00 000", leaking the contrast of the original data.
I find that this is an important lesson to remember: no tool can catch you using the wrong algorithm, especially when the code "mostly" follows the design requirements that can never cover every possible corner case. Tools can catch interesting problems, but the inherent complexity in software says that you can never really be sure what a program does until you've read an understood the whole program... which isn't possible in the general case (halting problem).
So we can only hope to try and keep everything as simple as possible... as this winning entry shows that even 55 lines of clean code are enough complexity to hide what could be malicious code.
I have, for a number of years now, found the 2008 Winning entry by John Meacham to be an important reminder. The trick isn't any preprocessor abuse, pointer-math problem, or any of the usual places in C where the complexity can easily obscure what is really going on. The program uses several idiomatic construct like
to walk the PPM data. It does exactly what it is supposed to do. (output black (zeros) for pixes in a given region.To find the problem, you have to understand the entire problem and the written algorithm, as this isn't a "bug" - it doesn't implement the spec properly. It walks char by char - which looks fine at first - but that means it zeros "1 12 123" into "0 00 000", leaking the contrast of the original data.
I find that this is an important lesson to remember: no tool can catch you using the wrong algorithm, especially when the code "mostly" follows the design requirements that can never cover every possible corner case. Tools can catch interesting problems, but the inherent complexity in software says that you can never really be sure what a program does until you've read an understood the whole program... which isn't possible in the general case (halting problem).
So we can only hope to try and keep everything as simple as possible... as this winning entry shows that even 55 lines of clean code are enough complexity to hide what could be malicious code.