]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
analyzer: fix ICE on infoleak with poisoned size
authorDavid Malcolm <dmalcolm@redhat.com>
Fri, 8 Dec 2023 20:59:43 +0000 (15:59 -0500)
committerDavid Malcolm <dmalcolm@redhat.com>
Fri, 8 Dec 2023 20:59:43 +0000 (15:59 -0500)
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>
gcc/analyzer/region-model.cc
gcc/testsuite/gcc.dg/plugin/infoleak-uninit-size-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/plugin/infoleak-uninit-size-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/plugin/plugin.exp

index 6a7a8bc9f48845ad9731bebf664c78cc1ef17fa4..2315751870d305978afb5d874ac5fac5f3826a74 100644 (file)
@@ -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 (file)
index 0000000..7466112
--- /dev/null
@@ -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 (file)
index 0000000..a8a383f
--- /dev/null
@@ -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'" } */
+}
index f0b4bb7a051fee73b8bce58afd7c617dcb325c74..d6cccb269df258b7cd0c01139ce6224574b86359 100644 (file)
@@ -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 \