diff options
author | David Malcolm <dmalcolm@redhat.com> | 2023-12-08 15:59:43 -0500 |
---|---|---|
committer | David Malcolm <dmalcolm@redhat.com> | 2023-12-08 15:59:43 -0500 |
commit | 08262e78209ed4a69f309b6fdf79e7c0be0c6793 (patch) | |
tree | 8bcf272539b88b28c19c1ca73f26a71bcadf1d31 /gcc | |
parent | 48cb51827c9eb991b92014a3f59d31eb237ce03f (diff) | |
download | gcc-08262e78209ed4a69f309b6fdf79e7c0be0c6793.zip gcc-08262e78209ed4a69f309b6fdf79e7c0be0c6793.tar.gz gcc-08262e78209ed4a69f309b6fdf79e7c0be0c6793.tar.bz2 |
analyzer: fix ICE on infoleak with poisoned size
gcc/analyzer/ChangeLog:
* region-model.cc (contains_uninit_p): Only check for
svalues that the infoleak warning can handle.
gcc/testsuite/ChangeLog:
* gcc.dg/plugin/infoleak-uninit-size-1.c: New test.
* gcc.dg/plugin/infoleak-uninit-size-2.c: New test.
* gcc.dg/plugin/plugin.exp: Add the new tests.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/analyzer/region-model.cc | 37 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/plugin/infoleak-uninit-size-1.c | 20 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/plugin/infoleak-uninit-size-2.c | 20 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/plugin/plugin.exp | 2 |
4 files changed, 66 insertions, 13 deletions
diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc index 6a7a8bc..2315751 100644 --- a/gcc/analyzer/region-model.cc +++ b/gcc/analyzer/region-model.cc @@ -6576,22 +6576,33 @@ private: static bool contains_uninit_p (const svalue *sval) { - struct uninit_finder : public visitor - { - public: - uninit_finder () : m_found_uninit (false) {} - void visit_poisoned_svalue (const poisoned_svalue *sval) + switch (sval->get_kind ()) { - if (sval->get_poison_kind () == POISON_KIND_UNINIT) - m_found_uninit = true; - } - bool m_found_uninit; - }; + default: + return false; + case SK_POISONED: + { + const poisoned_svalue *psval + = as_a <const poisoned_svalue *> (sval); + return psval->get_poison_kind () == POISON_KIND_UNINIT; + } + case SK_COMPOUND: + { + const compound_svalue *compound_sval + = as_a <const compound_svalue *> (sval); - uninit_finder v; - sval->accept (&v); + for (auto iter : *compound_sval) + { + const svalue *sval = iter.second; + if (const poisoned_svalue *psval + = sval->dyn_cast_poisoned_svalue ()) + if (psval->get_poison_kind () == POISON_KIND_UNINIT) + return true; + } - return v.m_found_uninit; + return false; + } + } } /* Function for use by plugins when simulating writing data through a diff --git a/gcc/testsuite/gcc.dg/plugin/infoleak-uninit-size-1.c b/gcc/testsuite/gcc.dg/plugin/infoleak-uninit-size-1.c new file mode 100644 index 0000000..7466112 --- /dev/null +++ b/gcc/testsuite/gcc.dg/plugin/infoleak-uninit-size-1.c @@ -0,0 +1,20 @@ +/* Reduced from infoleak ICE seen on Linux kernel with + -Wno-analyzer-use-of-uninitialized-value. + + Verify that we don't ICE when complaining about an infoleak + when the size is uninitialized. */ + +/* { dg-do compile } */ +/* { dg-options "-fanalyzer -Wno-analyzer-use-of-uninitialized-value" } */ +/* { dg-require-effective-target analyzer } */ + +extern unsigned long +copy_to_user(void* to, const void* from, unsigned long n); + +unsigned long +test_uninit_size (void *to, void *from) +{ + unsigned long n; + char buf[16]; + return copy_to_user(to, from, n); +} diff --git a/gcc/testsuite/gcc.dg/plugin/infoleak-uninit-size-2.c b/gcc/testsuite/gcc.dg/plugin/infoleak-uninit-size-2.c new file mode 100644 index 0000000..a8a383f --- /dev/null +++ b/gcc/testsuite/gcc.dg/plugin/infoleak-uninit-size-2.c @@ -0,0 +1,20 @@ +/* Reduced from infoleak ICE seen on Linux kernel with + -Wno-analyzer-use-of-uninitialized-value. + + Verify that we complain about the uninit value when + -Wno-analyzer-use-of-uninitialized-value isn't supplied. */ + +/* { dg-do compile } */ +/* { dg-options "-fanalyzer" } */ +/* { dg-require-effective-target analyzer } */ + +extern unsigned long +copy_to_user(void* to, const void* from, unsigned long n); + +unsigned long +test_uninit_size (void *to, void *from) +{ + unsigned long n; + char buf[16]; + return copy_to_user(to, from, n); /* { dg-warning "use of uninitialized value 'n'" } */ +} diff --git a/gcc/testsuite/gcc.dg/plugin/plugin.exp b/gcc/testsuite/gcc.dg/plugin/plugin.exp index f0b4bb7..d6cccb2 100644 --- a/gcc/testsuite/gcc.dg/plugin/plugin.exp +++ b/gcc/testsuite/gcc.dg/plugin/plugin.exp @@ -150,6 +150,8 @@ set plugin_test_list [list \ infoleak-CVE-2017-18550-1.c \ infoleak-antipatterns-1.c \ infoleak-fixit-1.c \ + infoleak-uninit-size-1.c \ + infoleak-uninit-size-2.c \ infoleak-net-ethtool-ioctl.c \ infoleak-vfio_iommu_type1.c \ taint-CVE-2011-0521-1-fixed.c \ |