Safeguard
Application Security•

CWE-824 Access of Uninitialized Pointer: Causes and Fixes

A pointer that was never set points somewhere unknown. CWE-824 turns that into crashes, leaks and sometimes code execution. Here is how to avoid it.

Safeguard Security Team
3 min read

CWE-824 is the use of a pointer that has not been initialized. Whatever bytes happened to be in that memory become the address the program reads, writes, or even calls.

MITRE lists C and C++, the memory-unsafe languages where this can happen. It often appears at the end of a chain, where an earlier slip leaves a variable unset.

How it happens

A local pointer is declared and not assigned. An error path skips the assignment. A struct is allocated but a pointer member is never filled. A union is read through the wrong member. The program then dereferences it.

// Vulnerable: p is only set on one path
char *p;
if (ok) p = buf;
use(p);   // p is garbage when ok is false

MITRE's observed examples are mostly chains.

  • CVE-2019-3836: a secure communications library does not initialize a local variable for a data structure, leading to access of an uninitialized pointer.
  • CVE-2018-14641: a C union member is not initialized, leading to access of an invalid pointer.
  • CVE-2010-0211: an unchecked return value leads to a free of an invalid, uninitialized pointer.
  • CVE-2024-32878: an LLM product frees an uninitialized pointer.

What an attacker gains

Depending on memory layout and how the program manages memory, an attacker may influence the content of the uninitialized pointer. MITRE lists three outcomes: reading sensitive memory, crashing the program, and, when the pointer is used for a function call or a write, code execution.

How to find it

MITRE names static analysis and dynamic analysis with compiler runtime checks such as AddressSanitizer. Compilers also warn about many uses of uninitialized variables, so turn on warnings and treat them as errors. Crafted inputs are needed to reach error paths, so test failure cases on purpose.

How to fix it

The record has no formal mitigations. These are widely used practices.

  1. Initialize every pointer at declaration, to a valid object or to NULL.
  2. Check return values so a failed call does not leave a pointer unset.
  3. Check for NULL before use.
  4. In C++, prefer smart pointers and constructors that set every member.
  5. Compile with strict warnings and run tests under a memory checker.
char *p = NULL;
if (ok) p = buf;
if (p) use(p);

Quick check

Is initializing to NULL enough?

It turns a wild pointer into a predictable one, but you still need to check it before use. A NULL dereference is still a crash.

Sources

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.