CWE-195, Signed to Unsigned Conversion Error, arises when a product casts a signed value to an unsigned one and the value cannot be represented in the unsigned type. The result is a number nobody intended. It affects C and C++.
How it happens
MITRE points out that functions often return negative values to indicate failure. If that result is used as a size parameter, the negative value becomes a very large unsigned number. Passed to the standard memory copy or allocation functions, it can cause an exploitable buffer overflow or underflow.
// Vulnerable
int n = recv(sock, hdr, sizeof hdr, 0); // returns -1 on error
memcpy(dst, src, n); // n converts to size_t, about 2^64 minus 1
// Fixed
int n = recv(sock, hdr, sizeof hdr, 0);
if (n < 0 || (size_t)n > sizeof dst) {
return -1;
}
memcpy(dst, src, (size_t)n);
The record lists two examples. CVE-2025-27363 is a font rendering library that assigned a signed short value to an unsigned long, leading to an integer wraparound, a buffer that was too small, and then memory corruption. CVE-2007-4268 is a chain where an integer signedness error passed a signed comparison, leading to a heap overflow.
What an attacker gains
MITRE lists integrity and an unexpected state. From a security standpoint the conversion is most often associated with integer overflow and buffer overflow vulnerabilities.
How to find it
MITRE says automated static analysis (SAST) can find some instances by modelling data flow. Turn on sign conversion warnings, and search for any call that passes a signed variable into a size, length or count parameter without a prior range check.
How to fix it
The record has no mitigations, so these are general steps.
- Check for negative values before converting to unsigned.
- Do not rely on implicit casts between signed and unsigned numbers.
- Keep the same signedness across a calculation and its comparisons.
- Use APIs that return errors separately from sizes.
Quick check
Why is a signed comparison not enough?
A check like n less than max passes for negative n, yet the later unsigned use sees a huge value. The check and the use must agree on the type.