CWE-839 is a check that a value is no more than a maximum, without also verifying it is at least a minimum. MITRE lists C and C++.
How it happens
Code often uses signed integers for values that should never be negative, then validates only the upper bound. A negative number passes the check and is used as a size, an index or an allocation length. MITRE also gives a non-memory example: a shopping cart that checks only a maximum quantity.
// Vulnerable: negative n passes the check
int n = atoi(input);
if (n > 64) return -1;
memcpy(buf, src, n); // n converts to a huge size_t when negative
MITRE's examples are mostly chains. CVE-2010-1866: an integer overflow produced a negative value that bypassed a maximum-only check and led to a heap overflow. CVE-2009-1099: a 16-bit counter interpreted as negative led to a buffer underwrite. CVE-2011-0521: a missing negative check led to memory corruption. CVE-2010-3704: a parser used atoi without checking for a negative value.
What an attacker gains
MITRE lists reading and writing memory outside buffer bounds, resource consumption in some contexts, modification of application data, and potentially code execution.
How to find it
MITRE lists automated static analysis. Review each bounds check: does it test both ends? Test with zero, negative one, the minimum integer value and values near type limits.
How to fix it
From MITRE:
- Enforcement by conversion. If the number is always expected to be positive, change the type from signed to unsigned or size_t.
- Input validation. If the specification requires a signed value but correctness needs it positive, add an explicit check that it is positive.
long n = strtol(input, &end, 10);
if (end == input || n < 0 || n > 64) return -1;
memcpy(buf, src, (size_t)n);
Quick check
Why does a negative value become dangerous in memcpy?
The length parameter is unsigned. A negative signed value converts to a very large unsigned number.