Skip to content

Analysis Categories

Hugo edited this page Sep 25, 2026 · 2 revisions

Analysis Categories

The analyzer performs stack-safety, resource-lifetime, uninitialized-use, and code-quality checks. Each diagnostic includes severity, source location, and machine-readable identifiers (errCode and/or ruleId).


Stack Overflow Detection

StackFrameTooLarge

Severity: Error CWE: CWE-121 (Stack-based Buffer Overflow)

Triggers when a function's total stack usage (local frame + callees) exceeds the configured limit (default: 8 MiB).

int main(void) {
    char buf[8192000000];  // way too large for stack
    return 0;
}
// [!!Error] potential stack overflow: exceeds limit of 8388608 bytes

Includes callee propagation: if main calls foo, and foo uses a huge stack, main inherits the overflow.


Buffer Overflow Detection

StackBufferOverflow

Severity: Warning CWE: CWE-121

Detects out-of-bounds access on stack-allocated buffers. Tracks alias chains, pointer dereferences, and both constant and dynamic indices.

char buf[10];
buf[15] = 'x';
// [!!Warn] potential stack buffer overflow on variable 'buf' (size 10)
//   constant index 15 is out of bounds (0..9)
//   (this is a write access)

Features:

  • Constant index bounds checking
  • Alias path tracking (e.g., ptr -> buf)
  • Struct internal array overflow detection
  • Read vs write access distinction

NegativeStackIndex

Severity: Warning

Detects negative index access on stack buffers.

char buf[10];
buf[-1] = 'c';
// [!!Warn] constant index 18446744073709551615 is out of bounds (0..9)

Dynamic Allocation Analysis

VLAUsage

Severity: Warning CWE: CWE-770 (Allocation of Resources Without Limits)

Detects variable-length arrays on the stack.

void process(int n) {
    char data[n];  // VLA - size not known at compile time
}
// [!!Warn] variable-length array detected

AllocaUserControlled

Severity: Warning (can be escalated to Error in recursive contexts)

Detects alloca or VLA whose size comes from user-controlled input (e.g., scanf).

int n;
scanf("%d", &n);
char buf[n];  // user-controlled stack allocation
// [ !!Warn ] user-controlled alloca size for variable 'buf'

AllocaTooLarge

Severity: Error

Detects constant allocations that are unreasonably large, or dynamic allocations in recursive functions.

char data[1024 * 1024 * 100];  // 100 MiB on stack
// [!!Error] oversized constant dynamic allocation

AllocaUsageWarning

Severity: Warning

General dynamic alloca usage that does not fall into the above categories. Flags the use of runtime-sized stack allocations.


Memory Operation Overflows

MemcpyWithStackDest

Severity: Warning CWE: CWE-120 (Buffer Copy without Checking Size)

Detects memcpy/memset overflows when the destination is a stack buffer.

char buf[10];
memcpy(buf, src, 20);  // copies 20 bytes into 10-byte buffer
// [!!Warn] memcpy overflow: destination buffer 'buf' is 10 bytes, but 20 bytes copied

MultipleStoresToStackBuffer

Severity: Info

Reports when multiple store instructions write to the same stack buffer at different index expressions. Not necessarily a bug, but a signal to verify index correctness.

char buf[10];
buf[0] = 'a';
buf[5] = 'b';
buf[9] = 'c';
// [!Info] multiple stores to stack buffer 'buf' (3 store instructions, 3 distinct indices)

Stack Pointer Escape Detection

StackPointerEscape

Severity: Warning CWE: CWE-562 (Return of Stack Variable Address)

Detects when a pointer to a stack variable is leaked outside its scope. Escape kinds include:

store_unknown -- storing the pointer in a non-local location (global, heap, out-parameter):

char buf[10];
global_ptr = buf;  // leaking stack address
// [!!Warn] stack pointer escape: store_unknown

call_callback -- passing a stack pointer to an indirect call (callback):

char buf[10];
callback(buf);  // indirect call, may capture pointer
// [!!Warn] stack pointer escape: call_callback

call_arg -- passing to a direct function that may capture it:

char buf[10];
consume(buf);  // direct call, callee may capture pointer
// [ !!Warn ] stack pointer escape

return -- returning a pointer to stack memory:

char buf[10];
return buf;  // pointer escapes function lifetime
// [ !!Warn ] stack pointer escape

Resolution order for escape analysis:

  1. LLVM call-site attributes (nocapture, byval, byref)
  2. Inter-procedural summary (for analyzed definitions)
  3. External escape model (--escape-model)
  4. Opaque external call: no strong diagnostic emitted

Resource Lifetime Analysis

ResourceLifetimeIssue

Severity: Warning CWE: CWE-772 (Missing Release) / CWE-415 (Double Free)

Model-driven analysis using external API definitions. Requires --resource-model=<path>.

Missing release (ResourceLifetime.MissingRelease):

handle_t h;
acquire_handle(&h);
return 0;  // forgot to release
// [!!Warn] potential resource leak: 'GenericHandle' acquired in handle 'h' is not released

Double release (ResourceLifetime.DoubleRelease):

release_handle(h);
release_handle(h);  // double free
// [!!!Error] potential double release of 'GenericHandle'

Constructor/destructor mismatch (ResourceLifetime.MissingDestructorRelease):

Reports when a class field acquired in the constructor is not released in the destructor.

Incomplete inter-procedural (ResourceLifetime.IncompleteInterproc):

Warning when a local release depends on an unmodeled callee and no cross-TU summary is available.

Features:

  • Cross-TU summary propagation with fixed-point iteration
  • Per-module caching (filesystem or memory-only)
  • Supports C malloc/free, C++ new/delete, Vulkan, and custom APIs

Uninitialized Variable Detection

UninitializedLocalRead

Severity: Warning CWE: CWE-457 (Use of Uninitialized Variable)

Detects reads from local variables before they are written to.

int x;
printf("%d\n", x);  // read before initialization
// [!!Warn] use of uninitialized local variable 'x'

Features:

  • Cross-TU tracking via inter-procedural summaries
  • Branch-aware analysis (detects conditional initialization)
  • Struct partial initialization detection
  • Array initialization tracking
  • Two emitted rule IDs: UninitializedLocalRead and UninitializedLocalVariable

Code Quality Checks

DuplicateIfCondition

Severity: Warning

Detects duplicate conditions in if-else chains that create dead code.

if (x > 0) { ... }
else if (x > 0) { ... }  // duplicate condition, dead branch
// [!!Warn] duplicate condition in if-else chain

Handles:

  • Simple comparisons
  • Boolean expressions
  • Enum comparisons
  • Pointer comparisons
  • Commutative reordering
  • Nested loop contexts

ConstParameterNotModified

Severity: Info

Reports function parameters that are never modified and could be declared const.

void process(int* data, int count) {
    // 'count' is never modified
    for (int i = 0; i < count; i++) { ... }
}
// [!Info] parameter 'count' is never modified; consider declaring it const

SizeMinusOneWrite

Severity: Warning

Detects potential off-by-one errors in buffer writes using size - 1 patterns (e.g., strncpy(dst, src, sizeof(dst) - 1)).

InvalidBaseReconstruction

Severity: Warning or Error

Detects unsafe pointer arithmetic patterns where inttoptr/ptrtoint casts produce incorrect base addresses (common with container_of macro misuse).


Recursion Analysis

Recursion.Detected

Severity: Info · CWE: none

A function is recursive or mutually recursive. This is a pattern to know about when reading a stack budget, not a flaw — which is why it carries no CWE and is not ranked among security findings.

Recursion.Unconditional

Severity: Error · CWE: CWE-674

Self-recursion with no base case: every path recurses. This will overflow the stack at run time.

void f(int n) { f(n - 1); }   // nothing stops it

SMT refinement can be restricted to these rules with --smt-rules=recursion.


Integer Handling

Integers that feed a size or an index computation, where a wrap or a truncation turns into a memory-safety problem.

Rule CWE Detects
IntegerOverflow.SizeComputation CWE-190 A size computation that can wrap
IntegerOverflow.SignedArithmetic CWE-190 Signed arithmetic overflow
IntegerConversion.SignedToSize CWE-195 A signed value converted to a size type
IntegerTruncation.SizeComputation CWE-197 A size truncated to a narrower type

All four are Warning.


Out-of-Bounds Reads

OutOfBoundsRead.MissingNullTerminator

Severity: Warning · CWE: CWE-125

A string buffer may reach a read API without a null terminator; the report names the buffer size and the last write size. An unterminated string makes a read API scan past the buffer bounds.

OutOfBoundsRead.HeapIndex

Severity: Warning · CWE: CWE-125

A read on a heap buffer through an unchecked index, reported with the inferred heap capacity.

Out-of-range constant indices are resolved at their program point, so a constant that is provably in range is not reported and one that is provably out of range is reported with certainty rather than as a maybe.


Null Pointer Dereference

NullPointerDereference

Severity: Error, or Warning when the path is conditional · CWE: CWE-476

A dereference of a pointer that may be null. An unconditional dereference is an error; a dereference reachable only on one path stays a warning.


Type Confusion

TypeConfusion.IncompatibleStructView

Severity: Warning · CWE: CWE-843

Incompatible struct views on the same pointer: a field access through a larger view than the object actually has may read or write outside its real layout. The report names the smaller observed view, the accessed view and the byte offset.


Injection and Sequencing

CommandInjection.NonLiteralCommand

Severity: Warning · CWE: CWE-78

A non-literal command string reaches a command-execution API: the argument is not a compile-time string literal. Validate or sanitize external input, or avoid composing shell commands.

TOCTOU.PathCheckThenUse

Severity: Warning · CWE: CWE-367

A path is checked with one API and then used with another; the file target may change between check and use. Prefer descriptor-based validation — open then fstat on the same handle.


Initialization Beyond Locals

GlobalReadBeforeWrite

Severity: Warning · CWE: CWE-665

A global is read before any definite write. Tracked across translation units.

InformationExposure.UninitializedStackBytes

Severity: Warning · CWE: CWE-200

A local variable may expose uninitialized bytes through an external sink: the transmitted range is not fully initialized on all control-flow paths.


When the Analysis Could Not Conclude

These are not findings about the code. They report that the analysis did not reach a conclusion, and they are deliberately Info with no CWE so they neither rank among security findings nor fail a build.

Rule Meaning
UninitializedLocalRead.AnalysisIncomplete The initialization fixpoint did not converge
ResourceLifetime.AnalysisIncomplete Resource ownership could not be decided
ResourceLifetime.IncompleteInterproc Partial interprocedural view (Warning, still no CWE)

A clean report that contains them means nothing was proven, not nothing is wrong.

The same principle applies to stack budgets: a call the analyzer cannot resolve makes the function's maximum stack unknown rather than silently under-counted. Use --assume-external-frame=<value> to charge a fixed budget per unresolved call instead.


Diagnostic Fields

Every diagnostic includes:

Field Description
filePath Source file where the issue was found
funcName Function containing the issue
line, column Source location
startLine, startColumn, endLine, endColumn SARIF range
severity Info, Warning, or Error
errCode Internal enum (e.g., StackBufferOverflow)
ruleId Dotted rule identifier (e.g., ResourceLifetime.MissingRelease)
confidence [0, 1] float when applicable
cweId CWE identifier (e.g., CWE-772)
message Human-readable diagnostic message

Clone this wiki locally