This patch kit makes improvements to the analyzer's new strlen
implementation, and wires it up to strcpy and strcat.
For example, given:
#include <string.h>
void test (void)
{
char buf[10];
strcpy (buf, "hello world!");
}
we now emit:
demo.c: In function ‘test’:
demo.c:6:3: warning: stack-based buffer overflow [CWE-121]
[-Wanalyzer-out-of-bounds]
6 | strcpy (buf, "hello world!");
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
‘test’: events 1-2
|
| 5 | char buf[10];
| | ^~~
| | |
| | (1) capacity: 10 bytes
| 6 | strcpy (buf, "hello world!");
| | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (2) out-of-bounds write from byte 10 till byte 12 but ‘buf’ ends
at byte 10
|
demo.c:6:3: note: write of 3 bytes to beyond the end of ‘buf’
6 | strcpy (buf, "hello world!");
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
demo.c:6:3: note: valid subscripts for ‘buf’ are ‘[0]’ to ‘[9]’
┌─────┬─────┬────┬────┬────┬────┬────┬────┬────┬────┐┌─────┬─────┬─────┐
│ [0] │ [1] │[2] │[3] │[4] │[5] │[6] │[7] │[8] │[9] ││[10] │[11] │[12] │
├─────┼─────┼────┼────┼────┼────┼────┼────┼────┼────┤├─────┼─────┼─────┤
│ ‘h’ │ ‘e’ │‘l’ │‘l’ │‘o’ │‘ ’ │‘w’ │‘o’ │‘r’ │‘l’ ││ ‘d’ │ ‘!’ │ NUL │
├─────┴─────┴────┴────┴────┴────┴────┴────┴────┴────┴┴─────┴─────┴─────┤
│ string literal (type: ‘char[13]’) │
└──────────────────────────────────────────────────────────────────────┘
│ │ │ │ │ │ │ │ │ │ │ │ │
│ │ │ │ │ │ │ │ │ │ │ │ │
v v v v v v v v v v v v v
┌─────┬────────────────────────────────────────┬────┐┌─────────────────┐
│ [0] │ ... │[9] ││ │
├─────┴────────────────────────────────────────┴────┤│after valid range│
│ ‘buf’ (type: ‘char[10]’) ││ │
└───────────────────────────────────────────────────┘└─────────────────┘
├─────────────────────────┬─────────────────────────┤├────────┬────────┤
│ │
╭─────────┴────────╮ ╭───────────┴──────────╮
│capacity: 10 bytes│ │⚠️ overflow of 3 bytes│
╰──────────────────╯ ╰──────────────────────╯
in addition to the pre-existing:
demo.c:6:3: warning: ‘__builtin_memcpy’ writing 13 bytes into a region of size
10 overflows the destination [-Wstringop-overflow=]
demo.c:5:8: note: destination object ‘buf’ of size 10
5 | char buf[10];
| ^~~
Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu.
Pushed to trunk as r14-3461-g9aaec66917c96a through to
r14-3469-gbbdc0e0d0042ae.
David Malcolm (9):
analyzer: add logging to impl_path_context
analyzer: handle symbolic bindings in scan_for_null_terminator
[PR105899]
analyzer: reimplement kf_strcpy [PR105899]
analyzer: eliminate region_model::get_string_size [PR105899]
analyzer: reimplement kf_memcpy_memmove
analyzer: handle strlen(INIT_VAL(STRING_REG)) [PR105899]
analyzer: handle INIT_VAL(ELEMENT_REG(STRING_REG), CONSTANT_SVAL)
[PR105899]
analyzer: handle strlen(BITS_WITHIN) [PR105899]
analyzer: implement kf_strcat [PR105899]
gcc/analyzer/call-details.cc | 12 +-
gcc/analyzer/call-details.h | 5 +-
gcc/analyzer/engine.cc | 13 +-
gcc/analyzer/kf.cc | 116 +++++---
gcc/analyzer/region-model-manager.cc | 19 ++
gcc/analyzer/region-model.cc | 261 +++++++++++++-----
gcc/analyzer/region-model.h | 22 +-
gcc/doc/invoke.texi | 1 +
.../analyzer/out-of-bounds-diagram-16.c | 31 +++
gcc/testsuite/gcc.dg/analyzer/sprintf-1.c | 11 +
gcc/testsuite/gcc.dg/analyzer/strcat-1.c | 136 +++++++++
gcc/testsuite/gcc.dg/analyzer/strcpy-1.c | 22 ++
gcc/testsuite/gcc.dg/analyzer/strcpy-3.c | 8 +
gcc/testsuite/gcc.dg/analyzer/strcpy-4.c | 51 ++++
14 files changed, 601 insertions(+), 107 deletions(-)
create mode 100644 gcc/testsuite/gcc.dg/analyzer/out-of-bounds-diagram-16.c
create mode 100644 gcc/testsuite/gcc.dg/analyzer/strcat-1.c
create mode 100644 gcc/testsuite/gcc.dg/analyzer/strcpy-4.c
--
2.26.3