Arithmetic or Conversion Fault (ARC) Class

Definition

We define Arithmetic or Conversion Fault (ARC) as:
Operations in software produce a faulty result due to conversions between primitive types, range violations, or domain violations.
Range violation and domain violation include overflow, underflow, wrap around, round off, divide by zero, and negative shift.
Overflow is when the combined value of the two operands exceeds the range of the typed operator1. Range violation also includes use of the wrong typed operation2. Conversions between primitive types, range violations, and domain violations are all considered to be operand faults.
Operations on pointers (memory addresses) are not ARC3.
Floating point overflow and underflow, conversion between floating point types, and conversion between floating point and integer types are ARC. Numerical analysis errors, such as loss of precision, failure to converge, and conditioning problems, are not ARC.
Function calls with incorrect arguments, such as memcpy() with overlapping ranges, are ARG, not ARC.
The model is that an operation causes (implicit) conversion of its operands’ values, then the operation is performed. How does argument passing and the C cast fit this model? Argument passing can be seen as an implicit conversion then a null operation (or, equivalently, an identity operation is performed). The C cast can be seen as explicit conversion then null.

Type

Low (language-related).

Taxonomy

Fig. 1 depicts ARC causes, attributes and consequences.

Fig 1. Arithmetic or Conversion Fault (ARC) Class - click on image for detailed view.

Attributes

The attributes of ARC are:
Result Fault4 – Overflow, Underflow, Undefined, Loss of Precision, Truncation, Distortion.
This indicates what resulted because of the fault.
Wraparound is expressed as either overflow (value became too large) or underflow (value became less than the least expressible value).
Overflow and Underflow are when the result won’t fit in the destination. Distortion are when the result does fit, but the value is changed, for example, unsignedVar = negativeValue;
Some examples for each value of the Result Fault attribute are as follows:
• Overflow – e.g. INT_MAX + 1 or -LONG_MIN)
• Underflow – e.g. UINT_MIN - 1 or float becomes very tiny, e.g., MIN_POS_FLOAT/2)
• Undefined – e.g. `j/0`
• Loss of Precision – e.g. `c = (f - 32) * (5/9)` – often called rounding. Includes truncation toward zero or fractional part discarded if the programmer expected rounding,
• Truncation – that is, cut off information that does not fit, e.g. `int = long`)
• Distortion – e.g. `unsigned = negative_number`
Operation5 – Arithmetic, Relational, Bitwise Shift, Assignment, Explicit Conversion, Argument Passing.
Examples of arithmetic operations are: `+`,  `/`, `%`, `--`, `unary -`. Examples of relational operations are `<`, `!=`. Bitwise shifts are `>>` and `<<`. Examples of assignments are `=`, `+=`. Explicit conversion is also called cast. Argument passing is in a function call.
Operand Error6 – Value Exceeds Type, Inadequate Type, Domain error
This specifies what the problem is with the operands. It is typically a relationship between operands of the operation, not just the characteristic of one operand.
Value Exceeds Type is a superset of Value Too Big and Type Too Small – yields Overflow, Underflow, or Truncation. Inadequate Type yields Loss of Precision, Underflow, or Distortion. Domain Error yields Undefined.
Type(s)7`int`, `double`, `long int` -> `short`, `unsigned` x `unsigned` -> `unsigned`, etc.
This is the type(s) of the operand(s) and/or the result.
Magnitude8 – Small, Moderate, Large.
This indicates how far out of range it was. Small is one or two. Moderate is half a dozen. Large is hundreds.
Excursion9 – Continuous, Discrete.
This indicates whether the out-of-range condition occurred because of continuous steps, which went out, or it was one step.

Consequences

The graph of consequences shows that BOF is not a direct consequence. Incorrect Result may cause Data Exceeds Array or Wrong Index / Pointer Out Of Range, which may cause BOF. Also Infinite Loop can lead to Program Crash or Resource Exposition, and eventually to Denial of Service (DoS).

Sites

Any use of the operators listed under the Operation attribute, which include explicit conversion (cast) and passing arguments in a function call.
The conditional operator (`?:`) is not a site. A common type is chosen for the result of the operator by performing the usual arithmetic conversion on the two operands of the colon (that is, for `a ? b : c`, it is between b and c), but this never results in ARC. The C bitwise operators `&`, `|`, `~`, and `^` are not sites. The reasons are the same as others. The C comma operator (`,`) never causes conversion, and therefore is not a site. The C logical operators, which are `&&`, `||`, and `!`, never cause conversion, and therefore are not sites.
Relational perators (e.g. `<`, `!=`) are sites. For instance, in the following:
` float f;`
` int i;`
` If (f == i) ...`
i is converted to float, but a 32-bit int may be too big to be represented correctly as a 32-bit float.
CERT INT30-C points out that some operation/operand combinations never have wrap-around, thus may be excluded:
• Operations on a variable and `0` (except division or remainder by `0`)
• Subtracting any variable from its type's maximum; for example, any unsigned int may safely be subtracted from UINT_MAX
• Multiplying any variable by `1`
• Division or remainder, as long as the divisor is nonzero
• Right-shifting any type by any number no larger than the type’s size; for example, `UINT_MAX >> x` is valid as long as `0 <= x < 32` (assuming that the precision of unsigned int is 32 bits)
“The only integer type conversions that are guaranteed to be safe for all data values and all possible conforming implementations are conversions of an integral value to a wider type of the same signedness [according to] The C Standard, subclause 6.3.1.3 [ISO/IEC 9899:2011], …”

Related BF Classes

BF classes related to ARC are: BOF, <<content to be added>>.

Related CWEs, SFP, and SEI/CERT Rules and Recommendations

Related SFP secondary cluster is Glitch in Computation (CWE-998).
BF Descriptions of ARC Related CWEs are provided here.

Application

Application examples are provided here.

Notes

On the term "primitive types"
• C11 calls them "basic types"
• Java SE 8 calls them "primitive types"
(https://docs.oracle.com/javase/specs/jls/se8/jls8.pdf 1.1 Organization of the Specification "The primitive types are ... various sizes of two's-complement integers, single- and double-precision IEEE 754 standard floating-point numbers, a boolean type, and a Unicode character char type." Accessed January 2017)
• C# 4.0 calls them "simple types"
(https://www.microsoft.com/en-us/download/details.aspx?id=7029 1.3 Types and variables The table shows that simple types comprise Signed integral, Unsigned integral, Unicode characters, IEEE floating point, High-precision decimal, and Boolean. Simple types do not include Enum types. Accessed January 2017)
Justification: We use “operations” instead of “an operation” because we often consider the assignment operator together with the binary (and other) operators that produce the result, e.g., `a = b + c;`
Explanation: Although we use the plural (e.g. “operations”, “conversions”, “primitive types”), there may be only one operator or there may be only one conversion of the value of one operand.
Explanation: Except in case of range and domain violations (e.g. overflow because of addition or undefined because of divide by zero), the fault occurs during the conversion, not during the operation. Thus the class might be called “Faulty Conversion”. But that name could lead readers to think only of the explicit cast operator, and the vast majority of faulty conversions are implicit conversions associated with operations.
Explanation: If the programmer meant to subtract, but wrote “+”, it is a bug, not ARC.
Additional note: The C standard [ISO/IEC 9899:2011, 7.12.1] distinguishes three types of faults: domain error, pole error, and range error. We lump these all into range or domain violation. (There is a summary of these three in SEI/CERT Rule FLP32-C.)
_______________________________
1Overflow can be viewed as a domain violation. Think of a binary operator, say `+`, as a unary operator (call it `pair+`) that takes a pair (of numbers). Just as division handles many numbers, but not zero, this `pair+` operator handles many inputs (pairs of numbers), but not all. The domain of `pair+` is then the pairs of numbers whose sum does not overflow.
The plus operator, `+`, represents a set of summing operations. Different operations are chosen depending on operand types. Thus `+` in `a + b` is taken to mean `short+short` if `a` and `b` are short, `int+int` if one is short and the other is `int`, and so forth. Each operation produces a result of a certain type.
Note: The compiler inserts a conversion in some cases. Consider this example:
` short a;`
` int b;`
` int c = a + b;`
The expression becomes `((int)a) int+int b`. That is, a is converted to an `int`, then the `int+int` addition operation is performed.
2Use of an operation of the wrong type can be viewed as a range violation. Consider this example of a faulty Fahrenheit to Centigrade conversion:
` float f;`
` float c = (f - 32) * 5/9;`
Since both operands of “/” are integers, the compiler selects integer division, resulting in Loss of Precision fault. The division takes place, the result is between the maximum and minimum integer, but the operation does not produce the resolution (precision) desired. This occurs in CVE-2016-5223.
Conceivably, there could be too much resolution. Consider this example of computing the number of reams of paper needed:
`constant int sheetsPerReam = 500;`
`int reams = +(sheetsNeeded + sheetsPerReam - 1) / sheetsPerReam;`
In C99 and later, integer division truncates toward zero. If floating point division were done, then rounded, it would not do what we want. So sheetsNeeded must be int or cast to int. If sheetsNeeded changed to be float, floating point division is performed instead of integer division.
3Why are pointer (memory address) operations not ARC? Observe that only relational, equality, and only a few additive operations (e.g. >, !=, +, --) are defined for pointers because pointer arithmetic mimics array accesses. In particular, `pointer / int` and `pointer + pointer` are not defined. (However, `pointer - pointer`is defined if the pointers are to the same allocation.)
4Although the attribute is named OperaTION, usually the operaTOR is written. We use “operator” to mean the syntactic representation and “operation” to mean the function that is executed. For example, the operator “+” corresponds to the addition operation. The distinction is like that between a numeral and a number.
5The attribute “Result Fault” indicates what resulted because of the fault.
Wraparound is expressed as either overflow (value became too large) or underflow (value became less than the least expressible value).
6Value Exceeds Type is a superset comprised of two conditions: Value Too Big and Type Too Small. How does one determine which condition it is? One must consider the context, that is, the programmer’s intent or what a correct program should do. In some cases, the operand value was just too big and should have been rejected (suggests Input Not Checked Properly). In other cases, the result should have been handled, so the type should have been larger (suggests Programmer Error).
7 Unary `-`, `++`, etc. may overflow. So some ARCs have only one operand and one type.
Type(s) is an informative attribute. It typically doesn’t describe the fault, just gives additional information that may be available. For instance, it documents the types that are involved.
8The actual values of the attribute are continuous; partitioning the values into three discrete intervals is somewhat arbitrary. These intervals are copied from BOF and make sense in explaining why some protection or detection schemes work with some BOFs and not others. It’s not clear if these intervals are meaningful for ARC or, indeed, whether the attribute is useful at all.
9 Increments, especially in a loop, indicate continuous. For example,
`i++;`
`j += 2;`
Other computations indicate discrete excursion. For example (from CVE-2016-2326):
`pts + pkt->duration * 10000`
Again, it is not clear if this attribute is useful.

References