I agree that converting legacy code to use one of the techniques I suggest isn't
always going to be easy and inexpensive. My posting was aimed at those saying
that something better than C/C++ should be used for new security-critical
applications (which I agree is preferable), and I was pointing out that there
are ways of using C++ so as to avoid its troublesome "array=pointer" feature.

Converting legacy code so as to conform to my second suggested style may be
worthwhile if the code is known to have buffer overrun problems that need to be
addressed. The normal solution would likely involve adding an extra "buffer
limit" parameter to many functions that take a pointer to a buffer as a
parameter. Changing the type of the buffer pointer from "X*" to "Array<X>" (or
from "const X*" to "ConstArray<X>") is no more difficult and leads to clearer
code. The semantics of Array<X> mimic those of X*, so very little extra code
need be written, apart from introducing the buffer overflow checks where they
are needed, and changing each initialisation of the form "X* x = a" (where a is
an array of length n) to "Array<X> x (a, n)" to initialise the limit part as

As for system calls that use arrays, these are indeed a problem if using STL
classes instead of arrays, but not if the Array and ConstArray classes are used
to regulate access to ordinary arrays. As for unsafe system calls, the
documentation of any system or library call should include a guaranteed maximum
value it will use as an index into the array parameter it is given, and a check
can be inserted prior to the call that the buffer is large enough. System or
library calls that provide no such guarantee (such as "gets" in the ANSI C
library) must never be used.

Of course, there are many other flaws in C and C++ and I advocate applying the
MISRA-C rules (other than Rule 1 if using C++) as well, together with additional
rules to avoid some other dangerous features of C++.

David Crocker
Consultancy & contracting for dependable software development

-----Original Message-----
Behalf Of Jared W. Robinson
Sent: 10 June 2004 17:13
Subject: Re: [SC-L] opinion, ACM Queue: Buffer Overrun Madness

On Wed, Jun 09, 2004 at 03:34:52PM +0100, David Crocker wrote:
> Apart from the obvious solution of choosing another language, there are at
> two ways to avoid these problems in C++:
> 1. Ban arrays (to quote Marshall Cline's "C++ FAQ Lite", arrays are evil!).
> classes from the STL, or another template library instead. Arrays should be
> only in the template library, where their use can be controlled.
> 2. If you really must have naked arrays, ban the use of indexing and
> on naked pointers to arrays (i.e. if p is a pointer, then p[x], p+x, p-x, ++p
> and --p are all banned). Instead, refer to arrays using instances of a
> class "Array<X>" that encapsulates both the pointer (an X*) and the limit (an
> unsigned int).

Unfortunately, I don't think this advice will work for many projects.

First, Many programs must make system calls that only use arrays.
Some of those calls are unsafe.

Second, There is a lot of "legacy" code written with the error-prone
array indexing that you condemn. While the code must be maintained,
changing it introduces risks of new bugs that lead to instability, and
many people aren't willing to take that risk. So I think your advice
to ban arrays could only be applied to new code, and new projects.
Either that, or the conversion must be made gradually, and must be timed
at the right stage of a maintenance cycle.

- Jared

Reply via email to