diff options
author | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2015-01-20 20:39:52 +0000 |
---|---|---|
committer | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2015-01-20 20:39:52 +0000 |
commit | 0f9736fac5fd53b99c7e45c434607433ba8d80cd (patch) | |
tree | 62486ce633b46c7bf8945dc5e7352f4f545b2b55 | |
parent | 69d99fc497f9f846a8b829525eae5e7d53763238 (diff) | |
download | gcc-0f9736fac5fd53b99c7e45c434607433ba8d80cd.tar.gz |
PR sanitizer/64632
* ubsan/ubsan_type_hash.cc: Cherry pick upstream r224972.
* g++.dg/ubsan/pr64632.C: New test.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@219912 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/testsuite/ChangeLog | 3 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/ubsan/pr64632.C | 23 | ||||
-rw-r--r-- | libsanitizer/ChangeLog | 5 | ||||
-rw-r--r-- | libsanitizer/ubsan/ubsan_type_hash.cc | 47 |
4 files changed, 52 insertions, 26 deletions
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 598843154b6..ee46288d373 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2015-01-20 Jakub Jelinek <jakub@redhat.com> + PR sanitizer/64632 + * g++.dg/ubsan/pr64632.C: New test. + PR debug/64663 * gcc.dg/pr64663.c: New test. diff --git a/gcc/testsuite/g++.dg/ubsan/pr64632.C b/gcc/testsuite/g++.dg/ubsan/pr64632.C new file mode 100644 index 00000000000..0d2a7aa9aef --- /dev/null +++ b/gcc/testsuite/g++.dg/ubsan/pr64632.C @@ -0,0 +1,23 @@ +// PR sanitizer/64632 +// { dg-do run } +// { dg-options "-fsanitize=vptr -fno-sanitize-recover=vptr" } + +struct S +{ + S () : a(0) {} + int a; + int f () { return a; } + virtual int v () { return 0; } +}; + +struct X : virtual S +{ + int v () { return 2; } +}; + +int +main () +{ + X x; + return x.f (); +} diff --git a/libsanitizer/ChangeLog b/libsanitizer/ChangeLog index 3de7396f854..cb0f98c7e83 100644 --- a/libsanitizer/ChangeLog +++ b/libsanitizer/ChangeLog @@ -1,3 +1,8 @@ +2015-01-20 Jakub Jelinek <jakub@redhat.com> + + PR sanitizer/64632 + * ubsan/ubsan_type_hash.cc: Cherry pick upstream r224972. + 2015-01-19 Jakub Jelinek <jakub@redhat.com> PR sanitizer/64435 diff --git a/libsanitizer/ubsan/ubsan_type_hash.cc b/libsanitizer/ubsan/ubsan_type_hash.cc index 8758f6c84c5..d01009426db 100644 --- a/libsanitizer/ubsan/ubsan_type_hash.cc +++ b/libsanitizer/ubsan/ubsan_type_hash.cc @@ -113,8 +113,7 @@ __ubsan::__ubsan_vptr_type_cache[__ubsan::VptrTypeCacheSize]; /// \brief Determine whether \p Derived has a \p Base base class subobject at /// offset \p Offset. -static bool isDerivedFromAtOffset(sptr Object, - const abi::__class_type_info *Derived, +static bool isDerivedFromAtOffset(const abi::__class_type_info *Derived, const abi::__class_type_info *Base, sptr Offset) { if (Derived->__type_name == Base->__type_name) @@ -122,7 +121,7 @@ static bool isDerivedFromAtOffset(sptr Object, if (const abi::__si_class_type_info *SI = dynamic_cast<const abi::__si_class_type_info*>(Derived)) - return isDerivedFromAtOffset(Object, SI->__base_type, Base, Offset); + return isDerivedFromAtOffset(SI->__base_type, Base, Offset); const abi::__vmi_class_type_info *VTI = dynamic_cast<const abi::__vmi_class_type_info*>(Derived); @@ -137,13 +136,13 @@ static bool isDerivedFromAtOffset(sptr Object, sptr OffsetHere = VTI->base_info[base].__offset_flags >> abi::__base_class_type_info::__offset_shift; if (VTI->base_info[base].__offset_flags & - abi::__base_class_type_info::__virtual_mask) { - sptr VTable = *reinterpret_cast<const sptr *>(Object); - OffsetHere = *reinterpret_cast<const sptr *>(VTable + OffsetHere); - } - if (isDerivedFromAtOffset(Object + OffsetHere, - VTI->base_info[base].__base_type, Base, - Offset - OffsetHere)) + abi::__base_class_type_info::__virtual_mask) + // For now, just punt on virtual bases and say 'yes'. + // FIXME: OffsetHere is the offset in the vtable of the virtual base + // offset. Read the vbase offset out of the vtable and use it. + return true; + if (isDerivedFromAtOffset(VTI->base_info[base].__base_type, + Base, Offset - OffsetHere)) return true; } @@ -152,15 +151,14 @@ static bool isDerivedFromAtOffset(sptr Object, /// \brief Find the derived-most dynamic base class of \p Derived at offset /// \p Offset. -static const abi::__class_type_info * -findBaseAtOffset(sptr Object, const abi::__class_type_info *Derived, - sptr Offset) { +static const abi::__class_type_info *findBaseAtOffset( + const abi::__class_type_info *Derived, sptr Offset) { if (!Offset) return Derived; if (const abi::__si_class_type_info *SI = dynamic_cast<const abi::__si_class_type_info*>(Derived)) - return findBaseAtOffset(Object, SI->__base_type, Offset); + return findBaseAtOffset(SI->__base_type, Offset); const abi::__vmi_class_type_info *VTI = dynamic_cast<const abi::__vmi_class_type_info*>(Derived); @@ -172,13 +170,12 @@ findBaseAtOffset(sptr Object, const abi::__class_type_info *Derived, sptr OffsetHere = VTI->base_info[base].__offset_flags >> abi::__base_class_type_info::__offset_shift; if (VTI->base_info[base].__offset_flags & - abi::__base_class_type_info::__virtual_mask) { - sptr VTable = *reinterpret_cast<const sptr *>(Object); - OffsetHere = *reinterpret_cast<const sptr *>(VTable + OffsetHere); - } - if (const abi::__class_type_info *Base = findBaseAtOffset( - Object + OffsetHere, VTI->base_info[base].__base_type, - Offset - OffsetHere)) + abi::__base_class_type_info::__virtual_mask) + // FIXME: Can't handle virtual bases yet. + continue; + if (const abi::__class_type_info *Base = + findBaseAtOffset(VTI->base_info[base].__base_type, + Offset - OffsetHere)) return Base; } @@ -230,8 +227,7 @@ bool __ubsan::checkDynamicType(void *Object, void *Type, HashValue Hash) { return false; abi::__class_type_info *Base = (abi::__class_type_info*)Type; - if (!isDerivedFromAtOffset(reinterpret_cast<sptr>(Object), Derived, Base, - -Vtable->Offset)) + if (!isDerivedFromAtOffset(Derived, Base, -Vtable->Offset)) return false; // Success. Cache this result. @@ -245,9 +241,8 @@ __ubsan::DynamicTypeInfo __ubsan::getDynamicTypeInfo(void *Object) { if (!Vtable) return DynamicTypeInfo(0, 0, 0); const abi::__class_type_info *ObjectType = findBaseAtOffset( - reinterpret_cast<sptr>(Object), - static_cast<const abi::__class_type_info *>(Vtable->TypeInfo), - -Vtable->Offset); + static_cast<const abi::__class_type_info*>(Vtable->TypeInfo), + -Vtable->Offset); return DynamicTypeInfo(Vtable->TypeInfo->__type_name, -Vtable->Offset, ObjectType ? ObjectType->__type_name : "<unknown>"); } |