diff options
Diffstat (limited to 'compiler-rt/lib/sanitizer_common')
26 files changed, 553 insertions, 72 deletions
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_allocator.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_allocator.cpp index 8d07906cca03..906d4af7f5ee 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_allocator.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_allocator.cpp @@ -213,7 +213,7 @@ void *LowLevelAllocator::Allocate(uptr size) { // Align allocation size. size = RoundUpTo(size, low_level_alloc_min_alignment); if (allocated_end_ - allocated_current_ < (sptr)size) { - uptr size_to_allocate = Max(size, GetPageSizeCached()); + uptr size_to_allocate = RoundUpTo(size, GetPageSizeCached()); allocated_current_ = (char*)MmapOrDie(size_to_allocate, __func__); allocated_end_ = allocated_current_ + size_to_allocate; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common.h b/compiler-rt/lib/sanitizer_common/sanitizer_common.h index 87b8f02b5b73..3b52172c483c 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common.h @@ -552,7 +552,7 @@ bool operator!=(const InternalMmapVectorNoCtor<T> &lhs, template<typename T> class InternalMmapVector : public InternalMmapVectorNoCtor<T> { public: - InternalMmapVector() { InternalMmapVectorNoCtor<T>::Initialize(1); } + InternalMmapVector() { InternalMmapVectorNoCtor<T>::Initialize(0); } explicit InternalMmapVector(uptr cnt) { InternalMmapVectorNoCtor<T>::Initialize(cnt); this->resize(cnt); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc index 50e3558b52e8..2a4ab7e67a5c 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc @@ -79,13 +79,15 @@ #define devname __devname50 #define fgetpos __fgetpos50 #define fsetpos __fsetpos50 +#define fstatvfs __fstatvfs90 +#define fstatvfs1 __fstatvfs190 #define fts_children __fts_children60 #define fts_close __fts_close60 #define fts_open __fts_open60 #define fts_read __fts_read60 #define fts_set __fts_set60 #define getitimer __getitimer50 -#define getmntinfo __getmntinfo13 +#define getmntinfo __getmntinfo90 #define getpwent __getpwent50 #define getpwnam __getpwnam50 #define getpwnam_r __getpwnam_r50 @@ -95,6 +97,7 @@ #define getutxent __getutxent50 #define getutxid __getutxid50 #define getutxline __getutxline50 +#define getvfsstat __getvfsstat90 #define pututxline __pututxline50 #define glob __glob30 #define gmtime __gmtime50 @@ -116,6 +119,8 @@ #define sigprocmask __sigprocmask14 #define sigtimedwait __sigtimedwait50 #define stat __stat50 +#define statvfs __statvfs90 +#define statvfs1 __statvfs190 #define time __time50 #define times __times13 #define unvis __unvis50 @@ -4177,11 +4182,27 @@ INTERCEPTOR(int, pthread_mutex_unlock, void *m) { #if SANITIZER_INTERCEPT___PTHREAD_MUTEX INTERCEPTOR(int, __pthread_mutex_lock, void *m) { - return WRAP(pthread_mutex_lock)(m); + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, __pthread_mutex_lock, m); + COMMON_INTERCEPTOR_MUTEX_PRE_LOCK(ctx, m); + int res = REAL(__pthread_mutex_lock)(m); + if (res == errno_EOWNERDEAD) + COMMON_INTERCEPTOR_MUTEX_REPAIR(ctx, m); + if (res == 0 || res == errno_EOWNERDEAD) + COMMON_INTERCEPTOR_MUTEX_POST_LOCK(ctx, m); + if (res == errno_EINVAL) + COMMON_INTERCEPTOR_MUTEX_INVALID(ctx, m); + return res; } INTERCEPTOR(int, __pthread_mutex_unlock, void *m) { - return WRAP(pthread_mutex_unlock)(m); + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, __pthread_mutex_unlock, m); + COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m); + int res = REAL(__pthread_mutex_unlock)(m); + if (res == errno_EINVAL) + COMMON_INTERCEPTOR_MUTEX_INVALID(ctx, m); + return res; } #define INIT___PTHREAD_MUTEX_LOCK \ @@ -9623,6 +9644,95 @@ INTERCEPTOR(int, getentropy, void *buf, SIZE_T buflen) { #define INIT_GETENTROPY #endif +#if SANITIZER_INTERCEPT_QSORT +// Glibc qsort uses a temporary buffer allocated either on stack or on heap. +// Poisoned memory from there may get copied into the comparator arguments, +// where it needs to be dealt with. But even that is not enough - the results of +// the sort may be copied into the input/output array based on the results of +// the comparator calls, but directly from the temp memory, bypassing the +// unpoisoning done in wrapped_qsort_compar. We deal with this by, again, +// unpoisoning the entire array after the sort is done. +// +// We can not check that the entire array is initialized at the beginning. IMHO, +// it's fine for parts of the sorted objects to contain uninitialized memory, +// ex. as padding in structs. +typedef int (*qsort_compar_f)(const void *, const void *); +static THREADLOCAL qsort_compar_f qsort_compar; +static THREADLOCAL SIZE_T qsort_size; +int wrapped_qsort_compar(const void *a, const void *b) { + COMMON_INTERCEPTOR_UNPOISON_PARAM(2); + COMMON_INTERCEPTOR_INITIALIZE_RANGE(a, qsort_size); + COMMON_INTERCEPTOR_INITIALIZE_RANGE(b, qsort_size); + return qsort_compar(a, b); +} + +INTERCEPTOR(void, qsort, void *base, SIZE_T nmemb, SIZE_T size, + qsort_compar_f compar) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, qsort, base, nmemb, size, compar); + // Run the comparator over all array elements to detect any memory issues. + if (nmemb > 1) { + for (SIZE_T i = 0; i < nmemb - 1; ++i) { + void *p = (void *)((char *)base + i * size); + void *q = (void *)((char *)base + (i + 1) * size); + COMMON_INTERCEPTOR_UNPOISON_PARAM(2); + compar(p, q); + } + } + qsort_compar_f old_compar = qsort_compar; + qsort_compar = compar; + SIZE_T old_size = qsort_size; + qsort_size = size; + REAL(qsort)(base, nmemb, size, wrapped_qsort_compar); + qsort_compar = old_compar; + qsort_size = old_size; + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, base, nmemb * size); +} +#define INIT_QSORT COMMON_INTERCEPT_FUNCTION(qsort) +#else +#define INIT_QSORT +#endif + +#if SANITIZER_INTERCEPT_QSORT_R +typedef int (*qsort_r_compar_f)(const void *, const void *, void *); +static THREADLOCAL qsort_r_compar_f qsort_r_compar; +static THREADLOCAL SIZE_T qsort_r_size; +int wrapped_qsort_r_compar(const void *a, const void *b, void *arg) { + COMMON_INTERCEPTOR_UNPOISON_PARAM(3); + COMMON_INTERCEPTOR_INITIALIZE_RANGE(a, qsort_r_size); + COMMON_INTERCEPTOR_INITIALIZE_RANGE(b, qsort_r_size); + return qsort_r_compar(a, b, arg); +} + +INTERCEPTOR(void, qsort_r, void *base, SIZE_T nmemb, SIZE_T size, + qsort_r_compar_f compar, void *arg) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, qsort_r, base, nmemb, size, compar, arg); + // Run the comparator over all array elements to detect any memory issues. + if (nmemb > 1) { + for (SIZE_T i = 0; i < nmemb - 1; ++i) { + void *p = (void *)((char *)base + i * size); + void *q = (void *)((char *)base + (i + 1) * size); + COMMON_INTERCEPTOR_UNPOISON_PARAM(3); + compar(p, q, arg); + } + } + qsort_r_compar_f old_compar = qsort_r_compar; + qsort_r_compar = compar; + SIZE_T old_size = qsort_r_size; + qsort_r_size = size; + REAL(qsort_r)(base, nmemb, size, wrapped_qsort_r_compar, arg); + qsort_r_compar = old_compar; + qsort_r_size = old_size; + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, base, nmemb * size); +} +#define INIT_QSORT_R COMMON_INTERCEPT_FUNCTION(qsort_r) +#else +#define INIT_QSORT_R +#endif + +#include "sanitizer_common_interceptors_netbsd_compat.inc" + static void InitializeCommonInterceptors() { #if SI_POSIX static u64 metadata_mem[sizeof(MetadataHashMap) / sizeof(u64) + 1]; @@ -9924,6 +10034,8 @@ static void InitializeCommonInterceptors() { INIT_CRYPT; INIT_CRYPT_R; INIT_GETENTROPY; + INIT_QSORT; + INIT_QSORT_R; INIT___PRINTF_CHK; } diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_netbsd_compat.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_netbsd_compat.inc new file mode 100644 index 000000000000..6aa73ec8c6a2 --- /dev/null +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_netbsd_compat.inc @@ -0,0 +1,128 @@ +//===-- sanitizer_common_interceptors_netbsd_compat.inc ---------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// Common function interceptors for tools like AddressSanitizer, +// ThreadSanitizer, MemorySanitizer, etc. +// +// Interceptors for NetBSD old function calls that have been versioned. +// +// NetBSD minimal version supported 9.0. +// NetBSD current version supported 9.99.26. +// +//===----------------------------------------------------------------------===// + +#if SANITIZER_NETBSD + +// First undef all mangled symbols. +// Next, define compat interceptors. +// Finally, undef INIT_ and redefine it. +// This allows to avoid preprocessor issues. + +#undef fstatvfs +#undef fstatvfs1 +#undef getmntinfo +#undef getvfsstat +#undef statvfs +#undef statvfs1 + +INTERCEPTOR(int, statvfs, char *path, void *buf) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, statvfs, path, buf); + if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); + // FIXME: under ASan the call below may write to freed memory and corrupt + // its metadata. See + // https://github.com/google/sanitizers/issues/321. + int res = REAL(statvfs)(path, buf); + if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs90_sz); + return res; +} + +INTERCEPTOR(int, fstatvfs, int fd, void *buf) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, fstatvfs, fd, buf); + COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); + // FIXME: under ASan the call below may write to freed memory and corrupt + // its metadata. See + // https://github.com/google/sanitizers/issues/321. + int res = REAL(fstatvfs)(fd, buf); + if (!res) { + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs90_sz); + if (fd >= 0) + COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); + } + return res; +} + +#undef INIT_STATVFS +#define INIT_STATVFS \ + COMMON_INTERCEPT_FUNCTION(statvfs); \ + COMMON_INTERCEPT_FUNCTION(fstatvfs); \ + COMMON_INTERCEPT_FUNCTION(__statvfs90); \ + COMMON_INTERCEPT_FUNCTION(__fstatvfs90) + +INTERCEPTOR(int, __getmntinfo13, void **mntbufp, int flags) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, __getmntinfo13, mntbufp, flags); + int cnt = REAL(__getmntinfo13)(mntbufp, flags); + if (cnt > 0 && mntbufp) { + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mntbufp, sizeof(void *)); + if (*mntbufp) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *mntbufp, cnt * struct_statvfs90_sz); + } + return cnt; +} + +#undef INIT_GETMNTINFO +#define INIT_GETMNTINFO \ + COMMON_INTERCEPT_FUNCTION(__getmntinfo13); \ + COMMON_INTERCEPT_FUNCTION(__getmntinfo90) + +INTERCEPTOR(int, getvfsstat, void *buf, SIZE_T bufsize, int flags) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, getvfsstat, buf, bufsize, flags); + int ret = REAL(getvfsstat)(buf, bufsize, flags); + if (buf && ret > 0) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, ret * struct_statvfs90_sz); + return ret; +} + +#undef INIT_GETVFSSTAT +#define INIT_GETVFSSTAT \ + COMMON_INTERCEPT_FUNCTION(getvfsstat); \ + COMMON_INTERCEPT_FUNCTION(__getvfsstat90) + +INTERCEPTOR(int, statvfs1, const char *path, void *buf, int flags) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, statvfs1, path, buf, flags); + if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); + int res = REAL(statvfs1)(path, buf, flags); + if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs90_sz); + return res; +} + +INTERCEPTOR(int, fstatvfs1, int fd, void *buf, int flags) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, fstatvfs1, fd, buf, flags); + COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); + int res = REAL(fstatvfs1)(fd, buf, flags); + if (!res) { + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs90_sz); + if (fd >= 0) + COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); + } + return res; +} + +#undef INIT_STATVFS1 +#define INIT_STATVFS1 \ + COMMON_INTERCEPT_FUNCTION(statvfs1); \ + COMMON_INTERCEPT_FUNCTION(fstatvfs1); \ + COMMON_INTERCEPT_FUNCTION(__statvfs190); \ + COMMON_INTERCEPT_FUNCTION(__fstatvfs190) + +#endif diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_flag_parser.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_flag_parser.cpp index 1e2bc6652617..9e274268bf2a 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_flag_parser.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_flag_parser.cpp @@ -56,9 +56,16 @@ char *FlagParser::ll_strndup(const char *s, uptr n) { } void FlagParser::PrintFlagDescriptions() { + char buffer[128]; + buffer[sizeof(buffer) - 1] = '\0'; Printf("Available flags for %s:\n", SanitizerToolName); - for (int i = 0; i < n_flags_; ++i) - Printf("\t%s\n\t\t- %s\n", flags_[i].name, flags_[i].desc); + for (int i = 0; i < n_flags_; ++i) { + bool truncated = !(flags_[i].handler->Format(buffer, sizeof(buffer))); + CHECK_EQ(buffer[sizeof(buffer) - 1], '\0'); + const char *truncation_str = truncated ? " Truncated" : ""; + Printf("\t%s\n\t\t- %s (Current Value%s: %s)\n", flags_[i].name, + flags_[i].desc, truncation_str, buffer); + } } void FlagParser::fatal_error(const char *err) { diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_flag_parser.h b/compiler-rt/lib/sanitizer_common/sanitizer_flag_parser.h index c24ad25626ba..fac5dff34633 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_flag_parser.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_flag_parser.h @@ -22,9 +22,23 @@ namespace __sanitizer { class FlagHandlerBase { public: virtual bool Parse(const char *value) { return false; } + // Write the C string representation of the current value (truncated to fit) + // into the buffer of size `size`. Returns false if truncation occurred and + // returns true otherwise. + virtual bool Format(char *buffer, uptr size) { + if (size > 0) + buffer[0] = '\0'; + return false; + } protected: ~FlagHandlerBase() {} + + inline bool FormatString(char *buffer, uptr size, const char *str_to_use) { + uptr num_symbols_should_write = + internal_snprintf(buffer, size, "%s", str_to_use); + return num_symbols_should_write < size; + } }; template <typename T> @@ -34,6 +48,7 @@ class FlagHandler : public FlagHandlerBase { public: explicit FlagHandler(T *t) : t_(t) {} bool Parse(const char *value) final; + bool Format(char *buffer, uptr size) final; }; inline bool ParseBool(const char *value, bool *b) { @@ -60,6 +75,11 @@ inline bool FlagHandler<bool>::Parse(const char *value) { } template <> +inline bool FlagHandler<bool>::Format(char *buffer, uptr size) { + return FormatString(buffer, size, *t_ ? "true" : "false"); +} + +template <> inline bool FlagHandler<HandleSignalMode>::Parse(const char *value) { bool b; if (ParseBool(value, &b)) { @@ -76,12 +96,23 @@ inline bool FlagHandler<HandleSignalMode>::Parse(const char *value) { } template <> +inline bool FlagHandler<HandleSignalMode>::Format(char *buffer, uptr size) { + uptr num_symbols_should_write = internal_snprintf(buffer, size, "%d", *t_); + return num_symbols_should_write < size; +} + +template <> inline bool FlagHandler<const char *>::Parse(const char *value) { *t_ = value; return true; } template <> +inline bool FlagHandler<const char *>::Format(char *buffer, uptr size) { + return FormatString(buffer, size, *t_); +} + +template <> inline bool FlagHandler<int>::Parse(const char *value) { const char *value_end; *t_ = internal_simple_strtoll(value, &value_end, 10); @@ -91,6 +122,12 @@ inline bool FlagHandler<int>::Parse(const char *value) { } template <> +inline bool FlagHandler<int>::Format(char *buffer, uptr size) { + uptr num_symbols_should_write = internal_snprintf(buffer, size, "%d", *t_); + return num_symbols_should_write < size; +} + +template <> inline bool FlagHandler<uptr>::Parse(const char *value) { const char *value_end; *t_ = internal_simple_strtoll(value, &value_end, 10); @@ -100,6 +137,12 @@ inline bool FlagHandler<uptr>::Parse(const char *value) { } template <> +inline bool FlagHandler<uptr>::Format(char *buffer, uptr size) { + uptr num_symbols_should_write = internal_snprintf(buffer, size, "%p", *t_); + return num_symbols_should_write < size; +} + +template <> inline bool FlagHandler<s64>::Parse(const char *value) { const char *value_end; *t_ = internal_simple_strtoll(value, &value_end, 10); @@ -108,6 +151,12 @@ inline bool FlagHandler<s64>::Parse(const char *value) { return ok; } +template <> +inline bool FlagHandler<s64>::Format(char *buffer, uptr size) { + uptr num_symbols_should_write = internal_snprintf(buffer, size, "%lld", *t_); + return num_symbols_should_write < size; +} + class FlagParser { static const int kMaxFlags = 200; struct Flag { diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_flags.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_flags.cpp index 66a0a5579ed3..684ee1e0b999 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_flags.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_flags.cpp @@ -75,11 +75,13 @@ void SubstituteForFlagValue(const char *s, char *out, uptr out_size) { class FlagHandlerInclude : public FlagHandlerBase { FlagParser *parser_; bool ignore_missing_; + const char *original_path_; public: explicit FlagHandlerInclude(FlagParser *parser, bool ignore_missing) - : parser_(parser), ignore_missing_(ignore_missing) {} + : parser_(parser), ignore_missing_(ignore_missing), original_path_("") {} bool Parse(const char *value) final { + original_path_ = value; if (internal_strchr(value, '%')) { char *buf = (char *)MmapOrDie(kMaxPathLength, "FlagHandlerInclude"); SubstituteForFlagValue(value, buf, kMaxPathLength); @@ -89,6 +91,12 @@ class FlagHandlerInclude : public FlagHandlerBase { } return parser_->ParseFile(value, ignore_missing_); } + bool Format(char *buffer, uptr size) { + // Note `original_path_` isn't actually what's parsed due to `%` + // substitutions. Printing the substituted path would require holding onto + // mmap'ed memory. + return FormatString(buffer, size, original_path_); + } }; void RegisterIncludeFlags(FlagParser *parser, CommonFlags *cf) { diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_flags.inc b/compiler-rt/lib/sanitizer_common/sanitizer_flags.inc index 7d592bdcb61f..065258a5a6e1 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_flags.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_flags.inc @@ -132,6 +132,9 @@ COMMON_FLAG(uptr, soft_rss_limit_mb, 0, " until the RSS goes below the soft limit." " This limit does not affect memory allocations other than" " malloc/new.") +COMMON_FLAG(uptr, max_allocation_size_mb, 0, + "If non-zero, malloc/new calls larger than this size will return " + "nullptr (or crash if allocator_may_return_null=false).") COMMON_FLAG(bool, heap_profile, false, "Experimental heap profiler, asan-only") COMMON_FLAG(s32, allocator_release_to_os_interval_ms, ((bool)SANITIZER_FUCHSIA || (bool)SANITIZER_WINDOWS) ? -1 : 5000, diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_interceptors_ioctl_netbsd.inc b/compiler-rt/lib/sanitizer_common/sanitizer_interceptors_ioctl_netbsd.inc index 03ef7c1788cd..d0cc4da9755f 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_interceptors_ioctl_netbsd.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_interceptors_ioctl_netbsd.inc @@ -24,7 +24,7 @@ struct ioctl_desc { const char *name; }; -const unsigned ioctl_table_max = 1236; +const unsigned ioctl_table_max = 1238; static ioctl_desc ioctl_table[ioctl_table_max]; static unsigned ioctl_table_size = 0; @@ -166,9 +166,6 @@ static void ioctl_table_fill() { _(FE_ENABLE_HIGH_LNB_VOLTAGE, READ, sizeof(int)); _(FE_SET_FRONTEND_TUNE_MODE, READ, sizeof(unsigned int)); _(FE_DISHNETWORK_SEND_LEGACY_CMD, READ, sizeof(unsigned long)); - /* Entries from file: dev/filemon/filemon.h */ - _(FILEMON_SET_FD, READWRITE, sizeof(int)); - _(FILEMON_SET_PID, READWRITE, sizeof(int)); /* Entries from file: dev/hdaudio/hdaudioio.h */ _(HDAUDIO_FGRP_INFO, READWRITE, struct_plistref_sz); _(HDAUDIO_FGRP_GETCONFIG, READWRITE, struct_plistref_sz); @@ -653,6 +650,7 @@ static void ioctl_table_fill() { _(NVMM_IOC_MACHINE_CONFIGURE, READ, struct_nvmm_ioc_machine_configure_sz); _(NVMM_IOC_VCPU_CREATE, READ, struct_nvmm_ioc_vcpu_create_sz); _(NVMM_IOC_VCPU_DESTROY, READ, struct_nvmm_ioc_vcpu_destroy_sz); + _(NVMM_IOC_VCPU_CONFIGURE, READ, struct_nvmm_ioc_vcpu_configure_sz); _(NVMM_IOC_VCPU_SETSTATE, READ, struct_nvmm_ioc_vcpu_setstate_sz); _(NVMM_IOC_VCPU_GETSTATE, READ, struct_nvmm_ioc_vcpu_getstate_sz); _(NVMM_IOC_VCPU_INJECT, READ, struct_nvmm_ioc_vcpu_inject_sz); @@ -735,6 +733,7 @@ static void ioctl_table_fill() { _(IOC_NPF_SAVE, WRITE, struct_nvlist_ref_sz); _(IOC_NPF_RULE, READWRITE, struct_nvlist_ref_sz); _(IOC_NPF_CONN_LOOKUP, READWRITE, struct_nvlist_ref_sz); + _(IOC_NPF_TABLE_REPLACE, READWRITE, struct_nvlist_ref_sz); /* Entries from file: net/if_pppoe.h */ _(PPPOESETPARMS, READ, struct_pppoediscparms_sz); _(PPPOEGETPARMS, READWRITE, struct_pppoediscparms_sz); @@ -1403,8 +1402,11 @@ static void ioctl_table_fill() { _(SNDCTL_DSP_SETRECVOL, READ, sizeof(unsigned int)); _(SNDCTL_DSP_SKIP, NONE, 0); _(SNDCTL_DSP_SILENCE, NONE, 0); + /* Entries from file: dev/filemon/filemon.h (compat <= 9.99.26) */ + _(FILEMON_SET_FD, READWRITE, sizeof(int)); + _(FILEMON_SET_PID, READWRITE, sizeof(int)); #undef _ -} // NOLINT +} // NOLINT static bool ioctl_initialized = false; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_internal_defs.h b/compiler-rt/lib/sanitizer_common/sanitizer_internal_defs.h index 00226305e07c..d0ffc79b0610 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_internal_defs.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_internal_defs.h @@ -105,7 +105,7 @@ // FIXME: do we have anything like this on Mac? #ifndef SANITIZER_CAN_USE_PREINIT_ARRAY #if ((SANITIZER_LINUX && !SANITIZER_ANDROID) || SANITIZER_OPENBSD || \ - SANITIZER_FUCHSIA) && !defined(PIC) + SANITIZER_FUCHSIA || SANITIZER_NETBSD) && !defined(PIC) #define SANITIZER_CAN_USE_PREINIT_ARRAY 1 // Before Solaris 11.4, .preinit_array is fully supported only with GNU ld. // FIXME: Check for those conditions. diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp index 0b53da6c349f..84453f1bd300 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp @@ -166,7 +166,7 @@ namespace __sanitizer { #if !SANITIZER_SOLARIS && !SANITIZER_NETBSD #if !SANITIZER_S390 && !SANITIZER_OPENBSD uptr internal_mmap(void *addr, uptr length, int prot, int flags, int fd, - OFF_T offset) { + u64 offset) { #if SANITIZER_FREEBSD || SANITIZER_LINUX_USES_64BIT_SYSCALLS return internal_syscall(SYSCALL(mmap), (uptr)addr, length, prot, flags, fd, offset); @@ -407,7 +407,10 @@ uptr internal_unlink(const char *path) { } uptr internal_rename(const char *oldpath, const char *newpath) { -#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS || SANITIZER_OPENBSD +#if defined(__riscv) + return internal_syscall(SYSCALL(renameat2), AT_FDCWD, (uptr)oldpath, AT_FDCWD, + (uptr)newpath, 0); +#elif SANITIZER_USES_CANONICAL_LINUX_SYSCALLS || SANITIZER_OPENBSD return internal_syscall(SYSCALL(renameat), AT_FDCWD, (uptr)oldpath, AT_FDCWD, (uptr)newpath); #else @@ -1972,6 +1975,11 @@ static void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) { # endif *bp = ucontext->uc_mcontext.gregs[11]; *sp = ucontext->uc_mcontext.gregs[15]; +#elif defined(__riscv) + ucontext_t *ucontext = (ucontext_t*)context; + *pc = ucontext->uc_mcontext.__gregs[REG_PC]; + *bp = ucontext->uc_mcontext.__gregs[REG_S0]; + *sp = ucontext->uc_mcontext.__gregs[REG_SP]; #else # error "Unsupported arch" #endif diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp index cd503718205a..edbe8402808a 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp @@ -50,6 +50,7 @@ #if SANITIZER_NETBSD #include <sys/sysctl.h> #include <sys/tls.h> +#include <lwp.h> #endif #if SANITIZER_SOLARIS @@ -399,13 +400,7 @@ uptr ThreadSelf() { #if SANITIZER_NETBSD static struct tls_tcb * ThreadSelfTlsTcb() { - struct tls_tcb * tcb; -# ifdef __HAVE___LWP_GETTCB_FAST - tcb = (struct tls_tcb *)__lwp_gettcb_fast(); -# elif defined(__HAVE___LWP_GETPRIVATE_FAST) - tcb = (struct tls_tcb *)__lwp_getprivate_fast(); -# endif - return tcb; + return (struct tls_tcb *)_lwp_getprivate(); } uptr ThreadSelf() { diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux_s390.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux_s390.cpp index 41e187eaf8da..9e3b4f13a436 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux_s390.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux_s390.cpp @@ -27,7 +27,7 @@ namespace __sanitizer { // --------------- sanitizer_libc.h uptr internal_mmap(void *addr, uptr length, int prot, int flags, int fd, - OFF_T offset) { + u64 offset) { struct s390_mmap_params { unsigned long addr; unsigned long length; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_netbsd.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_netbsd.cpp index 4e74f6a3b516..49a951e04b37 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_netbsd.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_netbsd.cpp @@ -95,7 +95,7 @@ static void *GetRealLibcAddress(const char *symbol) { // --------------- sanitizer_libc.h uptr internal_mmap(void *addr, uptr length, int prot, int flags, int fd, - OFF_T offset) { + u64 offset) { CHECK(&__mmap); return (uptr)__mmap(addr, length, prot, flags, fd, 0, offset); } diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform.h index b45c975358db..c68bfa258755 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform.h @@ -255,11 +255,11 @@ #define SANITIZER_SIGN_EXTENDED_ADDRESSES 0 #endif -// The AArch64 linux port uses the canonical syscall set as mandated by -// the upstream linux community for all new ports. Other ports may still -// use legacy syscalls. +// The AArch64 and RISC-V linux ports use the canonical syscall set as +// mandated by the upstream linux community for all new ports. Other ports +// may still use legacy syscalls. #ifndef SANITIZER_USES_CANONICAL_LINUX_SYSCALLS -# if defined(__aarch64__) && SANITIZER_LINUX +# if (defined(__aarch64__) || defined(__riscv)) && SANITIZER_LINUX # define SANITIZER_USES_CANONICAL_LINUX_SYSCALLS 1 # else # define SANITIZER_USES_CANONICAL_LINUX_SYSCALLS 0 diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h index 61a6b82ef818..4cc69af1241d 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h @@ -90,6 +90,24 @@ # define SI_IOS 0 #endif +#if SANITIZER_IOSSIM +# define SI_IOSSIM 1 +#else +# define SI_IOSSIM 0 +#endif + +#if SANITIZER_WATCHOS +# define SI_WATCHOS 1 +#else +# define SI_WATCHOS 0 +#endif + +#if SANITIZER_TVOS +# define SI_TVOS 1 +#else +# define SI_TVOS 0 +#endif + #if SANITIZER_FUCHSIA # define SI_NOT_FUCHSIA 0 #else @@ -575,5 +593,8 @@ #define SANITIZER_INTERCEPT_ATEXIT SI_NETBSD #define SANITIZER_INTERCEPT_PTHREAD_ATFORK SI_NETBSD #define SANITIZER_INTERCEPT_GETENTROPY SI_FREEBSD +#define SANITIZER_INTERCEPT_QSORT \ + (SI_POSIX && !SI_IOSSIM && !SI_WATCHOS && !SI_TVOS) +#define SANITIZER_INTERCEPT_QSORT_R (SI_LINUX && !SI_ANDROID) #endif // #ifndef SANITIZER_PLATFORM_INTERCEPTORS_H diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_linux.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_linux.cpp index 842bc789f479..c51327e1269e 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_linux.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_linux.cpp @@ -65,7 +65,7 @@ namespace __sanitizer { #if !defined(__powerpc64__) && !defined(__x86_64__) && !defined(__aarch64__)\ && !defined(__mips__) && !defined(__s390__)\ - && !defined(__sparc__) + && !defined(__sparc__) && !defined(__riscv) COMPILER_CHECK(struct___old_kernel_stat_sz == sizeof(struct __old_kernel_stat)); #endif diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_netbsd.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_netbsd.cpp index f01de6c995e6..48a78c8998a2 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_netbsd.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_netbsd.cpp @@ -17,6 +17,7 @@ #define _KMEMUSER #define RAY_DO_SIGLEV +#define __LEGACY_PT_LWPINFO // clang-format off #include <sys/param.h> @@ -71,6 +72,15 @@ #include <sys/msg.h> #include <sys/mtio.h> #include <sys/ptrace.h> + +// Compat for NetBSD < 9.99.30. +#ifndef PT_LWPSTATUS +#define PT_LWPSTATUS 24 +#endif +#ifndef PT_LWPNEXT +#define PT_LWPNEXT 25 +#endif + #include <sys/resource.h> #include <sys/sem.h> #include <sys/sha1.h> @@ -109,7 +119,12 @@ #include <dev/dmover/dmover_io.h> #include <dev/dtv/dtvio_demux.h> #include <dev/dtv/dtvio_frontend.h> +#if !__NetBSD_Prereq__(9, 99, 26) #include <dev/filemon/filemon.h> +#else +#define FILEMON_SET_FD _IOWR('S', 1, int) +#define FILEMON_SET_PID _IOWR('S', 2, pid_t) +#endif #include <dev/hdaudio/hdaudioio.h> #include <dev/hdmicec/hdmicecio.h> #include <dev/hpc/hpcfbio.h> @@ -287,6 +302,8 @@ int ptrace_pt_get_event_mask = PT_GET_EVENT_MASK; int ptrace_pt_get_process_state = PT_GET_PROCESS_STATE; int ptrace_pt_set_siginfo = PT_SET_SIGINFO; int ptrace_pt_get_siginfo = PT_GET_SIGINFO; +int ptrace_pt_lwpstatus = PT_LWPSTATUS; +int ptrace_pt_lwpnext = PT_LWPNEXT; int ptrace_piod_read_d = PIOD_READ_D; int ptrace_piod_write_d = PIOD_WRITE_D; int ptrace_piod_read_i = PIOD_READ_I; @@ -319,6 +336,8 @@ int ptrace_pt_getdbregs = -1; unsigned struct_ptrace_ptrace_io_desc_struct_sz = sizeof(struct ptrace_io_desc); unsigned struct_ptrace_ptrace_lwpinfo_struct_sz = sizeof(struct ptrace_lwpinfo); +unsigned struct_ptrace_ptrace_lwpstatus_struct_sz = + sizeof(struct __sanitizer_ptrace_lwpstatus); unsigned struct_ptrace_ptrace_event_struct_sz = sizeof(ptrace_event_t); unsigned struct_ptrace_ptrace_siginfo_struct_sz = sizeof(ptrace_siginfo_t); @@ -698,6 +717,7 @@ unsigned struct_nvmm_ioc_machine_configure_sz = sizeof(nvmm_ioc_machine_configure); unsigned struct_nvmm_ioc_vcpu_create_sz = sizeof(nvmm_ioc_vcpu_create); unsigned struct_nvmm_ioc_vcpu_destroy_sz = sizeof(nvmm_ioc_vcpu_destroy); +unsigned struct_nvmm_ioc_vcpu_configure_sz = sizeof(nvmm_ioc_vcpu_configure); unsigned struct_nvmm_ioc_vcpu_setstate_sz = sizeof(nvmm_ioc_vcpu_destroy); unsigned struct_nvmm_ioc_vcpu_getstate_sz = sizeof(nvmm_ioc_vcpu_getstate); unsigned struct_nvmm_ioc_vcpu_inject_sz = sizeof(nvmm_ioc_vcpu_inject); @@ -1458,6 +1478,7 @@ unsigned IOCTL_NVMM_IOC_MACHINE_DESTROY = NVMM_IOC_MACHINE_DESTROY; unsigned IOCTL_NVMM_IOC_MACHINE_CONFIGURE = NVMM_IOC_MACHINE_CONFIGURE; unsigned IOCTL_NVMM_IOC_VCPU_CREATE = NVMM_IOC_VCPU_CREATE; unsigned IOCTL_NVMM_IOC_VCPU_DESTROY = NVMM_IOC_VCPU_DESTROY; +unsigned IOCTL_NVMM_IOC_VCPU_CONFIGURE = NVMM_IOC_VCPU_CONFIGURE; unsigned IOCTL_NVMM_IOC_VCPU_SETSTATE = NVMM_IOC_VCPU_SETSTATE; unsigned IOCTL_NVMM_IOC_VCPU_GETSTATE = NVMM_IOC_VCPU_GETSTATE; unsigned IOCTL_NVMM_IOC_VCPU_INJECT = NVMM_IOC_VCPU_INJECT; @@ -1534,6 +1555,7 @@ unsigned IOCTL_IOC_NPF_STATS = IOC_NPF_STATS; unsigned IOCTL_IOC_NPF_SAVE = IOC_NPF_SAVE; unsigned IOCTL_IOC_NPF_RULE = IOC_NPF_RULE; unsigned IOCTL_IOC_NPF_CONN_LOOKUP = IOC_NPF_CONN_LOOKUP; +unsigned IOCTL_IOC_NPF_TABLE_REPLACE = IOC_NPF_TABLE_REPLACE; unsigned IOCTL_PPPOESETPARMS = PPPOESETPARMS; unsigned IOCTL_PPPOEGETPARMS = PPPOEGETPARMS; unsigned IOCTL_PPPOEGETSESSION = PPPOEGETSESSION; @@ -2392,4 +2414,42 @@ CHECK_SIZE_AND_OFFSET(modctl_load_t, ml_flags); CHECK_SIZE_AND_OFFSET(modctl_load_t, ml_props); CHECK_SIZE_AND_OFFSET(modctl_load_t, ml_propslen); +// Compat with 9.0 +struct statvfs90 { + unsigned long f_flag; + unsigned long f_bsize; + unsigned long f_frsize; + unsigned long f_iosize; + + u64 f_blocks; + u64 f_bfree; + u64 f_bavail; + u64 f_bresvd; + + u64 f_files; + u64 f_ffree; + u64 f_favail; + u64 f_fresvd; + + u64 f_syncreads; + u64 f_syncwrites; + + u64 f_asyncreads; + u64 f_asyncwrites; + + struct { + s32 __fsid_val[2]; + } f_fsidx; + unsigned long f_fsid; + unsigned long f_namemax; + u32 f_owner; + + u32 f_spare[4]; + + char f_fstypename[32]; + char f_mntonname[32]; + char f_mntfromname[32]; +}; +unsigned struct_statvfs90_sz = sizeof(struct statvfs90); + #endif // SANITIZER_NETBSD diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_netbsd.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_netbsd.h index 4fb3b8c0e06f..794efdb6eff6 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_netbsd.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_netbsd.h @@ -354,7 +354,13 @@ struct __sanitizer_addrinfo { int ai_family; int ai_socktype; int ai_protocol; +#if defined(__sparc__) && defined(_LP64) + int __ai_pad0; +#endif unsigned ai_addrlen; +#if defined(__alpha__) || (defined(__i386__) && defined(_LP64)) + int __ai_pad0; +#endif char *ai_canonname; void *ai_addr; struct __sanitizer_addrinfo *ai_next; @@ -406,6 +412,8 @@ extern int ptrace_pt_get_event_mask; extern int ptrace_pt_get_process_state; extern int ptrace_pt_set_siginfo; extern int ptrace_pt_get_siginfo; +extern int ptrace_pt_lwpstatus; +extern int ptrace_pt_lwpnext; extern int ptrace_piod_read_d; extern int ptrace_piod_write_d; extern int ptrace_piod_read_i; @@ -430,8 +438,17 @@ struct __sanitizer_ptrace_lwpinfo { int pl_event; }; +struct __sanitizer_ptrace_lwpstatus { + __sanitizer_lwpid_t pl_lwpid; + __sanitizer_sigset_t pl_sigpend; + __sanitizer_sigset_t pl_sigmask; + char pl_name[20]; + void *pl_private; +}; + extern unsigned struct_ptrace_ptrace_io_desc_struct_sz; extern unsigned struct_ptrace_ptrace_lwpinfo_struct_sz; +extern unsigned struct_ptrace_ptrace_lwpstatus_struct_sz; extern unsigned struct_ptrace_ptrace_event_struct_sz; extern unsigned struct_ptrace_ptrace_siginfo_struct_sz; @@ -856,6 +873,7 @@ extern unsigned struct_nvmm_ioc_machine_destroy_sz; extern unsigned struct_nvmm_ioc_machine_configure_sz; extern unsigned struct_nvmm_ioc_vcpu_create_sz; extern unsigned struct_nvmm_ioc_vcpu_destroy_sz; +extern unsigned struct_nvmm_ioc_vcpu_configure_sz; extern unsigned struct_nvmm_ioc_vcpu_setstate_sz; extern unsigned struct_nvmm_ioc_vcpu_getstate_sz; extern unsigned struct_nvmm_ioc_vcpu_inject_sz; @@ -1605,6 +1623,7 @@ extern unsigned IOCTL_NVMM_IOC_MACHINE_DESTROY; extern unsigned IOCTL_NVMM_IOC_MACHINE_CONFIGURE; extern unsigned IOCTL_NVMM_IOC_VCPU_CREATE; extern unsigned IOCTL_NVMM_IOC_VCPU_DESTROY; +extern unsigned IOCTL_NVMM_IOC_VCPU_CONFIGURE; extern unsigned IOCTL_NVMM_IOC_VCPU_SETSTATE; extern unsigned IOCTL_NVMM_IOC_VCPU_GETSTATE; extern unsigned IOCTL_NVMM_IOC_VCPU_INJECT; @@ -1679,6 +1698,7 @@ extern unsigned IOCTL_IOC_NPF_STATS; extern unsigned IOCTL_IOC_NPF_SAVE; extern unsigned IOCTL_IOC_NPF_RULE; extern unsigned IOCTL_IOC_NPF_CONN_LOOKUP; +extern unsigned IOCTL_IOC_NPF_TABLE_REPLACE; extern unsigned IOCTL_PPPOESETPARMS; extern unsigned IOCTL_PPPOEGETPARMS; extern unsigned IOCTL_PPPOEGETSESSION; @@ -2400,6 +2420,9 @@ struct __sanitizer_cdbw { #define SIGACTION_SYMNAME __sigaction14 +// Compat with 9.0 +extern unsigned struct_statvfs90_sz; + #endif // SANITIZER_NETBSD #endif diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp index 9852e6ba7879..aa845df4dde4 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp @@ -230,7 +230,7 @@ namespace __sanitizer { // has been removed from glibc 2.28. #if defined(__aarch64__) || defined(__s390x__) || defined (__mips64) \ || defined(__powerpc64__) || defined(__arch64__) || defined(__sparcv9) \ - || defined(__x86_64__) + || defined(__x86_64__) || (defined(__riscv) && __riscv_xlen == 64) #define SIZEOF_STRUCT_USTAT 32 #elif defined(__arm__) || defined(__i386__) || defined(__mips__) \ || defined(__powerpc__) || defined(__s390__) || defined(__sparc__) @@ -1128,11 +1128,9 @@ CHECK_SIZE_AND_OFFSET(ipc_perm, uid); CHECK_SIZE_AND_OFFSET(ipc_perm, gid); CHECK_SIZE_AND_OFFSET(ipc_perm, cuid); CHECK_SIZE_AND_OFFSET(ipc_perm, cgid); -#if (!defined(__aarch64__) || !SANITIZER_LINUX || __GLIBC_PREREQ (2, 21)) && \ - !defined(__arm__) -/* On aarch64 glibc 2.20 and earlier provided incorrect mode field. */ -/* On Arm newer glibc provide a different mode field, it's hard to detect - so just disable the check. */ +#if !SANITIZER_LINUX || __GLIBC_PREREQ (2, 31) +/* glibc 2.30 and earlier provided 16-bit mode field instead of 32-bit + on many architectures. */ CHECK_SIZE_AND_OFFSET(ipc_perm, mode); #endif diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h index db2c4f07b3ae..5337b26b29b8 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h @@ -98,6 +98,9 @@ const unsigned struct_kernel_stat64_sz = 144; const unsigned struct___old_kernel_stat_sz = 0; const unsigned struct_kernel_stat_sz = 64; const unsigned struct_kernel_stat64_sz = 104; +#elif defined(__riscv) && __riscv_xlen == 64 +const unsigned struct_kernel_stat_sz = 128; +const unsigned struct_kernel_stat64_sz = 104; #endif struct __sanitizer_perf_event_attr { unsigned type; @@ -204,26 +207,13 @@ struct __sanitizer_ipc_perm { u64 __unused1; u64 __unused2; #elif defined(__sparc__) -#if defined(__arch64__) unsigned mode; - unsigned short __pad1; -#else - unsigned short __pad1; - unsigned short mode; unsigned short __pad2; -#endif unsigned short __seq; unsigned long long __unused1; unsigned long long __unused2; -#elif defined(__mips__) || defined(__aarch64__) || defined(__s390x__) - unsigned int mode; - unsigned short __seq; - unsigned short __pad1; - unsigned long __unused1; - unsigned long __unused2; #else - unsigned short mode; - unsigned short __pad1; + unsigned int mode; unsigned short __seq; unsigned short __pad2; #if defined(__x86_64__) && !defined(_LP64) diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_posix.h b/compiler-rt/lib/sanitizer_common/sanitizer_posix.h index 05fb0f630207..70c71f04d2d3 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_posix.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_posix.h @@ -39,7 +39,7 @@ uptr internal_write(fd_t fd, const void *buf, uptr count); // Memory uptr internal_mmap(void *addr, uptr length, int prot, int flags, - int fd, OFF_T offset); + int fd, u64 offset); uptr internal_munmap(void *addr, uptr length); int internal_mprotect(void *addr, uptr length, int prot); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_netbsd_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_netbsd_libcdep.cpp index 5690d75097f9..1ed21343254d 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_netbsd_libcdep.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_netbsd_libcdep.cpp @@ -120,10 +120,18 @@ bool ThreadSuspender::SuspendAllThreads() { VReport(2, "Attached to process %d.\n", pid_); +#ifdef PT_LWPNEXT + struct ptrace_lwpstatus pl; + int op = PT_LWPNEXT; +#else struct ptrace_lwpinfo pl; - int val; + int op = PT_LWPINFO; +#endif + pl.pl_lwpid = 0; - while ((val = ptrace(PT_LWPINFO, pid_, (void *)&pl, sizeof(pl))) != -1 && + + int val; + while ((val = ptrace(op, pid_, (void *)&pl, sizeof(pl))) != -1 && pl.pl_lwpid != 0) { suspended_threads_list_.Append(pl.pl_lwpid); VReport(2, "Appended thread %d in process %d.\n", pl.pl_lwpid, pid_); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_mac.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_mac.cpp index a619ed092f0b..f26efe5c50b5 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_mac.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_mac.cpp @@ -31,6 +31,9 @@ bool DlAddrSymbolizer::SymbolizePC(uptr addr, SymbolizedStack *stack) { Dl_info info; int result = dladdr((const void *)addr, &info); if (!result) return false; + + CHECK(addr >= reinterpret_cast<uptr>(info.dli_saddr)); + stack->info.function_offset = addr - reinterpret_cast<uptr>(info.dli_saddr); const char *demangled = DemangleSwiftAndCXX(info.dli_sname); if (!demangled) return false; stack->info.function = internal_strdup(demangled); @@ -145,12 +148,29 @@ bool AtosSymbolizer::SymbolizePC(uptr addr, SymbolizedStack *stack) { const char *buf = process_->SendCommand(command); if (!buf) return false; uptr line; + uptr start_address = AddressInfo::kUnknown; if (!ParseCommandOutput(buf, addr, &stack->info.function, &stack->info.module, - &stack->info.file, &line, nullptr)) { + &stack->info.file, &line, &start_address)) { process_ = nullptr; return false; } stack->info.line = (int)line; + + if (start_address == AddressInfo::kUnknown) { + // Fallback to dladdr() to get function start address if atos doesn't report + // it. + Dl_info info; + int result = dladdr((const void *)addr, &info); + if (result) + start_address = reinterpret_cast<uptr>(info.dli_saddr); + } + + // Only assig to `function_offset` if we were able to get the function's + // start address. + if (start_address != AddressInfo::kUnknown) { + CHECK(addr >= start_address); + stack->info.function_offset = addr - start_address; + } return true; } diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_syscalls_netbsd.inc b/compiler-rt/lib/sanitizer_common/sanitizer_syscalls_netbsd.inc index 21b521669630..02b7e11b1677 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_syscalls_netbsd.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_syscalls_netbsd.inc @@ -42,8 +42,8 @@ // DO NOT EDIT! THIS FILE HAS BEEN GENERATED! // // Generated with: generate_netbsd_syscalls.awk -// Generated date: 2018-10-30 -// Generated from: syscalls.master,v 1.293 2018/07/31 13:00:13 rjs Exp +// Generated date: 2019-12-24 +// Generated from: syscalls.master,v 1.296 2019/09/22 22:59:39 christos Exp // //===----------------------------------------------------------------------===// @@ -323,6 +323,16 @@ PRE_SYSCALL(ptrace) PRE_READ(addr_, struct_ptrace_ptrace_siginfo_struct_sz); } else if (req_ == ptrace_pt_get_siginfo) { PRE_WRITE(addr_, struct_ptrace_ptrace_siginfo_struct_sz); + } else if (req_ == ptrace_pt_lwpstatus) { + struct __sanitizer_ptrace_lwpstatus *addr = + (struct __sanitizer_ptrace_lwpstatus *)addr_; + PRE_READ(&addr->pl_lwpid, sizeof(__sanitizer_lwpid_t)); + PRE_WRITE(addr, struct_ptrace_ptrace_lwpstatus_struct_sz); + } else if (req_ == ptrace_pt_lwpnext) { + struct __sanitizer_ptrace_lwpstatus *addr = + (struct __sanitizer_ptrace_lwpstatus *)addr_; + PRE_READ(&addr->pl_lwpid, sizeof(__sanitizer_lwpid_t)); + PRE_WRITE(addr, struct_ptrace_ptrace_lwpstatus_struct_sz); } else if (req_ == ptrace_pt_setregs) { PRE_READ(addr_, struct_ptrace_reg_struct_sz); } else if (req_ == ptrace_pt_getregs) { @@ -366,6 +376,16 @@ POST_SYSCALL(ptrace) POST_READ(addr_, struct_ptrace_ptrace_siginfo_struct_sz); } else if (req_ == ptrace_pt_get_siginfo) { POST_WRITE(addr_, struct_ptrace_ptrace_siginfo_struct_sz); + } else if (req_ == ptrace_pt_lwpstatus) { + struct __sanitizer_ptrace_lwpstatus *addr = + (struct __sanitizer_ptrace_lwpstatus *)addr_; + POST_READ(&addr->pl_lwpid, sizeof(__sanitizer_lwpid_t)); + POST_WRITE(addr, struct_ptrace_ptrace_lwpstatus_struct_sz); + } else if (req_ == ptrace_pt_lwpnext) { + struct __sanitizer_ptrace_lwpstatus *addr = + (struct __sanitizer_ptrace_lwpstatus *)addr_; + POST_READ(&addr->pl_lwpid, sizeof(__sanitizer_lwpid_t)); + POST_WRITE(addr, struct_ptrace_ptrace_lwpstatus_struct_sz); } else if (req_ == ptrace_pt_setregs) { POST_READ(addr_, struct_ptrace_reg_struct_sz); } else if (req_ == ptrace_pt_getregs) { @@ -2433,30 +2453,31 @@ PRE_SYSCALL(uuidgen)(void *store_, long long count_) { /* Nothing to do */ } POST_SYSCALL(uuidgen)(long long res, void *store_, long long count_) { /* Nothing to do */ } -PRE_SYSCALL(getvfsstat)(void *buf_, long long bufsize_, long long flags_) { +PRE_SYSCALL(compat_90_getvfsstat) +(void *buf_, long long bufsize_, long long flags_) { /* Nothing to do */ } -POST_SYSCALL(getvfsstat) +POST_SYSCALL(compat_90_getvfsstat) (long long res, void *buf_, long long bufsize_, long long flags_) { /* Nothing to do */ } -PRE_SYSCALL(statvfs1)(void *path_, void *buf_, long long flags_) { +PRE_SYSCALL(compat_90_statvfs1)(void *path_, void *buf_, long long flags_) { const char *path = (const char *)path_; if (path) { PRE_READ(path, __sanitizer::internal_strlen(path) + 1); } } -POST_SYSCALL(statvfs1) +POST_SYSCALL(compat_90_statvfs1) (long long res, void *path_, void *buf_, long long flags_) { const char *path = (const char *)path_; if (path) { POST_READ(path, __sanitizer::internal_strlen(path) + 1); } } -PRE_SYSCALL(fstatvfs1)(long long fd_, void *buf_, long long flags_) { +PRE_SYSCALL(compat_90_fstatvfs1)(long long fd_, void *buf_, long long flags_) { /* Nothing to do */ } -POST_SYSCALL(fstatvfs1) +POST_SYSCALL(compat_90_fstatvfs1) (long long res, long long fd_, void *buf_, long long flags_) { /* Nothing to do */ } @@ -2853,13 +2874,13 @@ PRE_SYSCALL(__fhopen40)(void *fhp_, long long fh_size_, long long flags_) { } POST_SYSCALL(__fhopen40) (long long res, void *fhp_, long long fh_size_, long long flags_) {} -PRE_SYSCALL(__fhstatvfs140) +PRE_SYSCALL(compat_90_fhstatvfs1) (void *fhp_, long long fh_size_, void *buf_, long long flags_) { if (fhp_) { PRE_READ(fhp_, fh_size_); } } -POST_SYSCALL(__fhstatvfs140) +POST_SYSCALL(compat_90_fhstatvfs1) (long long res, void *fhp_, long long fh_size_, void *buf_, long long flags_) {} PRE_SYSCALL(compat_50___fhstat40)(void *fhp_, long long fh_size_, void *sb_) { if (fhp_) { @@ -3768,6 +3789,41 @@ POST_SYSCALL(clock_getcpuclockid2) (long long res, long long idtype_, long long id_, void *clock_id_) { /* Nothing to do */ } +PRE_SYSCALL(__getvfsstat90)(void *buf_, long long bufsize_, long long flags_) { + /* Nothing to do */ +} +POST_SYSCALL(__getvfsstat90) +(long long res, void *buf_, long long bufsize_, long long flags_) { + /* Nothing to do */ +} +PRE_SYSCALL(__statvfs190)(void *path_, void *buf_, long long flags_) { + const char *path = (const char *)path_; + if (path) { + PRE_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +POST_SYSCALL(__statvfs190) +(long long res, void *path_, void *buf_, long long flags_) { + const char *path = (const char *)path_; + if (path) { + POST_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +PRE_SYSCALL(__fstatvfs190)(long long fd_, void *buf_, long long flags_) { + /* Nothing to do */ +} +POST_SYSCALL(__fstatvfs190) +(long long res, long long fd_, void *buf_, long long flags_) { + /* Nothing to do */ +} +PRE_SYSCALL(__fhstatvfs190) +(void *fhp_, long long fh_size_, void *buf_, long long flags_) { + if (fhp_) { + PRE_READ(fhp_, fh_size_); + } +} +POST_SYSCALL(__fhstatvfs190) +(long long res, void *fhp_, long long fh_size_, void *buf_, long long flags_) {} #undef SYS_MAXSYSARGS } // extern "C" diff --git a/compiler-rt/lib/sanitizer_common/symbolizer/sanitizer_wrappers.cpp b/compiler-rt/lib/sanitizer_common/symbolizer/sanitizer_wrappers.cpp index ac351d3a8362..d3c59e357d46 100644 --- a/compiler-rt/lib/sanitizer_common/symbolizer/sanitizer_wrappers.cpp +++ b/compiler-rt/lib/sanitizer_common/symbolizer/sanitizer_wrappers.cpp @@ -19,13 +19,6 @@ #include <tuple> -// Need to match ../sanitizer_common/sanitizer_internal_defs.h -#if defined(ARCH_PPC) -#define OFF_T unsigned long -#else -#define OFF_T unsigned long long -#endif - namespace __sanitizer { unsigned long internal_open(const char *filename, int flags); unsigned long internal_open(const char *filename, int flags, unsigned mode); @@ -35,7 +28,7 @@ unsigned long internal_lstat(const char *path, void *buf); unsigned long internal_fstat(int fd, void *buf); size_t internal_strlen(const char *s); unsigned long internal_mmap(void *addr, unsigned long length, int prot, - int flags, int fd, OFF_T offset); + int flags, int fd, unsigned long long offset); void *internal_memcpy(void *dest, const void *src, unsigned long n); // Used to propagate errno. bool internal_iserror(unsigned long retval, int *rverrno = 0); |