Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu.
Successful run of analyzer integration tests on x86_64-pc-linux-gnu.
Pushed to trunk as r16-7470-g29ad594504dcc1.
gcc/analyzer/ChangeLog:
PR analyzer/117369
* kf.cc (kf_sprintf::impl_call_pre): Use the capacity of the
region when "faking" a write to the destination buffer, to
avoid buffer overflow false +ves.
gcc/testsuite/ChangeLog:
PR analyzer/117369
* c-c++-common/analyzer/sprintf-pr117369.c: New test.
* gcc.dg/analyzer/doom-d_main-IdentifyVersion.c: Update expected
results to reflect complexity limits being hit earlier.
Signed-off-by: David Malcolm <[email protected]>
---
gcc/analyzer/kf.cc | 6 ++
.../c-c++-common/analyzer/sprintf-pr117369.c | 13 ++++
.../analyzer/doom-d_main-IdentifyVersion.c | 64 ++++++++++---------
3 files changed, 54 insertions(+), 29 deletions(-)
create mode 100644 gcc/testsuite/c-c++-common/analyzer/sprintf-pr117369.c
diff --git a/gcc/analyzer/kf.cc b/gcc/analyzer/kf.cc
index b6b4f8f93acbc..82aaee1dcb581 100644
--- a/gcc/analyzer/kf.cc
+++ b/gcc/analyzer/kf.cc
@@ -1245,6 +1245,12 @@ public:
const svalue *dst_ptr = cd.get_arg_svalue (0);
const region *dst_reg
= model->deref_rvalue (dst_ptr, cd.get_arg_tree (0), ctxt);
+ /* Restrict the region we consider to be affected to the valid capacity
+ so that we don't trigger buffer overflow false positives. */
+ const svalue *capacity = model->get_capacity (dst_reg);
+ dst_reg = model->get_manager ()->get_sized_region (dst_reg,
+ NULL_TREE,
+ capacity);
const svalue *content = cd.get_or_create_conjured_svalue (dst_reg);
model->set_value (dst_reg, content, ctxt);
cd.set_any_lhs_with_defaults ();
diff --git a/gcc/testsuite/c-c++-common/analyzer/sprintf-pr117369.c
b/gcc/testsuite/c-c++-common/analyzer/sprintf-pr117369.c
new file mode 100644
index 0000000000000..ed12831daf040
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/analyzer/sprintf-pr117369.c
@@ -0,0 +1,13 @@
+/* { dg-additional-options "-O" } */
+
+extern int
+sprintf (char *__restrict __s,
+ const char *__restrict __format, ...)
+ __attribute__ ((__nothrow__));
+
+int
+main()
+{
+ char buf[16];
+ sprintf(buf + 1, "."); /* { dg-bogus "buffer overflow" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/doom-d_main-IdentifyVersion.c
b/gcc/testsuite/gcc.dg/analyzer/doom-d_main-IdentifyVersion.c
index e55c378c7ecc4..a52e3528cfa18 100644
--- a/gcc/testsuite/gcc.dg/analyzer/doom-d_main-IdentifyVersion.c
+++ b/gcc/testsuite/gcc.dg/analyzer/doom-d_main-IdentifyVersion.c
@@ -220,53 +220,59 @@ IdentifyVersion(void)
if (!access(doom2wad, 4)) {
gamemode = commercial;
D_AddFile(doom2wad);
- return; /* { dg-warning "leak of 'doom2wad'" } */
- /* { dg-warning "leak of 'doomuwad'" "leak" { target *-*-* } .-1 } */
- /* { dg-warning "leak of 'doomwad'" "leak" { target *-*-* } .-2 } */
- /* { dg-warning "leak of 'doom1wad'" "leak" { target *-*-* } .-3 } */
- /* { dg-warning "leak of 'plutoniawad'" "leak" { target *-*-* } .-4 } */
- /* { dg-warning "leak of 'tntwad'" "leak" { target *-*-* } .-5 } */
- /* { dg-warning "leak of 'doom2fwad'" "leak" { target *-*-* } .-6 } */
+ return; /* { dg-warning "leak of 'doom2wad'" "" { xfail *-*-* } } */
+ /* { dg-warning "leak of 'doomuwad'" "leak" { xfail *-*-* } .-1 } */
+ /* { dg-warning "leak of 'doomwad'" "leak" { xfail *-*-* } .-2 } */
+ /* { dg-warning "leak of 'doom1wad'" "leak" { xfail *-*-* } .-3 } */
+ /* { dg-warning "leak of 'plutoniawad'" "leak" { xfail *-*-* } .-4 } */
+ /* { dg-warning "leak of 'tntwad'" "leak" { xfail *-*-* } .-5 } */
+ /* { dg-warning "leak of 'doom2fwad'" "leak" { xfail *-*-* } .-6 } */
}
if (!access(plutoniawad, 4)) {
gamemode = commercial;
D_AddFile(plutoniawad);
- return; /* { dg-warning "leak of 'doom2wad'" } */
- /* { dg-warning "leak of 'doomuwad'" "leak" { target *-*-* } .-1 } */
- /* { dg-warning "leak of 'doomwad'" "leak" { target *-*-* } .-2 } */
- /* { dg-warning "leak of 'doom1wad'" "leak" { target *-*-* } .-3 } */
- /* { dg-warning "leak of 'plutoniawad'" "leak" { target *-*-* } .-4 } */
- /* { dg-warning "leak of 'tntwad'" "leak" { target *-*-* } .-5 } */
- /* { dg-warning "leak of 'doom2fwad'" "leak" { target *-*-* } .-6 } */
+ return; /* { dg-warning "leak of 'doom2wad'" "" { xfail *-*-* } } */
+ /* { dg-warning "leak of 'doomuwad'" "leak" { xfail *-*-* } .-1 } */
+ /* { dg-warning "leak of 'doomwad'" "leak" { xfail *-*-* } .-2 } */
+ /* { dg-warning "leak of 'doom1wad'" "leak" { xfail *-*-* } .-3 } */
+ /* { dg-warning "leak of 'plutoniawad'" "leak" { xfail *-*-* } .-4 } */
+ /* { dg-warning "leak of 'tntwad'" "leak" { xfail *-*-* } .-5 } */
+ /* { dg-warning "leak of 'doom2fwad'" "leak" { xfail *-*-* } .-6 } */
}
if (!access(tntwad, 4)) {
gamemode = commercial;
D_AddFile(tntwad);
- return; /* { dg-warning "leak of 'doom2wad'" } */
- /* { dg-warning "leak of 'doomuwad'" "leak" { target *-*-* } .-1 } */
- /* { dg-warning "leak of 'doomwad'" "leak" { target *-*-* } .-2 } */
- /* { dg-warning "leak of 'doom1wad'" "leak" { target *-*-* } .-3 } */
- /* { dg-warning "leak of 'plutoniawad'" "leak" { target *-*-* } .-4 } */
- /* { dg-warning "leak of 'tntwad'" "leak" { target *-*-* } .-5 } */
- /* { dg-warning "leak of 'doom2fwad'" "leak" { target *-*-* } .-6 } */
+ return; /* { dg-warning "leak of 'doom2wad'" "" { xfail *-*-* } } */
+ /* { dg-warning "leak of 'doomuwad'" "leak" { xfail *-*-* } .-1 } */
+ /* { dg-warning "leak of 'doomwad'" "leak" { xfail *-*-* } .-2 } */
+ /* { dg-warning "leak of 'doom1wad'" "leak" { xfail *-*-* } .-3 } */
+ /* { dg-warning "leak of 'plutoniawad'" "leak" { xfail *-*-* } .-4 } */
+ /* { dg-warning "leak of 'tntwad'" "leak" { xfail *-*-* } .-5 } */
+ /* { dg-warning "leak of 'doom2fwad'" "leak" { xfail *-*-* } .-6 } */
}
if (!access(doomuwad, 4)) {
gamemode = retail;
D_AddFile(doomuwad);
- return; /* { dg-warning "leak of 'doom2wad'" } */
- /* { dg-warning "leak of 'doomuwad'" "leak" { target *-*-* } .-1 } */
- /* { dg-warning "leak of 'doomwad'" "leak" { target *-*-* } .-2 } */
- /* { dg-warning "leak of 'doom1wad'" "leak" { target *-*-* } .-3 } */
- /* { dg-warning "leak of 'plutoniawad'" "leak" { target *-*-* } .-4 } */
- /* { dg-warning "leak of 'tntwad'" "leak" { target *-*-* } .-5 } */
- /* { dg-warning "leak of 'doom2fwad'" "leak" { target *-*-* } .-6 } */
+ return; /* { dg-warning "leak of 'doom2wad'" "" { xfail *-*-* } } */
+ /* { dg-warning "leak of 'doomuwad'" "leak" { xfail *-*-* } .-1 } */
+ /* { dg-warning "leak of 'doomwad'" "leak" { xfail *-*-* } .-2 } */
+ /* { dg-warning "leak of 'doom1wad'" "leak" { xfail *-*-* } .-3 } */
+ /* { dg-warning "leak of 'plutoniawad'" "leak" { xfail *-*-* } .-4 } */
+ /* { dg-warning "leak of 'tntwad'" "leak" { xfail *-*-* } .-5 } */
+ /* { dg-warning "leak of 'doom2fwad'" "leak" { xfail *-*-* } .-6 } */
}
/* [...snip...] */
printf("Game mode indeterminate.\n");
gamemode = indetermined;
-}
+} /* { dg-warning "leak of 'doom2wad'" } */
+/* { dg-warning "leak of 'doomuwad'" "leak" { target *-*-* } .-1 } */
+/* { dg-warning "leak of 'doomwad'" "leak" { target *-*-* } .-2 } */
+/* { dg-warning "leak of 'doom1wad'" "leak" { target *-*-* } .-3 } */
+/* { dg-warning "leak of 'plutoniawad'" "leak" { target *-*-* } .-4 } */
+/* { dg-warning "leak of 'tntwad'" "leak" { target *-*-* } .-5 } */
+/* { dg-warning "leak of 'doom2fwad'" "leak" { target *-*-* } .-6 } */
--
2.26.3