This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Fix for PR/62089 (enable missing Asan checks)
- From: Yury Gribov <y dot gribov at samsung dot com>
- To: Jakub Jelinek <jakub at redhat dot com>
- Cc: GCC Patches <gcc-patches at gcc dot gnu dot org>, Viacheslav Garbuzov <v dot garbuzov at samsung dot com>
- Date: Fri, 15 Aug 2014 18:53:25 +0400
- Subject: Re: [PATCH] Fix for PR/62089 (enable missing Asan checks)
- Authentication-results: sourceware.org; auth=none
- References: <53EB395D dot 2060604 at samsung dot com> <20140813101358 dot GS1784 at tucnak dot redhat dot com> <53EC4D46 dot 7030902 at samsung dot com> <20140814080408 dot GD1784 at tucnak dot redhat dot com>
On 08/14/2014 12:04 PM, Jakub Jelinek wrote:
No, this should be if, not else if, and be after the } below.
We really can't handle it otherwise.
Generally, the bitfield COMPONENT_REFs should have
DECL_BIT_FIELD_REPRESENTATIVE which is not a bitfield, therefore the common
case will be handled.
Makes sense, I've attached new patch (retested as usual).
-Y
commit 77f65357c65fd86650027ce9498c4960953a2760
Author: Yury Gribov <y.gribov@samsung.com>
Date: Mon Aug 11 15:09:45 2014 +0400
2014-08-15 Yury Gribov <y.gribov@samsung.com>
gcc/
PR sanitizer/62089
* asan.c (instrument_derefs): Fix bitfield check.
gcc/testsuite/
PR sanitizer/62089
* c-c++-common/asan/pr62089.c: New test.
* c-c++-common/asan/bitfield-1.c: New test.
* c-c++-common/asan/bitfield-2.c: New test.
* c-c++-common/asan/bitfield-3.c: New test.
* c-c++-common/asan/bitfield-4.c: New test.
diff --git a/gcc/asan.c b/gcc/asan.c
index 4e6f438..15c0737 100644
--- a/gcc/asan.c
+++ b/gcc/asan.c
@@ -1690,21 +1690,19 @@ instrument_derefs (gimple_stmt_iterator *iter, tree t,
int volatilep = 0, unsignedp = 0;
tree inner = get_inner_reference (t, &bitsize, &bitpos, &offset,
&mode, &unsignedp, &volatilep, false);
- if (((size_in_bytes & (size_in_bytes - 1)) == 0
- && (bitpos % (size_in_bytes * BITS_PER_UNIT)))
- || bitsize != size_in_bytes * BITS_PER_UNIT)
+
+ if (TREE_CODE (t) == COMPONENT_REF
+ && DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1)) != NULL_TREE)
{
- if (TREE_CODE (t) == COMPONENT_REF
- && DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1)) != NULL_TREE)
- {
- tree repr = DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1));
- instrument_derefs (iter, build3 (COMPONENT_REF, TREE_TYPE (repr),
- TREE_OPERAND (t, 0), repr,
- NULL_TREE), location, is_store);
- }
+ tree repr = DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1));
+ instrument_derefs (iter, build3 (COMPONENT_REF, TREE_TYPE (repr),
+ TREE_OPERAND (t, 0), repr,
+ NULL_TREE), location, is_store);
return;
}
- if (bitpos % BITS_PER_UNIT)
+
+ if (bitpos % BITS_PER_UNIT
+ || bitsize != size_in_bytes * BITS_PER_UNIT)
return;
if (TREE_CODE (inner) == VAR_DECL
diff --git a/gcc/testsuite/c-c++-common/asan/bitfield-1.c b/gcc/testsuite/c-c++-common/asan/bitfield-1.c
new file mode 100644
index 0000000..b3f300c
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/asan/bitfield-1.c
@@ -0,0 +1,25 @@
+/* Check that Asan correctly instruments bitfields with non-round size. */
+
+/* { dg-do run } */
+/* { dg-shouldfail "asan" } */
+
+struct A
+{
+ char base;
+ int : 4;
+ long x : 7;
+};
+
+int __attribute__ ((noinline, noclone))
+f (void *p) {
+ return ((struct A *)p)->x;
+}
+
+int
+main ()
+{
+ char a = 0;
+ return f (&a);
+}
+
+/* { dg-output "ERROR: AddressSanitizer: stack-buffer-overflow" } */
diff --git a/gcc/testsuite/c-c++-common/asan/bitfield-2.c b/gcc/testsuite/c-c++-common/asan/bitfield-2.c
new file mode 100644
index 0000000..8ab0f80
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/asan/bitfield-2.c
@@ -0,0 +1,25 @@
+/* Check that Asan correctly instruments bitfields with non-round offset. */
+
+/* { dg-do run } */
+/* { dg-shouldfail "asan" } */
+
+struct A
+{
+ char base;
+ int : 7;
+ int x : 8;
+};
+
+int __attribute__ ((noinline, noclone))
+f (void *p) {
+ return ((struct A *)p)->x;
+}
+
+int
+main ()
+{
+ char a = 0;
+ return f (&a);
+}
+
+/* { dg-output "ERROR: AddressSanitizer: stack-buffer-overflow" } */
diff --git a/gcc/testsuite/c-c++-common/asan/bitfield-3.c b/gcc/testsuite/c-c++-common/asan/bitfield-3.c
new file mode 100644
index 0000000..c590778
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/asan/bitfield-3.c
@@ -0,0 +1,25 @@
+/* Check that Asan correctly instruments bitfields with round offset. */
+
+/* { dg-do run } */
+/* { dg-shouldfail "asan" } */
+
+struct A
+{
+ char base;
+ int : 8;
+ int x : 8;
+};
+
+int __attribute__ ((noinline, noclone))
+f (void *p) {
+ return ((struct A *)p)->x;
+}
+
+int
+main ()
+{
+ char a = 0;
+ return f (&a);
+}
+
+/* { dg-output "ERROR: AddressSanitizer: stack-buffer-overflow" } */
diff --git a/gcc/testsuite/c-c++-common/asan/bitfield-4.c b/gcc/testsuite/c-c++-common/asan/bitfield-4.c
new file mode 100644
index 0000000..94de9a4
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/asan/bitfield-4.c
@@ -0,0 +1,25 @@
+/* Check that Asan correctly instruments bitfields with round offset. */
+
+/* { dg-do run } */
+/* { dg-shouldfail "asan" } */
+
+struct A
+{
+ char base;
+ int : 0;
+ int x : 8;
+};
+
+int __attribute__ ((noinline, noclone))
+f (void *p) {
+ return ((struct A *)p)->x;
+}
+
+int
+main ()
+{
+ char a = 0;
+ return f (&a);
+}
+
+/* { dg-output "ERROR: AddressSanitizer: stack-buffer-overflow" } */
diff --git a/gcc/testsuite/c-c++-common/asan/pr62089.c b/gcc/testsuite/c-c++-common/asan/pr62089.c
new file mode 100644
index 0000000..22b877b
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/asan/pr62089.c
@@ -0,0 +1,37 @@
+/* { dg-do run } */
+/* { dg-shouldfail "asan" } */
+
+#include <sanitizer/asan_interface.h>
+
+struct vfsmount {};
+struct dentry {};
+
+struct path {
+ struct vfsmount *mnt;
+ struct dentry *dentry;
+};
+
+struct fs_struct {
+ int users;
+ int lock;
+ int seq;
+ int umask;
+ int in_exec;
+ struct path root, pwd;
+};
+
+void __attribute__((noinline, noclone))
+copy_fs_struct(struct fs_struct *a, struct fs_struct *b) {
+ a->root = b->root;
+}
+
+struct fs_struct a, b;
+
+int
+main () {
+ __asan_poison_memory_region (&a.root, sizeof (a.root));
+ copy_fs_struct (&a, &b);
+ return 0;
+}
+
+/* { dg-output "ERROR: AddressSanitizer: use-after-poison" } */