SV.TAINTED.CALL.BINOPUse of Unvalidated Integers in Binary Operations via function callsWhenever input data is accepted from the user or the outside environment, it should be validated for type, length, format, and range before it is used. Until this data is properly validated, it is said to be tainted. The SV.TAINTED family of checkers looks for the use of tainted data in code. The SV.TAINTED.BINOP checker flags code that uses tainted data, via a function call, in arithmetic binary operations, such as addition, subtraction, or multiplication. Vulnerability and riskWhen integer data input to the code is not validated properly and is used as an operand to a binary operation, the result can be an integer overflow or wraparound. This potential situation could allow an attacker to alter the normal control flow, causing an unexpected program behavior. In the worst-case scenarios, an attacker could:
Mitigation and preventionTo avoid tainted input errors:
Vulnerable code example1 int get_altitude(); 2 void set_altitude(int); 3 4 int get_untrusted() { 5 int i; 6 scanf("%d", &i); 7 return i; 8 } 9 10 extern const int max_altitude; 11 12 int get_new_altitude(int shift) { 13 int current_altitude = get_altitude(); 14 return current_altitude + shift; 15 } 16 17 void increase_altitude() { 18 int shift = get_untrusted(); 19 if (shift > 0) { 20 int new_altitude = get_new_altitude(shift); 21 if (new_altitude < max_altitude) { 22 set_altitude(new_altitude); 23 } 24 } 25 } In the above example, an attacker can provide an arbitrarily large value for variable 'new_altitude'. If the binary operation at line 14 overflows, this can result in a negative value of variable 'new_altitude' at line 20, and cause unexpected program behavior. Klocwork reports an SV.TAINTED.BINOP defect at line 20, indicating: "Unvalidated integer value 'shift' that is received from 'get_untrusted' at line 18 is used as an operand to a binary operator via a call to 'get_new_altitude' at line 20". Fixed code example1 int get_altitude(); 2 void set_altitude(int); 3 4 int get_untrusted() { 5 int i; 6 scanf("%d", &i); 7 return i; 8 } 9 10 extern const int max_altitude; 11 extern const int max_trusted_shift; 12 13 int get_new_altitude(int shift) { 14 int current_altitude = get_altitude(); 15 return current_altitude + shift; 16 } 17 18 void increase_altitude() { 19 int shift = get_untrusted(); 20 if (shift > 0 && shift < max_trusted_shift) { 21 int new_altitude = get_new_altitude(shift); 22 if (new_altitude < max_altitude) { 23 set_altitude(new_altitude); 24 } 25 } 26 } The Klocwork checker no longer produces the defect report here, since the integer value 'shift' is validated at line 20 before being used in the binary operation. Related checkersExternal guidance |