Secure Coding mailing list archives

Variable comparisons


From: "David A. Wheeler" <dwheeler () ida org>
Date: Wed, 03 Dec 2003 17:35:12 +0000



Chris Richards said:

A technique I have developed is to do the following instead
  if(WIFE == spouse)


Yes, that's a reasonable technique to avoid the "=" vs. "==" problem in 
C/C++
and related languages.  I've seen PHP code done this way too, for the 
same reason.
That idea has been re-invented a number of times; I think I've seen such 
formats

at least in the mid 1980s and it was probably around much earlier.


This is counter to the way we generally tend to think when writing
mathematical expressions,


And therein lies a problem.  Many find code formatted this way ugly, which
slows down reading of the code, and we want people to be able read code
easily to find all sorts of problems.  So, while I'll work with code 
formatted
this way, a lot of people will NOT want to code this way.  Aesthetics 
matter too.
Having to rewrite code to look non-standard mathematically is jarring to 
many

other humans the code is supposed to communicate with.  Even assemblers
try to be gentle with mathematical expectations.  For example, an assembler
could require prefix notation like (+ 5 (* 3 2)), but assemblers almost 
always support
infix notation.  After all, we train people for over a decade on 
standard mathematical
notation, and people don't want to give up a useful shared heritage so 
easily.


Most modern C compilers can warn about this.  More specifically, gcc
`-Wparentheses' (included in -Wall) will give a warning if the assignment
isn't surrounded by extra parentheses.  I find I have less trouble getting
people to surround assignments-in-conditionals with extra parentheses and
then enable warning flags for compilers.  Adding warnings can be done
incrementally, people have "pretty code" that's still error-checked, and
warnings can find lots of other problems too (not just this one).
I particularly like the last point - I want LOTS of checks on my code,
since I'm fallible, not just this one.
The Linux kernel developers have warning flags on, so clearly
it's not impossible to get people on big projects to turn on those flags.

The warning flags even work as a hint to programmers that something
unusual is going on.  When an attacker tried to insert a Trojan Horse
into the Linux kernel code that tried to hide
using "=" vs. "==", the additional parentheses immediately
looked suspicious to Linux kernel developers, since that's NOT the
normal appearance for an equality test. That quickly cued them
to the problem. More details are at:
 http://kerneltrap.org/node/view/1584

Of course, the best approach is to modify the language to reduce the 
problem.

It's too late for C/C++.  But Java handles nearly all cases; conditionals
require a bool, and unless you're assigning a bool to a bool the problem
will be caught.  And other languages like Ada don't allow assignments in
conditionals (eliminating the problem), and instead have syntax that let 
you easily

create loop-and-a-half constructs without needing an embedded assignment
in a conditional.

--- David A. Wheeler










Current thread: