An unsigned-to-signed conversion error takes place when a large unsigned primitive is used as a signed value.
Time of Introduction
Implementation
Applicable Platforms
Languages
C
C++
Common Consequences
Scope
Effect
Availability
Technical Impact: DoS: crash / exit /
restart
Incorrect sign conversions generally lead to undefined behavior, and
therefore crashes.
Integrity
Technical Impact: Modify memory
If a poor cast lead to a buffer overflow or similar condition, data
integrity may be affected.
Integrity
Confidentiality
Availability
Access Control
Technical Impact: Execute unauthorized code or
commands; Bypass protection
mechanism
Improper signed-to-unsigned conversions without proper checking can
sometimes trigger buffer overflows which can be used to execute
arbitrary code. This is usually outside the scope of a program's
implicit security policy.
Likelihood of Exploit
Medium
Demonstrative Examples
Example 1
In the following example, it is possible to request that memcpy move
a much larger segment of memory than assumed:
(Bad Code)
Example
Language: C
int returnChunkSize(void *) {
/* if chunk info is valid, return the size of usable
memory,
If returnChunkSize() happens to encounter an error, and returns -1,
memcpy will assume that the value is unsigned and therefore interpret it
as MAXINT-1, therefore copying far more memory than is likely available
in the destination buffer.
Potential Mitigations
Phase: Requirements
Choose a language which is not subject to these casting flaws.
Phase: Architecture and Design
Design object accessor functions to implicitly check values for valid
sizes. Ensure that all functions which will be used as a size are
checked previous to use as a size. If the language permits, throw
exceptions rather than using in-band errors.
Phase: Implementation
Error check the return values of all functions. Be aware of implicit
casts made, and use unsigned variables for sizes if at all
possible.
Other Notes
Often, functions will return negative values to indicate a failure. In the
case of functions that return values which are meant to be used as sizes,
negative return values can have unexpected results. If these values are
passed to the standard memory copy or allocation functions, they will
implicitly cast the negative error-indicating value to a large unsigned
value. In the case of allocation, this may not be an issue; however, in the
case of memory and string copy functions, this can lead to a buffer overflow
condition which may be exploitable. Also, if the variables in question are
used as indexes into a buffer, it may result in a buffer underflow
condition.
Although less frequent an issue than signed-to-unsigned casting,
unsigned-to-signed casting can be the perfect precursor to dangerous buffer
underwrite conditions that allow attackers to move down the stack where they
otherwise might not have access in a normal buffer overflow condition.
Buffer underwrites occur frequently when large unsigned values are cast to
signed values, and then used as indexes into a buffer or for pointer
arithmetic.
[REF-7] Mark Dowd, John McDonald
and Justin Schuh. "The Art of Software Security Assessment". Chapter 6, "Type Conversions", Page 223.. 1st Edition. Addison Wesley. 2006.