From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1851) id F364A3858C50; Sun, 30 Apr 2023 07:56:19 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org F364A3858C50 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1682841380; bh=jsJfYZ2Go2DEAAchdEbWIF0Y2HzO5jluuOgx1JO8xBA=; h=From:To:Subject:Date:From; b=iZmHeN+4xYXIHKjZ1vtKTgkHst7BgscSWNy15uWy0k/zZtKXIm8/BFULDvyHgUIsX l0mRD5YHvxbyRdnnbSkMgf0UIv9kBaQrDrBeF6vOKdokaNJiRf3VPsy1k6/L67m9oQ ZFpSfXIW/Yp9lg1kuoL+6aVFJTG2OJgUIX4yaYks= MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Martin Liska To: gcc-cvs@gcc.gnu.org Subject: [gcc r14-354] libsanitizer: merge from upstream (87e6e490e79384a5) X-Act-Checkin: gcc X-Git-Author: Martin Liska X-Git-Refname: refs/heads/master X-Git-Oldrev: d5e2694e82591d734008982bafdc9ce6da65c0b0 X-Git-Newrev: d96e14ceb9475f9bccbbc0325d5b11419fad9246 Message-Id: <20230430075619.F364A3858C50@sourceware.org> Date: Sun, 30 Apr 2023 07:56:19 +0000 (GMT) List-Id: https://gcc.gnu.org/g:d96e14ceb9475f9bccbbc0325d5b11419fad9246 commit r14-354-gd96e14ceb9475f9bccbbc0325d5b11419fad9246 Author: Martin Liska Date: Sun Apr 30 09:38:14 2023 +0200 libsanitizer: merge from upstream (87e6e490e79384a5) Diff: --- libsanitizer/MERGE | 2 +- libsanitizer/asan/asan_globals.cpp | 19 +++++++ libsanitizer/asan/asan_interceptors.h | 7 +-- libsanitizer/asan/asan_mapping.h | 2 +- libsanitizer/hwasan/hwasan.cpp | 30 ++++++++--- libsanitizer/hwasan/hwasan.h | 20 +++++-- libsanitizer/hwasan/hwasan_allocator.cpp | 48 +++++++++-------- libsanitizer/hwasan/hwasan_allocator.h | 10 ---- libsanitizer/hwasan/hwasan_checks.h | 23 +++++--- libsanitizer/hwasan/hwasan_interceptors.cpp | 36 +++++++++---- .../sanitizer_common_interceptors.inc | 49 ++--------------- .../sanitizer_common/sanitizer_common_syscalls.inc | 5 +- .../sanitizer_common/sanitizer_linux_libcdep.cpp | 4 -- libsanitizer/sanitizer_common/sanitizer_mac.cpp | 12 +---- libsanitizer/sanitizer_common/sanitizer_mac.h | 20 ------- .../sanitizer_platform_interceptors.h | 2 - .../sanitizer_platform_limits_linux.cpp | 5 +- .../sanitizer_platform_limits_posix.cpp | 8 --- .../sanitizer_platform_limits_posix.h | 6 ++- .../sanitizer_common/sanitizer_procmaps_mac.cpp | 62 ++++++++++++++++++---- .../sanitizer_common/sanitizer_stacktrace.cpp | 17 ++---- libsanitizer/tsan/tsan_rtl_ppc64.S | 1 - libsanitizer/ubsan/ubsan_flags.cpp | 1 - libsanitizer/ubsan/ubsan_handlers.cpp | 15 ------ libsanitizer/ubsan/ubsan_handlers.h | 8 --- libsanitizer/ubsan/ubsan_platform.h | 2 - 26 files changed, 202 insertions(+), 212 deletions(-) diff --git a/libsanitizer/MERGE b/libsanitizer/MERGE index cea6249d99c..ef904af5e35 100644 --- a/libsanitizer/MERGE +++ b/libsanitizer/MERGE @@ -1,4 +1,4 @@ -3185e47b5a8444e9fd70b746a7ad679dd131ffe4 +87e6e490e79384a523bc7f0216c3db60227d6d58 The first line of this file holds the git revision number of the last merge done from the master library sources. diff --git a/libsanitizer/asan/asan_globals.cpp b/libsanitizer/asan/asan_globals.cpp index 01a243927ca..4d391cb2a88 100644 --- a/libsanitizer/asan/asan_globals.cpp +++ b/libsanitizer/asan/asan_globals.cpp @@ -158,6 +158,23 @@ 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 @@ -203,6 +220,8 @@ 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); diff --git a/libsanitizer/asan/asan_interceptors.h b/libsanitizer/asan/asan_interceptors.h index 9a6c22c764a..c4bf087ea17 100644 --- a/libsanitizer/asan/asan_interceptors.h +++ b/libsanitizer/asan/asan_interceptors.h @@ -81,12 +81,7 @@ void InitializePlatformInterceptors(); #if ASAN_HAS_EXCEPTIONS && !SANITIZER_WINDOWS && !SANITIZER_SOLARIS && \ !SANITIZER_NETBSD # define ASAN_INTERCEPT___CXA_THROW 1 -# if ! defined(ASAN_HAS_CXA_RETHROW_PRIMARY_EXCEPTION) \ - || ASAN_HAS_CXA_RETHROW_PRIMARY_EXCEPTION -# define ASAN_INTERCEPT___CXA_RETHROW_PRIMARY_EXCEPTION 1 -# else -# define ASAN_INTERCEPT___CXA_RETHROW_PRIMARY_EXCEPTION 0 -# endif +# define ASAN_INTERCEPT___CXA_RETHROW_PRIMARY_EXCEPTION 1 # if defined(_GLIBCXX_SJLJ_EXCEPTIONS) || (SANITIZER_IOS && defined(__arm__)) # define ASAN_INTERCEPT__UNWIND_SJLJ_RAISEEXCEPTION 1 # else diff --git a/libsanitizer/asan/asan_mapping.h b/libsanitizer/asan/asan_mapping.h index 47ccf8444d3..c5f95c07a21 100644 --- a/libsanitizer/asan/asan_mapping.h +++ b/libsanitizer/asan/asan_mapping.h @@ -190,7 +190,7 @@ # elif defined(__aarch64__) # define ASAN_SHADOW_OFFSET_CONST 0x0000001000000000 # elif defined(__powerpc64__) -# define ASAN_SHADOW_OFFSET_CONST 0x0000020000000000 +# define ASAN_SHADOW_OFFSET_CONST 0x0000100000000000 # elif defined(__s390x__) # define ASAN_SHADOW_OFFSET_CONST 0x0010000000000000 # elif SANITIZER_FREEBSD diff --git a/libsanitizer/hwasan/hwasan.cpp b/libsanitizer/hwasan/hwasan.cpp index 097136fe548..26aae9b4869 100644 --- a/libsanitizer/hwasan/hwasan.cpp +++ b/libsanitizer/hwasan/hwasan.cpp @@ -445,16 +445,32 @@ void __hwasan_print_shadow(const void *p, uptr sz) { sptr __hwasan_test_shadow(const void *p, uptr sz) { if (sz == 0) return -1; - tag_t ptr_tag = GetTagFromPointer((uptr)p); - uptr ptr_raw = UntagAddr(reinterpret_cast(p)); + uptr ptr = reinterpret_cast(p); + tag_t ptr_tag = GetTagFromPointer(ptr); + uptr ptr_raw = UntagAddr(ptr); uptr shadow_first = MemToShadow(ptr_raw); - uptr shadow_last = MemToShadow(ptr_raw + sz - 1); - for (uptr s = shadow_first; s <= shadow_last; ++s) - if (*(tag_t *)s != ptr_tag) { - sptr offset = ShadowToMem(s) - ptr_raw; + uptr shadow_last = MemToShadow(ptr_raw + sz); + for (uptr s = shadow_first; s < shadow_last; ++s) { + if (UNLIKELY(*(tag_t *)s != ptr_tag)) { + uptr short_size = + ShortTagSize(*(tag_t *)s, AddTagToPointer(ShadowToMem(s), ptr_tag)); + sptr offset = ShadowToMem(s) - ptr_raw + short_size; return offset < 0 ? 0 : offset; } - return -1; + } + + uptr end = ptr + sz; + uptr tail_sz = end & (kShadowAlignment - 1); + if (!tail_sz) + return -1; + + uptr short_size = + ShortTagSize(*(tag_t *)shadow_last, end & ~(kShadowAlignment - 1)); + if (LIKELY(tail_sz <= short_size)) + return -1; + + sptr offset = sz - tail_sz + short_size; + return offset < 0 ? 0 : offset; } u16 __sanitizer_unaligned_load16(const uu16 *p) { diff --git a/libsanitizer/hwasan/hwasan.h b/libsanitizer/hwasan/hwasan.h index c3d71a28142..37ef4822285 100644 --- a/libsanitizer/hwasan/hwasan.h +++ b/libsanitizer/hwasan/hwasan.h @@ -16,6 +16,7 @@ #include "hwasan_flags.h" #include "hwasan_interface_internal.h" +#include "hwasan_mapping.h" #include "sanitizer_common/sanitizer_common.h" #include "sanitizer_common/sanitizer_flags.h" #include "sanitizer_common/sanitizer_internal_defs.h" @@ -78,12 +79,23 @@ const unsigned kRecordFPShift = 48; const unsigned kRecordFPLShift = 4; const unsigned kRecordFPModulus = 1 << (64 - kRecordFPShift + kRecordFPLShift); +static inline bool InTaggableRegion(uptr addr) { +#if defined(HWASAN_ALIASING_MODE) + // Aliases are mapped next to shadow so that the upper bits match the shadow + // base. + return (addr >> kTaggableRegionCheckShift) == + (__hwasan::GetShadowOffset() >> kTaggableRegionCheckShift); +#endif + return true; +} + static inline tag_t GetTagFromPointer(uptr p) { - return (p >> kAddressTagShift) & kTagMask; + return InTaggableRegion(p) ? ((p >> kAddressTagShift) & kTagMask) : 0; } static inline uptr UntagAddr(uptr tagged_addr) { - return tagged_addr & ~kAddressTagMask; + return InTaggableRegion(tagged_addr) ? (tagged_addr & ~kAddressTagMask) + : tagged_addr; } static inline void *UntagPtr(const void *tagged_ptr) { @@ -92,7 +104,9 @@ static inline void *UntagPtr(const void *tagged_ptr) { } static inline uptr AddTagToPointer(uptr p, tag_t tag) { - return (p & ~kAddressTagMask) | ((uptr)tag << kAddressTagShift); + return InTaggableRegion(p) + ? ((p & ~kAddressTagMask) | ((uptr)tag << kAddressTagShift)) + : p; } namespace __hwasan { diff --git a/libsanitizer/hwasan/hwasan_allocator.cpp b/libsanitizer/hwasan/hwasan_allocator.cpp index d3cb5c84572..3b59741df6e 100644 --- a/libsanitizer/hwasan/hwasan_allocator.cpp +++ b/libsanitizer/hwasan/hwasan_allocator.cpp @@ -213,7 +213,10 @@ static void *HwasanAllocate(StackTrace *stack, uptr orig_size, uptr alignment, ReportOutOfMemory(size, stack); } if (zeroise) { - internal_memset(allocated, 0, size); + // The secondary allocator mmaps memory, which should be zero-inited so we + // don't need to explicitly clear it. + if (allocator.FromPrimary(allocated)) + internal_memset(allocated, 0, size); } else if (flags()->max_malloc_fill_size > 0) { uptr fill_size = Min(size, (uptr)flags()->max_malloc_fill_size); internal_memset(allocated, flags()->malloc_fill_byte, fill_size); @@ -287,9 +290,7 @@ static void HwasanDeallocate(StackTrace *stack, void *tagged_ptr) { CHECK(tagged_ptr); RunFreeHooks(tagged_ptr); - bool in_taggable_region = - InTaggableRegion(reinterpret_cast(tagged_ptr)); - void *untagged_ptr = in_taggable_region ? UntagPtr(tagged_ptr) : tagged_ptr; + void *untagged_ptr = UntagPtr(tagged_ptr); if (CheckInvalidFree(stack, untagged_ptr, tagged_ptr)) return; @@ -308,6 +309,9 @@ static void HwasanDeallocate(StackTrace *stack, void *tagged_ptr) { u32 alloc_context_id = meta->GetAllocStackId(); u32 alloc_thread_id = meta->GetAllocThreadId(); + bool in_taggable_region = + InTaggableRegion(reinterpret_cast(tagged_ptr)); + // Check tail magic. uptr tagged_size = TaggedSize(orig_size); if (flags()->free_checks_tail_magic && orig_size && @@ -370,10 +374,7 @@ static void HwasanDeallocate(StackTrace *stack, void *tagged_ptr) { static void *HwasanReallocate(StackTrace *stack, void *tagged_ptr_old, uptr new_size, uptr alignment) { - void *untagged_ptr_old = - InTaggableRegion(reinterpret_cast(tagged_ptr_old)) - ? UntagPtr(tagged_ptr_old) - : tagged_ptr_old; + void *untagged_ptr_old = UntagPtr(tagged_ptr_old); if (CheckInvalidFree(stack, untagged_ptr_old, tagged_ptr_old)) return nullptr; void *tagged_ptr_new = @@ -381,9 +382,9 @@ static void *HwasanReallocate(StackTrace *stack, void *tagged_ptr_old, if (tagged_ptr_old && tagged_ptr_new) { Metadata *meta = reinterpret_cast(allocator.GetMetaData(untagged_ptr_old)); - internal_memcpy( - UntagPtr(tagged_ptr_new), untagged_ptr_old, - Min(new_size, static_cast(meta->GetRequestedSize()))); + void *untagged_ptr_new = UntagPtr(tagged_ptr_new); + internal_memcpy(untagged_ptr_new, untagged_ptr_old, + Min(new_size, static_cast(meta->GetRequestedSize()))); HwasanDeallocate(stack, tagged_ptr_old); } return tagged_ptr_new; @@ -426,12 +427,13 @@ static const void *AllocationBegin(const void *p) { return (const void *)AddTagToPointer((uptr)beg, tag); } -static uptr AllocationSize(const void *tagged_ptr) { - const void *untagged_ptr = UntagPtr(tagged_ptr); +static uptr AllocationSize(const void *p) { + const void *untagged_ptr = UntagPtr(p); if (!untagged_ptr) return 0; const void *beg = allocator.GetBlockBegin(untagged_ptr); - Metadata *b = (Metadata *)allocator.GetMetaData(untagged_ptr); - if (beg != untagged_ptr) return 0; + if (!beg) + return 0; + Metadata *b = (Metadata *)allocator.GetMetaData(beg); return b->GetRequestedSize(); } @@ -540,7 +542,7 @@ void GetAllocatorGlobalRange(uptr *begin, uptr *end) { } uptr PointsIntoChunk(void *p) { - p = __hwasan::InTaggableRegion(reinterpret_cast(p)) ? UntagPtr(p) : p; + p = UntagPtr(p); uptr addr = reinterpret_cast(p); uptr chunk = reinterpret_cast(__hwasan::allocator.GetBlockBeginFastLocked(p)); @@ -558,8 +560,7 @@ uptr PointsIntoChunk(void *p) { } uptr GetUserBegin(uptr chunk) { - if (__hwasan::InTaggableRegion(chunk)) - CHECK_EQ(UntagAddr(chunk), chunk); + CHECK_EQ(UntagAddr(chunk), chunk); void *block = __hwasan::allocator.GetBlockBeginFastLocked( reinterpret_cast(chunk)); if (!block) @@ -573,15 +574,14 @@ uptr GetUserBegin(uptr chunk) { } uptr GetUserAddr(uptr chunk) { - tag_t mem_tag = *(tag_t *)__hwasan::MemToShadow(chunk); - if (!__hwasan::InTaggableRegion(chunk)) + if (!InTaggableRegion(chunk)) return chunk; + tag_t mem_tag = *(tag_t *)__hwasan::MemToShadow(chunk); return AddTagToPointer(chunk, mem_tag); } LsanMetadata::LsanMetadata(uptr chunk) { - if (__hwasan::InTaggableRegion(chunk)) - CHECK_EQ(UntagAddr(chunk), chunk); + CHECK_EQ(UntagAddr(chunk), chunk); metadata_ = chunk ? __hwasan::allocator.GetMetaData(reinterpret_cast(chunk)) : nullptr; @@ -619,7 +619,7 @@ void ForEachChunk(ForEachChunkCallback callback, void *arg) { } IgnoreObjectResult IgnoreObject(const void *p) { - p = __hwasan::InTaggableRegion(reinterpret_cast(p)) ? UntagPtr(p) : p; + p = UntagPtr(p); uptr addr = reinterpret_cast(p); uptr chunk = reinterpret_cast(__hwasan::allocator.GetBlockBegin(p)); if (!chunk) @@ -674,3 +674,5 @@ const void *__sanitizer_get_allocated_begin(const void *p) { } uptr __sanitizer_get_allocated_size(const void *p) { return AllocationSize(p); } + +void __sanitizer_purge_allocator() { allocator.ForceReleaseToOS(); } diff --git a/libsanitizer/hwasan/hwasan_allocator.h b/libsanitizer/hwasan/hwasan_allocator.h index b7a06da0b65..ecf3f6816fc 100644 --- a/libsanitizer/hwasan/hwasan_allocator.h +++ b/libsanitizer/hwasan/hwasan_allocator.h @@ -127,16 +127,6 @@ typedef RingBuffer HeapAllocationsRingBuffer; void GetAllocatorStats(AllocatorStatCounters s); -inline bool InTaggableRegion(uptr addr) { -#if defined(HWASAN_ALIASING_MODE) - // Aliases are mapped next to shadow so that the upper bits match the shadow - // base. - return (addr >> kTaggableRegionCheckShift) == - (GetShadowOffset() >> kTaggableRegionCheckShift); -#endif - return true; -} - } // namespace __hwasan #endif // HWASAN_ALLOCATOR_H diff --git a/libsanitizer/hwasan/hwasan_checks.h b/libsanitizer/hwasan/hwasan_checks.h index 514d351cf7d..0911af30dcb 100644 --- a/libsanitizer/hwasan/hwasan_checks.h +++ b/libsanitizer/hwasan/hwasan_checks.h @@ -125,8 +125,22 @@ __attribute__((always_inline)) static void SigTrap(uptr p, uptr size) { // __builtin_unreachable(); } -__attribute__((always_inline, nodebug)) static bool PossiblyShortTagMatches( - tag_t mem_tag, uptr ptr, uptr sz) { +__attribute__((always_inline, nodebug)) static inline uptr ShortTagSize( + tag_t mem_tag, uptr ptr) { + DCHECK(IsAligned(ptr, kShadowAlignment)); + tag_t ptr_tag = GetTagFromPointer(ptr); + if (ptr_tag == mem_tag) + return kShadowAlignment; + if (!mem_tag || mem_tag >= kShadowAlignment) + return 0; + if (*(u8 *)(ptr | (kShadowAlignment - 1)) != ptr_tag) + return 0; + return mem_tag; +} + +__attribute__((always_inline, nodebug)) static inline bool +PossiblyShortTagMatches(tag_t mem_tag, uptr ptr, uptr sz) { + DCHECK(IsAligned(ptr, kShadowAlignment)); tag_t ptr_tag = GetTagFromPointer(ptr); if (ptr_tag == mem_tag) return true; @@ -134,9 +148,6 @@ __attribute__((always_inline, nodebug)) static bool PossiblyShortTagMatches( return false; if ((ptr & (kShadowAlignment - 1)) + sz > mem_tag) return false; -#if !defined(__aarch64__) && !(SANITIZER_RISCV64) - ptr = UntagAddr(ptr); -#endif return *(u8 *)(ptr | (kShadowAlignment - 1)) == ptr_tag; } @@ -169,7 +180,7 @@ __attribute__((always_inline, nodebug)) static void CheckAddressSized(uptr p, __builtin_unreachable(); } uptr end = p + sz; - uptr tail_sz = end & 0xf; + uptr tail_sz = end & (kShadowAlignment - 1); if (UNLIKELY(tail_sz != 0 && !PossiblyShortTagMatches( *shadow_last, end & ~(kShadowAlignment - 1), tail_sz))) { diff --git a/libsanitizer/hwasan/hwasan_interceptors.cpp b/libsanitizer/hwasan/hwasan_interceptors.cpp index 16ac85eb858..67edba40b5b 100644 --- a/libsanitizer/hwasan/hwasan_interceptors.cpp +++ b/libsanitizer/hwasan/hwasan_interceptors.cpp @@ -14,9 +14,11 @@ // sanitizer_common/sanitizer_common_interceptors.h //===----------------------------------------------------------------------===// -#include "interception/interception.h" #include "hwasan.h" +#include "hwasan_checks.h" #include "hwasan_thread.h" +#include "interception/interception.h" +#include "sanitizer_common/sanitizer_linux.h" #include "sanitizer_common/sanitizer_stackdepot.h" #if !SANITIZER_FUCHSIA @@ -28,31 +30,47 @@ using namespace __hwasan; struct ThreadStartArg { thread_callback_t callback; void *param; + __sanitizer_sigset_t starting_sigset_; }; static void *HwasanThreadStartFunc(void *arg) { __hwasan_thread_enter(); ThreadStartArg A = *reinterpret_cast(arg); + SetSigProcMask(&A.starting_sigset_, nullptr); UnmapOrDie(arg, GetPageSizeCached()); return A.callback(A.param); } +# define COMMON_SYSCALL_PRE_READ_RANGE(p, s) __hwasan_loadN((uptr)p, (uptr)s) +# define COMMON_SYSCALL_PRE_WRITE_RANGE(p, s) \ + __hwasan_storeN((uptr)p, (uptr)s) +# define COMMON_SYSCALL_POST_READ_RANGE(p, s) \ + do { \ + (void)(p); \ + (void)(s); \ + } while (false) +# define COMMON_SYSCALL_POST_WRITE_RANGE(p, s) \ + do { \ + (void)(p); \ + (void)(s); \ + } while (false) +# include "sanitizer_common/sanitizer_common_syscalls.inc" +# include "sanitizer_common/sanitizer_syscalls_netbsd.inc" + INTERCEPTOR(int, pthread_create, void *th, void *attr, void *(*callback)(void*), void * param) { EnsureMainThreadIDIsCorrect(); ScopedTaggingDisabler tagging_disabler; ThreadStartArg *A = reinterpret_cast (MmapOrDie( GetPageSizeCached(), "pthread_create")); - *A = {callback, param}; - int res; - { - // ASAN uses the same approach to disable leaks from pthread_create. + A->callback = callback; + A->param = param; + ScopedBlockSignals block(&A->starting_sigset_); + // ASAN uses the same approach to disable leaks from pthread_create. # if CAN_SANITIZE_LEAKS - __lsan::ScopedInterceptorDisabler lsan_disabler; + __lsan::ScopedInterceptorDisabler lsan_disabler; # endif - res = REAL(pthread_create)(th, attr, &HwasanThreadStartFunc, A); - } - return res; + return REAL(pthread_create)(th, attr, &HwasanThreadStartFunc, A); } INTERCEPTOR(int, pthread_join, void *t, void **arg) { diff --git a/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc b/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc index 3bd73cf8748..490a8b12d8b 100644 --- a/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc +++ b/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc @@ -7748,8 +7748,7 @@ static void write_protoent(void *ctx, struct __sanitizer_protoent *p) { for (char **pp = p->p_aliases; *pp; ++pp, ++pp_size) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *pp, internal_strlen(*pp) + 1); - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->p_aliases, - pp_size * sizeof(char **)); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->p_aliases, pp_size * sizeof(char *)); } INTERCEPTOR(struct __sanitizer_protoent *, getprotoent) { @@ -7855,8 +7854,7 @@ INTERCEPTOR(struct __sanitizer_netent *, getnetent) { for (char **nn = n->n_aliases; *nn; ++nn, ++nn_size) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *nn, internal_strlen(*nn) + 1); - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_aliases, - nn_size * sizeof(char **)); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_aliases, nn_size * sizeof(char *)); } return n; } @@ -7877,8 +7875,7 @@ INTERCEPTOR(struct __sanitizer_netent *, getnetbyname, const char *name) { for (char **nn = n->n_aliases; *nn; ++nn, ++nn_size) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *nn, internal_strlen(*nn) + 1); - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_aliases, - nn_size * sizeof(char **)); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_aliases, nn_size * sizeof(char *)); } return n; } @@ -7897,8 +7894,7 @@ INTERCEPTOR(struct __sanitizer_netent *, getnetbyaddr, u32 net, int type) { for (char **nn = n->n_aliases; *nn; ++nn, ++nn_size) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *nn, internal_strlen(*nn) + 1); - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_aliases, - nn_size * sizeof(char **)); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_aliases, nn_size * sizeof(char *)); } return n; } @@ -10090,41 +10086,6 @@ INTERCEPTOR(SSIZE_T, getrandom, void *buf, SIZE_T buflen, unsigned int flags) { #define INIT_GETRANDOM #endif -#if SANITIZER_INTERCEPT_CRYPT -INTERCEPTOR(char *, crypt, char *key, char *salt) { - void *ctx; - COMMON_INTERCEPTOR_ENTER(ctx, crypt, key, salt); - COMMON_INTERCEPTOR_READ_RANGE(ctx, key, internal_strlen(key) + 1); - COMMON_INTERCEPTOR_READ_RANGE(ctx, salt, internal_strlen(salt) + 1); - char *res = REAL(crypt)(key, salt); - if (res != nullptr) - COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1); - return res; -} -#define INIT_CRYPT COMMON_INTERCEPT_FUNCTION(crypt); -#else -#define INIT_CRYPT -#endif - -#if SANITIZER_INTERCEPT_CRYPT_R -INTERCEPTOR(char *, crypt_r, char *key, char *salt, void *data) { - void *ctx; - COMMON_INTERCEPTOR_ENTER(ctx, crypt_r, key, salt, data); - COMMON_INTERCEPTOR_READ_RANGE(ctx, key, internal_strlen(key) + 1); - COMMON_INTERCEPTOR_READ_RANGE(ctx, salt, internal_strlen(salt) + 1); - char *res = REAL(crypt_r)(key, salt, data); - if (res != nullptr) { - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, - __sanitizer::struct_crypt_data_sz); - COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1); - } - return res; -} -#define INIT_CRYPT_R COMMON_INTERCEPT_FUNCTION(crypt_r); -#else -#define INIT_CRYPT_R -#endif - #if SANITIZER_INTERCEPT_GETENTROPY INTERCEPTOR(int, getentropy, void *buf, SIZE_T buflen) { void *ctx; @@ -10702,8 +10663,6 @@ static void InitializeCommonInterceptors() { INIT_GETUSERSHELL; INIT_SL_INIT; INIT_GETRANDOM; - INIT_CRYPT; - INIT_CRYPT_R; INIT_GETENTROPY; INIT_QSORT; INIT_QSORT_R; diff --git a/libsanitizer/sanitizer_common/sanitizer_common_syscalls.inc b/libsanitizer/sanitizer_common/sanitizer_common_syscalls.inc index 93b988ba163..3900bcf22b7 100644 --- a/libsanitizer/sanitizer_common/sanitizer_common_syscalls.inc +++ b/libsanitizer/sanitizer_common/sanitizer_common_syscalls.inc @@ -1374,9 +1374,8 @@ PRE_SYSCALL(io_setup)(long nr_reqs, void **ctx) { } POST_SYSCALL(io_setup)(long res, long nr_reqs, void **ctx) { - if (res >= 0) { - if (ctx) - POST_WRITE(ctx, sizeof(*ctx)); + if (res >= 0 && ctx) { + POST_WRITE(ctx, sizeof(*ctx)); // (*ctx) is actually a pointer to a kernel mapped page, and there are // people out there who are crazy enough to peek into that page's 32-byte // header. diff --git a/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cpp b/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cpp index 2720a3cab2c..37b2b57c0c8 100644 --- a/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cpp +++ b/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cpp @@ -838,13 +838,9 @@ 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 } diff --git a/libsanitizer/sanitizer_common/sanitizer_mac.cpp b/libsanitizer/sanitizer_common/sanitizer_mac.cpp index e1f83e4002a..24e3d111252 100644 --- a/libsanitizer/sanitizer_common/sanitizer_mac.cpp +++ b/libsanitizer/sanitizer_common/sanitizer_mac.cpp @@ -38,7 +38,7 @@ extern char **environ; # endif -# if defined(__has_include) && __has_include() && defined(__BLOCKS__) +# if defined(__has_include) && __has_include() # define SANITIZER_OS_TRACE 1 # include # else @@ -71,15 +71,7 @@ extern char ***_NSGetArgv(void); # include # include # include -# if defined(__has_builtin) && __has_builtin(__builtin_os_log_format) -# include -# else - /* Without support for __builtin_os_log_format, fall back to the older - method. */ -# define OS_LOG_DEFAULT 0 -# define os_log_error(A,B,C) \ - asl_log(nullptr, nullptr, ASL_LEVEL_ERR, "%s", (C)); -# endif +# include # include # include # include diff --git a/libsanitizer/sanitizer_common/sanitizer_mac.h b/libsanitizer/sanitizer_common/sanitizer_mac.h index 1cf2e298cc9..f0a97d098ee 100644 --- a/libsanitizer/sanitizer_common/sanitizer_mac.h +++ b/libsanitizer/sanitizer_common/sanitizer_mac.h @@ -14,26 +14,6 @@ #include "sanitizer_common.h" #include "sanitizer_platform.h" - -/* TARGET_OS_OSX is not present in SDKs before Darwin16 (macOS 10.12) use - TARGET_OS_MAC (we have no support for iOS in any form for these versions, - so there's no ambiguity). */ -#if !defined(TARGET_OS_OSX) && TARGET_OS_MAC -# define TARGET_OS_OSX 1 -#endif - -/* Other TARGET_OS_xxx are not present on earlier versions, define them to - 0 (we have no support for them; they are not valid targets anyway). */ -#ifndef TARGET_OS_IOS -#define TARGET_OS_IOS 0 -#endif -#ifndef TARGET_OS_TV -#define TARGET_OS_TV 0 -#endif -#ifndef TARGET_OS_WATCH -#define TARGET_OS_WATCH 0 -#endif - #if SANITIZER_APPLE #include "sanitizer_posix.h" diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_interceptors.h b/libsanitizer/sanitizer_common/sanitizer_platform_interceptors.h index eb39fabfd59..c82ab5c2105 100644 --- a/libsanitizer/sanitizer_common/sanitizer_platform_interceptors.h +++ b/libsanitizer/sanitizer_common/sanitizer_platform_interceptors.h @@ -569,8 +569,6 @@ #define SANITIZER_INTERCEPT_FDEVNAME SI_FREEBSD #define SANITIZER_INTERCEPT_GETUSERSHELL (SI_POSIX && !SI_ANDROID) #define SANITIZER_INTERCEPT_SL_INIT (SI_FREEBSD || SI_NETBSD) -#define SANITIZER_INTERCEPT_CRYPT (SI_POSIX && !SI_ANDROID) -#define SANITIZER_INTERCEPT_CRYPT_R (SI_LINUX && !SI_ANDROID) #define SANITIZER_INTERCEPT_GETRANDOM \ ((SI_LINUX && __GLIBC_PREREQ(2, 25)) || SI_FREEBSD) diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_limits_linux.cpp b/libsanitizer/sanitizer_common/sanitizer_platform_limits_linux.cpp index c278c8797f7..bf0f355847c 100644 --- a/libsanitizer/sanitizer_common/sanitizer_platform_limits_linux.cpp +++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_linux.cpp @@ -26,10 +26,7 @@ // 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. Beware that with , 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 -// struct stat:s. +// fine with newer headers, too. #include # if defined(__x86_64__) || defined(__mips__) || defined(__hexagon__) # include diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cpp b/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cpp index a04eed7aa5a..6d61d276d77 100644 --- a/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cpp +++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cpp @@ -177,10 +177,6 @@ typedef struct user_fpregs elf_fpregset_t; # include "sanitizer_platform_interceptors.h" # include "sanitizer_platform_limits_posix.h" -#if SANITIZER_INTERCEPT_CRYPT_R -#include -#endif - namespace __sanitizer { unsigned struct_utsname_sz = sizeof(struct utsname); unsigned struct_stat_sz = sizeof(struct stat); @@ -300,10 +296,6 @@ namespace __sanitizer { unsigned struct_statvfs64_sz = sizeof(struct statvfs64); #endif // SANITIZER_GLIBC -#if SANITIZER_INTERCEPT_CRYPT_R - unsigned struct_crypt_data_sz = sizeof(struct crypt_data); -#endif - #if SANITIZER_LINUX && !SANITIZER_ANDROID unsigned struct_timex_sz = sizeof(struct timex); unsigned struct_msqid_ds_sz = sizeof(struct msqid_ds); diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h b/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h index cfca7bdedbe..58244c9944a 100644 --- a/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h +++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h @@ -309,7 +309,6 @@ extern unsigned struct_msqid_ds_sz; extern unsigned struct_mq_attr_sz; extern unsigned struct_timex_sz; extern unsigned struct_statvfs_sz; -extern unsigned struct_crypt_data_sz; #endif // SANITIZER_LINUX && !SANITIZER_ANDROID struct __sanitizer_iovec { @@ -578,8 +577,13 @@ struct __sanitizer_sigset_t { #endif struct __sanitizer_siginfo_pad { +#if SANITIZER_X32 + // x32 siginfo_t is aligned to 8 bytes. + u64 pad[128 / sizeof(u64)]; +#else // Require uptr, because siginfo_t is always pointer-size aligned on Linux. uptr pad[128 / sizeof(uptr)]; +#endif }; #if SANITIZER_LINUX diff --git a/libsanitizer/sanitizer_common/sanitizer_procmaps_mac.cpp b/libsanitizer/sanitizer_common/sanitizer_procmaps_mac.cpp index f2f38467121..b44e016a0e5 100644 --- a/libsanitizer/sanitizer_common/sanitizer_procmaps_mac.cpp +++ b/libsanitizer/sanitizer_common/sanitizer_procmaps_mac.cpp @@ -146,13 +146,8 @@ static bool IsDyldHdr(const mach_header *hdr) { // until we hit a Mach header matching dyld instead. These recurse // calls are expensive, but the first memory map generation occurs // early in the process, when dyld is one of the only images loaded, -// so it will be hit after only a few iterations. These assumptions don't -// hold on macOS 13+ anymore (dyld itself has moved into the shared cache). - -// FIXME: Unfortunately, the upstream revised version to deal with macOS 13+ -// is incompatible with GCC and also uses APIs not available on earlier -// systems which we support; backed out for now. - +// so it will be hit after only a few iterations. These assumptions don't hold +// on macOS 13+ anymore (dyld itself has moved into the shared cache). static mach_header *GetDyldImageHeaderViaVMRegion() { vm_address_t address = 0; @@ -176,17 +171,64 @@ static mach_header *GetDyldImageHeaderViaVMRegion() { } } +extern "C" { +struct dyld_shared_cache_dylib_text_info { + uint64_t version; // current version 2 + // following fields all exist in version 1 + uint64_t loadAddressUnslid; + uint64_t textSegmentSize; + uuid_t dylibUuid; + const char *path; // pointer invalid at end of iterations + // following fields all exist in version 2 + uint64_t textSegmentOffset; // offset from start of cache +}; +typedef struct dyld_shared_cache_dylib_text_info + dyld_shared_cache_dylib_text_info; + +extern bool _dyld_get_shared_cache_uuid(uuid_t uuid); +extern const void *_dyld_get_shared_cache_range(size_t *length); +extern int dyld_shared_cache_iterate_text( + const uuid_t cacheUuid, + void (^callback)(const dyld_shared_cache_dylib_text_info *info)); +} // extern "C" + +static mach_header *GetDyldImageHeaderViaSharedCache() { + uuid_t uuid; + bool hasCache = _dyld_get_shared_cache_uuid(uuid); + if (!hasCache) + return nullptr; + + size_t cacheLength; + __block uptr cacheStart = (uptr)_dyld_get_shared_cache_range(&cacheLength); + CHECK(cacheStart && cacheLength); + + __block mach_header *dyldHdr = nullptr; + int res = dyld_shared_cache_iterate_text( + uuid, ^(const dyld_shared_cache_dylib_text_info *info) { + CHECK_GE(info->version, 2); + mach_header *hdr = + (mach_header *)(cacheStart + info->textSegmentOffset); + if (IsDyldHdr(hdr)) + dyldHdr = hdr; + }); + CHECK_EQ(res, 0); + + return dyldHdr; +} + const mach_header *get_dyld_hdr() { if (!dyld_hdr) { // On macOS 13+, dyld itself has moved into the shared cache. Looking it up // via vm_region_recurse_64() causes spins/hangs/crashes. - // FIXME: find a way to do this compatible with GCC. if (GetMacosAlignedVersion() >= MacosVersion(13, 0)) { + dyld_hdr = GetDyldImageHeaderViaSharedCache(); + if (!dyld_hdr) { VReport(1, - "looking up the dyld image header in the shared cache on " - "macOS 13+ is not yet supported. Falling back to " + "Failed to lookup the dyld image header in the shared cache on " + "macOS 13+ (or no shared cache in use). Falling back to " "lookup via vm_region_recurse_64().\n"); dyld_hdr = GetDyldImageHeaderViaVMRegion(); + } } else { dyld_hdr = GetDyldImageHeaderViaVMRegion(); } diff --git a/libsanitizer/sanitizer_common/sanitizer_stacktrace.cpp b/libsanitizer/sanitizer_common/sanitizer_stacktrace.cpp index 661495e2340..d24fae98213 100644 --- a/libsanitizer/sanitizer_common/sanitizer_stacktrace.cpp +++ b/libsanitizer/sanitizer_common/sanitizer_stacktrace.cpp @@ -87,8 +87,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 GCC. - return bp_prev - 1; + // layouts. Assume LLVM. + return bp_prev; #else return (uhwptr*)bp; #endif @@ -111,21 +111,14 @@ 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 on 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 at offset + // 16 of 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]; #elif defined(__loongarch__) || defined(__riscv) diff --git a/libsanitizer/tsan/tsan_rtl_ppc64.S b/libsanitizer/tsan/tsan_rtl_ppc64.S index 9e533a71a9c..8285e21aa1e 100644 --- a/libsanitizer/tsan/tsan_rtl_ppc64.S +++ b/libsanitizer/tsan/tsan_rtl_ppc64.S @@ -1,6 +1,5 @@ #include "tsan_ppc_regs.h" - .machine altivec .section .text .hidden __tsan_setjmp .globl _setjmp diff --git a/libsanitizer/ubsan/ubsan_flags.cpp b/libsanitizer/ubsan/ubsan_flags.cpp index 9a66bd37518..25cefd46ce2 100644 --- a/libsanitizer/ubsan/ubsan_flags.cpp +++ b/libsanitizer/ubsan/ubsan_flags.cpp @@ -50,7 +50,6 @@ void InitializeFlags() { { CommonFlags cf; cf.CopyFrom(*common_flags()); - cf.print_summary = false; cf.external_symbolizer_path = GetFlag("UBSAN_SYMBOLIZER_PATH"); OverrideCommonFlags(cf); } diff --git a/libsanitizer/ubsan/ubsan_handlers.cpp b/libsanitizer/ubsan/ubsan_handlers.cpp index 970075e69a6..410292a0d53 100644 --- a/libsanitizer/ubsan/ubsan_handlers.cpp +++ b/libsanitizer/ubsan/ubsan_handlers.cpp @@ -894,21 +894,6 @@ 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) { diff --git a/libsanitizer/ubsan/ubsan_handlers.h b/libsanitizer/ubsan/ubsan_handlers.h index 9f412353fc0..219fb15de55 100644 --- a/libsanitizer/ubsan/ubsan_handlers.h +++ b/libsanitizer/ubsan/ubsan_handlers.h @@ -215,20 +215,12 @@ 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) diff --git a/libsanitizer/ubsan/ubsan_platform.h b/libsanitizer/ubsan/ubsan_platform.h index ad3e883f0f3..d2cc2e10bd2 100644 --- a/libsanitizer/ubsan/ubsan_platform.h +++ b/libsanitizer/ubsan/ubsan_platform.h @@ -12,7 +12,6 @@ #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(__DragonFly__) || \ @@ -22,6 +21,5 @@ #else # define CAN_SANITIZE_UB 0 #endif -#endif //CAN_SANITIZE_UB #endif