From: Yury Gribov Date: Mon, 18 Aug 2014 08:23:47 +0000 (+0000) Subject: re PR sanitizer/62089 (Sanitizer may fail to instrument struct accesses) X-Git-Tag: releases/gcc-5.1.0~5424 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=87d1d65af7ebef1ca7240bbd25f3cd6873b1455a;p=thirdparty%2Fgcc.git re PR sanitizer/62089 (Sanitizer may fail to instrument struct accesses) 2014-08-18 Yury Gribov PR sanitizer/62089 gcc/ * asan.c (instrument_derefs): Fix bitfield check. gcc/testsuite/ * 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. From-SVN: r214086 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c70d519bc294..a4f386a096a5 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2014-08-18 Yury Gribov + + PR sanitizer/62089 + * asan.c (instrument_derefs): Fix bitfield check. + 2014-08-17 Segher Boessenkool * config/rs6000/constraints.md ("S"): Require TARGET_POWERPC64. diff --git a/gcc/asan.c b/gcc/asan.c index 4e6f43860fa4..15c073785f94 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/ChangeLog b/gcc/testsuite/ChangeLog index 87f51d54fdb0..d3781693b461 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2014-08-18 Yury Gribov + + 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. + 2014-08-18 Kugan Vivekanandarajah PR tree-optimization/52904 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 000000000000..b3f300c6484a --- /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 000000000000..8ab0f8069f37 --- /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 000000000000..c5907786f76b --- /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 000000000000..94de9a4376c4 --- /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 000000000000..22b877b4c5bd --- /dev/null +++ b/gcc/testsuite/c-c++-common/asan/pr62089.c @@ -0,0 +1,37 @@ +/* { dg-do run } */ +/* { dg-shouldfail "asan" } */ + +#include + +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" } */