Reapply all revisions mentioned in LOCAL_PATCHES.
2019-08-14 Martin Liska <mliska@suse.cz> * asan/asan_globals.cpp (CheckODRViolationViaIndicator): Reapply patch from trunk. (CheckODRViolationViaPoisoning): Likewise. (RegisterGlobal): Likewise. * asan/asan_mapping.h: Likewise. * sanitizer_common/sanitizer_linux_libcdep.cpp (defined): Likewise. * sanitizer_common/sanitizer_mac.cpp (defined): Likewise. * sanitizer_common/sanitizer_platform_limits_linux.cpp (defined): Likewise. * sanitizer_common/sanitizer_platform_limits_posix.h (defined): Likewise. * sanitizer_common/sanitizer_stacktrace.cpp (GetCanonicFrame): Likewise. * ubsan/ubsan_handlers.cpp (__ubsan::__ubsan_handle_cfi_bad_icall): Likewise. (__ubsan::__ubsan_handle_cfi_bad_icall_abort): Likewise. * ubsan/ubsan_handlers.h (struct CFIBadIcallData): Likewise. (struct CFICheckFailData): Likewise. (RECOVERABLE): Likewise. * ubsan/ubsan_platform.h: Likewise. From-SVN: r274427
This commit is contained in:
parent
b667dd7017
commit
47f0255fbb
11 changed files with 68 additions and 29 deletions
|
@ -1,3 +1,22 @@
|
|||
2019-08-14 Martin Liska <mliska@suse.cz>
|
||||
|
||||
* asan/asan_globals.cpp (CheckODRViolationViaIndicator): Reapply
|
||||
patch from trunk.
|
||||
(CheckODRViolationViaPoisoning): Likewise.
|
||||
(RegisterGlobal): Likewise.
|
||||
* asan/asan_mapping.h: Likewise.
|
||||
* sanitizer_common/sanitizer_linux_libcdep.cpp (defined): Likewise.
|
||||
* sanitizer_common/sanitizer_mac.cpp (defined): Likewise.
|
||||
* sanitizer_common/sanitizer_platform_limits_linux.cpp (defined): Likewise.
|
||||
* sanitizer_common/sanitizer_platform_limits_posix.h (defined): Likewise.
|
||||
* sanitizer_common/sanitizer_stacktrace.cpp (GetCanonicFrame): Likewise.
|
||||
* ubsan/ubsan_handlers.cpp (__ubsan::__ubsan_handle_cfi_bad_icall): Likewise.
|
||||
(__ubsan::__ubsan_handle_cfi_bad_icall_abort): Likewise.
|
||||
* ubsan/ubsan_handlers.h (struct CFIBadIcallData): Likewise.
|
||||
(struct CFICheckFailData): Likewise.
|
||||
(RECOVERABLE): Likewise.
|
||||
* ubsan/ubsan_platform.h: Likewise.
|
||||
|
||||
2019-08-14 Martin Liska <mliska@suse.cz>
|
||||
|
||||
PR sanitizer/89832
|
||||
|
|
|
@ -154,23 +154,6 @@ static void CheckODRViolationViaIndicator(const Global *g) {
|
|||
}
|
||||
}
|
||||
|
||||
// Check ODR violation for given global G by checking if it's already poisoned.
|
||||
// We use this method in case compiler doesn't use private aliases for global
|
||||
// variables.
|
||||
static void CheckODRViolationViaPoisoning(const Global *g) {
|
||||
if (__asan_region_is_poisoned(g->beg, g->size_with_redzone)) {
|
||||
// This check may not be enough: if the first global is much larger
|
||||
// the entire redzone of the second global may be within the first global.
|
||||
for (ListOfGlobals *l = list_of_all_globals; l; l = l->next) {
|
||||
if (g->beg == l->g->beg &&
|
||||
(flags()->detect_odr_violation >= 2 || g->size != l->g->size) &&
|
||||
!IsODRViolationSuppressed(g->name))
|
||||
ReportODRViolation(g, FindRegistrationSite(g),
|
||||
l->g, FindRegistrationSite(l->g));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Clang provides two different ways for global variables protection:
|
||||
// it can poison the global itself or its private alias. In former
|
||||
// case we may poison same symbol multiple times, that can help us to
|
||||
|
@ -216,8 +199,6 @@ static void RegisterGlobal(const Global *g) {
|
|||
// where two globals with the same name are defined in different modules.
|
||||
if (UseODRIndicator(g))
|
||||
CheckODRViolationViaIndicator(g);
|
||||
else
|
||||
CheckODRViolationViaPoisoning(g);
|
||||
}
|
||||
if (CanPoisonMemory())
|
||||
PoisonRedZones(*g);
|
||||
|
|
|
@ -163,7 +163,7 @@ static const u64 kDefaultShort64bitShadowOffset =
|
|||
static const u64 kAArch64_ShadowOffset64 = 1ULL << 36;
|
||||
static const u64 kMIPS32_ShadowOffset32 = 0x0aaa0000;
|
||||
static const u64 kMIPS64_ShadowOffset64 = 1ULL << 37;
|
||||
static const u64 kPPC64_ShadowOffset64 = 1ULL << 44;
|
||||
static const u64 kPPC64_ShadowOffset64 = 1ULL << 41;
|
||||
static const u64 kSystemZ_ShadowOffset64 = 1ULL << 52;
|
||||
static const u64 kSPARC64_ShadowOffset64 = 1ULL << 43; // 0x80000000000
|
||||
static const u64 kFreeBSD_ShadowOffset32 = 1ULL << 30; // 0x40000000
|
||||
|
|
|
@ -701,9 +701,13 @@ u32 GetNumberOfCPUs() {
|
|||
#elif SANITIZER_SOLARIS
|
||||
return sysconf(_SC_NPROCESSORS_ONLN);
|
||||
#else
|
||||
#if defined(CPU_COUNT)
|
||||
cpu_set_t CPUs;
|
||||
CHECK_EQ(sched_getaffinity(0, sizeof(cpu_set_t), &CPUs), 0);
|
||||
return CPU_COUNT(&CPUs);
|
||||
#else
|
||||
return 1;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
extern char **environ;
|
||||
#endif
|
||||
|
||||
#if defined(__has_include) && __has_include(<os/trace.h>)
|
||||
#if defined(__has_include) && __has_include(<os/trace.h>) && defined(__BLOCKS__)
|
||||
#define SANITIZER_OS_TRACE 1
|
||||
#include <os/trace.h>
|
||||
#else
|
||||
|
|
|
@ -26,9 +26,12 @@
|
|||
|
||||
// With old kernels (and even new kernels on powerpc) asm/stat.h uses types that
|
||||
// are not defined anywhere in userspace headers. Fake them. This seems to work
|
||||
// fine with newer headers, too.
|
||||
// fine with newer headers, too. Beware that with <sys/stat.h>, struct stat
|
||||
// takes the form of struct stat64 on 32-bit platforms if _FILE_OFFSET_BITS=64.
|
||||
// Also, for some platforms (e.g. mips) there are additional members in the
|
||||
// <sys/stat.h> struct stat:s.
|
||||
#include <linux/posix_types.h>
|
||||
#if defined(__x86_64__) || defined(__mips__)
|
||||
#if defined(__x86_64__)
|
||||
#include <sys/stat.h>
|
||||
#else
|
||||
#define ino_t __kernel_ino_t
|
||||
|
|
|
@ -81,7 +81,7 @@ namespace __sanitizer {
|
|||
#elif defined(__mips__)
|
||||
const unsigned struct_kernel_stat_sz =
|
||||
SANITIZER_ANDROID ? FIRST_32_SECOND_64(104, 128) :
|
||||
FIRST_32_SECOND_64(160, 216);
|
||||
FIRST_32_SECOND_64(144, 216);
|
||||
const unsigned struct_kernel_stat64_sz = 104;
|
||||
#elif defined(__s390__) && !defined(__s390x__)
|
||||
const unsigned struct_kernel_stat_sz = 64;
|
||||
|
|
|
@ -60,8 +60,8 @@ static inline uhwptr *GetCanonicFrame(uptr bp,
|
|||
// Nope, this does not look right either. This means the frame after next does
|
||||
// not have a valid frame pointer, but we can still extract the caller PC.
|
||||
// Unfortunately, there is no way to decide between GCC and LLVM frame
|
||||
// layouts. Assume LLVM.
|
||||
return bp_prev;
|
||||
// layouts. Assume GCC.
|
||||
return bp_prev - 1;
|
||||
#else
|
||||
return (uhwptr*)bp;
|
||||
#endif
|
||||
|
@ -84,14 +84,21 @@ void BufferedStackTrace::UnwindFast(uptr pc, uptr bp, uptr stack_top,
|
|||
IsAligned((uptr)frame, sizeof(*frame)) &&
|
||||
size < max_depth) {
|
||||
#ifdef __powerpc__
|
||||
// PowerPC ABIs specify that the return address is saved at offset
|
||||
// 16 of the *caller's* stack frame. Thus we must dereference the
|
||||
// back chain to find the caller frame before extracting it.
|
||||
// PowerPC ABIs specify that the return address is saved on the
|
||||
// *caller's* stack frame. Thus we must dereference the back chain
|
||||
// to find the caller frame before extracting it.
|
||||
uhwptr *caller_frame = (uhwptr*)frame[0];
|
||||
if (!IsValidFrame((uptr)caller_frame, stack_top, bottom) ||
|
||||
!IsAligned((uptr)caller_frame, sizeof(uhwptr)))
|
||||
break;
|
||||
// For most ABIs the offset where the return address is saved is two
|
||||
// register sizes. The exception is the SVR4 ABI, which uses an
|
||||
// offset of only one register size.
|
||||
#ifdef _CALL_SYSV
|
||||
uhwptr pc1 = caller_frame[1];
|
||||
#else
|
||||
uhwptr pc1 = caller_frame[2];
|
||||
#endif
|
||||
#elif defined(__s390__)
|
||||
uhwptr pc1 = frame[14];
|
||||
#else
|
||||
|
|
|
@ -800,6 +800,21 @@ void __ubsan_handle_cfi_bad_type(CFICheckFailData *Data, ValueHandle Vtable,
|
|||
|
||||
} // namespace __ubsan
|
||||
|
||||
void __ubsan::__ubsan_handle_cfi_bad_icall(CFIBadIcallData *CallData,
|
||||
ValueHandle Function) {
|
||||
GET_REPORT_OPTIONS(false);
|
||||
CFICheckFailData Data = {CFITCK_ICall, CallData->Loc, CallData->Type};
|
||||
handleCFIBadIcall(&Data, Function, Opts);
|
||||
}
|
||||
|
||||
void __ubsan::__ubsan_handle_cfi_bad_icall_abort(CFIBadIcallData *CallData,
|
||||
ValueHandle Function) {
|
||||
GET_REPORT_OPTIONS(true);
|
||||
CFICheckFailData Data = {CFITCK_ICall, CallData->Loc, CallData->Type};
|
||||
handleCFIBadIcall(&Data, Function, Opts);
|
||||
Die();
|
||||
}
|
||||
|
||||
void __ubsan::__ubsan_handle_cfi_check_fail(CFICheckFailData *Data,
|
||||
ValueHandle Value,
|
||||
uptr ValidVtable) {
|
||||
|
|
|
@ -207,12 +207,20 @@ enum CFITypeCheckKind : unsigned char {
|
|||
CFITCK_VMFCall,
|
||||
};
|
||||
|
||||
struct CFIBadIcallData {
|
||||
SourceLocation Loc;
|
||||
const TypeDescriptor &Type;
|
||||
};
|
||||
|
||||
struct CFICheckFailData {
|
||||
CFITypeCheckKind CheckKind;
|
||||
SourceLocation Loc;
|
||||
const TypeDescriptor &Type;
|
||||
};
|
||||
|
||||
/// \brief Handle control flow integrity failure for indirect function calls.
|
||||
RECOVERABLE(cfi_bad_icall, CFIBadIcallData *Data, ValueHandle Function)
|
||||
|
||||
/// \brief Handle control flow integrity failures.
|
||||
RECOVERABLE(cfi_check_fail, CFICheckFailData *Data, ValueHandle Function,
|
||||
uptr VtableIsValid)
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#ifndef UBSAN_PLATFORM_H
|
||||
#define UBSAN_PLATFORM_H
|
||||
|
||||
#ifndef CAN_SANITIZE_UB
|
||||
// Other platforms should be easy to add, and probably work as-is.
|
||||
#if defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__) || \
|
||||
defined(__NetBSD__) || defined(__OpenBSD__) || \
|
||||
|
@ -21,5 +22,6 @@
|
|||
#else
|
||||
# define CAN_SANITIZE_UB 0
|
||||
#endif
|
||||
#endif //CAN_SANITIZE_UB
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Add table
Reference in a new issue