Repository navigation
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).
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 bytesIncludes callee propagation: if main calls foo, and foo uses a huge stack, main inherits the overflow.
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
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)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 detectedSeverity: 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'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 allocationSeverity: Warning
General dynamic alloca usage that does not fall into the above categories. Flags the use of runtime-sized stack allocations.
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 copiedSeverity: 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)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_unknowncall_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_callbackcall_arg -- passing to a direct function that may capture it:
char buf[10];
consume(buf); // direct call, callee may capture pointer
// [ !!Warn ] stack pointer escapereturn -- returning a pointer to stack memory:
char buf[10];
return buf; // pointer escapes function lifetime
// [ !!Warn ] stack pointer escapeResolution order for escape analysis:
- LLVM call-site attributes (
nocapture,byval,byref) - Inter-procedural summary (for analyzed definitions)
- External escape model (
--escape-model) - Opaque external call: no strong diagnostic emitted
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 releasedDouble 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
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:
UninitializedLocalReadandUninitializedLocalVariable
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 chainHandles:
- Simple comparisons
- Boolean expressions
- Enum comparisons
- Pointer comparisons
- Commutative reordering
- Nested loop contexts
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 constSeverity: Warning
Detects potential off-by-one errors in buffer writes using size - 1 patterns (e.g., strncpy(dst, src, sizeof(dst) - 1)).
Severity: Warning or Error
Detects unsafe pointer arithmetic patterns where inttoptr/ptrtoint casts produce incorrect base addresses (common with container_of macro misuse).
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.
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 itSMT refinement can be restricted to these rules with --smt-rules=recursion.
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.
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.
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.
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.
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.
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.
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.
Severity: Warning · CWE: CWE-665
A global is read before any definite write. Tracked across translation units.
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.
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.
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 |