NUM.OVERFLOW

Numeric overflow due to incorrect type casting

The NUM.OVERFLOW checker detects overflow events when a variable is incorrectly typecast.

Vulnerability and risk

Numeric overflow due to incorrect type casting can lead to an incorrect result. This is also difficult to trace by debugging; mostly because incorrect results usually appear as a sub-expression within a bigger expression and the overflowed values they produce are not easy to work with. In order to prevent these problems, operator precedence needs to be examined and applied carefully in a complex expression. The checker kicks off only when there is an explicit type casting that is done incorrectly.

Vulnerable code example

Copy
  typedef unsigned long long uint64_t;
  typedef unsigned int uint32_t;
  uint64_t foo(uint32_t x, uint32_t y) {
    uint64_t z;
    z = (uint64_t) ( x * y );
    z = (uint64_t) ( y * 1000000U );
    return z;
  }

In the above example, on line 5 and 6, the developer is expecting the result of the multiplication operation to take up 64 bits even though the operands are both 32 bits. Both lines have incorrect type casting; since the multiplication will be executed first in 32 bits (causing the overflow), followed by the up-cast. Klocwork produces NUM.OVERFLOW on both line 5 and 6.

Fixed code example 1

Copy
  typedef unsigned long long uint64_t;
  typedef unsigned int uint32_t;
  uint64_t foo(uint32_t x, uint32_t y) {
    uint64_t z;
    z = (uint64_t) ( x ) * y;
    z = (uint64_t) ( y ) * 1000000U; //or: y*1000000ULL
    return z;
  }

On line 5, the variable 'x' was up-casted first. This will cause 'y' to be promoted automatically; leading to a full 64-bit multiplication. In case of constants (on line 6) proper use of postfix (ULL in this case) will tell the compiler to promote 'y' as well.

Vulnerable code example 2

Copy
  typedef unsigned long long uint64_t;
  typedef unsigned int uint32_t;
  uint32_t get_val();
  uint64_t foo(uint32_t x, uint32_t y) {
    uint64_t z;
    z = (uint64_t) ( y * get_val() );
    return z;
  }

The above example shows a similar problem on line 6, but this time with function call.

Fixed code example 2

Copy
  typedef unsigned long long uint64_t;
  typedef unsigned int uint32_t;
  uint32_t get_val();
  uint64_t foo(uint32_t x, uint32_t y) {
    uint64_t z;
    z = (uint64_t) ( y ) * get_val();
    return z;
  }

Security training

Application security training materials provided by Secure Code Warrior.

Extension

This checker cannot be extended.