Index: compiler-rt/lib/asan/asan_suppressions.cpp =================================================================== --- compiler-rt/lib/asan/asan_suppressions.cpp +++ compiler-rt/lib/asan/asan_suppressions.cpp @@ -15,6 +15,7 @@ #include "asan_stack.h" #include "sanitizer_common/sanitizer_placement_new.h" +#include "sanitizer_common/sanitizer_ptrauth.h" #include "sanitizer_common/sanitizer_suppressions.h" #include "sanitizer_common/sanitizer_symbolizer.h" @@ -71,7 +72,7 @@ Symbolizer *symbolizer = Symbolizer::GetOrInit(); Suppression *s; for (uptr i = 0; i < stack->size && stack->trace[i]; i++) { - uptr addr = stack->trace[i]; + uptr addr = STRIP_PAC(stack->trace[i]); if (suppression_ctx->HasSuppressionType(kInterceptorViaLibrary)) { // Match "interceptor_via_lib" suppressions. Index: compiler-rt/lib/lsan/lsan_common.cpp =================================================================== --- compiler-rt/lib/lsan/lsan_common.cpp +++ compiler-rt/lib/lsan/lsan_common.cpp @@ -18,6 +18,7 @@ #include "sanitizer_common/sanitizer_flags.h" #include "sanitizer_common/sanitizer_placement_new.h" #include "sanitizer_common/sanitizer_procmaps.h" +#include "sanitizer_common/sanitizer_ptrauth.h" #include "sanitizer_common/sanitizer_report_decorator.h" #include "sanitizer_common/sanitizer_stackdepot.h" #include "sanitizer_common/sanitizer_stacktrace.h" @@ -506,8 +507,9 @@ caller_pc = GetCallerPC(stack_id, param->stack_depot_reverse_map); // If caller_pc is unknown, this chunk may be allocated in a coroutine. Mark // it as reachable, as we can't properly report its allocation stack anyway. - if (caller_pc == 0 || (param->skip_linker_allocations && - GetLinker()->containsAddress(caller_pc))) { + if (caller_pc == 0 || + (param->skip_linker_allocations && + GetLinker()->containsAddress(STRIP_PAC(caller_pc)))) { m.set_tag(kReachable); param->frontier->push_back(chunk); } @@ -785,7 +787,7 @@ StackTrace stack = StackDepotGet(stack_trace_id); for (uptr i = 0; i < stack.size; i++) { Suppression *s = GetSuppressionForAddr( - StackTrace::GetPreviousInstructionPc(stack.trace[i])); + StackTrace::GetPreviousInstructionPc(STRIP_PAC(stack.trace[i]))); if (s) { suppressed_stacks_sorted = false; suppressed_stacks.push_back(stack_trace_id); Index: compiler-rt/lib/sanitizer_common/sanitizer_ptrauth.h =================================================================== --- compiler-rt/lib/sanitizer_common/sanitizer_ptrauth.h +++ compiler-rt/lib/sanitizer_common/sanitizer_ptrauth.h @@ -11,6 +11,24 @@ #if __has_feature(ptrauth_calls) #include +#elif defined(__aarch64__) +inline unsigned long ptrauth_strip(unsigned long __value, unsigned int __key) { + // On the stack the link register could be protected with Pointer + // Authentication Code when compiled with -mbranch-protection. + // Let's stripping the PAC unconditionally because xpaclri is in + // the NOP space so will do nothing when it is not enabled or not available. + unsigned long ret; + asm volatile( + "mov x30, %1\n\t" + "xpaclri\n\t" + "mov %0, x30\n\t" + : "=r"(ret) + : "r"(__value) + : "x30"); + return ret; +} +#define ptrauth_auth_data(__value, __old_key, __old_data) __value +#define ptrauth_string_discriminator(__string) ((int)0) #else // Copied from #define ptrauth_strip(__value, __key) __value @@ -18,6 +36,6 @@ #define ptrauth_string_discriminator(__string) ((int)0) #endif -#define STRIP_PC(pc) ((uptr)ptrauth_strip(pc, 0)) +#define STRIP_PAC(ptr) ((uptr)ptrauth_strip((uptr)ptr, 0)) #endif // SANITIZER_PTRAUTH_H Index: compiler-rt/lib/sanitizer_common/sanitizer_stackdepot.cpp =================================================================== --- compiler-rt/lib/sanitizer_common/sanitizer_stackdepot.cpp +++ compiler-rt/lib/sanitizer_common/sanitizer_stackdepot.cpp @@ -14,6 +14,7 @@ #include "sanitizer_common.h" #include "sanitizer_hash.h" +#include "sanitizer_ptrauth.h" #include "sanitizer_stackdepotbase.h" namespace __sanitizer { @@ -42,7 +43,8 @@ return false; uptr i = 0; for (; i < size; i++) { - if (stack[i] != args.trace[i]) return false; + if (STRIP_PAC(stack[i]) != STRIP_PAC(args.trace[i])) + return false; } return true; } @@ -51,7 +53,7 @@ } static u32 hash(const args_type &args) { MurMur2HashBuilder H(args.size * sizeof(uptr)); - for (uptr i = 0; i < args.size; i++) H.add(args.trace[i]); + for (uptr i = 0; i < args.size; i++) H.add(STRIP_PAC(args.trace[i])); return H.get(); } static bool is_valid(const args_type &args) { Index: compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.cpp =================================================================== --- compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.cpp +++ compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.cpp @@ -15,6 +15,7 @@ #include "sanitizer_common.h" #include "sanitizer_flags.h" #include "sanitizer_platform.h" +#include "sanitizer_ptrauth.h" namespace __sanitizer { @@ -158,7 +159,9 @@ uptr BufferedStackTrace::LocatePcInTrace(uptr pc) { uptr best = 0; for (uptr i = 1; i < size; ++i) { - if (Distance(trace[i], pc) < Distance(trace[best], pc)) best = i; + if (Distance(STRIP_PAC(trace[i]), pc) < + Distance(STRIP_PAC(trace[best]), pc)) + best = i; } return best; } Index: compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cpp =================================================================== --- compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cpp +++ compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cpp @@ -12,6 +12,7 @@ #include "sanitizer_common.h" #include "sanitizer_placement_new.h" +#include "sanitizer_ptrauth.h" #include "sanitizer_stacktrace.h" #include "sanitizer_stacktrace_printer.h" #include "sanitizer_symbolizer.h" @@ -31,7 +32,7 @@ for (uptr i = 0; i < size && trace[i]; i++) { // PCs in stack traces are actually the return addresses, that is, // addresses of the next instructions after the call. - uptr pc = GetPreviousInstructionPc(trace[i]); + uptr pc = GetPreviousInstructionPc(STRIP_PAC(trace[i])); SymbolizedStack *frames; if (symbolize) frames = Symbolizer::GetOrInit()->SymbolizePC(pc); Index: compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_report.cpp =================================================================== --- compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_report.cpp +++ compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_report.cpp @@ -15,6 +15,7 @@ #include "sanitizer_file.h" #include "sanitizer_flags.h" #include "sanitizer_procmaps.h" +#include "sanitizer_ptrauth.h" #include "sanitizer_report_decorator.h" #include "sanitizer_stacktrace.h" #include "sanitizer_stacktrace_printer.h" @@ -81,7 +82,7 @@ } // Currently, we include the first stack frame into the report summary. // Maybe sometimes we need to choose another frame (e.g. skip memcpy/etc). - uptr pc = StackTrace::GetPreviousInstructionPc(stack->trace[0]); + uptr pc = StackTrace::GetPreviousInstructionPc(STRIP_PAC(stack->trace[0])); SymbolizedStack *frame = Symbolizer::GetOrInit()->SymbolizePC(pc); ReportErrorSummary(error_type, frame->info, alt_tool_name); frame->ClearAll(); Index: compiler-rt/lib/tsan/rtl/tsan_external.cpp =================================================================== --- compiler-rt/lib/tsan/rtl/tsan_external.cpp +++ compiler-rt/lib/tsan/rtl/tsan_external.cpp @@ -111,12 +111,12 @@ SANITIZER_INTERFACE_ATTRIBUTE void __tsan_external_read(void *addr, void *caller_pc, void *tag) { - ExternalAccess(addr, STRIP_PC(caller_pc), tag, MemoryRead); + ExternalAccess(addr, STRIP_PAC(caller_pc), tag, MemoryRead); } SANITIZER_INTERFACE_ATTRIBUTE void __tsan_external_write(void *addr, void *caller_pc, void *tag) { - ExternalAccess(addr, STRIP_PC(caller_pc), tag, MemoryWrite); + ExternalAccess(addr, STRIP_PAC(caller_pc), tag, MemoryWrite); } } // extern "C" Index: compiler-rt/lib/tsan/rtl/tsan_interface.cpp =================================================================== --- compiler-rt/lib/tsan/rtl/tsan_interface.cpp +++ compiler-rt/lib/tsan/rtl/tsan_interface.cpp @@ -40,13 +40,13 @@ } void __tsan_read16_pc(void *addr, void *pc) { - MemoryRead(cur_thread(), STRIP_PC(pc), (uptr)addr, kSizeLog8); - MemoryRead(cur_thread(), STRIP_PC(pc), (uptr)addr + 8, kSizeLog8); + MemoryRead(cur_thread(), STRIP_PAC(pc), (uptr)addr, kSizeLog8); + MemoryRead(cur_thread(), STRIP_PAC(pc), (uptr)addr + 8, kSizeLog8); } void __tsan_write16_pc(void *addr, void *pc) { - MemoryWrite(cur_thread(), STRIP_PC(pc), (uptr)addr, kSizeLog8); - MemoryWrite(cur_thread(), STRIP_PC(pc), (uptr)addr + 8, kSizeLog8); + MemoryWrite(cur_thread(), STRIP_PAC(pc), (uptr)addr, kSizeLog8); + MemoryWrite(cur_thread(), STRIP_PAC(pc), (uptr)addr + 8, kSizeLog8); } // __tsan_unaligned_read/write calls are emitted by compiler. Index: compiler-rt/lib/tsan/rtl/tsan_interface_inl.h =================================================================== --- compiler-rt/lib/tsan/rtl/tsan_interface_inl.h +++ compiler-rt/lib/tsan/rtl/tsan_interface_inl.h @@ -51,35 +51,35 @@ } void __tsan_read1_pc(void *addr, void *pc) { - MemoryRead(cur_thread(), STRIP_PC(pc), (uptr)addr, kSizeLog1); + MemoryRead(cur_thread(), STRIP_PAC(pc), (uptr)addr, kSizeLog1); } void __tsan_read2_pc(void *addr, void *pc) { - MemoryRead(cur_thread(), STRIP_PC(pc), (uptr)addr, kSizeLog2); + MemoryRead(cur_thread(), STRIP_PAC(pc), (uptr)addr, kSizeLog2); } void __tsan_read4_pc(void *addr, void *pc) { - MemoryRead(cur_thread(), STRIP_PC(pc), (uptr)addr, kSizeLog4); + MemoryRead(cur_thread(), STRIP_PAC(pc), (uptr)addr, kSizeLog4); } void __tsan_read8_pc(void *addr, void *pc) { - MemoryRead(cur_thread(), STRIP_PC(pc), (uptr)addr, kSizeLog8); + MemoryRead(cur_thread(), STRIP_PAC(pc), (uptr)addr, kSizeLog8); } void __tsan_write1_pc(void *addr, void *pc) { - MemoryWrite(cur_thread(), STRIP_PC(pc), (uptr)addr, kSizeLog1); + MemoryWrite(cur_thread(), STRIP_PAC(pc), (uptr)addr, kSizeLog1); } void __tsan_write2_pc(void *addr, void *pc) { - MemoryWrite(cur_thread(), STRIP_PC(pc), (uptr)addr, kSizeLog2); + MemoryWrite(cur_thread(), STRIP_PAC(pc), (uptr)addr, kSizeLog2); } void __tsan_write4_pc(void *addr, void *pc) { - MemoryWrite(cur_thread(), STRIP_PC(pc), (uptr)addr, kSizeLog4); + MemoryWrite(cur_thread(), STRIP_PAC(pc), (uptr)addr, kSizeLog4); } void __tsan_write8_pc(void *addr, void *pc) { - MemoryWrite(cur_thread(), STRIP_PC(pc), (uptr)addr, kSizeLog8); + MemoryWrite(cur_thread(), STRIP_PAC(pc), (uptr)addr, kSizeLog8); } void __tsan_vptr_update(void **vptr_p, void *new_val) { @@ -100,9 +100,7 @@ thr->is_vptr_access = false; } -void __tsan_func_entry(void *pc) { - FuncEntry(cur_thread(), STRIP_PC(pc)); -} +void __tsan_func_entry(void *pc) { FuncEntry(cur_thread(), STRIP_PAC(pc)); } void __tsan_func_exit() { FuncExit(cur_thread()); @@ -125,9 +123,9 @@ } void __tsan_read_range_pc(void *addr, uptr size, void *pc) { - MemoryAccessRange(cur_thread(), STRIP_PC(pc), (uptr)addr, size, false); + MemoryAccessRange(cur_thread(), STRIP_PAC(pc), (uptr)addr, size, false); } void __tsan_write_range_pc(void *addr, uptr size, void *pc) { - MemoryAccessRange(cur_thread(), STRIP_PC(pc), (uptr)addr, size, true); + MemoryAccessRange(cur_thread(), STRIP_PAC(pc), (uptr)addr, size, true); } Index: compiler-rt/lib/tsan/rtl/tsan_rtl_report.cpp =================================================================== --- compiler-rt/lib/tsan/rtl/tsan_rtl_report.cpp +++ compiler-rt/lib/tsan/rtl/tsan_rtl_report.cpp @@ -15,6 +15,7 @@ #include "sanitizer_common/sanitizer_stackdepot.h" #include "sanitizer_common/sanitizer_common.h" #include "sanitizer_common/sanitizer_stacktrace.h" +#include "sanitizer_common/sanitizer_ptrauth.h" #include "tsan_platform.h" #include "tsan_rtl.h" #include "tsan_suppressions.h" @@ -119,11 +120,11 @@ SymbolizedStack *top = nullptr; for (uptr si = 0; si < trace.size; si++) { const uptr pc = trace.trace[si]; - uptr pc1 = pc; + uptr pc1 = STRIP_PAC(pc); // We obtain the return address, but we're interested in the previous // instruction. if ((pc & kExternalPCBit) == 0) - pc1 = StackTrace::GetPreviousInstructionPc(pc); + pc1 = StackTrace::GetPreviousInstructionPc(STRIP_PAC(pc)); SymbolizedStack *ent = SymbolizeCode(pc1); CHECK_NE(ent, 0); SymbolizedStack *last = ent;