 
                            | Wiki Markup | 
|---|
| The incorrect use of arrays has traditionally been a source of exploitable vulnerabilities. Elements referenced within an array using the subscript operator \[\] are not checked unless the programmer provides adequate bounds checking. As a result, the expression {{array \[pos\] = value}} can be used by an attacker to transfer control to arbitrary code. | 
...
| Wiki Markup | 
|---|
| If the attacker can control the values of both {{pos}} and {{value}} in the expression {{array \[pos\] = value}}, he or she can perform an arbitrary write (overwrite other storage locations with contents of his or her choice).  The consequences range from changing a variable used to determine what permissions the program grants to executing arbitrary code with the permissions of the vulnerable process.  Arrays are also a common source of buffer overflows when iterators exceed the bounds of the array. | 
...
An
...
array
...
is
...
a
...
series
...
of
...
objects,
...
all
...
of
...
which
...
are
...
the
...
same
...
size
...
and
...
type.
...
Each
...
object
...
in
...
an
...
array
...
is
...
called
...
an
...
array
...
element
...
.
...
The
...
entire
...
array
...
is
...
stored
...
contiguously
...
in
...
memory
...
(that
...
is,
...
there
...
are
...
no
...
gaps
...
between
...
elements).
...
Arrays
...
are
...
commonly
...
used
...
to
...
represent
...
a
...
sequence
...
of
...
elements
...
where
...
random
...
access
...
is
...
important
...
but
...
there
...
is
...
little
...
or
...
no
...
need
...
to
...
insert
...
new
...
elements
...
into
...
the
...
sequence
...
(which
...
can
...
be
...
an
...
expensive
...
operation
...
with
...
arrays).
...
Arrays
...
containing
...
a
...
constant
...
number
...
of
...
elements
...
can
...
be
...
declared
...
as
...
follows:
| Code Block | 
|---|
| } enum { ARRAY_SIZE = 12 }; int dis[ARRAY_SIZE]; {code} | 
These
...
statements
...
allocate
...
storage
...
for
...
an
...
array
...
of
...
12
...
integers
...
referenced
...
by
...
dis
...
.
...
Arrays
...
are
...
indexed
...
from
...
0..n-1
...
(where
...
n
...
represents
...
an
...
array
...
bound).
...
Arrays
...
can
...
also
...
be
...
declared
...
as
...
follows:
| Code Block | 
|---|
| } int ita[]; {code} | 
This
...
is
...
called
...
an
...
incomplete
...
type
...
because
...
the
...
size
...
is
...
unknown.
...
If
...
an
...
array
...
of
...
unknown
...
size
...
is
...
initialized,
...
its
...
size
...
is
...
determined
...
by
...
the
...
largest
...
indexed
...
element
...
with
...
an
...
explicit
...
initializer.
...
At
...
the
...
end
...
of
...
its
...
initializer
...
list,
...
the
...
array
...
no
...
longer
...
has
...
incomplete
...
type.
| Code Block | 
|---|
| } int ita[] = { 1, 2 }; {code} | 
While
...
these
...
declarations
...
work
...
fine
...
when
...
the
...
size
...
of
...
the
...
array
...
is
...
known
...
at
...
compilation
...
time,
...
it
...
is
...
not
...
possible
...
to
...
declare
...
an
...
array
...
in
...
this
...
fashion
...
when
...
the
...
size
...
can
...
be
...
determined
...
only
...
at
...
runtime.
...
The
...
C99
...
standard
...
adds
...
support
...
for
...
variable-length
...
arrays
...
or
...
arrays
...
whose
...
size
...
is
...
determined
...
at
...
runtime.
...
Before
...
the
...
introduction
...
of
...
variable-length
...
arrays
...
in
...
C99,
...
however,
...
these
...
"arrays"
...
were
...
typically
...
implemented
...
as
...
pointers
...
to
...
their
...
respective
...
element
...
types
...
allocated
...
using
...
malloc()
...
,
...
as
...
shown
...
in
...
this
...
example.
| Code Block | 
|---|
| } int *dat = (int *)malloc(ARRAY_SIZE * sizeof(int)); {code} | 
It
...
is
...
important
...
to
...
retain
...
any
...
pointer
...
value
...
returned
...
by
...
malloc()
...
so
...
that
...
the
...
referenced
...
memory
...
may
...
eventually
...
be
...
deallocated.
...
One
...
possible
...
way
...
of
...
preserving
...
such
...
a
...
value
...
is
...
to
...
use
...
a
...
constant
...
pointer.
| Code Block | 
|---|
| }
int * const dat = (int * const)malloc(
  ARRAY_SIZE * sizeof(int)
);
/* ... */
free(dat);
dat = NULL;
 | 
Both dis and dat arrays can be initialized as follows:
| Code Block | 
|---|
| {code} Both {{dis}} and {{dat}} arrays can be initialized as follows: {code} for (i = 0; i < ARRAY_SIZE; i++) { dis[i] = 42; /* Assigns 42 to each element; */ /* ... */ } {code} The {{dat}} array can also be initialized as follows: {code} | 
The dat array can also be initialized as follows:
| Code Block | 
|---|
| 
for (i = 0; i < ARRAY_SIZE; i++) {
   *dat = 42;
   dat++;
}
dat -= ARRAY_SIZE;
 | 
The
...
dis
...
identifier
...
cannot
...
be
...
incremented,
...
so
...
the
...
expression
...
dis+
...
+
...
results
...
in
...
a
...
fatal
...
compilation
...
error.
...
Both
...
arrays
...
can
...
be
...
initialized
...
as
...
follows:
| Code Block | 
|---|
| } int *p = dis; for (i = 0; i < ARRAY_SIZE; i++) { *p = 42; // Assigns 42 to each element; p++; } {code} | 
The
...
variable
...
p
...
is
...
declared
...
as
...
a
...
pointer
...
to
...
an
...
integer
...
and
...
then
...
incremented
...
in
...
the
...
loop.
...
This
...
technique
...
can
...
be
...
used
...
to
...
initialize
...
both
...
arrays
...
and
...
is
...
a
...
better
...
style
...
of
...
programming
...
than
...
incrementing
...
the
...
pointer
...
to
...
the
...
array
...
because
...
it
...
does
...
not
...
change
...
the
...
pointer
...
to
...
the
...
start
...
of
...
the
...
array.
...
| Wiki Markup | 
|---|
| Obviously, there is a relationship between array subscripts {{\[\]}} and pointers. The expression {{dis\[i\]}} is equivalent to {{\*(dis+i)}}. In other words, if {{dis}} is an array object (equivalently, a pointer to the initial element of an array object) and {{i}} is an integer, {{dis\[i\]}} designates the {{i{}}}th element of {{dis}} (counting from zero). In fact, because {{\*(dis+i)}} can be expressed as {{\*(i+dis)}}, the expression {{dis\[i\]}} can be represented as {{i\[dis\]}}, although doing so is not encouraged. | 
...
| Wiki Markup | 
|---|
| The initial element of an array is accessed using an index of zero; for example, {{dat\[0\]}} references the first element of {{dat}} array. The {{dat}} identifier points to the start of the array, so adding zero is inconsequential in that {{\*(dat+i)}} is equivalent to {{\*(dat+0)}}, which is equivalent to {{\*(dat)}}. | 
...
Risk
...
Assessment
...
Arrays
...
are
...
a
...
common
...
source
...
of
...
vulnerabilities
...
in
...
C
...
language
...
programs
...
because
...
they
...
are
...
frequently
...
used
...
but
...
not
...
always
...
fully
...
understood.
...
| Recommendation | Severity | Likelihood | Remediation Cost | Priority | Level | 
|---|---|---|---|---|---|
| ARR00-C | high | probable | high | P6 | L2 | 
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
References
| Wiki Markup | 
|---|
| \[[ISO/IEC 9899:1999|AA. C References#ISO/IEC 9899-1999]\] Section 6.7.5.2, "Array declarators"
\[[MITRE 07|AA. C References#MITRE 07]\] [CWE ID 119|http://cwe.mitre.org/data/definitions/119.html], "Failure to Constrain Operations within the Bounds of an Allocated Memory Buffer," and [CWE ID 129|http://cwe.mitre.org/data/definitions/129.html], "Unchecked Array Indexing" | 
...
...
...
...