forked from OSchip/llvm-project
Revert "ubsan: Implement memory permission validation for vtables."
This reverts r247484 and two follow-up commits. Breaks ppc and x86_64 sanitizer bots. llvm-svn: 247921
This commit is contained in:
parent
d2e2137b4c
commit
6e663a1e32
|
@ -17,7 +17,6 @@
|
|||
#include "ubsan_type_hash.h"
|
||||
|
||||
#include "sanitizer_common/sanitizer_common.h"
|
||||
#include "sanitizer_common/sanitizer_procmaps.h"
|
||||
|
||||
// The following are intended to be binary compatible with the definitions
|
||||
// given in the Itanium ABI. We make no attempt to be ODR-compatible with
|
||||
|
@ -192,45 +191,7 @@ struct VtablePrefix {
|
|||
/// The type_info object describing the most-derived class type.
|
||||
std::type_info *TypeInfo;
|
||||
};
|
||||
|
||||
#if SANITIZER_LINUX && !defined(__powerpc64__)
|
||||
bool isValidVptr(void *Vtable) {
|
||||
// Validate the memory permissions of the vtable pointer and the first
|
||||
// function pointer in the vtable. They should be r-- or r-x and r-x
|
||||
// respectively. Only enabled for Linux; this hasn't been tested on FreeBSD,
|
||||
// and vtables are writable on Mac (PR24782) so this won't work there.
|
||||
uptr FirstFunctionPtr = *reinterpret_cast<uptr *>(Vtable);
|
||||
bool ValidVtable = false, ValidFirstFunctionPtr = false;
|
||||
MemoryMappingLayout Layout(/*cache_enabled=*/true);
|
||||
uptr Start, End, Prot;
|
||||
while (Layout.Next(&Start, &End, 0, 0, 0, &Prot)) {
|
||||
if (Start <= ((uptr)Vtable) && ((uptr)Vtable) <= End &&
|
||||
(Prot == MemoryMappingLayout::kProtectionRead ||
|
||||
Prot == (MemoryMappingLayout::kProtectionRead |
|
||||
MemoryMappingLayout::kProtectionExecute)))
|
||||
ValidVtable = true;
|
||||
if (Start <= FirstFunctionPtr && FirstFunctionPtr <= End &&
|
||||
Prot == (MemoryMappingLayout::kProtectionRead |
|
||||
MemoryMappingLayout::kProtectionExecute))
|
||||
ValidFirstFunctionPtr = true;
|
||||
if (ValidVtable && ValidFirstFunctionPtr)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#else // !SANITIZER_LINUX || __powerpc64__
|
||||
bool isValidVptr(void *Vtable) {
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
VtablePrefix *getVtablePrefix(void *Vtable) {
|
||||
if (!IsAccessibleMemoryRange((uptr)Vtable, sizeof(void *)))
|
||||
return 0;
|
||||
|
||||
if (!isValidVptr(Vtable))
|
||||
return 0;
|
||||
|
||||
VtablePrefix *Vptr = reinterpret_cast<VtablePrefix*>(Vtable);
|
||||
if (!Vptr)
|
||||
return 0;
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
// RUN: %clangxx -frtti -fsanitize=vptr -fno-sanitize-recover=vptr -g %s -O3 -o %t
|
||||
// RUN: not %run %t 2>&1 | FileCheck %s
|
||||
|
||||
// Tests that we consider vtable pointers in writable memory to be invalid.
|
||||
|
||||
// REQUIRES: vptr-validation
|
||||
|
||||
#include <string.h>
|
||||
|
||||
struct A {
|
||||
virtual void f();
|
||||
};
|
||||
|
||||
void A::f() {}
|
||||
|
||||
struct B {
|
||||
virtual void f();
|
||||
};
|
||||
|
||||
void B::f() {}
|
||||
|
||||
int main() {
|
||||
// Create a fake vtable for A in writable memory and copy A's vtable into it.
|
||||
void *fake_vtable[3];
|
||||
A a;
|
||||
void ***vtp = (void ***)&a;
|
||||
memcpy(fake_vtable, *vtp - 2, sizeof(void *) * 3);
|
||||
*vtp = fake_vtable + 2;
|
||||
|
||||
// A's vtable is invalid because it lives in writable memory.
|
||||
// CHECK: invalid vptr
|
||||
reinterpret_cast<B*>(&a)->f();
|
||||
}
|
|
@ -77,7 +77,3 @@ if config.host_os == 'Windows':
|
|||
# because the test hangs or fails on one configuration and not the other.
|
||||
if config.target_arch.startswith('arm') == False:
|
||||
config.available_features.add('stable-runtime')
|
||||
|
||||
if config.host_os == 'Linux' and config.target_arch != 'powerpc64' and \
|
||||
config.target_arch != 'powerpc64le':
|
||||
config.available_features.add('vptr-validation')
|
||||
|
|
Loading…
Reference in New Issue