
...
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 | ||||
---|---|---|---|---|
| ||||
#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 short
s 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 | ||||
---|---|---|---|---|
| ||||
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 | ||||
---|---|---|---|---|
| ||||
#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 | ||||
---|---|---|---|---|
| ||||
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 short
s 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 | ||||
---|---|---|---|---|
| ||||
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 |
| Supported | |||||||
CodeSonar |
| 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 | ||||||
| CC2.INT02 | Fully implemented | |||||||
Helix QAC |
| 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 |
| MISRA.CAST.INT MISRA.CAST.UNSIGNED_BITS MISRA.CONV.INT.SIGN MISRA.CVALUE.IMPL.CAST MISRA.UMINUS.UNSIGNED PRECISION.LOSS | |||||||
LDRA tool suite |
| 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 |
| CERT_C-INT02-a | Implicit conversions from wider to narrower integral type which may result in a loss of information shall not be used | ||||||
PC-lint Plus |
| 501, 502, 569, 570, 573, | Partially supported | ||||||
Polyspace Bug Finder |
| Checks for sign change integer conversion overflow (rec. fully supported) |
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 | ||||||||||||||||||||||||||||||||||||||||||||||||||
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 | Fully implemented | Parasoft C/C++test | ||||||||||||||||||||||||||||||||||||||||||||||||||
Include Page | Parasoft_V | Parasoft_V | CERT_C-INT02-a | Implicit conversions from wider to narrower integral type which may result in a loss of information shall not be used | PC-lint Plus | |||||||||||||||||||||||||||||||||||||||||||||||||
Include Page | PC-lint Plus_V | PC-lint Plus_V | 501, 502, 569, 570, 573, | Partially supported | Polyspace Bug Finder | |||||||||||||||||||||||||||||||||||||||||||||||||
Include Page | Polyspace Bug Finder_V | Polyspace Bug Finder_V | Checks for sign change integer conversion overflow (rec. fully supported) | PRQA QA-C | ||||||||||||||||||||||||||||||||||||||||||||||||||
Include Page | PRQA QA-C_v | PRQA QA-C_v | 1250, 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 | Fully implemented|||||||||||||||||||||||||||||||||||||||||||||||||||
PVS-Studio |
| V555, V605, V673, V5006 |
Related Vulnerabilities
...