DBZ.ITERATOR

Loop iterator might be used in a division by zero

An attempt to do a division or modulo operation using zero as the divisor causes a runtime error. Division by zero defects often occur due to ineffective error handling or race conditions, and typically cause abnormal program termination. Before a value is used as the divisor of a division or modulo operation in C/C++ code, it must be checked to confirm that it is not equal to zero.

The DBZ checkers look for instances in which a zero constant value is used as the divisor of a division or modulo operation.

The DBZ.ITERATOR checker flags situations in which a loop iterator that has been assigned a zero constant value in the execution of the loop might subsequently be used explicitly or passed to a function that might use it as a divisor of a division or modulo operation without checking it for the zero value.

Vulnerability and risk

Integer division by zero usually result in the failure of the process or an exception. It can also result in success of the operation, but gives an erroneous answer. Floating-point division by zero is more subtle. It depends on the implementation of the compiler. If the compiler is following the IEEE floating-point standard (IEEE 754), then the result of the floating-point division by zero has a well-defined result. However, the C and C++ standards do not enforce compliance to IEEE 754. Thus, floating-point division by zero has an undefined behavior in C and C++ and might result in the failure of the process or an exception.

Division by zero issues typically occur due to ineffective exception handling. To avoid this vulnerability, check for a zero value before using it as the divisor of a division or modulo operation.

Vulnerable code example

Copy
  int count_sum_of_custom_arithmetic_series()
  {    
      int sum = 0;
      for (int i = -10; i < 10; ++i) {
          sum += 3628800 / i;
      }    
      return sum;
  }

Klocwork produces an issue report at line 5 indicating that the loop iterator 'i' is assigned a zero constant value during the loop iteration and this value is used as the divisor of the division operation. A division by zero can produce unexpected and unintended results.

Fixed code example

Copy
  int count_sum_of_custom_arithmetic_series()
  {    
      int sum = 0;
      for (int i = -10; i < 10; ++i) {
          if (i != 0) {
              sum += 3628800 / i;
          }
      }
      return sum;
  }

The problem from the previous snippet is fixed: the input variable ‘size’ is checked for the exceptional case of the zero constant value in line 5 and prevents the value 0 to be used in the division in line 6.

Security training

Application security training materials provided by Secure Code Warrior.

Extension

This checker can be extended through the Klocwork knowledge base. See Tuning C/C++ analysis for more information.

Limitations

This checker does not deal with abstract symbolic expressions evaluating to zero. This means that defects involving this kind of reasoning may not be detected by this checker. For example:
Copy
  int count_sum_of_custom_arithmetic_series()
  {
      int sum = 0;
      for (int i = -10; i < 10; ++i) {
          sum += 3628800 / (i - i);   // Divide by zero will happen here since i - i = 0. Not detected by this checker.
      }
      return sum;
  }
This checker only deals with loop iterators having a step (or increment) of +1 or -1. This means that defects involving loop iterators having a step different than +1 or -1 will not be detected by this checker. For example:
Copy
  intcount_sum_of_custom_arithmetic_series_with_step_of_two()
  {
      int sum = 0;
      for (int i = -10; i < 10; i += 2) {
          sum += 3628800 / i;            // Divide by zero will not be detected here since it the step of i is +2.
      }
      return sum;
  }