CWE-467 is a small C and C++ mistake with a large blast radius. The code calls sizeof() on a pointer type, which gives the wrong answer if the programmer meant the size of the data being pointed to.
MITRE notes that sizeof on a pointer can occasionally be useful, for example to find the word size of a platform. More often than not, sizeof(pointer) indicates a bug.
How it happens
The pointer's size is a few bytes, regardless of what it points at. Two examples from the entry.
First, an allocation:
double *foo;
...
foo = (double *)malloc(sizeof(foo)); /* size of the pointer */
Here sizeof(foo) is the size of the pointer, so the buffer may be smaller than a double or other intended structure.
Second, an authentication function that compares credentials:
char *username = "admin";
char *pass = "password";
int AuthenticateUser(char *inUser, char *inPass) {
if (strncmp(username, inUser, sizeof(username))) {
return AUTH_FAIL;
}
if (!strncmp(pass, inPass, sizeof(pass))) {
return AUTH_SUCCESS;
}
return AUTH_FAIL;
}
MITRE explains that because sizeof is applied to a pointer, it may return 4 on many platforms, so strncmp compares only the first four characters. That is a partial comparison leading to improper authentication. MITRE lists passwords such as pass5, passABCDEFGH and passWORD, which would all succeed for the admin user, and notes the reduced search space for an attacker.
What an attacker gains
From the record: integrity and confidentiality impact through modifying and reading memory. The error often causes a buffer much smaller than needed, leading to resultant weaknesses like buffer overflows. The authentication example shows another route, a weakened credential check.
How to find it
MITRE says static analysis (SAST) can find some instances by modeling data flow. Two quick checks help too:
- Search the code for sizeof applied to a variable that is a pointer, especially inside malloc, memcpy and strncmp arguments.
- Compile with warnings. Many compilers can flag sizeof on a pointer parameter.
How to fix it
MITRE's mitigation: use expressions such as sizeof(*pointer) instead of sizeof(pointer), unless you intend to take the size of a pointer for platform independence or you are allocating a variable on the stack.
foo = (double *)malloc(sizeof(*foo)); /* size of the double */
For string comparison, use the real length of the value, for example strlen or a length passed along with the buffer, and compare with a function that checks both sides fully.
Try it yourself
A static code scan is a fast way to see this sort of pattern flagged.
Click through it at your own pace, or open it full screen.
Quick check
What does sizeof(foo) return when foo is a double pointer?
The size of the pointer itself, not the size of a double. Use sizeof(*foo) for the pointed-to type.
Why did the password check accept longer passwords?
sizeof on a pointer parameter returned 4 on many platforms, so only four characters were compared.