aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2023-12-08 15:59:43 -0500
committerDavid Malcolm <dmalcolm@redhat.com>2023-12-08 15:59:43 -0500
commit08262e78209ed4a69f309b6fdf79e7c0be0c6793 (patch)
tree8bcf272539b88b28c19c1ca73f26a71bcadf1d31
parent48cb51827c9eb991b92014a3f59d31eb237ce03f (diff)
downloadgcc-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>
-rw-r--r--gcc/analyzer/region-model.cc37
-rw-r--r--gcc/testsuite/gcc.dg/plugin/infoleak-uninit-size-1.c20
-rw-r--r--gcc/testsuite/gcc.dg/plugin/infoleak-uninit-size-2.c20
-rw-r--r--gcc/testsuite/gcc.dg/plugin/plugin.exp2
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 \