Repository navigation
Closed
Labels
bugSomething isn't workingSomething isn't working
Description
StackBufferOverflow does not report a write that a callee makes through a pointer past the end of its caller's stack array.
Two separate changes affect the example below. Do not confuse them:
- The old report was wrong, and removing it was correct. Before feat(stack-buffer): bound stack array indexes with ScalarEvolution on a promoted copy #264, the line that forms
&buf[8]was reported as a write, because any store of an element's address counted as one. Forming a pointer one past the end is valid C. The same rule caused the false positives of False positive: StackBufferOverflow on the end of a range-based for over a local array #206. - The real overflow now has no diagnostic.
leafwritesbuf[8]through its parameter, and nothing reports that write. feat(stack-buffer): bound stack array indexes with ScalarEvolution on a promoted copy #264 removed the misplaced report. fix(stack-buffer): check accesses through a local pointer to an array element #265 follows pointer variables only to accesses in the same function.
Passing &buf[8] directly as the argument has never been reported, before #264 or after.
Example
callee-write.c:
void leaf(char* p) { *p = 42; }
void bridge(char* p)
{
char* q = p;
leaf(q);
}
void caller(void)
{
char buf[8] = {0};
char* p = &buf[8];
bridge(p);
}Before and after
| Version | Diagnostic |
|---|---|
| c59f696, before #264 | One warning, on line 12 (char* p = &buf[8];). It is misplaced: no write happens there. |
| 276a0d6, head of #264 | None |
| f79fcce, head of #265 | None |
Output on c59f696:
$ stack_usage_analyzer callee-write.c --warnings-only
Function: caller
at line 12, column 11
[ !!Warn ] potential stack buffer overflow on variable 'buf' (size 8)
↳ alias path: buf
↳ constant index 8 is out of bounds (0..7)
↳ (this is a write access)
On f79fcce, the result is also empty with --smt=on, and when the three functions are in three files analyzed together.
Expected
The report should be on the write in leaf, and should name buf and the call that passes it: leaf writes 1 byte at offset 8 of buf, which holds 8 bytes. The line that forms the address should not be reported.
Each case must give the same result whether its functions are in one file or in several:
| Case | Expected |
|---|---|
buf + 8 passed to the callee, never dereferenced |
no report |
1-byte write through buf + 7 |
no report |
1-byte write through buf + 8 |
overflow |
| the same write after several pointer copies and calls | overflow |
| the pointer reassigned to a large enough object before the call | no report |
| the write behind a guard in the callee that excludes the overflow | no report |
Related
- Design: buffer extent and length tracking (symbolic sizes, cross-TU extents, taint) for the overflow rules #247, step 3: the extent a function requires of each pointer parameter. This issue covers only the stack-array case above.
- feat(stack-buffer): bound stack array indexes with ScalarEvolution on a promoted copy #264 introduces the loss. fix(stack-buffer): check accesses through a local pointer to an array element #265 restores the report only for accesses in the same function.
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working
Activity