From: David Malcolm Date: Fri, 8 Dec 2023 20:59:43 +0000 (-0500) Subject: analyzer: fix ICE on infoleak with poisoned size X-Git-Tag: basepoints/gcc-15~3791 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=08262e78209ed4a69f309b6fdf79e7c0be0c6793;p=thirdparty%2Fgcc.git 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 --- diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc index 6a7a8bc9f488..2315751870d3 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 (sval); + return psval->get_poison_kind () == POISON_KIND_UNINIT; + } + case SK_COMPOUND: + { + const compound_svalue *compound_sval + = as_a (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 000000000000..7466112fe149 --- /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 000000000000..a8a383f4b2d3 --- /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 f0b4bb7a051f..d6cccb269df2 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 \