]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
ubsan: Fix ICE due to -fsanitize=object-size [PR105093]
authorJakub Jelinek <jakub@redhat.com>
Wed, 30 Mar 2022 08:49:47 +0000 (10:49 +0200)
committerJakub Jelinek <jakub@redhat.com>
Wed, 11 May 2022 06:17:57 +0000 (08:17 +0200)
The following testcase ICEs, because for a volatile X & RESULT_DECL
ubsan wants to take address of that reference.  instrument_object_size
is called with x, so the base is equal to the access and the var
is automatic, so there is no risk of an out of bounds access for it.
Normally we wouldn't instrument those because we fold address of the
t - address of inner to 0, add constant size of the decl and it is
equal to what __builtin_object_size computes.  But the volatile
results in the subtraction not being folded.

The first hunk fixes it by punting if we access the whole automatic
decl, so that even volatile won't cause a problem.
The second hunk (not strictly needed for this testcase) is similar
to what has been added to asan.cc recently, if we actually take
address of a decl and keep it in the IL, we better mark it addressable.

2022-03-30  Jakub Jelinek  <jakub@redhat.com>

PR sanitizer/105093
* ubsan.c (instrument_object_size): If t is equal to inner and
is a decl other than global var, punt.  When emitting call to
UBSAN_OBJECT_SIZE ifn, make sure base is addressable.

* g++.dg/ubsan/pr105093.C: New test.

(cherry picked from commit e3e68fa59ead502c24950298b53c637bbe535a74)

gcc/testsuite/g++.dg/ubsan/pr105093.C [new file with mode: 0644]
gcc/ubsan.c

diff --git a/gcc/testsuite/g++.dg/ubsan/pr105093.C b/gcc/testsuite/g++.dg/ubsan/pr105093.C
new file mode 100644 (file)
index 0000000..49f75ed
--- /dev/null
@@ -0,0 +1,12 @@
+// PR sanitizer/105093
+// { dg-do compile }
+// { dg-options "-O2 -fsanitize=undefined -Wno-volatile" }
+
+struct X { X (); ~X (); };
+
+volatile X
+foo ()
+{
+  X x;
+  return x;
+}
index 516a6ea1b8189532b7dc3a3f9808417036046433..1803f2d5cf9328e554970088dfd2f7d2ac9e0daa 100644 (file)
@@ -2112,6 +2112,8 @@ instrument_object_size (gimple_stmt_iterator *gsi, tree t, bool is_lhs)
           || TREE_CODE (inner) == RESULT_DECL)
          && DECL_REGISTER (inner))
        return;
+      if (t == inner && !is_global_var (t))
+       return;
       base = inner;
     }
   else if (TREE_CODE (inner) == MEM_REF)
@@ -2209,6 +2211,11 @@ instrument_object_size (gimple_stmt_iterator *gsi, tree t, bool is_lhs)
        }
     }
 
+  if (DECL_P (base)
+      && decl_function_context (base) == current_function_decl
+      && !TREE_ADDRESSABLE (base))
+    mark_addressable (base);
+
   if (bos_stmt && gimple_call_builtin_p (bos_stmt, BUILT_IN_OBJECT_SIZE))
     ubsan_create_edge (bos_stmt);