Safeguard
Application Security•

CWE-416 Use After Free: How It Happens and How to Fix It

Using memory after it has been freed can leak data, crash a process or give an attacker code execution. CWE-416 with examples, detection and fixes.

Safeguard Security Team
4 min read

CWE-416, use after free, happens when a product references memory after it has been freed. MITRE describes the sequel: the memory may be allocated again and held by another pointer, so the original pointer now refers somewhere inside someone else's allocation. Anything done through the old pointer is no longer valid.

It affects memory unsafe languages, mainly C and C++: operating system kernels, browsers, network stacks and native libraries.

How it happens

Three ingredients are common. An object is freed. A pointer to it survives. Code later uses that pointer.

/* Vulnerable */
struct session *s = get_session(id);
close_session(s);          /* frees s */
log_user(s->user);         /* use after free */

Concurrency makes it worse. MITRE's observed examples include several chains:

  • A browser where two threads used the same resource and one destroyed it before the other finished (CVE-2022-2621).
  • A mobile platform race condition leading to use after free, noted by MITRE as exploited in the wild per CISA KEV (CVE-2021-0920).
  • A kernel where insufficient resource locking led to use after free (CVE-2022-20141).
  • TCP/IP code in an operating system with a use after free that could leak heap memory contents (CVE-2023-38160).

What an attacker gains

The record lists several outcomes:

  • Modify memory. Valid data can be corrupted if the area has been reallocated and used elsewhere.
  • Crash. If chunk consolidation happens after the use, invalid data can crash the process.
  • Read memory. Reads of freed memory can leak sensitive information instead of crashing.
  • Execute code. If malicious data is placed before chunk consolidation, a write what where primitive may allow arbitrary code execution.

How to find it

MITRE lists three methods:

  • Fuzzing to generate many diverse inputs and look for crashes and corruption.
  • Automated static analysis (SAST), which can find some instances by modeling data flow.
  • Automated dynamic analysis with compiler integrated checks such as AddressSanitizer, which flags use of freed memory at runtime. Crafted inputs are required to reach the faulty code.
clang -fsanitize=address -g -o app app.c

Vulnerable library versions are a separate problem. Your own code may be clean while a native dependency is not. Run a free dependency scan on your manifest. It stays in your browser and covers up to 100 dependencies.

How to fix it

The MITRE record lists no formal mitigations here, so these are common practices.

  1. Clear pointers after free. Set them to NULL so a stray use fails loudly and predictably.
  2. Clarify ownership. One owner frees. Others borrow and never outlive the owner.
  3. Use smart pointers in C++. std::unique_ptr and std::shared_ptr tie lifetime to scope and reference counts.
  4. Synchronize shared objects. Use locks or reference counting when threads share a resource, so one cannot destroy it while another uses it.
  5. Consider memory safe languages for new components that parse untrusted input.
  6. Update native dependencies quickly when fixes ship.
/* Fixed: do not touch s after closing, and clear the pointer */
struct session *s = get_session(id);
log_user(s->user);
close_session(s);
s = NULL;

Try it yourself

The SAST demo shows how static analysis flags risky patterns in source code.

Click through it at your own pace, or open it full screen.

Quick check

Why can reading freed memory be dangerous even without a crash?

The memory may now hold another allocation's data. A read can return secrets from it instead of failing.

How does a race condition lead to use after free?

One thread frees a resource while another still holds a pointer to it. The second thread then uses freed memory.

Is nulling the pointer a complete fix?

It helps with the pointer you cleared, but copies elsewhere stay dangling. Clear ownership and lifetime rules matter more.

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.