Skip to content

VNX-415: Double free

Reports a C or C++ pointer released twice on one path: free/g_free/kfree/OPENSSL_free/delete of the same expression again within 20 lines with no reassignment, exit or branch in between, and a release followed by goto to cleanup code that releases it again. Nulled pointers, if/else and switch branches, other functions, macros and comments are not reported.

Updated 02 Nov 2026Checked against cli@de9b52a
Field Value
Rule ID VNX-415
Severity High
SARIF level error
Kind sast
Languages C, C++
CWE CWE-415
CAPEC CAPEC-66
ATT&CK T1190
CWSS vector CWSS:1.0/TI:H/AP:RU/AL:S/IC:N/FC:LT/RP:RU/RL:S/AV:L/AS:N/IN:A/SC:A/BI:H/DI:H/EX:H/EC:N/P:H
Tags double-free memory-safety cwe-415
Source internal/sast/rules/vnx-415.rego

Overview

VNX-415 maps to CWE-415: Double Free. Releasing the same heap block twice corrupts the allocator’s free lists; an attacker who controls the allocations in between can usually turn that into a write of their choosing.

The rule reports two shapes:

  1. A second release on the same path. free, g_free, kfree, vfree, kvfree, OPENSSL_free, CRYPTO_free, xfree, std::free, delete or delete[] of a variable or member expression, followed within 20 lines by another release of the same expression, with nothing in between that reassigns it (p = NULL, p = malloc(n), get(&p), reassigning the struct that holds the member), leaves the path (return, break, continue, goto, exit, abort, throw at the release’s nesting level) or starts another branch (else, case, default, #else, the end of the function).
  2. Release, then goto cleanup. A release immediately followed by goto LABEL, where the cleanup code under LABEL releases the same expression again without it having been nulled.

What Gets Flagged

free(buf);
if (rc != 0) {
    log_error("invalid header");
}
free(buf);              // FLAGGED: second release on the same path
if (token == NULL) {
    free(name);         // FLAGGED: the cleanup label frees name again
    goto out;
}
...
out:
    free(token);
    free(name);

What Is Not Flagged

  • A pointer set to NULL or reassigned between the two releases.
  • Releases on the two arms of an if/else or in different cases, and a release followed by return.
  • Releases in different functions, #define macros, string literals and comments.
  • Project-specific wrappers (other than xfree) and aliases (q = p; free(p); free(q)), which are not tracked.

Remediation

Release each allocation in exactly one place, and set the pointer to NULL right after releasing it when other code may release it later:

free(name);
name = NULL;
goto out;

References

Suppressing this rule

Put a nosec comment on the line, or on line 1 to cover the whole file. Use the comment marker of the file’s language (#, //, -- or ;):

# nosec vnx-415
// nosec vnx-415

Or record an ignore rule: vulnetix ignore add --rule vnx-415 --reason "...". See Suppressing findings.

Edit this pageSources: cli/internal/sast/rules/vnx-415.rego, cli/internal/sast/docs/vnx-415.md
esc
↑ ↓ move↵ openSearches in your browser. A key like autonomy.max or a code like threshold_required jumps straight to it.