Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: REM Cost Reform

...

Noncompliant Code Example

This noncompliant code In this example, adapted from the Cryptography Services blog, demonstrates how signed overflow can occur even when it seems that only unsigned types are in use:a character is iterated from 0 to CHAR_MAX. However, on a platform where char is signed (such as 32-bit x86), max  is set to 0x80  while i  increments from 0x79  to {{0xffffff80} (aka -127):

Code Block
bgColor#FFcccc
langc
#include <limits.h>

unsigned shortchar xmax = 45000, y = 50000;
unsigned int z = x * y;

On implementations where short is 16 bits wide and int is 32 bits wide, the program results in undefined behavior due to signed overflow. This is because the unsigned shorts become signed when they are automatically promoted to integer, and their mathematical product (2250000000) is greater than the largest signed 32-bit integer (231 - 1, which is 2147483647).

Compliant Solution

In this compliant solution, by manually casting one of the operands to unsigned int, the multiplication will be unsigned and so will not result in undefined behavior:

Code Block
bgColor#ccccff
langc
unsigned short x = 45000, y = 50000;
unsigned int z = x * (unsigned int)y;

Risk Assessment

Misunderstanding integer conversion rules can lead to errors, which in turn can lead to exploitable vulnerabilities. The major risks occur when narrowing the type (which requires a specific cast or assignment), converting from unsigned to signed, or converting from negative to unsigned.

...

Recommendation

...

Severity

...

Likelihood

...

Remediation Cost

...

Priority

...

Level

...

INT02-C

...

Medium

...

Probable

...

Medium

...

P8

...

L2

CHAR_MAX + 1;
for (char i = 0; i < max; ++i) {
  printf("i=0x%08x max=0x%08x\n", i, max);
}

Compliant Solution

There are several ways to rectify this example. One way is to treat both chars as unsigned, which prevents wraparound:

Code Block
bgColor#ccccff
langc
#include <limits.h>

unsigned char max = CHAR_MAX + 1;
for (unsigned char i = 0; i < max; ++i) {
  printf("i=0x%08x max=0x%08x\n", i, max);
}

Noncompliant Code Example

This noncompliant code example, adapted from the Cryptography Services blog, demonstrates how signed overflow can occur even when it seems that only unsigned types are in use:

Code Block
bgColor#FFcccc
langc
unsigned short x = 45000, y = 50000;
unsigned int z = x * y;

On implementations where short is 16 bits wide and int is 32 bits wide, the program results in undefined behavior due to signed overflow. This is because the unsigned shorts become signed when they are automatically promoted to integer, and their mathematical product (2250000000) is greater than the largest signed 32-bit integer (231 - 1, which is 2147483647).

Compliant Solution

In this compliant solution, by manually casting one of the operands to unsigned int, the multiplication will be unsigned and so will not result in undefined behavior:

Code Block
bgColor#ccccff
langc
unsigned short x = 45000, y = 50000;
unsigned int z = x * (unsigned int)y;

Risk Assessment

Misunderstanding integer conversion rules can lead to errors, which in turn can lead to exploitable vulnerabilities. The major risks occur when narrowing the type (which requires a specific cast or assignment), converting from unsigned to signed, or converting from negative to unsigned.

Recommendation

Severity

Likelihood

Detectable

Repairable

Priority

Level

INT02-C

Medium

Probable

No

No

P4

L3

Automated Detection

Tool

Version

Checker

Description

Astrée
Include Page
Astrée_V
Astrée_V

Supported
CodeSonar
Include Page
CodeSonar_V
CodeSonar_V

ALLOC.SIZE.TRUNC

LANG.CAST.COERCE

LANG.CAST.VALUE

MISC.MEM.SIZE.TRUNC

Truncation of Allocation Size

Coercion Alters Value

Cast Alters Value

Truncation of Size

ECLAIR

Include Page
ECLAIR_V
ECLAIR_V

CC2.INT02

Fully implemented

Helix QAC

Include Page
Helix QAC_V
Helix QAC_V

C1250, C1251, C1252, C1253, C1256, C1257, C1260, C1263, C1266, C1274, C1290, C1291, C1292, C1293, C1294, C1295, C1296, C1297, C1298, C1299, C1800, C1802, C1803, C1804, C1810, C1811, C1812, C1813, C1820, C1821, C1822, C1823, C1824, C1830, C1831, C1832, C1833, C1834, C1840, C1841, C1842, C1843, C1844, C1850, C1851, C1852, C1853, C1854, C1860, C1861, C1862, C1863, C1864, C1880, C1881, C1882, C2100, C2101, C2102, C2103, C2104, C2105, C2106, C2107, C2109, C2110, C2111, C2112, C2113, C2114, C2115, C2116, C2117, C2118, C2119, C2120, C2122, C2124, C2130, C2132, C2134, C4401, C4402, C4403, C4404, C4405, C4410, C4412, C4413, C4414, C4415, C4420, C4421, C4422, C4423, C4424, C4425, C4430, C4431, C4432, C4434, C4435, C4436, C4437, C4440, C4441, C4442, C4443, C4445, C4446, C4447, C4460, C4461, C4463, C4464, C4470, C4471, C4480, C4481


Klocwork
Include Page
Klocwork_V
Klocwork_V
MISRA.CAST.INT
MISRA.CAST.UNSIGNED_BITS
MISRA.CONV.INT.SIGN
MISRA.CVALUE.IMPL.CAST
MISRA.UMINUS.UNSIGNED
PRECISION.LOSS

LDRA tool suite
Include Page
LDRA_V
LDRA_V


52 S, 93 S, 96 S, 101 S, 107 S, 332 S, 334 S, 433 S, 434 S, 446 S, 452 S, 457 S, 458 S

Fully implemented

Parasoft C/C++test
Include Page
Parasoft_V
Parasoft_V

CERT_C-INT02-a
CERT_C-INT02-b

Implicit conversions from wider to narrower integral type which may result in a loss of information shall not be used
Avoid mixing arithmetic of different precisions in the same expression

PC-lint Plus

Include Page
PC-lint Plus_V
PC-lint Plus_V

501, 502, 569, 570, 573,
574, 701, 702, 732, 734,
737

Partially supported

Polyspace Bug Finder

Include Page
Polyspace Bug Finder_V
Polyspace Bug Finder_V

CERT C: Rec. INT02-C


Checks for sign change integer conversion overflow (rec. fully supported)

Automated Detection

52 S, 93 S, 96 S, 101 S, 107 S, 332 S, 334 S, 433 S, 434 S, 446 S, 452 S, 457 S, 458 S

CERT C: Rec. INT02-C

Fully implemented

Tool

Version

Checker

Description

Astrée
Include Page
Astrée_VAstrée_VSupportedCodeSonar
Include Page
CodeSonar_VCodeSonar_V

ALLOC.SIZE.TRUNC

LANG.CAST.COERCE

LANG.CAST.VALUE

MISC.MEM.SIZE.TRUNC

Truncation of Allocation Size

Coercion Alters Value

Cast Alters Value

Truncation of Size

ECLAIR

Include Page
ECLAIR_VECLAIR_V

CC2.INT02

Fully implemented

Helix QAC
Include Page
Helix QAC_VHelix QAC_V

C1250, C1251, C1252, C1253, C1256, C1257, C1260, C1263, C1266, C1274, C1290, C1291, C1292, C1293, C1294, C1295, C1296, C1297, C1298, C1299, C1800, C1802, C1803, C1804, C1810, C1811, C1812, C1813, C1820, C1821, C1822, C1823, C1824, C1830, C1831, C1832, C1833, C1834, C1840, C1841, C1842, C1843, C1844, C1850, C1851, C1852, C1853, C1854, C1860, C1861, C1862, C1863, C1864, C1880, C1881, C1882, C2100, C2101, C2102, C2103, C2104, C2105, C2106, C2107, C2109, C2110, C2111, C2112, C2113, C2114, C2115, C2116, C2117, C2118, C2119, C2120, C2122, C2124, C2130, C2132, C2134, C4401, C4402, C4403, C4404, C4405, C4410, C4412, C4413, C4414, C4415, C4420, C4421, C4422, C4423, C4424, C4425, C4430, C4431, C4432, C4434, C4435, C4436, C4437, C4440, C4441, C4442, C4443, C4445, C4446, C4447, C4460, C4461, C4463, C4464, C4470, C4471, C4480, C4481

Klocwork
Include Page
Klocwork_VKlocwork_V MISRA.CAST.INT
MISRA.CAST.UNSIGNED_BITS
MISRA.CONV.INT.SIGN
MISRA.CVALUE.IMPL.CAST
MISRA.UMINUS.UNSIGNED
PRECISION.LOSS
LDRA tool suite
Include Page
LDRA_VLDRA_V

Fully implemented

Parasoft C/C++test
Include Page
Parasoft_VParasoft_V

CERT_C-INT02-a
CERT_C-INT02-b

Implicit conversions from wider to narrower integral type which may result in a loss of information shall not be used
Avoid mixing arithmetic of different precisions in the same expression

PC-lint Plus
Include Page
PC-lint Plus_VPC-lint Plus_V

501, 502, 569, 570, 573,
574, 701, 702, 732, 734,
737

Partially supported

Polyspace Bug Finder
Include Page
Polyspace Bug Finder_VPolyspace Bug Finder_V

Checks for sign change integer conversion overflow (rec. fully supported)

PRQA QA-C
Include Page
PRQA QA-C_vPRQA QA-C_v1250, 1251, 1252, 1253, 1256, 1257, 1260, 1263, 1266, 1274, 1290, 1291, 1292, 1293, 1294, 1295, 1296, 1297, 1298, 1299, 1800, 1802, 1803, 1804, 1810, 1811, 1812, 1813, 1820, 1821, 1822, 1823, 1824, 1830, 1831, 1832, 1833, 1834, 1840, 1841, 1842, 1843, 1844, 1850, 1851, 1852, 1853, 1854, 1860, 1861, 1862, 1863, 1864, 1880, 1881, 1882, 2100, 2101, 2102, 2103, 2104, 2105, 2106, 2107, 2109, 2110, 2111, 2112, 2113, 2114, 2115, 2116, 2117, 2118, 2119, 2120, 2122, 2124, 2130, 2132, 2134, 4401, 4402, 4403, 4404, 4405, 4410, 4412, 4413, 4414, 4415, 4420, 4421, 4422, 4423, 4424, 4425, 4430, 4431, 4432, 4434, 4435, 4436, 4437, 4440, 4441, 4442, 4443, 4445, 4446, 4447, 4460, 4461, 4463, 4464, 4470, 4471, 4480, 4481

PVS-Studio

Include Page
PVS-Studio_V
PVS-Studio_V

V555, V605, V673, V5006

...