Overview
Truncation errors occur when a primitive is cast to a
primitive of a smaller size and data is lost in the
conversion.
Consequences
- Integrity: The true value of the data is lost
and corrupted data is used.
Exposure
period
- Implementation: Truncation errors almost
exclusively occur at implementation time.
Platform
- Languages: C, C++, Assembly
Required
resources
Any
Severity
Low
Likelihood
of
exploit
Low
Avoidance
and
mitigation
- Implementation: Ensure that no casts, implicit
or explicit, take place that move from a larger size
primitive or a smaller size primitive.
Discussion
When a primitive is cast to a smaller primitive, the
high order bits of the large value are lost in the
conversion, resulting in a non-sense value with no
relation to the original value. This value may be
required as an index into a buffer, a loop iterator, or
simply necessary state data. In any case, the value
cannot be trusted and the system will be in an undefined
state.
While this method may be employed viably to isolate
the low bits of a value, this usage is rare, and
truncation usually implies that an implementation error
has occurred.
Examples
This example, while not exploitable, shows the
possible mangling of values associated with truncation
errors:
#include <stdio.h>
int main() {
int intPrimitive;
short shortPrimitive;
intPrimitive = (int)(~((int)0) ^ (1 << (sizeof(int)*8-1)));
shortPrimitive = intPrimitive;
printf("Int MAXINT: %d\nShort MAXINT: %d\n",
intPrimitive, shortPrimitive);
return (0);
}
The above code, when compiled and run, returns the
following output:
Int MAXINT: 2147483647
Short MAXINT: -1
A frequent paradigm for such a problem being
exploitable is when the truncated value is used as an
array index, which can happen implicitly when 64-bit
values are used as indexes, as they are truncated to 32
bits.