diff options
Diffstat (limited to 'libsanitizer/sanitizer_common')
63 files changed, 2287 insertions, 1612 deletions
diff --git a/libsanitizer/sanitizer_common/sancov_flags.inc b/libsanitizer/sanitizer_common/sancov_flags.inc index cca33fc..de9ede2 100644 --- a/libsanitizer/sanitizer_common/sancov_flags.inc +++ b/libsanitizer/sanitizer_common/sancov_flags.inc @@ -14,7 +14,7 @@ #endif SANCOV_FLAG(bool, symbolize, true, - "If set, converage information will be symbolized by sancov tool " + "If set, coverage information will be symbolized by sancov tool " "after dumping.") SANCOV_FLAG(bool, help, false, "Print flags help.") diff --git a/libsanitizer/sanitizer_common/sanitizer_addrhashmap.h b/libsanitizer/sanitizer_common/sanitizer_addrhashmap.h index 15f81a0..73b48cb 100644 --- a/libsanitizer/sanitizer_common/sanitizer_addrhashmap.h +++ b/libsanitizer/sanitizer_common/sanitizer_addrhashmap.h @@ -56,7 +56,7 @@ class AddrHashMap { static const uptr kBucketSize = 3; struct Bucket { - RWMutex mtx; + Mutex mtx; atomic_uintptr_t add; Cell cells[kBucketSize]; }; diff --git a/libsanitizer/sanitizer_common/sanitizer_allocator_primary64.h b/libsanitizer/sanitizer_common/sanitizer_allocator_primary64.h index b142ee0..3710947 100644 --- a/libsanitizer/sanitizer_common/sanitizer_allocator_primary64.h +++ b/libsanitizer/sanitizer_common/sanitizer_allocator_primary64.h @@ -161,7 +161,7 @@ class SizeClassAllocator64 { void ForceReleaseToOS() { MemoryMapperT memory_mapper(*this); for (uptr class_id = 1; class_id < kNumClasses; class_id++) { - BlockingMutexLock l(&GetRegionInfo(class_id)->mutex); + Lock l(&GetRegionInfo(class_id)->mutex); MaybeReleaseToOS(&memory_mapper, class_id, true /*force*/); } } @@ -178,7 +178,7 @@ class SizeClassAllocator64 { uptr region_beg = GetRegionBeginBySizeClass(class_id); CompactPtrT *free_array = GetFreeArray(region_beg); - BlockingMutexLock l(®ion->mutex); + Lock l(®ion->mutex); uptr old_num_chunks = region->num_freed_chunks; uptr new_num_freed_chunks = old_num_chunks + n_chunks; // Failure to allocate free array space while releasing memory is non @@ -204,7 +204,7 @@ class SizeClassAllocator64 { uptr region_beg = GetRegionBeginBySizeClass(class_id); CompactPtrT *free_array = GetFreeArray(region_beg); - BlockingMutexLock l(®ion->mutex); + Lock l(®ion->mutex); #if SANITIZER_WINDOWS /* On Windows unmapping of memory during __sanitizer_purge_allocator is explicit and immediate, so unmapped regions must be explicitly mapped back @@ -282,6 +282,8 @@ class SizeClassAllocator64 { CHECK(kMetadataSize); uptr class_id = GetSizeClass(p); uptr size = ClassIdToSize(class_id); + if (!size) + return nullptr; uptr chunk_idx = GetChunkIdx(reinterpret_cast<uptr>(p), size); uptr region_beg = GetRegionBeginBySizeClass(class_id); return reinterpret_cast<void *>(GetMetadataEnd(region_beg) - @@ -315,7 +317,7 @@ class SizeClassAllocator64 { Printf( "%s %02zd (%6zd): mapped: %6zdK allocs: %7zd frees: %7zd inuse: %6zd " "num_freed_chunks %7zd avail: %6zd rss: %6zdK releases: %6zd " - "last released: %6zdK region: 0x%zx\n", + "last released: %6lldK region: 0x%zx\n", region->exhausted ? "F" : " ", class_id, ClassIdToSize(class_id), region->mapped_user >> 10, region->stats.n_allocated, region->stats.n_freed, in_use, region->num_freed_chunks, avail_chunks, @@ -623,7 +625,7 @@ class SizeClassAllocator64 { static const uptr kRegionSize = kSpaceSize / kNumClassesRounded; // FreeArray is the array of free-d chunks (stored as 4-byte offsets). - // In the worst case it may reguire kRegionSize/SizeClassMap::kMinSize + // In the worst case it may require kRegionSize/SizeClassMap::kMinSize // elements, but in reality this will not happen. For simplicity we // dedicate 1/8 of the region's virtual space to FreeArray. static const uptr kFreeArraySize = kRegionSize / 8; @@ -665,7 +667,7 @@ class SizeClassAllocator64 { }; struct ALIGNED(SANITIZER_CACHE_LINE_SIZE) RegionInfo { - BlockingMutex mutex; + Mutex mutex; uptr num_freed_chunks; // Number of elements in the freearray. uptr mapped_free_array; // Bytes mapped for freearray. uptr allocated_user; // Bytes allocated for user memory. diff --git a/libsanitizer/sanitizer_common/sanitizer_allocator_size_class_map.h b/libsanitizer/sanitizer_common/sanitizer_allocator_size_class_map.h index c50d133..361793f 100644 --- a/libsanitizer/sanitizer_common/sanitizer_allocator_size_class_map.h +++ b/libsanitizer/sanitizer_common/sanitizer_allocator_size_class_map.h @@ -193,13 +193,13 @@ class SizeClassMap { uptr cached = MaxCachedHint(s) * s; if (i == kBatchClassID) d = p = l = 0; - Printf("c%02zd => s: %zd diff: +%zd %02zd%% l %zd " - "cached: %zd %zd; id %zd\n", - i, Size(i), d, p, l, MaxCachedHint(s), cached, ClassID(s)); + Printf( + "c%02zu => s: %zu diff: +%zu %02zu%% l %zu cached: %zu %zu; id %zu\n", + i, Size(i), d, p, l, MaxCachedHint(s), cached, ClassID(s)); total_cached += cached; prev_s = s; } - Printf("Total cached: %zd\n", total_cached); + Printf("Total cached: %zu\n", total_cached); } static void Validate() { diff --git a/libsanitizer/sanitizer_common/sanitizer_asm.h b/libsanitizer/sanitizer_common/sanitizer_asm.h index 803af32..b544542 100644 --- a/libsanitizer/sanitizer_common/sanitizer_asm.h +++ b/libsanitizer/sanitizer_common/sanitizer_asm.h @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// // -// Various support for assemebler. +// Various support for assembler. // //===----------------------------------------------------------------------===// @@ -61,7 +61,7 @@ #if defined(__ELF__) && (defined(__GNU__) || defined(__FreeBSD__) || \ defined(__Fuchsia__) || defined(__linux__)) // clang-format off -#define NO_EXEC_STACK_DIRECTIVE .section .note.GNU-stack,"",%progbits // NOLINT +#define NO_EXEC_STACK_DIRECTIVE .section .note.GNU-stack,"",%progbits // clang-format on #else #define NO_EXEC_STACK_DIRECTIVE diff --git a/libsanitizer/sanitizer_common/sanitizer_atomic_clang_mips.h b/libsanitizer/sanitizer_common/sanitizer_atomic_clang_mips.h index 2b39097..f3d3052 100644 --- a/libsanitizer/sanitizer_common/sanitizer_atomic_clang_mips.h +++ b/libsanitizer/sanitizer_common/sanitizer_atomic_clang_mips.h @@ -18,7 +18,7 @@ namespace __sanitizer { // MIPS32 does not support atomics > 4 bytes. To address this lack of // functionality, the sanitizer library provides helper methods which use an -// internal spin lock mechanism to emulate atomic oprations when the size is +// internal spin lock mechanism to emulate atomic operations when the size is // 8 bytes. static void __spin_lock(volatile int *lock) { while (__sync_lock_test_and_set(lock, 1)) diff --git a/libsanitizer/sanitizer_common/sanitizer_common.h b/libsanitizer/sanitizer_common/sanitizer_common.h index cbdbb0c..17c29c7 100644 --- a/libsanitizer/sanitizer_common/sanitizer_common.h +++ b/libsanitizer/sanitizer_common/sanitizer_common.h @@ -222,8 +222,8 @@ void CatastrophicErrorWrite(const char *buffer, uptr length); void RawWrite(const char *buffer); bool ColorizeReports(); void RemoveANSIEscapeSequencesFromString(char *buffer); -void Printf(const char *format, ...); -void Report(const char *format, ...); +void Printf(const char *format, ...) FORMAT(1, 2); +void Report(const char *format, ...) FORMAT(1, 2); void SetPrintfAndReportCallback(void (*callback)(const char *)); #define VReport(level, ...) \ do { \ @@ -618,7 +618,7 @@ class InternalScopedString { buffer_.resize(1); buffer_[0] = '\0'; } - void append(const char *format, ...); + void append(const char *format, ...) FORMAT(2, 3); const char *data() const { return buffer_.data(); } char *data() { return buffer_.data(); } @@ -697,7 +697,8 @@ enum ModuleArch { kModuleArchARMV7S, kModuleArchARMV7K, kModuleArchARM64, - kModuleArchRISCV64 + kModuleArchRISCV64, + kModuleArchHexagon }; // Sorts and removes duplicates from the container. @@ -764,6 +765,8 @@ inline const char *ModuleArchToString(ModuleArch arch) { return "arm64"; case kModuleArchRISCV64: return "riscv64"; + case kModuleArchHexagon: + return "hexagon"; } CHECK(0 && "Invalid module arch"); return ""; @@ -1063,17 +1066,10 @@ class ArrayRef { T *end_ = nullptr; }; -#define PRINTF_128(v) \ - (*((u8 *)&v + 0)), (*((u8 *)&v + 1)), (*((u8 *)&v + 2)), (*((u8 *)&v + 3)), \ - (*((u8 *)&v + 4)), (*((u8 *)&v + 5)), (*((u8 *)&v + 6)), \ - (*((u8 *)&v + 7)), (*((u8 *)&v + 8)), (*((u8 *)&v + 9)), \ - (*((u8 *)&v + 10)), (*((u8 *)&v + 11)), (*((u8 *)&v + 12)), \ - (*((u8 *)&v + 13)), (*((u8 *)&v + 14)), (*((u8 *)&v + 15)) - } // namespace __sanitizer inline void *operator new(__sanitizer::operator_new_size_type size, - __sanitizer::LowLevelAllocator &alloc) { // NOLINT + __sanitizer::LowLevelAllocator &alloc) { return alloc.Allocate(size); } diff --git a/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc b/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc index 5ac6cf4..9511a3b 100644 --- a/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc +++ b/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc @@ -204,7 +204,7 @@ extern const short *_tolower_tab_; #define COMMON_INTERCEPTOR_READ_STRING(ctx, s, n) \ COMMON_INTERCEPTOR_READ_RANGE((ctx), (s), \ - common_flags()->strict_string_checks ? (REAL(strlen)(s)) + 1 : (n) ) + common_flags()->strict_string_checks ? (internal_strlen(s)) + 1 : (n) ) #ifndef COMMON_INTERCEPTOR_ON_DLOPEN #define COMMON_INTERCEPTOR_ON_DLOPEN(filename, flag) \ @@ -435,7 +435,7 @@ INTERCEPTOR(char*, textdomain, const char *domainname) { if (domainname) COMMON_INTERCEPTOR_READ_STRING(ctx, domainname, 0); char *domain = REAL(textdomain)(domainname); if (domain) { - COMMON_INTERCEPTOR_INITIALIZE_RANGE(domain, REAL(strlen)(domain) + 1); + COMMON_INTERCEPTOR_INITIALIZE_RANGE(domain, internal_strlen(domain) + 1); } return domain; } @@ -575,8 +575,8 @@ INTERCEPTOR(int, strncasecmp, const char *s1, const char *s2, SIZE_T size) { #if SANITIZER_INTERCEPT_STRSTR || SANITIZER_INTERCEPT_STRCASESTR static inline void StrstrCheck(void *ctx, char *r, const char *s1, const char *s2) { - uptr len1 = REAL(strlen)(s1); - uptr len2 = REAL(strlen)(s2); + uptr len1 = internal_strlen(s1); + uptr len2 = internal_strlen(s2); COMMON_INTERCEPTOR_READ_STRING(ctx, s1, r ? r - s1 + len2 : len1 + 1); COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, len2 + 1); } @@ -640,10 +640,10 @@ INTERCEPTOR(char*, strtok, char *str, const char *delimiters) { // for subsequent calls). We do not need to check strtok's result. // As the delimiters can change, we check them every call. if (str != nullptr) { - COMMON_INTERCEPTOR_READ_RANGE(ctx, str, REAL(strlen)(str) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, str, internal_strlen(str) + 1); } COMMON_INTERCEPTOR_READ_RANGE(ctx, delimiters, - REAL(strlen)(delimiters) + 1); + internal_strlen(delimiters) + 1); return REAL(strtok)(str, delimiters); } else { // However, when strict_string_checks is disabled we cannot check the @@ -657,11 +657,11 @@ INTERCEPTOR(char*, strtok, char *str, const char *delimiters) { COMMON_INTERCEPTOR_READ_RANGE(ctx, delimiters, 1); char *result = REAL(strtok)(str, delimiters); if (result != nullptr) { - COMMON_INTERCEPTOR_READ_RANGE(ctx, result, REAL(strlen)(result) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, result, internal_strlen(result) + 1); } else if (str != nullptr) { // No delimiter were found, it's safe to assume that the entire str was // scanned. - COMMON_INTERCEPTOR_READ_RANGE(ctx, str, REAL(strlen)(str) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, str, internal_strlen(str) + 1); } return result; } @@ -706,7 +706,7 @@ INTERCEPTOR(char*, strchr, const char *s, int c) { if (common_flags()->intercept_strchr) { // Keep strlen as macro argument, as macro may ignore it. COMMON_INTERCEPTOR_READ_STRING(ctx, s, - (result ? result - s : REAL(strlen)(s)) + 1); + (result ? result - s : internal_strlen(s)) + 1); } return result; } @@ -737,7 +737,7 @@ INTERCEPTOR(char*, strrchr, const char *s, int c) { return internal_strrchr(s, c); COMMON_INTERCEPTOR_ENTER(ctx, strrchr, s, c); if (common_flags()->intercept_strchr) - COMMON_INTERCEPTOR_READ_RANGE(ctx, s, REAL(strlen)(s) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, s, internal_strlen(s) + 1); return REAL(strrchr)(s, c); } #define INIT_STRRCHR COMMON_INTERCEPT_FUNCTION(strrchr) @@ -751,7 +751,7 @@ INTERCEPTOR(SIZE_T, strspn, const char *s1, const char *s2) { COMMON_INTERCEPTOR_ENTER(ctx, strspn, s1, s2); SIZE_T r = REAL(strspn)(s1, s2); if (common_flags()->intercept_strspn) { - COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, REAL(strlen)(s2) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, internal_strlen(s2) + 1); COMMON_INTERCEPTOR_READ_STRING(ctx, s1, r + 1); } return r; @@ -762,7 +762,7 @@ INTERCEPTOR(SIZE_T, strcspn, const char *s1, const char *s2) { COMMON_INTERCEPTOR_ENTER(ctx, strcspn, s1, s2); SIZE_T r = REAL(strcspn)(s1, s2); if (common_flags()->intercept_strspn) { - COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, REAL(strlen)(s2) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, internal_strlen(s2) + 1); COMMON_INTERCEPTOR_READ_STRING(ctx, s1, r + 1); } return r; @@ -781,9 +781,9 @@ INTERCEPTOR(char *, strpbrk, const char *s1, const char *s2) { COMMON_INTERCEPTOR_ENTER(ctx, strpbrk, s1, s2); char *r = REAL(strpbrk)(s1, s2); if (common_flags()->intercept_strpbrk) { - COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, REAL(strlen)(s2) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, internal_strlen(s2) + 1); COMMON_INTERCEPTOR_READ_STRING(ctx, s1, - r ? r - s1 + 1 : REAL(strlen)(s1) + 1); + r ? r - s1 + 1 : internal_strlen(s1) + 1); } return r; } @@ -1251,7 +1251,7 @@ INTERCEPTOR(char *, fgets, char *s, SIZE_T size, void *file) { // https://github.com/google/sanitizers/issues/321. char *res = REAL(fgets)(s, size, file); if (res) - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, s, REAL(strlen)(s) + 1); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, s, internal_strlen(s) + 1); return res; } #define INIT_FGETS COMMON_INTERCEPT_FUNCTION(fgets) @@ -1265,7 +1265,7 @@ INTERCEPTOR_WITH_SUFFIX(int, fputs, char *s, void *file) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, fputs, s, file); if (!SANITIZER_MAC || s) { // `fputs(NULL, file)` is supported on Darwin. - COMMON_INTERCEPTOR_READ_RANGE(ctx, s, REAL(strlen)(s) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, s, internal_strlen(s) + 1); } return REAL(fputs)(s, file); } @@ -1280,7 +1280,7 @@ INTERCEPTOR(int, puts, char *s) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, puts, s); if (!SANITIZER_MAC || s) { // `puts(NULL)` is supported on Darwin. - COMMON_INTERCEPTOR_READ_RANGE(ctx, s, REAL(strlen)(s) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, s, internal_strlen(s) + 1); } return REAL(puts)(s); } @@ -1334,7 +1334,7 @@ static void unpoison_tm(void *ctx, __sanitizer_tm *tm) { // Can not use COMMON_INTERCEPTOR_WRITE_RANGE here, because tm->tm_zone // can point to shared memory and tsan would report a data race. COMMON_INTERCEPTOR_INITIALIZE_RANGE(tm->tm_zone, - REAL(strlen(tm->tm_zone)) + 1); + internal_strlen(tm->tm_zone) + 1); } #endif } @@ -1387,7 +1387,7 @@ INTERCEPTOR(char *, ctime, unsigned long *timep) { char *res = REAL(ctime)(timep); if (res) { COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1); } return res; } @@ -1400,7 +1400,7 @@ INTERCEPTOR(char *, ctime_r, unsigned long *timep, char *result) { char *res = REAL(ctime_r)(timep, result); if (res) { COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1); } return res; } @@ -1413,7 +1413,7 @@ INTERCEPTOR(char *, asctime, __sanitizer_tm *tm) { char *res = REAL(asctime)(tm); if (res) { COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, sizeof(*tm)); - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1); } return res; } @@ -1426,7 +1426,7 @@ INTERCEPTOR(char *, asctime_r, __sanitizer_tm *tm, char *result) { char *res = REAL(asctime_r)(tm, result); if (res) { COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, sizeof(*tm)); - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1); } return res; } @@ -1463,7 +1463,7 @@ INTERCEPTOR(char *, strptime, char *s, char *format, __sanitizer_tm *tm) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, strptime, s, format, tm); if (format) - COMMON_INTERCEPTOR_READ_RANGE(ctx, format, REAL(strlen)(format) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, format, internal_strlen(format) + 1); // FIXME: under ASan the call below may write to freed memory and corrupt // its metadata. See // https://github.com/google/sanitizers/issues/321. @@ -1843,9 +1843,9 @@ INTERCEPTOR(int, ioctl, int d, unsigned long request, ...) { const ioctl_desc *desc = ioctl_lookup(request); ioctl_desc decoded_desc; if (!desc) { - VPrintf(2, "Decoding unknown ioctl 0x%x\n", request); + VPrintf(2, "Decoding unknown ioctl 0x%lx\n", request); if (!ioctl_decode(request, &decoded_desc)) - Printf("WARNING: failed decoding unknown ioctl 0x%x\n", request); + Printf("WARNING: failed decoding unknown ioctl 0x%lx\n", request); else desc = &decoded_desc; } @@ -1869,26 +1869,26 @@ UNUSED static void unpoison_passwd(void *ctx, __sanitizer_passwd *pwd) { COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd, sizeof(*pwd)); if (pwd->pw_name) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd->pw_name, - REAL(strlen)(pwd->pw_name) + 1); + internal_strlen(pwd->pw_name) + 1); if (pwd->pw_passwd) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd->pw_passwd, - REAL(strlen)(pwd->pw_passwd) + 1); + internal_strlen(pwd->pw_passwd) + 1); #if !SANITIZER_ANDROID if (pwd->pw_gecos) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd->pw_gecos, - REAL(strlen)(pwd->pw_gecos) + 1); + internal_strlen(pwd->pw_gecos) + 1); #endif #if SANITIZER_MAC || SANITIZER_FREEBSD || SANITIZER_NETBSD if (pwd->pw_class) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd->pw_class, - REAL(strlen)(pwd->pw_class) + 1); + internal_strlen(pwd->pw_class) + 1); #endif if (pwd->pw_dir) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd->pw_dir, - REAL(strlen)(pwd->pw_dir) + 1); + internal_strlen(pwd->pw_dir) + 1); if (pwd->pw_shell) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd->pw_shell, - REAL(strlen)(pwd->pw_shell) + 1); + internal_strlen(pwd->pw_shell) + 1); } } @@ -1897,13 +1897,13 @@ UNUSED static void unpoison_group(void *ctx, __sanitizer_group *grp) { COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp, sizeof(*grp)); if (grp->gr_name) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp->gr_name, - REAL(strlen)(grp->gr_name) + 1); + internal_strlen(grp->gr_name) + 1); if (grp->gr_passwd) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp->gr_passwd, - REAL(strlen)(grp->gr_passwd) + 1); + internal_strlen(grp->gr_passwd) + 1); char **p = grp->gr_mem; for (; *p; ++p) { - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, REAL(strlen)(*p) + 1); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, internal_strlen(*p) + 1); } COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp->gr_mem, (p - grp->gr_mem + 1) * sizeof(*p)); @@ -1916,7 +1916,7 @@ INTERCEPTOR(__sanitizer_passwd *, getpwnam, const char *name) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, getpwnam, name); if (name) - COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1); __sanitizer_passwd *res = REAL(getpwnam)(name); unpoison_passwd(ctx, res); return res; @@ -1931,7 +1931,7 @@ INTERCEPTOR(__sanitizer_passwd *, getpwuid, u32 uid) { INTERCEPTOR(__sanitizer_group *, getgrnam, const char *name) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, getgrnam, name); - COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1); __sanitizer_group *res = REAL(getgrnam)(name); unpoison_group(ctx, res); return res; @@ -1957,7 +1957,7 @@ INTERCEPTOR(int, getpwnam_r, const char *name, __sanitizer_passwd *pwd, char *buf, SIZE_T buflen, __sanitizer_passwd **result) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, getpwnam_r, name, pwd, buf, buflen, result); - COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1); // FIXME: under ASan the call below may write to freed memory and corrupt // its metadata. See // https://github.com/google/sanitizers/issues/321. @@ -1984,7 +1984,7 @@ INTERCEPTOR(int, getgrnam_r, const char *name, __sanitizer_group *grp, char *buf, SIZE_T buflen, __sanitizer_group **result) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, getgrnam_r, name, grp, buf, buflen, result); - COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1); // FIXME: under ASan the call below may write to freed memory and corrupt // its metadata. See // https://github.com/google/sanitizers/issues/321. @@ -2229,8 +2229,20 @@ INTERCEPTOR(int, clock_getcpuclockid, pid_t pid, return res; } -#define INIT_CLOCK_GETCPUCLOCKID \ - COMMON_INTERCEPT_FUNCTION(clock_getcpuclockid); +INTERCEPTOR(int, pthread_getcpuclockid, uptr thread, + __sanitizer_clockid_t *clockid) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, pthread_getcpuclockid, thread, clockid); + int res = REAL(pthread_getcpuclockid)(thread, clockid); + if (!res && clockid) { + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, clockid, sizeof *clockid); + } + return res; +} + +#define INIT_CLOCK_GETCPUCLOCKID \ + COMMON_INTERCEPT_FUNCTION(clock_getcpuclockid); \ + COMMON_INTERCEPT_FUNCTION(pthread_getcpuclockid); #else #define INIT_CLOCK_GETCPUCLOCKID #endif @@ -2289,7 +2301,7 @@ static void unpoison_glob_t(void *ctx, __sanitizer_glob_t *pglob) { ctx, pglob->gl_pathv, (pglob->gl_pathc + 1) * sizeof(*pglob->gl_pathv)); for (SIZE_T i = 0; i < pglob->gl_pathc; ++i) { char *p = pglob->gl_pathv[i]; - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, REAL(strlen)(p) + 1); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, internal_strlen(p) + 1); } } @@ -2319,19 +2331,19 @@ static void *wrapped_gl_readdir(void *dir) { static void *wrapped_gl_opendir(const char *s) { COMMON_INTERCEPTOR_UNPOISON_PARAM(1); - COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, REAL(strlen)(s) + 1); + COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, internal_strlen(s) + 1); return pglob_copy->gl_opendir(s); } static int wrapped_gl_lstat(const char *s, void *st) { COMMON_INTERCEPTOR_UNPOISON_PARAM(2); - COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, REAL(strlen)(s) + 1); + COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, internal_strlen(s) + 1); return pglob_copy->gl_lstat(s, st); } static int wrapped_gl_stat(const char *s, void *st) { COMMON_INTERCEPTOR_UNPOISON_PARAM(2); - COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, REAL(strlen)(s) + 1); + COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, internal_strlen(s) + 1); return pglob_copy->gl_stat(s, st); } @@ -2519,7 +2531,7 @@ INTERCEPTOR(char *, inet_ntop, int af, const void *src, char *dst, u32 size) { // its metadata. See // https://github.com/google/sanitizers/issues/321. char *res = REAL(inet_ntop)(af, src, dst, size); - if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); + if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1); return res; } INTERCEPTOR(int, inet_pton, int af, const char *src, void *dst) { @@ -2548,7 +2560,7 @@ INTERCEPTOR(int, inet_pton, int af, const char *src, void *dst) { INTERCEPTOR(int, inet_aton, const char *cp, void *dst) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, inet_aton, cp, dst); - if (cp) COMMON_INTERCEPTOR_READ_RANGE(ctx, cp, REAL(strlen)(cp) + 1); + if (cp) COMMON_INTERCEPTOR_READ_RANGE(ctx, cp, internal_strlen(cp) + 1); // FIXME: under ASan the call below may write to freed memory and corrupt // its metadata. See // https://github.com/google/sanitizers/issues/321. @@ -2590,9 +2602,9 @@ INTERCEPTOR(int, getaddrinfo, char *node, char *service, struct __sanitizer_addrinfo **out) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, getaddrinfo, node, service, hints, out); - if (node) COMMON_INTERCEPTOR_READ_RANGE(ctx, node, REAL(strlen)(node) + 1); + if (node) COMMON_INTERCEPTOR_READ_RANGE(ctx, node, internal_strlen(node) + 1); if (service) - COMMON_INTERCEPTOR_READ_RANGE(ctx, service, REAL(strlen)(service) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, service, internal_strlen(service) + 1); if (hints) COMMON_INTERCEPTOR_READ_RANGE(ctx, hints, sizeof(__sanitizer_addrinfo)); // FIXME: under ASan the call below may write to freed memory and corrupt @@ -2608,7 +2620,7 @@ INTERCEPTOR(int, getaddrinfo, char *node, char *service, COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_addr, p->ai_addrlen); if (p->ai_canonname) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_canonname, - REAL(strlen)(p->ai_canonname) + 1); + internal_strlen(p->ai_canonname) + 1); p = p->ai_next; } } @@ -2634,9 +2646,9 @@ INTERCEPTOR(int, getnameinfo, void *sockaddr, unsigned salen, char *host, REAL(getnameinfo)(sockaddr, salen, host, hostlen, serv, servlen, flags); if (res == 0) { if (host && hostlen) - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, host, REAL(strlen)(host) + 1); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, host, internal_strlen(host) + 1); if (serv && servlen) - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, serv, REAL(strlen)(serv) + 1); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, serv, internal_strlen(serv) + 1); } return res; } @@ -2669,10 +2681,10 @@ INTERCEPTOR(int, getsockname, int sock_fd, void *addr, int *addrlen) { static void write_hostent(void *ctx, struct __sanitizer_hostent *h) { COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h, sizeof(__sanitizer_hostent)); if (h->h_name) - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h->h_name, REAL(strlen)(h->h_name) + 1); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h->h_name, internal_strlen(h->h_name) + 1); char **p = h->h_aliases; while (*p) { - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, REAL(strlen)(*p) + 1); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, internal_strlen(*p) + 1); ++p; } COMMON_INTERCEPTOR_WRITE_RANGE( @@ -3196,7 +3208,7 @@ INTERCEPTOR(int, sysinfo, void *info) { INTERCEPTOR(__sanitizer_dirent *, opendir, const char *path) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, opendir, path); - COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1); __sanitizer_dirent *res = REAL(opendir)(path); if (res) COMMON_INTERCEPTOR_DIR_ACQUIRE(ctx, path); @@ -3351,10 +3363,10 @@ INTERCEPTOR(char *, setlocale, int category, char *locale) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, setlocale, category, locale); if (locale) - COMMON_INTERCEPTOR_READ_RANGE(ctx, locale, REAL(strlen)(locale) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, locale, internal_strlen(locale) + 1); char *res = REAL(setlocale)(category, locale); if (res) { - COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1); + COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1); unpoison_ctype_arrays(ctx); } return res; @@ -3373,7 +3385,7 @@ INTERCEPTOR(char *, getcwd, char *buf, SIZE_T size) { // its metadata. See // https://github.com/google/sanitizers/issues/321. char *res = REAL(getcwd)(buf, size); - if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); + if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1); return res; } #define INIT_GETCWD COMMON_INTERCEPT_FUNCTION(getcwd); @@ -3389,7 +3401,7 @@ INTERCEPTOR(char *, get_current_dir_name, int fake) { // its metadata. See // https://github.com/google/sanitizers/issues/321. char *res = REAL(get_current_dir_name)(fake); - if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); + if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1); return res; } @@ -3663,12 +3675,23 @@ INTERCEPTOR(int, tcgetattr, int fd, void *termios_p) { INTERCEPTOR(char *, realpath, const char *path, char *resolved_path) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, realpath, path, resolved_path); - if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); + if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1); + + // Workaround a bug in glibc where dlsym(RTLD_NEXT, ...) returns the oldest + // version of a versioned symbol. For realpath(), this gives us something + // (called __old_realpath) that does not handle NULL in the second argument. + // Handle it as part of the interceptor. + char *allocated_path = nullptr; + if (!resolved_path) + allocated_path = resolved_path = (char *)WRAP(malloc)(path_max + 1); + char *res = REAL(realpath)(path, resolved_path); - if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); + if (allocated_path && !res) + WRAP(free)(allocated_path); + if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1); return res; } -#define INIT_REALPATH COMMON_INTERCEPT_FUNCTION_GLIBC_VER_MIN(realpath, "GLIBC_2.3"); +# define INIT_REALPATH COMMON_INTERCEPT_FUNCTION(realpath); #else #define INIT_REALPATH #endif @@ -3677,9 +3700,9 @@ INTERCEPTOR(char *, realpath, const char *path, char *resolved_path) { INTERCEPTOR(char *, canonicalize_file_name, const char *path) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, canonicalize_file_name, path); - if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); + if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1); char *res = REAL(canonicalize_file_name)(path); - if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); + if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1); return res; } #define INIT_CANONICALIZE_FILE_NAME \ @@ -3740,7 +3763,7 @@ INTERCEPTOR(char *, strerror, int errnum) { COMMON_INTERCEPTOR_ENTER(ctx, strerror, errnum); COMMON_INTERCEPTOR_STRERROR(); char *res = REAL(strerror)(errnum); - if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1); + if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1); return res; } #define INIT_STRERROR COMMON_INTERCEPT_FUNCTION(strerror); @@ -3782,9 +3805,9 @@ INTERCEPTOR(char *, strerror_r, int errnum, char *buf, SIZE_T buflen) { // https://github.com/google/sanitizers/issues/321. char *res = REAL(strerror_r)(errnum, buf, buflen); if (res == buf) - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1); else - COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1); + COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1); return res; } #endif //(_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && !_GNU_SOURCE || @@ -3804,7 +3827,7 @@ INTERCEPTOR(int, __xpg_strerror_r, int errnum, char *buf, SIZE_T buflen) { int res = REAL(__xpg_strerror_r)(errnum, buf, buflen); // This version always returns a null-terminated string. if (buf && buflen) - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, REAL(strlen)(buf) + 1); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, internal_strlen(buf) + 1); return res; } #define INIT_XPG_STRERROR_R COMMON_INTERCEPT_FUNCTION(__xpg_strerror_r); @@ -3840,7 +3863,7 @@ INTERCEPTOR(int, scandir, char *dirp, __sanitizer_dirent ***namelist, scandir_filter_f filter, scandir_compar_f compar) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, scandir, dirp, namelist, filter, compar); - if (dirp) COMMON_INTERCEPTOR_READ_RANGE(ctx, dirp, REAL(strlen)(dirp) + 1); + if (dirp) COMMON_INTERCEPTOR_READ_RANGE(ctx, dirp, internal_strlen(dirp) + 1); scandir_filter = filter; scandir_compar = compar; // FIXME: under ASan the call below may write to freed memory and corrupt @@ -3893,7 +3916,7 @@ INTERCEPTOR(int, scandir64, char *dirp, __sanitizer_dirent64 ***namelist, scandir64_filter_f filter, scandir64_compar_f compar) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, scandir64, dirp, namelist, filter, compar); - if (dirp) COMMON_INTERCEPTOR_READ_RANGE(ctx, dirp, REAL(strlen)(dirp) + 1); + if (dirp) COMMON_INTERCEPTOR_READ_RANGE(ctx, dirp, internal_strlen(dirp) + 1); scandir64_filter = filter; scandir64_compar = compar; // FIXME: under ASan the call below may write to freed memory and corrupt @@ -3989,19 +4012,20 @@ INTERCEPTOR(int, ppoll, __sanitizer_pollfd *fds, __sanitizer_nfds_t nfds, INTERCEPTOR(int, wordexp, char *s, __sanitizer_wordexp_t *p, int flags) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, wordexp, s, p, flags); - if (s) COMMON_INTERCEPTOR_READ_RANGE(ctx, s, REAL(strlen)(s) + 1); + if (s) COMMON_INTERCEPTOR_READ_RANGE(ctx, s, internal_strlen(s) + 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(wordexp)(s, p, flags); if (!res && p) { COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p)); - if (p->we_wordc) - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->we_wordv, - sizeof(*p->we_wordv) * p->we_wordc); - for (uptr i = 0; i < p->we_wordc; ++i) { + uptr we_wordc = + ((flags & wordexp_wrde_dooffs) ? p->we_offs : 0) + p->we_wordc; + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->we_wordv, + sizeof(*p->we_wordv) * (we_wordc + 1)); + for (uptr i = 0; i < we_wordc; ++i) { char *w = p->we_wordv[i]; - if (w) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, w, REAL(strlen)(w) + 1); + if (w) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, w, internal_strlen(w) + 1); } } return res; @@ -4207,7 +4231,7 @@ INTERCEPTOR(char **, backtrace_symbols, void **buffer, int size) { if (res && size) { COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, size * sizeof(*res)); for (int i = 0; i < size; ++i) - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res[i], REAL(strlen(res[i])) + 1); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res[i], internal_strlen(res[i]) + 1); } return res; } @@ -4325,16 +4349,16 @@ static void write_mntent(void *ctx, __sanitizer_mntent *mnt) { COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt, sizeof(*mnt)); if (mnt->mnt_fsname) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_fsname, - REAL(strlen)(mnt->mnt_fsname) + 1); + internal_strlen(mnt->mnt_fsname) + 1); if (mnt->mnt_dir) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_dir, - REAL(strlen)(mnt->mnt_dir) + 1); + internal_strlen(mnt->mnt_dir) + 1); if (mnt->mnt_type) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_type, - REAL(strlen)(mnt->mnt_type) + 1); + internal_strlen(mnt->mnt_type) + 1); if (mnt->mnt_opts) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_opts, - REAL(strlen)(mnt->mnt_opts) + 1); + internal_strlen(mnt->mnt_opts) + 1); } #endif @@ -4369,7 +4393,7 @@ INTERCEPTOR(__sanitizer_mntent *, getmntent_r, void *fp, INTERCEPTOR(int, statfs, char *path, void *buf) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, statfs, path, buf); - if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); + if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_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. @@ -4398,7 +4422,7 @@ INTERCEPTOR(int, fstatfs, int fd, void *buf) { INTERCEPTOR(int, statfs64, char *path, void *buf) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, statfs64, path, buf); - if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); + if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_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. @@ -4427,7 +4451,7 @@ INTERCEPTOR(int, fstatfs64, int fd, void *buf) { 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); + if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_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. @@ -4461,7 +4485,7 @@ INTERCEPTOR(int, fstatvfs, int fd, void *buf) { INTERCEPTOR(int, statvfs64, char *path, void *buf) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, statvfs64, path, buf); - if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); + if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_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. @@ -4490,7 +4514,7 @@ INTERCEPTOR(int, fstatvfs64, int fd, void *buf) { INTERCEPTOR(int, initgroups, char *user, u32 group) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, initgroups, user, group); - if (user) COMMON_INTERCEPTOR_READ_RANGE(ctx, user, REAL(strlen)(user) + 1); + if (user) COMMON_INTERCEPTOR_READ_RANGE(ctx, user, internal_strlen(user) + 1); int res = REAL(initgroups)(user, group); return res; } @@ -4505,13 +4529,13 @@ INTERCEPTOR(char *, ether_ntoa, __sanitizer_ether_addr *addr) { COMMON_INTERCEPTOR_ENTER(ctx, ether_ntoa, addr); if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr)); char *res = REAL(ether_ntoa)(addr); - if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1); + if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1); return res; } INTERCEPTOR(__sanitizer_ether_addr *, ether_aton, char *buf) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, ether_aton, buf); - if (buf) COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, REAL(strlen)(buf) + 1); + if (buf) COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, internal_strlen(buf) + 1); __sanitizer_ether_addr *res = REAL(ether_aton)(buf); if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, sizeof(*res)); return res; @@ -4533,14 +4557,14 @@ INTERCEPTOR(int, ether_ntohost, char *hostname, __sanitizer_ether_addr *addr) { // https://github.com/google/sanitizers/issues/321. int res = REAL(ether_ntohost)(hostname, addr); if (!res && hostname) - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, hostname, REAL(strlen)(hostname) + 1); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, hostname, internal_strlen(hostname) + 1); return res; } INTERCEPTOR(int, ether_hostton, char *hostname, __sanitizer_ether_addr *addr) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, ether_hostton, hostname, addr); if (hostname) - COMMON_INTERCEPTOR_READ_RANGE(ctx, hostname, REAL(strlen)(hostname) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, hostname, internal_strlen(hostname) + 1); // FIXME: under ASan the call below may write to freed memory and corrupt // its metadata. See // https://github.com/google/sanitizers/issues/321. @@ -4552,7 +4576,7 @@ INTERCEPTOR(int, ether_line, char *line, __sanitizer_ether_addr *addr, char *hostname) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, ether_line, line, addr, hostname); - if (line) COMMON_INTERCEPTOR_READ_RANGE(ctx, line, REAL(strlen)(line) + 1); + if (line) COMMON_INTERCEPTOR_READ_RANGE(ctx, line, internal_strlen(line) + 1); // FIXME: under ASan the call below may write to freed memory and corrupt // its metadata. See // https://github.com/google/sanitizers/issues/321. @@ -4560,7 +4584,7 @@ INTERCEPTOR(int, ether_line, char *line, __sanitizer_ether_addr *addr, if (!res) { if (addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr)); if (hostname) - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, hostname, REAL(strlen)(hostname) + 1); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, hostname, internal_strlen(hostname) + 1); } return res; } @@ -4581,14 +4605,14 @@ INTERCEPTOR(char *, ether_ntoa_r, __sanitizer_ether_addr *addr, char *buf) { // its metadata. See // https://github.com/google/sanitizers/issues/321. char *res = REAL(ether_ntoa_r)(addr, buf); - if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); + if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1); return res; } INTERCEPTOR(__sanitizer_ether_addr *, ether_aton_r, char *buf, __sanitizer_ether_addr *addr) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, ether_aton_r, buf, addr); - if (buf) COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, REAL(strlen)(buf) + 1); + if (buf) COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, internal_strlen(buf) + 1); // FIXME: under ASan the call below may write to freed memory and corrupt // its metadata. See // https://github.com/google/sanitizers/issues/321. @@ -4854,9 +4878,9 @@ INTERCEPTOR(char *, tmpnam, char *s) { // FIXME: under ASan the call below may write to freed memory and corrupt // its metadata. See // https://github.com/google/sanitizers/issues/321. - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, s, REAL(strlen)(s) + 1); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, s, internal_strlen(s) + 1); else - COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1); + COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1); } return res; } @@ -4873,7 +4897,7 @@ INTERCEPTOR(char *, tmpnam_r, char *s) { // its metadata. See // https://github.com/google/sanitizers/issues/321. char *res = REAL(tmpnam_r)(s); - if (res && s) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, s, REAL(strlen)(s) + 1); + if (res && s) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, s, internal_strlen(s) + 1); return res; } #define INIT_TMPNAM_R COMMON_INTERCEPT_FUNCTION(tmpnam_r); @@ -4887,7 +4911,7 @@ INTERCEPTOR(char *, ptsname, int fd) { COMMON_INTERCEPTOR_ENTER(ctx, ptsname, fd); char *res = REAL(ptsname)(fd); if (res != nullptr) - COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1); + COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1); return res; } #define INIT_PTSNAME COMMON_INTERCEPT_FUNCTION(ptsname); @@ -4901,7 +4925,7 @@ INTERCEPTOR(int, ptsname_r, int fd, char *name, SIZE_T namesize) { COMMON_INTERCEPTOR_ENTER(ctx, ptsname_r, fd, name, namesize); int res = REAL(ptsname_r)(fd, name, namesize); if (res == 0) - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, REAL(strlen)(name) + 1); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, internal_strlen(name) + 1); return res; } #define INIT_PTSNAME_R COMMON_INTERCEPT_FUNCTION(ptsname_r); @@ -4915,7 +4939,7 @@ INTERCEPTOR(char *, ttyname, int fd) { COMMON_INTERCEPTOR_ENTER(ctx, ttyname, fd); char *res = REAL(ttyname)(fd); if (res != nullptr) - COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1); + COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1); return res; } #define INIT_TTYNAME COMMON_INTERCEPT_FUNCTION(ttyname); @@ -4929,7 +4953,7 @@ INTERCEPTOR(int, ttyname_r, int fd, char *name, SIZE_T namesize) { COMMON_INTERCEPTOR_ENTER(ctx, ttyname_r, fd, name, namesize); int res = REAL(ttyname_r)(fd, name, namesize); if (res == 0) - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, REAL(strlen)(name) + 1); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, internal_strlen(name) + 1); return res; } #define INIT_TTYNAME_R COMMON_INTERCEPT_FUNCTION(ttyname_r); @@ -4941,10 +4965,10 @@ INTERCEPTOR(int, ttyname_r, int fd, char *name, SIZE_T namesize) { INTERCEPTOR(char *, tempnam, char *dir, char *pfx) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, tempnam, dir, pfx); - if (dir) COMMON_INTERCEPTOR_READ_RANGE(ctx, dir, REAL(strlen)(dir) + 1); - if (pfx) COMMON_INTERCEPTOR_READ_RANGE(ctx, pfx, REAL(strlen)(pfx) + 1); + if (dir) COMMON_INTERCEPTOR_READ_RANGE(ctx, dir, internal_strlen(dir) + 1); + if (pfx) COMMON_INTERCEPTOR_READ_RANGE(ctx, pfx, internal_strlen(pfx) + 1); char *res = REAL(tempnam)(dir, pfx); - if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1); + if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1); return res; } #define INIT_TEMPNAM COMMON_INTERCEPT_FUNCTION(tempnam); @@ -5404,7 +5428,7 @@ asm( INTERCEPTOR(SSIZE_T, listxattr, const char *path, char *list, SIZE_T size) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, listxattr, path, list, size); - if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); + if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_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. @@ -5417,7 +5441,7 @@ INTERCEPTOR(SSIZE_T, listxattr, const char *path, char *list, SIZE_T size) { INTERCEPTOR(SSIZE_T, llistxattr, const char *path, char *list, SIZE_T size) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, llistxattr, path, list, size); - if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); + if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_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. @@ -5448,8 +5472,8 @@ INTERCEPTOR(SSIZE_T, getxattr, const char *path, const char *name, char *value, SIZE_T size) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, getxattr, path, name, value, size); - if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); - if (name) COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); + if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1); + if (name) COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1); // FIXME: under ASan the call below may write to freed memory and corrupt // its metadata. See // https://github.com/google/sanitizers/issues/321. @@ -5461,8 +5485,8 @@ INTERCEPTOR(SSIZE_T, lgetxattr, const char *path, const char *name, char *value, SIZE_T size) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, lgetxattr, path, name, value, size); - if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); - if (name) COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); + if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1); + if (name) COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1); // FIXME: under ASan the call below may write to freed memory and corrupt // its metadata. See // https://github.com/google/sanitizers/issues/321. @@ -5474,7 +5498,7 @@ INTERCEPTOR(SSIZE_T, fgetxattr, int fd, const char *name, char *value, SIZE_T size) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, fgetxattr, fd, name, value, size); - if (name) COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); + if (name) COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1); // FIXME: under ASan the call below may write to freed memory and corrupt // its metadata. See // https://github.com/google/sanitizers/issues/321. @@ -5544,7 +5568,7 @@ INTERCEPTOR(int, getifaddrs, __sanitizer_ifaddrs **ifap) { COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(__sanitizer_ifaddrs)); if (p->ifa_name) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_name, - REAL(strlen)(p->ifa_name) + 1); + internal_strlen(p->ifa_name) + 1); if (p->ifa_addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_addr, struct_sockaddr_sz); if (p->ifa_netmask) @@ -5574,14 +5598,14 @@ INTERCEPTOR(char *, if_indextoname, unsigned int ifindex, char* ifname) { // https://github.com/google/sanitizers/issues/321. char *res = REAL(if_indextoname)(ifindex, ifname); if (res && ifname) - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ifname, REAL(strlen)(ifname) + 1); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ifname, internal_strlen(ifname) + 1); return res; } INTERCEPTOR(unsigned int, if_nametoindex, const char* ifname) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, if_nametoindex, ifname); if (ifname) - COMMON_INTERCEPTOR_READ_RANGE(ctx, ifname, REAL(strlen)(ifname) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, ifname, internal_strlen(ifname) + 1); return REAL(if_nametoindex)(ifname); } #define INIT_IF_INDEXTONAME \ @@ -5839,7 +5863,7 @@ INTERCEPTOR(int, xdr_string, __sanitizer_XDR *xdrs, char **p, COMMON_INTERCEPTOR_ENTER(ctx, xdr_string, xdrs, p, maxsize); if (p && xdrs->x_op == __sanitizer_XDR_ENCODE) { COMMON_INTERCEPTOR_READ_RANGE(ctx, p, sizeof(*p)); - COMMON_INTERCEPTOR_READ_RANGE(ctx, *p, REAL(strlen)(*p) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, *p, internal_strlen(*p) + 1); } // FIXME: under ASan the call below may write to freed memory and corrupt // its metadata. See @@ -5848,7 +5872,7 @@ INTERCEPTOR(int, xdr_string, __sanitizer_XDR *xdrs, char **p, if (p && xdrs->x_op == __sanitizer_XDR_DECODE) { COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p)); if (res && *p) - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, REAL(strlen)(*p) + 1); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, internal_strlen(*p) + 1); } return res; } @@ -6059,8 +6083,8 @@ INTERCEPTOR(int, __woverflow, __sanitizer_FILE *fp, int ch) { INTERCEPTOR(__sanitizer_FILE *, fopen, const char *path, const char *mode) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, fopen, path, mode); - if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); - COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1); + if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, internal_strlen(mode) + 1); __sanitizer_FILE *res = REAL(fopen)(path, mode); COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path); if (res) unpoison_file(res); @@ -6069,7 +6093,7 @@ INTERCEPTOR(__sanitizer_FILE *, fopen, const char *path, const char *mode) { INTERCEPTOR(__sanitizer_FILE *, fdopen, int fd, const char *mode) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, fdopen, fd, mode); - COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, internal_strlen(mode) + 1); __sanitizer_FILE *res = REAL(fdopen)(fd, mode); if (res) unpoison_file(res); return res; @@ -6078,8 +6102,8 @@ INTERCEPTOR(__sanitizer_FILE *, freopen, const char *path, const char *mode, __sanitizer_FILE *fp) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, freopen, path, mode, fp); - if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); - COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1); + if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, internal_strlen(mode) + 1); COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp); __sanitizer_FILE *res = REAL(freopen)(path, mode, fp); COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path); @@ -6103,7 +6127,7 @@ INTERCEPTOR(int, flopen, const char *path, int flags, ...) { va_end(ap); COMMON_INTERCEPTOR_ENTER(ctx, flopen, path, flags, mode); if (path) { - COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1); } return REAL(flopen)(path, flags, mode); } @@ -6116,7 +6140,7 @@ INTERCEPTOR(int, flopenat, int dirfd, const char *path, int flags, ...) { va_end(ap); COMMON_INTERCEPTOR_ENTER(ctx, flopen, path, flags, mode); if (path) { - COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1); } return REAL(flopenat)(dirfd, path, flags, mode); } @@ -6132,8 +6156,8 @@ INTERCEPTOR(int, flopenat, int dirfd, const char *path, int flags, ...) { INTERCEPTOR(__sanitizer_FILE *, fopen64, const char *path, const char *mode) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, fopen64, path, mode); - COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); - COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, internal_strlen(mode) + 1); __sanitizer_FILE *res = REAL(fopen64)(path, mode); COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path); if (res) unpoison_file(res); @@ -6143,8 +6167,8 @@ INTERCEPTOR(__sanitizer_FILE *, freopen64, const char *path, const char *mode, __sanitizer_FILE *fp) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, freopen64, path, mode, fp); - if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); - COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1); + if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, internal_strlen(mode) + 1); COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp); __sanitizer_FILE *res = REAL(freopen64)(path, mode, fp); COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path); @@ -6322,9 +6346,9 @@ INTERCEPTOR(char *, getpass, const char *prompt) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, getpass, prompt); if (prompt) - COMMON_INTERCEPTOR_READ_RANGE(ctx, prompt, REAL(strlen)(prompt)+1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, prompt, internal_strlen(prompt)+1); char *res = REAL(getpass)(prompt); - if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res)+1); + if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res)+1); return res; } @@ -6528,17 +6552,42 @@ INTERCEPTOR(int, sem_getvalue, __sanitizer_sem_t *s, int *sval) { } return res; } -#define INIT_SEM \ - COMMON_INTERCEPT_FUNCTION(sem_init); \ - COMMON_INTERCEPT_FUNCTION(sem_destroy); \ - COMMON_INTERCEPT_FUNCTION(sem_wait); \ - COMMON_INTERCEPT_FUNCTION(sem_trywait); \ - COMMON_INTERCEPT_FUNCTION(sem_timedwait); \ - COMMON_INTERCEPT_FUNCTION(sem_post); \ - COMMON_INTERCEPT_FUNCTION(sem_getvalue); + +INTERCEPTOR(__sanitizer_sem_t *, sem_open, const char *name, int oflag, ...) { + void *ctx; + va_list ap; + va_start(ap, oflag); + u32 mode = va_arg(ap, u32); + u32 value = va_arg(ap, u32); + COMMON_INTERCEPTOR_ENTER(ctx, sem_open, name, oflag, mode, value); + COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1); + __sanitizer_sem_t *s = REAL(sem_open)(name, oflag, mode, value); + if (s) + COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, sizeof(*s)); + va_end(ap); + return s; +} + +INTERCEPTOR(int, sem_unlink, const char *name) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, sem_unlink, name); + COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1); + return REAL(sem_unlink)(name); +} + +# define INIT_SEM \ + COMMON_INTERCEPT_FUNCTION(sem_init); \ + COMMON_INTERCEPT_FUNCTION(sem_destroy); \ + COMMON_INTERCEPT_FUNCTION(sem_wait); \ + COMMON_INTERCEPT_FUNCTION(sem_trywait); \ + COMMON_INTERCEPT_FUNCTION(sem_timedwait); \ + COMMON_INTERCEPT_FUNCTION(sem_post); \ + COMMON_INTERCEPT_FUNCTION(sem_getvalue); \ + COMMON_INTERCEPT_FUNCTION(sem_open); \ + COMMON_INTERCEPT_FUNCTION(sem_unlink); #else -#define INIT_SEM -#endif // SANITIZER_INTERCEPT_SEM +# define INIT_SEM +#endif // SANITIZER_INTERCEPT_SEM #if SANITIZER_INTERCEPT_PTHREAD_SETCANCEL INTERCEPTOR(int, pthread_setcancelstate, int state, int *oldstate) { @@ -6621,7 +6670,7 @@ INTERCEPTOR(char *, ctermid, char *s) { COMMON_INTERCEPTOR_ENTER(ctx, ctermid, s); char *res = REAL(ctermid)(s); if (res) { - COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1); + COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1); } return res; } @@ -6636,7 +6685,7 @@ INTERCEPTOR(char *, ctermid_r, char *s) { COMMON_INTERCEPTOR_ENTER(ctx, ctermid_r, s); char *res = REAL(ctermid_r)(s); if (res) { - COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1); + COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1); } return res; } @@ -6973,8 +7022,8 @@ INTERCEPTOR(SIZE_T, wcsnlen, const wchar_t *s, SIZE_T n) { INTERCEPTOR(wchar_t *, wcscat, wchar_t *dst, const wchar_t *src) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, wcscat, dst, src); - SIZE_T src_size = REAL(wcslen)(src); - SIZE_T dst_size = REAL(wcslen)(dst); + SIZE_T src_size = internal_wcslen(src); + SIZE_T dst_size = internal_wcslen(dst); COMMON_INTERCEPTOR_READ_RANGE(ctx, src, (src_size + 1) * sizeof(wchar_t)); COMMON_INTERCEPTOR_READ_RANGE(ctx, dst, (dst_size + 1) * sizeof(wchar_t)); COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst + dst_size, @@ -6985,8 +7034,8 @@ INTERCEPTOR(wchar_t *, wcscat, wchar_t *dst, const wchar_t *src) { INTERCEPTOR(wchar_t *, wcsncat, wchar_t *dst, const wchar_t *src, SIZE_T n) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, wcsncat, dst, src, n); - SIZE_T src_size = REAL(wcsnlen)(src, n); - SIZE_T dst_size = REAL(wcslen)(dst); + SIZE_T src_size = internal_wcsnlen(src, n); + SIZE_T dst_size = internal_wcslen(dst); COMMON_INTERCEPTOR_READ_RANGE(ctx, src, Min(src_size + 1, n) * sizeof(wchar_t)); COMMON_INTERCEPTOR_READ_RANGE(ctx, dst, (dst_size + 1) * sizeof(wchar_t)); @@ -7005,7 +7054,7 @@ INTERCEPTOR(wchar_t *, wcsncat, wchar_t *dst, const wchar_t *src, SIZE_T n) { INTERCEPTOR(wchar_t *, wcsdup, wchar_t *s) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, wcsdup, s); - SIZE_T len = REAL(wcslen)(s); + SIZE_T len = internal_wcslen(s); COMMON_INTERCEPTOR_READ_RANGE(ctx, s, sizeof(wchar_t) * (len + 1)); wchar_t *result = REAL(wcsdup)(s); if (result) @@ -7019,9 +7068,9 @@ INTERCEPTOR(wchar_t *, wcsdup, wchar_t *s) { #endif #if SANITIZER_INTERCEPT_STRXFRM -static SIZE_T RealStrLen(const char *str) { return REAL(strlen)(str); } +static SIZE_T RealStrLen(const char *str) { return internal_strlen(str); } -static SIZE_T RealStrLen(const wchar_t *str) { return REAL(wcslen)(str); } +static SIZE_T RealStrLen(const wchar_t *str) { return internal_wcslen(str); } #define STRXFRM_INTERCEPTOR_IMPL(strxfrm, dest, src, len, ...) \ { \ @@ -7095,7 +7144,7 @@ INTERCEPTOR(int, acct, const char *file) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, acct, file); if (file) - COMMON_INTERCEPTOR_READ_RANGE(ctx, file, REAL(strlen)(file) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, file, internal_strlen(file) + 1); return REAL(acct)(file); } #define INIT_ACCT COMMON_INTERCEPT_FUNCTION(acct) @@ -7110,7 +7159,7 @@ INTERCEPTOR(const char *, user_from_uid, u32 uid, int nouser) { COMMON_INTERCEPTOR_ENTER(ctx, user_from_uid, uid, nouser); user = REAL(user_from_uid)(uid, nouser); if (user) - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, user, REAL(strlen)(user) + 1); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, user, internal_strlen(user) + 1); return user; } #define INIT_USER_FROM_UID COMMON_INTERCEPT_FUNCTION(user_from_uid) @@ -7124,7 +7173,7 @@ INTERCEPTOR(int, uid_from_user, const char *name, u32 *uid) { int res; COMMON_INTERCEPTOR_ENTER(ctx, uid_from_user, name, uid); if (name) - COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1); res = REAL(uid_from_user)(name, uid); if (uid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, uid, sizeof(*uid)); @@ -7142,7 +7191,7 @@ INTERCEPTOR(const char *, group_from_gid, u32 gid, int nogroup) { COMMON_INTERCEPTOR_ENTER(ctx, group_from_gid, gid, nogroup); group = REAL(group_from_gid)(gid, nogroup); if (group) - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, group, REAL(strlen)(group) + 1); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, group, internal_strlen(group) + 1); return group; } #define INIT_GROUP_FROM_GID COMMON_INTERCEPT_FUNCTION(group_from_gid) @@ -7156,7 +7205,7 @@ INTERCEPTOR(int, gid_from_group, const char *group, u32 *gid) { int res; COMMON_INTERCEPTOR_ENTER(ctx, gid_from_group, group, gid); if (group) - COMMON_INTERCEPTOR_READ_RANGE(ctx, group, REAL(strlen)(group) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, group, internal_strlen(group) + 1); res = REAL(gid_from_group)(group, gid); if (gid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, gid, sizeof(*gid)); @@ -7172,7 +7221,7 @@ INTERCEPTOR(int, access, const char *path, int mode) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, access, path, mode); if (path) - COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1); return REAL(access)(path, mode); } #define INIT_ACCESS COMMON_INTERCEPT_FUNCTION(access) @@ -7185,7 +7234,7 @@ INTERCEPTOR(int, faccessat, int fd, const char *path, int mode, int flags) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, faccessat, fd, path, mode, flags); if (path) - COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1); return REAL(faccessat)(fd, path, mode, flags); } #define INIT_FACCESSAT COMMON_INTERCEPT_FUNCTION(faccessat) @@ -7200,7 +7249,7 @@ INTERCEPTOR(int, getgrouplist, const char *name, u32 basegid, u32 *groups, int res; COMMON_INTERCEPTOR_ENTER(ctx, getgrouplist, name, basegid, groups, ngroups); if (name) - COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1); if (ngroups) COMMON_INTERCEPTOR_READ_RANGE(ctx, ngroups, sizeof(*ngroups)); res = REAL(getgrouplist)(name, basegid, groups, ngroups); @@ -7224,7 +7273,7 @@ INTERCEPTOR(int, getgroupmembership, const char *name, u32 basegid, u32 *groups, COMMON_INTERCEPTOR_ENTER(ctx, getgroupmembership, name, basegid, groups, maxgrp, ngroups); if (name) - COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1); res = REAL(getgroupmembership)(name, basegid, groups, maxgrp, ngroups); if (!res && groups && ngroups) { COMMON_INTERCEPTOR_WRITE_RANGE(ctx, groups, sizeof(*groups) * (*ngroups)); @@ -7242,7 +7291,7 @@ INTERCEPTOR(int, getgroupmembership, const char *name, u32 basegid, u32 *groups, INTERCEPTOR(SSIZE_T, readlink, const char *path, char *buf, SIZE_T bufsiz) { void* ctx; COMMON_INTERCEPTOR_ENTER(ctx, readlink, path, buf, bufsiz); - COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1); SSIZE_T res = REAL(readlink)(path, buf, bufsiz); if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, res); @@ -7259,7 +7308,7 @@ INTERCEPTOR(SSIZE_T, readlinkat, int dirfd, const char *path, char *buf, SIZE_T bufsiz) { void* ctx; COMMON_INTERCEPTOR_ENTER(ctx, readlinkat, dirfd, path, buf, bufsiz); - COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1); SSIZE_T res = REAL(readlinkat)(dirfd, path, buf, bufsiz); if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, res); @@ -7277,7 +7326,7 @@ INTERCEPTOR(int, name_to_handle_at, int dirfd, const char *pathname, void* ctx; COMMON_INTERCEPTOR_ENTER(ctx, name_to_handle_at, dirfd, pathname, handle, mount_id, flags); - COMMON_INTERCEPTOR_READ_RANGE(ctx, pathname, REAL(strlen)(pathname) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, pathname, internal_strlen(pathname) + 1); __sanitizer_file_handle *sanitizer_handle = reinterpret_cast<__sanitizer_file_handle*>(handle); @@ -7341,7 +7390,7 @@ INTERCEPTOR(SIZE_T, strlcpy, char *dst, char *src, SIZE_T size) { ctx, src, Min(internal_strnlen(src, size), size - 1) + 1); } res = REAL(strlcpy)(dst, src, size); - COMMON_INTERCEPTOR_COPY_STRING(ctx, dst, src, REAL(strlen)(dst) + 1); + COMMON_INTERCEPTOR_COPY_STRING(ctx, dst, src, internal_strlen(dst) + 1); return res; } @@ -7416,7 +7465,7 @@ INTERCEPTOR(char *, devname, u64 dev, u32 type) { COMMON_INTERCEPTOR_ENTER(ctx, devname, dev, type); name = REAL(devname)(dev, type); if (name) - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, REAL(strlen)(name) + 1); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, internal_strlen(name) + 1); return name; } #define INIT_DEVNAME COMMON_INTERCEPT_FUNCTION(devname); @@ -7438,7 +7487,7 @@ INTERCEPTOR(DEVNAME_R_RETTYPE, devname_r, u64 dev, u32 type, char *path, COMMON_INTERCEPTOR_ENTER(ctx, devname_r, dev, type, path, len); DEVNAME_R_RETTYPE res = REAL(devname_r)(dev, type, path, len); if (DEVNAME_R_SUCCESS(res)) - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, path, REAL(strlen)(path) + 1); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, path, internal_strlen(path) + 1); return res; } #define INIT_DEVNAME_R COMMON_INTERCEPT_FUNCTION(devname_r); @@ -7468,7 +7517,7 @@ INTERCEPTOR(void, strmode, u32 mode, char *bp) { COMMON_INTERCEPTOR_ENTER(ctx, strmode, mode, bp); REAL(strmode)(mode, bp); if (bp) - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, bp, REAL(strlen)(bp) + 1); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, bp, internal_strlen(bp) + 1); } #define INIT_STRMODE COMMON_INTERCEPT_FUNCTION(strmode) #else @@ -7488,37 +7537,42 @@ INTERCEPTOR(struct __sanitizer_ttyent *, getttynam, char *name) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, getttynam, name); if (name) - COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1); struct __sanitizer_ttyent *ttyent = REAL(getttynam)(name); if (ttyent) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ttyent, struct_ttyent_sz); return ttyent; } +#define INIT_TTYENT \ + COMMON_INTERCEPT_FUNCTION(getttyent); \ + COMMON_INTERCEPT_FUNCTION(getttynam); +#else +#define INIT_TTYENT +#endif + +#if SANITIZER_INTERCEPT_TTYENTPATH INTERCEPTOR(int, setttyentpath, char *path) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, setttyentpath, path); if (path) - COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1); return REAL(setttyentpath)(path); } -#define INIT_TTYENT \ - COMMON_INTERCEPT_FUNCTION(getttyent); \ - COMMON_INTERCEPT_FUNCTION(getttynam); \ - COMMON_INTERCEPT_FUNCTION(setttyentpath) +#define INIT_TTYENTPATH COMMON_INTERCEPT_FUNCTION(setttyentpath); #else -#define INIT_TTYENT +#define INIT_TTYENTPATH #endif #if SANITIZER_INTERCEPT_PROTOENT static void write_protoent(void *ctx, struct __sanitizer_protoent *p) { COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p)); - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->p_name, REAL(strlen)(p->p_name) + 1); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->p_name, internal_strlen(p->p_name) + 1); SIZE_T pp_size = 1; // One handles the trailing \0 for (char **pp = p->p_aliases; *pp; ++pp, ++pp_size) - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *pp, REAL(strlen)(*pp) + 1); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *pp, internal_strlen(*pp) + 1); COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->p_aliases, pp_size * sizeof(char **)); @@ -7537,7 +7591,7 @@ INTERCEPTOR(struct __sanitizer_protoent *, getprotobyname, const char *name) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, getprotobyname, name); if (name) - COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1); struct __sanitizer_protoent *p = REAL(getprotobyname)(name); if (p) write_protoent(ctx, p); @@ -7581,7 +7635,7 @@ INTERCEPTOR(int, getprotobyname_r, const char *name, COMMON_INTERCEPTOR_ENTER(ctx, getprotobyname_r, name, result_buf, buf, buflen, result); if (name) - COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1); int res = REAL(getprotobyname_r)(name, result_buf, buf, buflen, result); COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof *result); @@ -7620,12 +7674,12 @@ INTERCEPTOR(struct __sanitizer_netent *, getnetent) { if (n) { COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n)); - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_name, REAL(strlen)(n->n_name) + 1); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_name, internal_strlen(n->n_name) + 1); SIZE_T nn_size = 1; // One handles the trailing \0 for (char **nn = n->n_aliases; *nn; ++nn, ++nn_size) - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *nn, REAL(strlen)(*nn) + 1); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *nn, internal_strlen(*nn) + 1); COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_aliases, nn_size * sizeof(char **)); @@ -7637,17 +7691,17 @@ INTERCEPTOR(struct __sanitizer_netent *, getnetbyname, const char *name) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, getnetbyname, name); if (name) - COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1); struct __sanitizer_netent *n = REAL(getnetbyname)(name); if (n) { COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n)); - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_name, REAL(strlen)(n->n_name) + 1); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_name, internal_strlen(n->n_name) + 1); SIZE_T nn_size = 1; // One handles the trailing \0 for (char **nn = n->n_aliases; *nn; ++nn, ++nn_size) - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *nn, REAL(strlen)(*nn) + 1); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *nn, internal_strlen(*nn) + 1); COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_aliases, nn_size * sizeof(char **)); @@ -7662,12 +7716,12 @@ INTERCEPTOR(struct __sanitizer_netent *, getnetbyaddr, u32 net, int type) { if (n) { COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n)); - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_name, REAL(strlen)(n->n_name) + 1); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_name, internal_strlen(n->n_name) + 1); SIZE_T nn_size = 1; // One handles the trailing \0 for (char **nn = n->n_aliases; *nn; ++nn, ++nn_size) - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *nn, REAL(strlen)(*nn) + 1); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *nn, internal_strlen(*nn) + 1); COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_aliases, nn_size * sizeof(char **)); @@ -7788,7 +7842,7 @@ INTERCEPTOR(int, regcomp, void *preg, const char *pattern, int cflags) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, regcomp, preg, pattern, cflags); if (pattern) - COMMON_INTERCEPTOR_READ_RANGE(ctx, pattern, REAL(strlen)(pattern) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, pattern, internal_strlen(pattern) + 1); int res = REAL(regcomp)(preg, pattern, cflags); if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, preg, struct_regex_sz); @@ -7801,7 +7855,7 @@ INTERCEPTOR(int, regexec, const void *preg, const char *string, SIZE_T nmatch, if (preg) COMMON_INTERCEPTOR_READ_RANGE(ctx, preg, struct_regex_sz); if (string) - COMMON_INTERCEPTOR_READ_RANGE(ctx, string, REAL(strlen)(string) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, string, internal_strlen(string) + 1); int res = REAL(regexec)(preg, string, nmatch, pmatch, eflags); if (!res && pmatch) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pmatch, nmatch * struct_regmatch_sz); @@ -7815,7 +7869,7 @@ INTERCEPTOR(SIZE_T, regerror, int errcode, const void *preg, char *errbuf, COMMON_INTERCEPTOR_READ_RANGE(ctx, preg, struct_regex_sz); SIZE_T res = REAL(regerror)(errcode, preg, errbuf, errbuf_size); if (errbuf) - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, errbuf, REAL(strlen)(errbuf) + 1); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, errbuf, internal_strlen(errbuf) + 1); return res; } INTERCEPTOR(void, regfree, const void *preg) { @@ -7840,15 +7894,15 @@ INTERCEPTOR(SSIZE_T, regnsub, char *buf, SIZE_T bufsiz, const char *sub, void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, regnsub, buf, bufsiz, sub, rm, str); if (sub) - COMMON_INTERCEPTOR_READ_RANGE(ctx, sub, REAL(strlen)(sub) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, sub, internal_strlen(sub) + 1); // The implementation demands and hardcodes 10 elements if (rm) COMMON_INTERCEPTOR_READ_RANGE(ctx, rm, 10 * struct_regmatch_sz); if (str) - COMMON_INTERCEPTOR_READ_RANGE(ctx, str, REAL(strlen)(str) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, str, internal_strlen(str) + 1); SSIZE_T res = REAL(regnsub)(buf, bufsiz, sub, rm, str); if (res > 0 && buf) - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, REAL(strlen)(buf) + 1); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, internal_strlen(buf) + 1); return res; } INTERCEPTOR(SSIZE_T, regasub, char **buf, const char *sub, @@ -7856,16 +7910,16 @@ INTERCEPTOR(SSIZE_T, regasub, char **buf, const char *sub, void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, regasub, buf, sub, rm, sstr); if (sub) - COMMON_INTERCEPTOR_READ_RANGE(ctx, sub, REAL(strlen)(sub) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, sub, internal_strlen(sub) + 1); // Hardcode 10 elements as this is hardcoded size if (rm) COMMON_INTERCEPTOR_READ_RANGE(ctx, rm, 10 * struct_regmatch_sz); if (sstr) - COMMON_INTERCEPTOR_READ_RANGE(ctx, sstr, REAL(strlen)(sstr) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, sstr, internal_strlen(sstr) + 1); SSIZE_T res = REAL(regasub)(buf, sub, rm, sstr); if (res > 0 && buf) { COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, sizeof(char *)); - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *buf, REAL(strlen)(*buf) + 1); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *buf, internal_strlen(*buf) + 1); } return res; } @@ -7887,7 +7941,7 @@ INTERCEPTOR(void *, fts_open, char *const *path_argv, int options, COMMON_INTERCEPTOR_READ_RANGE(ctx, pa, sizeof(char **)); if (!*pa) break; - COMMON_INTERCEPTOR_READ_RANGE(ctx, *pa, REAL(strlen)(*pa) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, *pa, internal_strlen(*pa) + 1); } } // TODO(kamil): handle compar callback @@ -7979,7 +8033,7 @@ INTERCEPTOR(int, sysctlbyname, char *sname, void *oldp, SIZE_T *oldlenp, COMMON_INTERCEPTOR_ENTER(ctx, sysctlbyname, sname, oldp, oldlenp, newp, newlen); if (sname) - COMMON_INTERCEPTOR_READ_RANGE(ctx, sname, REAL(strlen)(sname) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, sname, internal_strlen(sname) + 1); if (oldlenp) COMMON_INTERCEPTOR_READ_RANGE(ctx, oldlenp, sizeof(*oldlenp)); if (newp && newlen) @@ -8000,7 +8054,7 @@ INTERCEPTOR(int, sysctlnametomib, const char *sname, int *name, void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, sysctlnametomib, sname, name, namelenp); if (sname) - COMMON_INTERCEPTOR_READ_RANGE(ctx, sname, REAL(strlen)(sname) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, sname, internal_strlen(sname) + 1); if (namelenp) COMMON_INTERCEPTOR_READ_RANGE(ctx, namelenp, sizeof(*namelenp)); int res = REAL(sysctlnametomib)(sname, name, namelenp); @@ -8040,7 +8094,7 @@ INTERCEPTOR(void *, asysctlbyname, const char *sname, SIZE_T *len) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, asysctlbyname, sname, len); if (sname) - COMMON_INTERCEPTOR_READ_RANGE(ctx, sname, REAL(strlen)(sname) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, sname, internal_strlen(sname) + 1); void *res = REAL(asysctlbyname)(sname, len); if (res && len) { COMMON_INTERCEPTOR_WRITE_RANGE(ctx, len, sizeof(*len)); @@ -8063,7 +8117,7 @@ INTERCEPTOR(int, sysctlgetmibinfo, char *sname, int *name, COMMON_INTERCEPTOR_ENTER(ctx, sysctlgetmibinfo, sname, name, namelenp, cname, csz, rnode, v); if (sname) - COMMON_INTERCEPTOR_READ_RANGE(ctx, sname, REAL(strlen)(sname) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, sname, internal_strlen(sname) + 1); if (namelenp) COMMON_INTERCEPTOR_READ_RANGE(ctx, namelenp, sizeof(*namelenp)); if (csz) @@ -8097,7 +8151,7 @@ INTERCEPTOR(char *, nl_langinfo, long item) { COMMON_INTERCEPTOR_ENTER(ctx, nl_langinfo, item); char *ret = REAL(nl_langinfo)(item); if (ret) - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, REAL(strlen)(ret) + 1); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, internal_strlen(ret) + 1); return ret; } #define INIT_NL_LANGINFO COMMON_INTERCEPT_FUNCTION(nl_langinfo) @@ -8117,7 +8171,7 @@ INTERCEPTOR(int, modctl, int operation, void *argp) { COMMON_INTERCEPTOR_READ_RANGE(ctx, ml, sizeof(*ml)); if (ml->ml_filename) COMMON_INTERCEPTOR_READ_RANGE(ctx, ml->ml_filename, - REAL(strlen)(ml->ml_filename) + 1); + internal_strlen(ml->ml_filename) + 1); if (ml->ml_props) COMMON_INTERCEPTOR_READ_RANGE(ctx, ml->ml_props, ml->ml_propslen); } @@ -8125,7 +8179,7 @@ INTERCEPTOR(int, modctl, int operation, void *argp) { } else if (operation == modctl_unload) { if (argp) { const char *name = (const char *)argp; - COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1); } ret = REAL(modctl)(operation, argp); } else if (operation == modctl_stat) { @@ -8167,7 +8221,7 @@ INTERCEPTOR(long long, strtonum, const char *nptr, long long minval, if (errstr) { COMMON_INTERCEPTOR_WRITE_RANGE(ctx, errstr, sizeof(const char *)); if (*errstr) - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *errstr, REAL(strlen)(*errstr) + 1); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *errstr, internal_strlen(*errstr) + 1); } return ret; } @@ -8187,7 +8241,7 @@ INTERCEPTOR(char *, fparseln, __sanitizer_FILE *stream, SIZE_T *len, COMMON_INTERCEPTOR_READ_RANGE(ctx, delim, sizeof(delim[0]) * 3); char *ret = REAL(fparseln)(stream, len, lineno, delim, flags); if (ret) { - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, REAL(strlen)(ret) + 1); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, internal_strlen(ret) + 1); if (len) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, len, sizeof(*len)); if (lineno) @@ -8204,7 +8258,7 @@ INTERCEPTOR(char *, fparseln, __sanitizer_FILE *stream, SIZE_T *len, 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); + if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1); int res = REAL(statvfs1)(path, buf, flags); if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz); return res; @@ -8485,7 +8539,7 @@ INTERCEPTOR(char *, SHA1File, char *filename, char *buf) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, SHA1File, filename, buf); if (filename) - COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, REAL(strlen)(filename) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, internal_strlen(filename) + 1); char *ret = REAL(SHA1File)(filename, buf); if (ret) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA1_return_length); @@ -8496,7 +8550,7 @@ INTERCEPTOR(char *, SHA1FileChunk, char *filename, char *buf, OFF_T offset, void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, SHA1FileChunk, filename, buf, offset, length); if (filename) - COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, REAL(strlen)(filename) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, internal_strlen(filename) + 1); char *ret = REAL(SHA1FileChunk)(filename, buf, offset, length); if (ret) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA1_return_length); @@ -8572,7 +8626,7 @@ INTERCEPTOR(char *, MD4File, const char *filename, char *buf) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, MD4File, filename, buf); if (filename) - COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, REAL(strlen)(filename) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, internal_strlen(filename) + 1); char *ret = REAL(MD4File)(filename, buf); if (ret) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD4_return_length); @@ -8655,7 +8709,7 @@ INTERCEPTOR(char *, RMD160File, char *filename, char *buf) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, RMD160File, filename, buf); if (filename) - COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, REAL(strlen)(filename) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, internal_strlen(filename) + 1); char *ret = REAL(RMD160File)(filename, buf); if (ret) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, RMD160_return_length); @@ -8666,7 +8720,7 @@ INTERCEPTOR(char *, RMD160FileChunk, char *filename, char *buf, OFF_T offset, void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, RMD160FileChunk, filename, buf, offset, length); if (filename) - COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, REAL(strlen)(filename) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, internal_strlen(filename) + 1); char *ret = REAL(RMD160FileChunk)(filename, buf, offset, length); if (ret) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, RMD160_return_length); @@ -8742,7 +8796,7 @@ INTERCEPTOR(char *, MD5File, const char *filename, char *buf) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, MD5File, filename, buf); if (filename) - COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, REAL(strlen)(filename) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, internal_strlen(filename) + 1); char *ret = REAL(MD5File)(filename, buf); if (ret) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD5_return_length); @@ -8872,7 +8926,7 @@ INTERCEPTOR(char *, MD2File, const char *filename, char *buf) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, MD2File, filename, buf); if (filename) - COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, REAL(strlen)(filename) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, internal_strlen(filename) + 1); char *ret = REAL(MD2File)(filename, buf); if (ret) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD2_return_length); @@ -8950,7 +9004,7 @@ INTERCEPTOR(char *, MD2Data, const unsigned char *data, unsigned int len, void *ctx; \ COMMON_INTERCEPTOR_ENTER(ctx, SHA##LEN##_File, filename, buf); \ if (filename) \ - COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, REAL(strlen)(filename) + 1);\ + COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, internal_strlen(filename) + 1);\ char *ret = REAL(SHA##LEN##_File)(filename, buf); \ if (ret) \ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA##LEN##_return_length); \ @@ -8962,7 +9016,7 @@ INTERCEPTOR(char *, MD2Data, const unsigned char *data, unsigned int len, COMMON_INTERCEPTOR_ENTER(ctx, SHA##LEN##_FileChunk, filename, buf, offset, \ length); \ if (filename) \ - COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, REAL(strlen)(filename) + 1);\ + COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, internal_strlen(filename) + 1);\ char *ret = REAL(SHA##LEN##_FileChunk)(filename, buf, offset, length); \ if (ret) \ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA##LEN##_return_length); \ @@ -9026,7 +9080,7 @@ INTERCEPTOR(int, strvis, char *dst, const char *src, int flag) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, strvis, dst, src, flag); if (src) - COMMON_INTERCEPTOR_READ_RANGE(ctx, src, REAL(strlen)(src) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, src, internal_strlen(src) + 1); int len = REAL(strvis)(dst, src, flag); if (dst) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, len + 1); @@ -9036,7 +9090,7 @@ INTERCEPTOR(int, stravis, char **dst, const char *src, int flag) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, stravis, dst, src, flag); if (src) - COMMON_INTERCEPTOR_READ_RANGE(ctx, src, REAL(strlen)(src) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, src, internal_strlen(src) + 1); int len = REAL(stravis)(dst, src, flag); if (dst) { COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sizeof(char *)); @@ -9049,7 +9103,7 @@ INTERCEPTOR(int, strnvis, char *dst, SIZE_T dlen, const char *src, int flag) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, strnvis, dst, dlen, src, flag); if (src) - COMMON_INTERCEPTOR_READ_RANGE(ctx, src, REAL(strlen)(src) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, src, internal_strlen(src) + 1); int len = REAL(strnvis)(dst, dlen, src, flag); // The interface will be valid even if there is no space for NULL char if (dst && len > 0) @@ -9099,7 +9153,7 @@ INTERCEPTOR(char *, svis, char *dst, int c, int flag, int nextc, void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, svis, dst, c, flag, nextc, extra); if (extra) - COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, REAL(strlen)(extra) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, internal_strlen(extra) + 1); char *end = REAL(svis)(dst, c, flag, nextc, extra); if (dst && end) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, end - dst + 1); @@ -9110,7 +9164,7 @@ INTERCEPTOR(char *, snvis, char *dst, SIZE_T dlen, int c, int flag, int nextc, void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, snvis, dst, dlen, c, flag, nextc, extra); if (extra) - COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, REAL(strlen)(extra) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, internal_strlen(extra) + 1); char *end = REAL(snvis)(dst, dlen, c, flag, nextc, extra); if (dst && end) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, @@ -9122,9 +9176,9 @@ INTERCEPTOR(int, strsvis, char *dst, const char *src, int flag, void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, strsvis, dst, src, flag, extra); if (src) - COMMON_INTERCEPTOR_READ_RANGE(ctx, src, REAL(strlen)(src) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, src, internal_strlen(src) + 1); if (extra) - COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, REAL(strlen)(extra) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, internal_strlen(extra) + 1); int len = REAL(strsvis)(dst, src, flag, extra); if (dst) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, len + 1); @@ -9135,9 +9189,9 @@ INTERCEPTOR(int, strsnvis, char *dst, SIZE_T dlen, const char *src, int flag, void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, strsnvis, dst, dlen, src, flag, extra); if (src) - COMMON_INTERCEPTOR_READ_RANGE(ctx, src, REAL(strlen)(src) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, src, internal_strlen(src) + 1); if (extra) - COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, REAL(strlen)(extra) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, internal_strlen(extra) + 1); int len = REAL(strsnvis)(dst, dlen, src, flag, extra); // The interface will be valid even if there is no space for NULL char if (dst && len >= 0) @@ -9151,7 +9205,7 @@ INTERCEPTOR(int, strsvisx, char *dst, const char *src, SIZE_T len, int flag, if (src) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len); if (extra) - COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, REAL(strlen)(extra) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, internal_strlen(extra) + 1); int ret = REAL(strsvisx)(dst, src, len, flag, extra); if (dst) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1); @@ -9164,7 +9218,7 @@ INTERCEPTOR(int, strsnvisx, char *dst, SIZE_T dlen, const char *src, SIZE_T len, if (src) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len); if (extra) - COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, REAL(strlen)(extra) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, internal_strlen(extra) + 1); int ret = REAL(strsnvisx)(dst, dlen, src, len, flag, extra); if (dst && ret >= 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1); @@ -9178,7 +9232,7 @@ INTERCEPTOR(int, strsenvisx, char *dst, SIZE_T dlen, const char *src, if (src) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len); if (extra) - COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, REAL(strlen)(extra) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, internal_strlen(extra) + 1); // FIXME: only need to be checked when "flag | VIS_NOLOCALE" doesn't hold // according to the implementation if (cerr_ptr) @@ -9205,7 +9259,7 @@ INTERCEPTOR(int, strunvis, char *dst, const char *src) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, strunvis, dst, src); if (src) - COMMON_INTERCEPTOR_READ_RANGE(ctx, src, REAL(strlen)(src) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, src, internal_strlen(src) + 1); int ret = REAL(strunvis)(dst, src); if (ret != -1) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1); @@ -9215,7 +9269,7 @@ INTERCEPTOR(int, strnunvis, char *dst, SIZE_T dlen, const char *src) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, strnunvis, dst, dlen, src); if (src) - COMMON_INTERCEPTOR_READ_RANGE(ctx, src, REAL(strlen)(src) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, src, internal_strlen(src) + 1); int ret = REAL(strnunvis)(dst, dlen, src); if (ret != -1) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1); @@ -9225,7 +9279,7 @@ INTERCEPTOR(int, strunvisx, char *dst, const char *src, int flag) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, strunvisx, dst, src, flag); if (src) - COMMON_INTERCEPTOR_READ_RANGE(ctx, src, REAL(strlen)(src) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, src, internal_strlen(src) + 1); int ret = REAL(strunvisx)(dst, src, flag); if (ret != -1) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1); @@ -9236,7 +9290,7 @@ INTERCEPTOR(int, strnunvisx, char *dst, SIZE_T dlen, const char *src, void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, strnunvisx, dst, dlen, src, flag); if (src) - COMMON_INTERCEPTOR_READ_RANGE(ctx, src, REAL(strlen)(src) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, src, internal_strlen(src) + 1); int ret = REAL(strnunvisx)(dst, dlen, src, flag); if (ret != -1) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1); @@ -9272,7 +9326,7 @@ INTERCEPTOR(struct __sanitizer_cdbr *, cdbr_open, const char *path, int flags) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, cdbr_open, path, flags); if (path) - COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1); struct __sanitizer_cdbr *cdbr = REAL(cdbr_open)(path, flags); if (cdbr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cdbr, sizeof(*cdbr)); @@ -9464,7 +9518,7 @@ INTERCEPTOR(void *, getfsspec, const char *spec) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, getfsspec, spec); if (spec) - COMMON_INTERCEPTOR_READ_RANGE(ctx, spec, REAL(strlen)(spec) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, spec, internal_strlen(spec) + 1); void *ret = REAL(getfsspec)(spec); if (ret) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, struct_fstab_sz); @@ -9475,7 +9529,7 @@ INTERCEPTOR(void *, getfsfile, const char *file) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, getfsfile, file); if (file) - COMMON_INTERCEPTOR_READ_RANGE(ctx, file, REAL(strlen)(file) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, file, internal_strlen(file) + 1); void *ret = REAL(getfsfile)(file); if (ret) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, struct_fstab_sz); @@ -9519,9 +9573,9 @@ INTERCEPTOR(__sanitizer_FILE *, popen, const char *command, const char *type) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, popen, command, type); if (command) - COMMON_INTERCEPTOR_READ_RANGE(ctx, command, REAL(strlen)(command) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, command, internal_strlen(command) + 1); if (type) - COMMON_INTERCEPTOR_READ_RANGE(ctx, type, REAL(strlen)(type) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, type, internal_strlen(type) + 1); __sanitizer_FILE *res = REAL(popen)(command, type); COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, nullptr); if (res) unpoison_file(res); @@ -9538,13 +9592,13 @@ INTERCEPTOR(__sanitizer_FILE *, popenve, const char *path, void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, popenve, path, argv, envp, type); if (path) - COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1); if (argv) { for (char *const *pa = argv; ; ++pa) { COMMON_INTERCEPTOR_READ_RANGE(ctx, pa, sizeof(char **)); if (!*pa) break; - COMMON_INTERCEPTOR_READ_RANGE(ctx, *pa, REAL(strlen)(*pa) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, *pa, internal_strlen(*pa) + 1); } } if (envp) { @@ -9552,11 +9606,11 @@ INTERCEPTOR(__sanitizer_FILE *, popenve, const char *path, COMMON_INTERCEPTOR_READ_RANGE(ctx, pa, sizeof(char **)); if (!*pa) break; - COMMON_INTERCEPTOR_READ_RANGE(ctx, *pa, REAL(strlen)(*pa) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, *pa, internal_strlen(*pa) + 1); } } if (type) - COMMON_INTERCEPTOR_READ_RANGE(ctx, type, REAL(strlen)(type) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, type, internal_strlen(type) + 1); __sanitizer_FILE *res = REAL(popenve)(path, argv, envp, type); COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, nullptr); if (res) unpoison_file(res); @@ -9752,7 +9806,7 @@ INTERCEPTOR(char *, fdevname, int fd) { COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); char *name = REAL(fdevname)(fd); if (name) { - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, REAL(strlen)(name) + 1); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, internal_strlen(name) + 1); if (fd > 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); } @@ -9765,7 +9819,7 @@ INTERCEPTOR(char *, fdevname_r, int fd, char *buf, SIZE_T len) { COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); char *name = REAL(fdevname_r)(fd, buf, len); if (name && buf && len > 0) { - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, REAL(strlen)(buf) + 1); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, internal_strlen(buf) + 1); if (fd > 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); } @@ -9785,7 +9839,7 @@ INTERCEPTOR(char *, getusershell) { COMMON_INTERCEPTOR_ENTER(ctx, getusershell); char *res = REAL(getusershell)(); if (res) - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1); return res; } @@ -9810,7 +9864,7 @@ INTERCEPTOR(int, sl_add, void *sl, char *item) { if (sl) COMMON_INTERCEPTOR_READ_RANGE(ctx, sl, __sanitizer::struct_StringList_sz); if (item) - COMMON_INTERCEPTOR_READ_RANGE(ctx, item, REAL(strlen)(item) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, item, internal_strlen(item) + 1); int res = REAL(sl_add)(sl, item); if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sl, __sanitizer::struct_StringList_sz); @@ -9823,10 +9877,10 @@ INTERCEPTOR(char *, sl_find, void *sl, const char *item) { if (sl) COMMON_INTERCEPTOR_READ_RANGE(ctx, sl, __sanitizer::struct_StringList_sz); if (item) - COMMON_INTERCEPTOR_READ_RANGE(ctx, item, REAL(strlen)(item) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, item, internal_strlen(item) + 1); char *res = REAL(sl_find)(sl, item); if (res) - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1); return res; } @@ -9912,7 +9966,52 @@ INTERCEPTOR(int, getentropy, void *buf, SIZE_T buflen) { #define INIT_GETENTROPY #endif -#if SANITIZER_INTERCEPT_QSORT +#if SANITIZER_INTERCEPT_QSORT_R +typedef int (*qsort_r_compar_f)(const void *, const void *, void *); +struct qsort_r_compar_params { + SIZE_T size; + qsort_r_compar_f compar; + void *arg; +}; +static int wrapped_qsort_r_compar(const void *a, const void *b, void *arg) { + qsort_r_compar_params *params = (qsort_r_compar_params *)arg; + COMMON_INTERCEPTOR_UNPOISON_PARAM(3); + COMMON_INTERCEPTOR_INITIALIZE_RANGE(a, params->size); + COMMON_INTERCEPTOR_INITIALIZE_RANGE(b, params->size); + return params->compar(a, b, params->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_params params = {size, compar, arg}; + REAL(qsort_r)(base, nmemb, size, wrapped_qsort_r_compar, ¶ms); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, base, nmemb * size); +} +# define INIT_QSORT_R COMMON_INTERCEPT_FUNCTION(qsort_r) +#else +# define INIT_QSORT_R +#endif + +#if SANITIZER_INTERCEPT_QSORT && SANITIZER_INTERCEPT_QSORT_R +INTERCEPTOR(void, qsort, void *base, SIZE_T nmemb, SIZE_T size, + qsort_r_compar_f compar) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, qsort, base, nmemb, size, compar); + WRAP(qsort_r)(base, nmemb, size, compar, nullptr); +} +# define INIT_QSORT COMMON_INTERCEPT_FUNCTION(qsort) +#elif SANITIZER_INTERCEPT_QSORT && !SANITIZER_INTERCEPT_QSORT_R // 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 @@ -9927,7 +10026,7 @@ INTERCEPTOR(int, getentropy, void *buf, SIZE_T buflen) { 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) { +static 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); @@ -9969,60 +10068,34 @@ INTERCEPTOR(void, qsort, void *base, SIZE_T nmemb, SIZE_T size, } COMMON_INTERCEPTOR_WRITE_RANGE(ctx, base, nmemb * size); } -#define INIT_QSORT COMMON_INTERCEPT_FUNCTION(qsort) +# define INIT_QSORT COMMON_INTERCEPT_FUNCTION(qsort) #else -#define INIT_QSORT +# 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); +#if SANITIZER_INTERCEPT_BSEARCH +typedef int (*bsearch_compar_f)(const void *, const void *); +struct bsearch_compar_params { + const void *key; + bsearch_compar_f compar; +}; + +static int wrapped_bsearch_compar(const void *key, const void *b) { + const bsearch_compar_params *params = (const bsearch_compar_params *)key; + COMMON_INTERCEPTOR_UNPOISON_PARAM(2); + return params->compar(params->key, b); } -INTERCEPTOR(void, qsort_r, void *base, SIZE_T nmemb, SIZE_T size, - qsort_r_compar_f compar, void *arg) { +INTERCEPTOR(void *, bsearch, const void *key, const void *base, SIZE_T nmemb, + SIZE_T size, bsearch_compar_f compar) { 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; - SIZE_T old_size = qsort_r_size; - // Handle qsort_r() implementations that recurse using an - // interposable function call: - bool already_wrapped = compar == wrapped_qsort_r_compar; - if (already_wrapped) { - // This case should only happen if the qsort() implementation calls itself - // using a preemptible function call (e.g. the FreeBSD libc version). - // Check that the size and comparator arguments are as expected. - CHECK_NE(compar, qsort_r_compar); - CHECK_EQ(qsort_r_size, size); - } else { - qsort_r_compar = compar; - qsort_r_size = size; - } - REAL(qsort_r)(base, nmemb, size, wrapped_qsort_r_compar, arg); - if (!already_wrapped) { - qsort_r_compar = old_compar; - qsort_r_size = old_size; - } - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, base, nmemb * size); + COMMON_INTERCEPTOR_ENTER(ctx, bsearch, key, base, nmemb, size, compar); + bsearch_compar_params params = {key, compar}; + return REAL(bsearch)(¶ms, base, nmemb, size, wrapped_bsearch_compar); } -#define INIT_QSORT_R COMMON_INTERCEPT_FUNCTION(qsort_r) +# define INIT_BSEARCH COMMON_INTERCEPT_FUNCTION(bsearch) #else -#define INIT_QSORT_R +# define INIT_BSEARCH #endif #if SANITIZER_INTERCEPT_SIGALTSTACK @@ -10391,6 +10464,7 @@ static void InitializeCommonInterceptors() { INIT_GETENTROPY; INIT_QSORT; INIT_QSORT_R; + INIT_BSEARCH; INIT_SIGALTSTACK; INIT_UNAME; INIT___XUNAME; diff --git a/libsanitizer/sanitizer_common/sanitizer_common_interceptors_format.inc b/libsanitizer/sanitizer_common/sanitizer_common_interceptors_format.inc index 082398b..220abb8 100644 --- a/libsanitizer/sanitizer_common/sanitizer_common_interceptors_format.inc +++ b/libsanitizer/sanitizer_common/sanitizer_common_interceptors_format.inc @@ -324,8 +324,8 @@ static void scanf_common(void *ctx, int n_inputs, bool allowGnuMalloc, continue; int size = scanf_get_value_size(&dir); if (size == FSS_INVALID) { - Report("%s: WARNING: unexpected format specifier in scanf interceptor: ", - SanitizerToolName, "%.*s\n", dir.end - dir.begin, dir.begin); + Report("%s: WARNING: unexpected format specifier in scanf interceptor: %.*s\n", + SanitizerToolName, static_cast<int>(dir.end - dir.begin), dir.begin); break; } void *argp = va_arg(aq, void *); @@ -469,7 +469,7 @@ static int printf_get_value_size(PrintfDirective *dir) { break; \ default: \ Report("WARNING: unexpected floating-point arg size" \ - " in printf interceptor: %d\n", size); \ + " in printf interceptor: %zu\n", static_cast<uptr>(size)); \ return; \ } \ } else { \ @@ -484,7 +484,7 @@ static int printf_get_value_size(PrintfDirective *dir) { break; \ default: \ Report("WARNING: unexpected arg size" \ - " in printf interceptor: %d\n", size); \ + " in printf interceptor: %zu\n", static_cast<uptr>(size)); \ return; \ } \ } \ @@ -530,7 +530,7 @@ static void printf_common(void *ctx, const char *format, va_list aq) { Report( "%s: WARNING: unexpected format specifier in printf " "interceptor: %.*s (reported once per process)\n", - SanitizerToolName, dir.end - dir.begin, dir.begin); + SanitizerToolName, static_cast<int>(dir.end - dir.begin), dir.begin); break; } if (dir.convSpecifier == 'n') { diff --git a/libsanitizer/sanitizer_common/sanitizer_common_interceptors_netbsd_compat.inc b/libsanitizer/sanitizer_common/sanitizer_common_interceptors_netbsd_compat.inc index 6aa73ec..f6ac3fa 100644 --- a/libsanitizer/sanitizer_common/sanitizer_common_interceptors_netbsd_compat.inc +++ b/libsanitizer/sanitizer_common/sanitizer_common_interceptors_netbsd_compat.inc @@ -33,7 +33,7 @@ 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); + if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_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. @@ -99,7 +99,7 @@ INTERCEPTOR(int, getvfsstat, void *buf, SIZE_T bufsize, int flags) { 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); + if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1); int res = REAL(statvfs1)(path, buf, flags); if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs90_sz); return res; diff --git a/libsanitizer/sanitizer_common/sanitizer_common_nolibc.cpp b/libsanitizer/sanitizer_common/sanitizer_common_nolibc.cpp index 9a4e538..a20602d 100644 --- a/libsanitizer/sanitizer_common/sanitizer_common_nolibc.cpp +++ b/libsanitizer/sanitizer_common/sanitizer_common_nolibc.cpp @@ -25,6 +25,7 @@ void LogMessageOnPrintf(const char *str) {} #endif void WriteToSyslog(const char *buffer) {} void Abort() { internal__exit(1); } +bool CreateDir(const char *pathname) { return false; } #endif // !SANITIZER_WINDOWS #if !SANITIZER_WINDOWS && !SANITIZER_MAC diff --git a/libsanitizer/sanitizer_common/sanitizer_common_syscalls.inc b/libsanitizer/sanitizer_common/sanitizer_common_syscalls.inc index 1b89d6e..a38b134 100644 --- a/libsanitizer/sanitizer_common/sanitizer_common_syscalls.inc +++ b/libsanitizer/sanitizer_common/sanitizer_common_syscalls.inc @@ -43,45 +43,47 @@ #include "sanitizer_platform.h" #if SANITIZER_LINUX -#include "sanitizer_libc.h" +# include "sanitizer_libc.h" -#define PRE_SYSCALL(name) \ - SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_syscall_pre_impl_##name -#define PRE_READ(p, s) COMMON_SYSCALL_PRE_READ_RANGE(p, s) -#define PRE_WRITE(p, s) COMMON_SYSCALL_PRE_WRITE_RANGE(p, s) +# define PRE_SYSCALL(name) \ + SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_syscall_pre_impl_##name +# define PRE_READ(p, s) COMMON_SYSCALL_PRE_READ_RANGE(p, s) +# define PRE_WRITE(p, s) COMMON_SYSCALL_PRE_WRITE_RANGE(p, s) -#define POST_SYSCALL(name) \ - SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_syscall_post_impl_##name -#define POST_READ(p, s) COMMON_SYSCALL_POST_READ_RANGE(p, s) -#define POST_WRITE(p, s) COMMON_SYSCALL_POST_WRITE_RANGE(p, s) +# define POST_SYSCALL(name) \ + SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_syscall_post_impl_##name +# define POST_READ(p, s) COMMON_SYSCALL_POST_READ_RANGE(p, s) +# define POST_WRITE(p, s) COMMON_SYSCALL_POST_WRITE_RANGE(p, s) -#ifndef COMMON_SYSCALL_ACQUIRE -# define COMMON_SYSCALL_ACQUIRE(addr) ((void)(addr)) -#endif +# ifndef COMMON_SYSCALL_ACQUIRE +# define COMMON_SYSCALL_ACQUIRE(addr) ((void)(addr)) +# endif -#ifndef COMMON_SYSCALL_RELEASE -# define COMMON_SYSCALL_RELEASE(addr) ((void)(addr)) -#endif +# ifndef COMMON_SYSCALL_RELEASE +# define COMMON_SYSCALL_RELEASE(addr) ((void)(addr)) +# endif -#ifndef COMMON_SYSCALL_FD_CLOSE -# define COMMON_SYSCALL_FD_CLOSE(fd) ((void)(fd)) -#endif +# ifndef COMMON_SYSCALL_FD_CLOSE +# define COMMON_SYSCALL_FD_CLOSE(fd) ((void)(fd)) +# endif -#ifndef COMMON_SYSCALL_FD_ACQUIRE -# define COMMON_SYSCALL_FD_ACQUIRE(fd) ((void)(fd)) -#endif +# ifndef COMMON_SYSCALL_FD_ACQUIRE +# define COMMON_SYSCALL_FD_ACQUIRE(fd) ((void)(fd)) +# endif -#ifndef COMMON_SYSCALL_FD_RELEASE -# define COMMON_SYSCALL_FD_RELEASE(fd) ((void)(fd)) -#endif +# ifndef COMMON_SYSCALL_FD_RELEASE +# define COMMON_SYSCALL_FD_RELEASE(fd) ((void)(fd)) +# endif -#ifndef COMMON_SYSCALL_PRE_FORK -# define COMMON_SYSCALL_PRE_FORK() {} -#endif +# ifndef COMMON_SYSCALL_PRE_FORK +# define COMMON_SYSCALL_PRE_FORK() \ + {} +# endif -#ifndef COMMON_SYSCALL_POST_FORK -# define COMMON_SYSCALL_POST_FORK(res) {} -#endif +# ifndef COMMON_SYSCALL_POST_FORK +# define COMMON_SYSCALL_POST_FORK(res) \ + {} +# endif // FIXME: do some kind of PRE_READ for all syscall arguments (int(s) and such). @@ -130,8 +132,8 @@ struct sanitizer_kernel_sockaddr { // Declare it "void" to catch sizeof(kernel_sigset_t). typedef void kernel_sigset_t; -static void kernel_write_iovec(const __sanitizer_iovec *iovec, - SIZE_T iovlen, SIZE_T maxlen) { +static void kernel_write_iovec(const __sanitizer_iovec *iovec, SIZE_T iovlen, + SIZE_T maxlen) { for (SIZE_T i = 0; i < iovlen && maxlen; ++i) { SSIZE_T sz = Min(iovec[i].iov_len, maxlen); POST_WRITE(iovec[i].iov_base, sz); @@ -141,8 +143,8 @@ static void kernel_write_iovec(const __sanitizer_iovec *iovec, // This functions uses POST_READ, because it needs to run after syscall to know // the real read range. -static void kernel_read_iovec(const __sanitizer_iovec *iovec, - SIZE_T iovlen, SIZE_T maxlen) { +static void kernel_read_iovec(const __sanitizer_iovec *iovec, SIZE_T iovlen, + SIZE_T maxlen) { POST_READ(iovec, sizeof(*iovec) * iovlen); for (SIZE_T i = 0; i < iovlen && maxlen; ++i) { SSIZE_T sz = Min(iovec[i].iov_len, maxlen); @@ -155,8 +157,8 @@ PRE_SYSCALL(recvmsg)(long sockfd, sanitizer_kernel_msghdr *msg, long flags) { PRE_READ(msg, sizeof(*msg)); } -POST_SYSCALL(recvmsg)(long res, long sockfd, sanitizer_kernel_msghdr *msg, - long flags) { +POST_SYSCALL(recvmsg) +(long res, long sockfd, sanitizer_kernel_msghdr *msg, long flags) { if (res >= 0) { if (msg) { for (unsigned long i = 0; i < msg->msg_iovlen; ++i) { @@ -167,13 +169,14 @@ POST_SYSCALL(recvmsg)(long res, long sockfd, sanitizer_kernel_msghdr *msg, } } -PRE_SYSCALL(recvmmsg)(long fd, sanitizer_kernel_mmsghdr *msg, long vlen, - long flags, void *timeout) { +PRE_SYSCALL(recvmmsg) +(long fd, sanitizer_kernel_mmsghdr *msg, long vlen, long flags, void *timeout) { PRE_READ(msg, vlen * sizeof(*msg)); } -POST_SYSCALL(recvmmsg)(long res, long fd, sanitizer_kernel_mmsghdr *msg, - long vlen, long flags, void *timeout) { +POST_SYSCALL(recvmmsg) +(long res, long fd, sanitizer_kernel_mmsghdr *msg, long vlen, long flags, + void *timeout) { if (res >= 0) { if (msg) { for (unsigned long i = 0; i < msg->msg_hdr.msg_iovlen; ++i) { @@ -183,7 +186,8 @@ POST_SYSCALL(recvmmsg)(long res, long fd, sanitizer_kernel_mmsghdr *msg, POST_WRITE(msg->msg_hdr.msg_control, msg->msg_hdr.msg_controllen); POST_WRITE(&msg->msg_len, sizeof(msg->msg_len)); } - if (timeout) POST_WRITE(timeout, struct_timespec_sz); + if (timeout) + POST_WRITE(timeout, struct_timespec_sz); } } @@ -203,7 +207,8 @@ PRE_SYSCALL(time)(void *tloc) {} POST_SYSCALL(time)(long res, void *tloc) { if (res >= 0) { - if (tloc) POST_WRITE(tloc, sizeof(long)); + if (tloc) + POST_WRITE(tloc, sizeof(long)); } } @@ -211,7 +216,8 @@ PRE_SYSCALL(stime)(void *tptr) {} POST_SYSCALL(stime)(long res, void *tptr) { if (res >= 0) { - if (tptr) POST_WRITE(tptr, sizeof(long)); + if (tptr) + POST_WRITE(tptr, sizeof(long)); } } @@ -219,8 +225,10 @@ PRE_SYSCALL(gettimeofday)(void *tv, void *tz) {} POST_SYSCALL(gettimeofday)(long res, void *tv, void *tz) { if (res >= 0) { - if (tv) POST_WRITE(tv, timeval_sz); - if (tz) POST_WRITE(tz, struct_timezone_sz); + if (tv) + POST_WRITE(tv, timeval_sz); + if (tz) + POST_WRITE(tz, struct_timezone_sz); } } @@ -228,26 +236,30 @@ PRE_SYSCALL(settimeofday)(void *tv, void *tz) {} POST_SYSCALL(settimeofday)(long res, void *tv, void *tz) { if (res >= 0) { - if (tv) POST_WRITE(tv, timeval_sz); - if (tz) POST_WRITE(tz, struct_timezone_sz); + if (tv) + POST_WRITE(tv, timeval_sz); + if (tz) + POST_WRITE(tz, struct_timezone_sz); } } -#if !SANITIZER_ANDROID +# if !SANITIZER_ANDROID PRE_SYSCALL(adjtimex)(void *txc_p) {} POST_SYSCALL(adjtimex)(long res, void *txc_p) { if (res >= 0) { - if (txc_p) POST_WRITE(txc_p, struct_timex_sz); + if (txc_p) + POST_WRITE(txc_p, struct_timex_sz); } } -#endif +# endif PRE_SYSCALL(times)(void *tbuf) {} POST_SYSCALL(times)(long res, void *tbuf) { if (res >= 0) { - if (tbuf) POST_WRITE(tbuf, struct_tms_sz); + if (tbuf) + POST_WRITE(tbuf, struct_tms_sz); } } @@ -259,8 +271,10 @@ PRE_SYSCALL(nanosleep)(void *rqtp, void *rmtp) {} POST_SYSCALL(nanosleep)(long res, void *rqtp, void *rmtp) { if (res >= 0) { - if (rqtp) POST_WRITE(rqtp, struct_timespec_sz); - if (rmtp) POST_WRITE(rmtp, struct_timespec_sz); + if (rqtp) + POST_WRITE(rqtp, struct_timespec_sz); + if (rmtp) + POST_WRITE(rmtp, struct_timespec_sz); } } @@ -296,9 +310,12 @@ PRE_SYSCALL(getresuid)(void *ruid, void *euid, void *suid) {} POST_SYSCALL(getresuid)(long res, void *ruid, void *euid, void *suid) { if (res >= 0) { - if (ruid) POST_WRITE(ruid, sizeof(unsigned)); - if (euid) POST_WRITE(euid, sizeof(unsigned)); - if (suid) POST_WRITE(suid, sizeof(unsigned)); + if (ruid) + POST_WRITE(ruid, sizeof(unsigned)); + if (euid) + POST_WRITE(euid, sizeof(unsigned)); + if (suid) + POST_WRITE(suid, sizeof(unsigned)); } } @@ -306,9 +323,12 @@ PRE_SYSCALL(getresgid)(void *rgid, void *egid, void *sgid) {} POST_SYSCALL(getresgid)(long res, void *rgid, void *egid, void *sgid) { if (res >= 0) { - if (rgid) POST_WRITE(rgid, sizeof(unsigned)); - if (egid) POST_WRITE(egid, sizeof(unsigned)); - if (sgid) POST_WRITE(sgid, sizeof(unsigned)); + if (rgid) + POST_WRITE(rgid, sizeof(unsigned)); + if (egid) + POST_WRITE(egid, sizeof(unsigned)); + if (sgid) + POST_WRITE(sgid, sizeof(unsigned)); } } @@ -326,10 +346,11 @@ POST_SYSCALL(getsid)(long res, long pid) {} PRE_SYSCALL(getgroups)(long gidsetsize, void *grouplist) {} -POST_SYSCALL(getgroups)(long res, long gidsetsize, - __sanitizer___kernel_gid_t *grouplist) { +POST_SYSCALL(getgroups) +(long res, long gidsetsize, __sanitizer___kernel_gid_t *grouplist) { if (res >= 0) { - if (grouplist) POST_WRITE(grouplist, res * sizeof(*grouplist)); + if (grouplist) + POST_WRITE(grouplist, res * sizeof(*grouplist)); } } @@ -374,11 +395,12 @@ PRE_SYSCALL(setsid)() {} POST_SYSCALL(setsid)(long res) {} PRE_SYSCALL(setgroups)(long gidsetsize, __sanitizer___kernel_gid_t *grouplist) { - if (grouplist) POST_WRITE(grouplist, gidsetsize * sizeof(*grouplist)); + if (grouplist) + POST_WRITE(grouplist, gidsetsize * sizeof(*grouplist)); } -POST_SYSCALL(setgroups)(long res, long gidsetsize, - __sanitizer___kernel_gid_t *grouplist) {} +POST_SYSCALL(setgroups) +(long res, long gidsetsize, __sanitizer___kernel_gid_t *grouplist) {} PRE_SYSCALL(acct)(const void *name) { if (name) @@ -388,17 +410,21 @@ PRE_SYSCALL(acct)(const void *name) { POST_SYSCALL(acct)(long res, const void *name) {} PRE_SYSCALL(capget)(void *header, void *dataptr) { - if (header) PRE_READ(header, __user_cap_header_struct_sz); + if (header) + PRE_READ(header, __user_cap_header_struct_sz); } POST_SYSCALL(capget)(long res, void *header, void *dataptr) { if (res >= 0) - if (dataptr) POST_WRITE(dataptr, __user_cap_data_struct_sz); + if (dataptr) + POST_WRITE(dataptr, __user_cap_data_struct_sz); } PRE_SYSCALL(capset)(void *header, const void *data) { - if (header) PRE_READ(header, __user_cap_header_struct_sz); - if (data) PRE_READ(data, __user_cap_data_struct_sz); + if (header) + PRE_READ(header, __user_cap_header_struct_sz); + if (data) + PRE_READ(data, __user_cap_data_struct_sz); } POST_SYSCALL(capset)(long res, void *header, const void *data) {} @@ -411,7 +437,8 @@ PRE_SYSCALL(sigpending)(void *set) {} POST_SYSCALL(sigpending)(long res, void *set) { if (res >= 0) { - if (set) POST_WRITE(set, old_sigset_t_sz); + if (set) + POST_WRITE(set, old_sigset_t_sz); } } @@ -419,8 +446,10 @@ PRE_SYSCALL(sigprocmask)(long how, void *set, void *oset) {} POST_SYSCALL(sigprocmask)(long res, long how, void *set, void *oset) { if (res >= 0) { - if (set) POST_WRITE(set, old_sigset_t_sz); - if (oset) POST_WRITE(oset, old_sigset_t_sz); + if (set) + POST_WRITE(set, old_sigset_t_sz); + if (oset) + POST_WRITE(oset, old_sigset_t_sz); } } @@ -428,7 +457,8 @@ PRE_SYSCALL(getitimer)(long which, void *value) {} POST_SYSCALL(getitimer)(long res, long which, void *value) { if (res >= 0) { - if (value) POST_WRITE(value, struct_itimerval_sz); + if (value) + POST_WRITE(value, struct_itimerval_sz); } } @@ -436,19 +466,23 @@ PRE_SYSCALL(setitimer)(long which, void *value, void *ovalue) {} POST_SYSCALL(setitimer)(long res, long which, void *value, void *ovalue) { if (res >= 0) { - if (value) POST_WRITE(value, struct_itimerval_sz); - if (ovalue) POST_WRITE(ovalue, struct_itimerval_sz); + if (value) + POST_WRITE(value, struct_itimerval_sz); + if (ovalue) + POST_WRITE(ovalue, struct_itimerval_sz); } } -PRE_SYSCALL(timer_create)(long which_clock, void *timer_event_spec, - void *created_timer_id) {} +PRE_SYSCALL(timer_create) +(long which_clock, void *timer_event_spec, void *created_timer_id) {} -POST_SYSCALL(timer_create)(long res, long which_clock, void *timer_event_spec, - void *created_timer_id) { +POST_SYSCALL(timer_create) +(long res, long which_clock, void *timer_event_spec, void *created_timer_id) { if (res >= 0) { - if (timer_event_spec) POST_WRITE(timer_event_spec, struct_sigevent_sz); - if (created_timer_id) POST_WRITE(created_timer_id, sizeof(long)); + if (timer_event_spec) + POST_WRITE(timer_event_spec, struct_sigevent_sz); + if (created_timer_id) + POST_WRITE(created_timer_id, sizeof(long)); } } @@ -456,7 +490,8 @@ PRE_SYSCALL(timer_gettime)(long timer_id, void *setting) {} POST_SYSCALL(timer_gettime)(long res, long timer_id, void *setting) { if (res >= 0) { - if (setting) POST_WRITE(setting, struct_itimerspec_sz); + if (setting) + POST_WRITE(setting, struct_itimerspec_sz); } } @@ -464,15 +499,18 @@ PRE_SYSCALL(timer_getoverrun)(long timer_id) {} POST_SYSCALL(timer_getoverrun)(long res, long timer_id) {} -PRE_SYSCALL(timer_settime)(long timer_id, long flags, const void *new_setting, - void *old_setting) { - if (new_setting) PRE_READ(new_setting, struct_itimerspec_sz); +PRE_SYSCALL(timer_settime) +(long timer_id, long flags, const void *new_setting, void *old_setting) { + if (new_setting) + PRE_READ(new_setting, struct_itimerspec_sz); } -POST_SYSCALL(timer_settime)(long res, long timer_id, long flags, - const void *new_setting, void *old_setting) { +POST_SYSCALL(timer_settime) +(long res, long timer_id, long flags, const void *new_setting, + void *old_setting) { if (res >= 0) { - if (old_setting) POST_WRITE(old_setting, struct_itimerspec_sz); + if (old_setting) + POST_WRITE(old_setting, struct_itimerspec_sz); } } @@ -481,7 +519,8 @@ PRE_SYSCALL(timer_delete)(long timer_id) {} POST_SYSCALL(timer_delete)(long res, long timer_id) {} PRE_SYSCALL(clock_settime)(long which_clock, const void *tp) { - if (tp) PRE_READ(tp, struct_timespec_sz); + if (tp) + PRE_READ(tp, struct_timespec_sz); } POST_SYSCALL(clock_settime)(long res, long which_clock, const void *tp) {} @@ -490,37 +529,42 @@ PRE_SYSCALL(clock_gettime)(long which_clock, void *tp) {} POST_SYSCALL(clock_gettime)(long res, long which_clock, void *tp) { if (res >= 0) { - if (tp) POST_WRITE(tp, struct_timespec_sz); + if (tp) + POST_WRITE(tp, struct_timespec_sz); } } -#if !SANITIZER_ANDROID +# if !SANITIZER_ANDROID PRE_SYSCALL(clock_adjtime)(long which_clock, void *tx) {} POST_SYSCALL(clock_adjtime)(long res, long which_clock, void *tx) { if (res >= 0) { - if (tx) POST_WRITE(tx, struct_timex_sz); + if (tx) + POST_WRITE(tx, struct_timex_sz); } } -#endif +# endif PRE_SYSCALL(clock_getres)(long which_clock, void *tp) {} POST_SYSCALL(clock_getres)(long res, long which_clock, void *tp) { if (res >= 0) { - if (tp) POST_WRITE(tp, struct_timespec_sz); + if (tp) + POST_WRITE(tp, struct_timespec_sz); } } -PRE_SYSCALL(clock_nanosleep)(long which_clock, long flags, const void *rqtp, - void *rmtp) { - if (rqtp) PRE_READ(rqtp, struct_timespec_sz); +PRE_SYSCALL(clock_nanosleep) +(long which_clock, long flags, const void *rqtp, void *rmtp) { + if (rqtp) + PRE_READ(rqtp, struct_timespec_sz); } -POST_SYSCALL(clock_nanosleep)(long res, long which_clock, long flags, - const void *rqtp, void *rmtp) { +POST_SYSCALL(clock_nanosleep) +(long res, long which_clock, long flags, const void *rqtp, void *rmtp) { if (res >= 0) { - if (rmtp) POST_WRITE(rmtp, struct_timespec_sz); + if (rmtp) + POST_WRITE(rmtp, struct_timespec_sz); } } @@ -532,12 +576,14 @@ PRE_SYSCALL(sched_setscheduler)(long pid, long policy, void *param) {} POST_SYSCALL(sched_setscheduler)(long res, long pid, long policy, void *param) { if (res >= 0) { - if (param) POST_WRITE(param, struct_sched_param_sz); + if (param) + POST_WRITE(param, struct_sched_param_sz); } } PRE_SYSCALL(sched_setparam)(long pid, void *param) { - if (param) PRE_READ(param, struct_sched_param_sz); + if (param) + PRE_READ(param, struct_sched_param_sz); } POST_SYSCALL(sched_setparam)(long res, long pid, void *param) {} @@ -550,23 +596,26 @@ PRE_SYSCALL(sched_getparam)(long pid, void *param) {} POST_SYSCALL(sched_getparam)(long res, long pid, void *param) { if (res >= 0) { - if (param) POST_WRITE(param, struct_sched_param_sz); + if (param) + POST_WRITE(param, struct_sched_param_sz); } } PRE_SYSCALL(sched_setaffinity)(long pid, long len, void *user_mask_ptr) { - if (user_mask_ptr) PRE_READ(user_mask_ptr, len); + if (user_mask_ptr) + PRE_READ(user_mask_ptr, len); } -POST_SYSCALL(sched_setaffinity)(long res, long pid, long len, - void *user_mask_ptr) {} +POST_SYSCALL(sched_setaffinity) +(long res, long pid, long len, void *user_mask_ptr) {} PRE_SYSCALL(sched_getaffinity)(long pid, long len, void *user_mask_ptr) {} -POST_SYSCALL(sched_getaffinity)(long res, long pid, long len, - void *user_mask_ptr) { +POST_SYSCALL(sched_getaffinity) +(long res, long pid, long len, void *user_mask_ptr) { if (res >= 0) { - if (user_mask_ptr) POST_WRITE(user_mask_ptr, len); + if (user_mask_ptr) + POST_WRITE(user_mask_ptr, len); } } @@ -586,7 +635,8 @@ PRE_SYSCALL(sched_rr_get_interval)(long pid, void *interval) {} POST_SYSCALL(sched_rr_get_interval)(long res, long pid, void *interval) { if (res >= 0) { - if (interval) POST_WRITE(interval, struct_timespec_sz); + if (interval) + POST_WRITE(interval, struct_timespec_sz); } } @@ -610,13 +660,14 @@ PRE_SYSCALL(restart_syscall)() {} POST_SYSCALL(restart_syscall)(long res) {} -PRE_SYSCALL(kexec_load)(long entry, long nr_segments, void *segments, - long flags) {} +PRE_SYSCALL(kexec_load) +(long entry, long nr_segments, void *segments, long flags) {} -POST_SYSCALL(kexec_load)(long res, long entry, long nr_segments, void *segments, - long flags) { +POST_SYSCALL(kexec_load) +(long res, long entry, long nr_segments, void *segments, long flags) { if (res >= 0) { - if (segments) POST_WRITE(segments, struct_kexec_segment_sz); + if (segments) + POST_WRITE(segments, struct_kexec_segment_sz); } } @@ -630,22 +681,26 @@ POST_SYSCALL(exit_group)(long res, long error_code) {} PRE_SYSCALL(wait4)(long pid, void *stat_addr, long options, void *ru) {} -POST_SYSCALL(wait4)(long res, long pid, void *stat_addr, long options, - void *ru) { +POST_SYSCALL(wait4) +(long res, long pid, void *stat_addr, long options, void *ru) { if (res >= 0) { - if (stat_addr) POST_WRITE(stat_addr, sizeof(int)); - if (ru) POST_WRITE(ru, struct_rusage_sz); + if (stat_addr) + POST_WRITE(stat_addr, sizeof(int)); + if (ru) + POST_WRITE(ru, struct_rusage_sz); } } -PRE_SYSCALL(waitid)(long which, long pid, void *infop, long options, void *ru) { -} +PRE_SYSCALL(waitid) +(long which, long pid, void *infop, long options, void *ru) {} -POST_SYSCALL(waitid)(long res, long which, long pid, void *infop, long options, - void *ru) { +POST_SYSCALL(waitid) +(long res, long which, long pid, void *infop, long options, void *ru) { if (res >= 0) { - if (infop) POST_WRITE(infop, siginfo_t_sz); - if (ru) POST_WRITE(ru, struct_rusage_sz); + if (infop) + POST_WRITE(infop, siginfo_t_sz); + if (ru) + POST_WRITE(ru, struct_rusage_sz); } } @@ -653,7 +708,8 @@ PRE_SYSCALL(waitpid)(long pid, void *stat_addr, long options) {} POST_SYSCALL(waitpid)(long res, long pid, void *stat_addr, long options) { if (res >= 0) { - if (stat_addr) POST_WRITE(stat_addr, sizeof(int)); + if (stat_addr) + POST_WRITE(stat_addr, sizeof(int)); } } @@ -661,7 +717,8 @@ PRE_SYSCALL(set_tid_address)(void *tidptr) {} POST_SYSCALL(set_tid_address)(long res, void *tidptr) { if (res >= 0) { - if (tidptr) POST_WRITE(tidptr, sizeof(int)); + if (tidptr) + POST_WRITE(tidptr, sizeof(int)); } } @@ -682,11 +739,14 @@ POST_SYSCALL(delete_module)(long res, const void *name_user, long flags) {} PRE_SYSCALL(rt_sigprocmask)(long how, void *set, void *oset, long sigsetsize) {} -POST_SYSCALL(rt_sigprocmask)(long res, long how, kernel_sigset_t *set, - kernel_sigset_t *oset, long sigsetsize) { +POST_SYSCALL(rt_sigprocmask) +(long res, long how, kernel_sigset_t *set, kernel_sigset_t *oset, + long sigsetsize) { if (res >= 0) { - if (set) POST_WRITE(set, sigsetsize); - if (oset) POST_WRITE(oset, sigsetsize); + if (set) + POST_WRITE(set, sigsetsize); + if (oset) + POST_WRITE(oset, sigsetsize); } } @@ -694,29 +754,34 @@ PRE_SYSCALL(rt_sigpending)(void *set, long sigsetsize) {} POST_SYSCALL(rt_sigpending)(long res, kernel_sigset_t *set, long sigsetsize) { if (res >= 0) { - if (set) POST_WRITE(set, sigsetsize); + if (set) + POST_WRITE(set, sigsetsize); } } -PRE_SYSCALL(rt_sigtimedwait)(const kernel_sigset_t *uthese, void *uinfo, - const void *uts, long sigsetsize) { - if (uthese) PRE_READ(uthese, sigsetsize); - if (uts) PRE_READ(uts, struct_timespec_sz); +PRE_SYSCALL(rt_sigtimedwait) +(const kernel_sigset_t *uthese, void *uinfo, const void *uts, long sigsetsize) { + if (uthese) + PRE_READ(uthese, sigsetsize); + if (uts) + PRE_READ(uts, struct_timespec_sz); } -POST_SYSCALL(rt_sigtimedwait)(long res, const void *uthese, void *uinfo, - const void *uts, long sigsetsize) { +POST_SYSCALL(rt_sigtimedwait) +(long res, const void *uthese, void *uinfo, const void *uts, long sigsetsize) { if (res >= 0) { - if (uinfo) POST_WRITE(uinfo, siginfo_t_sz); + if (uinfo) + POST_WRITE(uinfo, siginfo_t_sz); } } PRE_SYSCALL(rt_tgsigqueueinfo)(long tgid, long pid, long sig, void *uinfo) {} -POST_SYSCALL(rt_tgsigqueueinfo)(long res, long tgid, long pid, long sig, - void *uinfo) { +POST_SYSCALL(rt_tgsigqueueinfo) +(long res, long tgid, long pid, long sig, void *uinfo) { if (res >= 0) { - if (uinfo) POST_WRITE(uinfo, siginfo_t_sz); + if (uinfo) + POST_WRITE(uinfo, siginfo_t_sz); } } @@ -736,7 +801,8 @@ PRE_SYSCALL(rt_sigqueueinfo)(long pid, long sig, void *uinfo) {} POST_SYSCALL(rt_sigqueueinfo)(long res, long pid, long sig, void *uinfo) { if (res >= 0) { - if (uinfo) POST_WRITE(uinfo, siginfo_t_sz); + if (uinfo) + POST_WRITE(uinfo, siginfo_t_sz); } } @@ -772,11 +838,11 @@ PRE_SYSCALL(bdflush)(long func, long data) {} POST_SYSCALL(bdflush)(long res, long func, long data) {} -PRE_SYSCALL(mount)(void *dev_name, void *dir_name, void *type, long flags, - void *data) {} +PRE_SYSCALL(mount) +(void *dev_name, void *dir_name, void *type, long flags, void *data) {} -POST_SYSCALL(mount)(long res, void *dev_name, void *dir_name, void *type, - long flags, void *data) { +POST_SYSCALL(mount) +(long res, void *dev_name, void *dir_name, void *type, long flags, void *data) { if (res >= 0) { if (dev_name) POST_WRITE(dev_name, @@ -826,11 +892,12 @@ PRE_SYSCALL(stat)(const void *filename, void *statbuf) { POST_SYSCALL(stat)(long res, const void *filename, void *statbuf) { if (res >= 0) { - if (statbuf) POST_WRITE(statbuf, struct___old_kernel_stat_sz); + if (statbuf) + POST_WRITE(statbuf, struct___old_kernel_stat_sz); } } -#if !SANITIZER_ANDROID +# if !SANITIZER_ANDROID PRE_SYSCALL(statfs)(const void *path, void *buf) { if (path) PRE_READ(path, __sanitizer::internal_strlen((const char *)path) + 1); @@ -838,7 +905,8 @@ PRE_SYSCALL(statfs)(const void *path, void *buf) { POST_SYSCALL(statfs)(long res, const void *path, void *buf) { if (res >= 0) { - if (buf) POST_WRITE(buf, struct_statfs_sz); + if (buf) + POST_WRITE(buf, struct_statfs_sz); } } @@ -849,7 +917,8 @@ PRE_SYSCALL(statfs64)(const void *path, long sz, void *buf) { POST_SYSCALL(statfs64)(long res, const void *path, long sz, void *buf) { if (res >= 0) { - if (buf) POST_WRITE(buf, struct_statfs64_sz); + if (buf) + POST_WRITE(buf, struct_statfs64_sz); } } @@ -857,7 +926,8 @@ PRE_SYSCALL(fstatfs)(long fd, void *buf) {} POST_SYSCALL(fstatfs)(long res, long fd, void *buf) { if (res >= 0) { - if (buf) POST_WRITE(buf, struct_statfs_sz); + if (buf) + POST_WRITE(buf, struct_statfs_sz); } } @@ -865,10 +935,11 @@ PRE_SYSCALL(fstatfs64)(long fd, long sz, void *buf) {} POST_SYSCALL(fstatfs64)(long res, long fd, long sz, void *buf) { if (res >= 0) { - if (buf) POST_WRITE(buf, struct_statfs64_sz); + if (buf) + POST_WRITE(buf, struct_statfs64_sz); } } -#endif // !SANITIZER_ANDROID +# endif // !SANITIZER_ANDROID PRE_SYSCALL(lstat)(const void *filename, void *statbuf) { if (filename) @@ -878,7 +949,8 @@ PRE_SYSCALL(lstat)(const void *filename, void *statbuf) { POST_SYSCALL(lstat)(long res, const void *filename, void *statbuf) { if (res >= 0) { - if (statbuf) POST_WRITE(statbuf, struct___old_kernel_stat_sz); + if (statbuf) + POST_WRITE(statbuf, struct___old_kernel_stat_sz); } } @@ -886,7 +958,8 @@ PRE_SYSCALL(fstat)(long fd, void *statbuf) {} POST_SYSCALL(fstat)(long res, long fd, void *statbuf) { if (res >= 0) { - if (statbuf) POST_WRITE(statbuf, struct___old_kernel_stat_sz); + if (statbuf) + POST_WRITE(statbuf, struct___old_kernel_stat_sz); } } @@ -898,7 +971,8 @@ PRE_SYSCALL(newstat)(const void *filename, void *statbuf) { POST_SYSCALL(newstat)(long res, const void *filename, void *statbuf) { if (res >= 0) { - if (statbuf) POST_WRITE(statbuf, struct_kernel_stat_sz); + if (statbuf) + POST_WRITE(statbuf, struct_kernel_stat_sz); } } @@ -910,7 +984,8 @@ PRE_SYSCALL(newlstat)(const void *filename, void *statbuf) { POST_SYSCALL(newlstat)(long res, const void *filename, void *statbuf) { if (res >= 0) { - if (statbuf) POST_WRITE(statbuf, struct_kernel_stat_sz); + if (statbuf) + POST_WRITE(statbuf, struct_kernel_stat_sz); } } @@ -918,19 +993,21 @@ PRE_SYSCALL(newfstat)(long fd, void *statbuf) {} POST_SYSCALL(newfstat)(long res, long fd, void *statbuf) { if (res >= 0) { - if (statbuf) POST_WRITE(statbuf, struct_kernel_stat_sz); + if (statbuf) + POST_WRITE(statbuf, struct_kernel_stat_sz); } } -#if !SANITIZER_ANDROID +# if !SANITIZER_ANDROID PRE_SYSCALL(ustat)(long dev, void *ubuf) {} POST_SYSCALL(ustat)(long res, long dev, void *ubuf) { if (res >= 0) { - if (ubuf) POST_WRITE(ubuf, struct_ustat_sz); + if (ubuf) + POST_WRITE(ubuf, struct_ustat_sz); } } -#endif // !SANITIZER_ANDROID +# endif // !SANITIZER_ANDROID PRE_SYSCALL(stat64)(const void *filename, void *statbuf) { if (filename) @@ -940,7 +1017,8 @@ PRE_SYSCALL(stat64)(const void *filename, void *statbuf) { POST_SYSCALL(stat64)(long res, const void *filename, void *statbuf) { if (res >= 0) { - if (statbuf) POST_WRITE(statbuf, struct_kernel_stat64_sz); + if (statbuf) + POST_WRITE(statbuf, struct_kernel_stat64_sz); } } @@ -948,7 +1026,8 @@ PRE_SYSCALL(fstat64)(long fd, void *statbuf) {} POST_SYSCALL(fstat64)(long res, long fd, void *statbuf) { if (res >= 0) { - if (statbuf) POST_WRITE(statbuf, struct_kernel_stat64_sz); + if (statbuf) + POST_WRITE(statbuf, struct_kernel_stat64_sz); } } @@ -960,71 +1039,80 @@ PRE_SYSCALL(lstat64)(const void *filename, void *statbuf) { POST_SYSCALL(lstat64)(long res, const void *filename, void *statbuf) { if (res >= 0) { - if (statbuf) POST_WRITE(statbuf, struct_kernel_stat64_sz); + if (statbuf) + POST_WRITE(statbuf, struct_kernel_stat64_sz); } } -PRE_SYSCALL(setxattr)(const void *path, const void *name, const void *value, - long size, long flags) { +PRE_SYSCALL(setxattr) +(const void *path, const void *name, const void *value, long size, long flags) { if (path) PRE_READ(path, __sanitizer::internal_strlen((const char *)path) + 1); if (name) PRE_READ(name, __sanitizer::internal_strlen((const char *)name) + 1); - if (value) PRE_READ(value, size); + if (value) + PRE_READ(value, size); } -POST_SYSCALL(setxattr)(long res, const void *path, const void *name, - const void *value, long size, long flags) {} +POST_SYSCALL(setxattr) +(long res, const void *path, const void *name, const void *value, long size, + long flags) {} -PRE_SYSCALL(lsetxattr)(const void *path, const void *name, const void *value, - long size, long flags) { +PRE_SYSCALL(lsetxattr) +(const void *path, const void *name, const void *value, long size, long flags) { if (path) PRE_READ(path, __sanitizer::internal_strlen((const char *)path) + 1); if (name) PRE_READ(name, __sanitizer::internal_strlen((const char *)name) + 1); - if (value) PRE_READ(value, size); + if (value) + PRE_READ(value, size); } -POST_SYSCALL(lsetxattr)(long res, const void *path, const void *name, - const void *value, long size, long flags) {} +POST_SYSCALL(lsetxattr) +(long res, const void *path, const void *name, const void *value, long size, + long flags) {} -PRE_SYSCALL(fsetxattr)(long fd, const void *name, const void *value, long size, - long flags) { +PRE_SYSCALL(fsetxattr) +(long fd, const void *name, const void *value, long size, long flags) { if (name) PRE_READ(name, __sanitizer::internal_strlen((const char *)name) + 1); - if (value) PRE_READ(value, size); + if (value) + PRE_READ(value, size); } -POST_SYSCALL(fsetxattr)(long res, long fd, const void *name, const void *value, - long size, long flags) {} +POST_SYSCALL(fsetxattr) +(long res, long fd, const void *name, const void *value, long size, + long flags) {} -PRE_SYSCALL(getxattr)(const void *path, const void *name, void *value, - long size) { +PRE_SYSCALL(getxattr) +(const void *path, const void *name, void *value, long size) { if (path) PRE_READ(path, __sanitizer::internal_strlen((const char *)path) + 1); if (name) PRE_READ(name, __sanitizer::internal_strlen((const char *)name) + 1); } -POST_SYSCALL(getxattr)(long res, const void *path, const void *name, - void *value, long size) { +POST_SYSCALL(getxattr) +(long res, const void *path, const void *name, void *value, long size) { if (size && res > 0) { - if (value) POST_WRITE(value, res); + if (value) + POST_WRITE(value, res); } } -PRE_SYSCALL(lgetxattr)(const void *path, const void *name, void *value, - long size) { +PRE_SYSCALL(lgetxattr) +(const void *path, const void *name, void *value, long size) { if (path) PRE_READ(path, __sanitizer::internal_strlen((const char *)path) + 1); if (name) PRE_READ(name, __sanitizer::internal_strlen((const char *)name) + 1); } -POST_SYSCALL(lgetxattr)(long res, const void *path, const void *name, - void *value, long size) { +POST_SYSCALL(lgetxattr) +(long res, const void *path, const void *name, void *value, long size) { if (size && res > 0) { - if (value) POST_WRITE(value, res); + if (value) + POST_WRITE(value, res); } } @@ -1033,10 +1121,11 @@ PRE_SYSCALL(fgetxattr)(long fd, const void *name, void *value, long size) { PRE_READ(name, __sanitizer::internal_strlen((const char *)name) + 1); } -POST_SYSCALL(fgetxattr)(long res, long fd, const void *name, void *value, - long size) { +POST_SYSCALL(fgetxattr) +(long res, long fd, const void *name, void *value, long size) { if (size && res > 0) { - if (value) POST_WRITE(value, res); + if (value) + POST_WRITE(value, res); } } @@ -1047,7 +1136,8 @@ PRE_SYSCALL(listxattr)(const void *path, void *list, long size) { POST_SYSCALL(listxattr)(long res, const void *path, void *list, long size) { if (size && res > 0) { - if (list) POST_WRITE(list, res); + if (list) + POST_WRITE(list, res); } } @@ -1058,7 +1148,8 @@ PRE_SYSCALL(llistxattr)(const void *path, void *list, long size) { POST_SYSCALL(llistxattr)(long res, const void *path, void *list, long size) { if (size && res > 0) { - if (list) POST_WRITE(list, res); + if (list) + POST_WRITE(list, res); } } @@ -1066,7 +1157,8 @@ PRE_SYSCALL(flistxattr)(long fd, void *list, long size) {} POST_SYSCALL(flistxattr)(long res, long fd, void *list, long size) { if (size && res > 0) { - if (list) POST_WRITE(list, res); + if (list) + POST_WRITE(list, res); } } @@ -1103,17 +1195,17 @@ PRE_SYSCALL(mprotect)(long start, long len, long prot) {} POST_SYSCALL(mprotect)(long res, long start, long len, long prot) {} -PRE_SYSCALL(mremap)(long addr, long old_len, long new_len, long flags, - long new_addr) {} +PRE_SYSCALL(mremap) +(long addr, long old_len, long new_len, long flags, long new_addr) {} -POST_SYSCALL(mremap)(long res, long addr, long old_len, long new_len, - long flags, long new_addr) {} +POST_SYSCALL(mremap) +(long res, long addr, long old_len, long new_len, long flags, long new_addr) {} -PRE_SYSCALL(remap_file_pages)(long start, long size, long prot, long pgoff, - long flags) {} +PRE_SYSCALL(remap_file_pages) +(long start, long size, long prot, long pgoff, long flags) {} -POST_SYSCALL(remap_file_pages)(long res, long start, long size, long prot, - long pgoff, long flags) {} +POST_SYSCALL(remap_file_pages) +(long res, long start, long size, long prot, long pgoff, long flags) {} PRE_SYSCALL(msync)(long start, long len, long flags) {} @@ -1189,7 +1281,8 @@ PRE_SYSCALL(link)(const void *oldname, const void *newname) { POST_SYSCALL(link)(long res, const void *oldname, const void *newname) {} PRE_SYSCALL(symlink)(const void *old, const void *new_) { - if (old) PRE_READ(old, __sanitizer::internal_strlen((const char *)old) + 1); + if (old) + PRE_READ(old, __sanitizer::internal_strlen((const char *)old) + 1); if (new_) PRE_READ(new_, __sanitizer::internal_strlen((const char *)new_) + 1); } @@ -1237,14 +1330,16 @@ PRE_SYSCALL(pipe)(void *fildes) {} POST_SYSCALL(pipe)(long res, void *fildes) { if (res >= 0) - if (fildes) POST_WRITE(fildes, sizeof(int) * 2); + if (fildes) + POST_WRITE(fildes, sizeof(int) * 2); } PRE_SYSCALL(pipe2)(void *fildes, long flags) {} POST_SYSCALL(pipe2)(long res, void *fildes, long flags) { if (res >= 0) - if (fildes) POST_WRITE(fildes, sizeof(int) * 2); + if (fildes) + POST_WRITE(fildes, sizeof(int) * 2); } PRE_SYSCALL(dup)(long fildes) {} @@ -1272,16 +1367,19 @@ PRE_SYSCALL(flock)(long fd, long cmd) {} POST_SYSCALL(flock)(long res, long fd, long cmd) {} PRE_SYSCALL(io_setup)(long nr_reqs, void **ctx) { - if (ctx) PRE_WRITE(ctx, sizeof(*ctx)); + if (ctx) + PRE_WRITE(ctx, sizeof(*ctx)); } POST_SYSCALL(io_setup)(long res, long nr_reqs, void **ctx) { if (res >= 0) { - if (ctx) POST_WRITE(ctx, sizeof(*ctx)); + if (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. - if (*ctx) POST_WRITE(*ctx, 32); + if (*ctx) + POST_WRITE(*ctx, 32); } } @@ -1289,16 +1387,21 @@ PRE_SYSCALL(io_destroy)(long ctx) {} POST_SYSCALL(io_destroy)(long res, long ctx) {} -PRE_SYSCALL(io_getevents)(long ctx_id, long min_nr, long nr, - __sanitizer_io_event *ioevpp, void *timeout) { - if (timeout) PRE_READ(timeout, struct_timespec_sz); +PRE_SYSCALL(io_getevents) +(long ctx_id, long min_nr, long nr, __sanitizer_io_event *ioevpp, + void *timeout) { + if (timeout) + PRE_READ(timeout, struct_timespec_sz); } -POST_SYSCALL(io_getevents)(long res, long ctx_id, long min_nr, long nr, - __sanitizer_io_event *ioevpp, void *timeout) { +POST_SYSCALL(io_getevents) +(long res, long ctx_id, long min_nr, long nr, __sanitizer_io_event *ioevpp, + void *timeout) { if (res >= 0) { - if (ioevpp) POST_WRITE(ioevpp, res * sizeof(*ioevpp)); - if (timeout) POST_WRITE(timeout, struct_timespec_sz); + if (ioevpp) + POST_WRITE(ioevpp, res * sizeof(*ioevpp)); + if (timeout) + POST_WRITE(timeout, struct_timespec_sz); } for (long i = 0; i < res; i++) { // We synchronize io_submit -> io_getevents/io_cancel using the @@ -1308,26 +1411,26 @@ POST_SYSCALL(io_getevents)(long res, long ctx_id, long min_nr, long nr, // synchronize on 0. But there does not seem to be a better solution // (except wrapping all operations in own context, which is unreliable). // We can not reliably extract fildes in io_getevents. - COMMON_SYSCALL_ACQUIRE((void*)ioevpp[i].data); + COMMON_SYSCALL_ACQUIRE((void *)ioevpp[i].data); } } PRE_SYSCALL(io_submit)(long ctx_id, long nr, __sanitizer_iocb **iocbpp) { for (long i = 0; i < nr; ++i) { uptr op = iocbpp[i]->aio_lio_opcode; - void *data = (void*)iocbpp[i]->aio_data; - void *buf = (void*)iocbpp[i]->aio_buf; + void *data = (void *)iocbpp[i]->aio_data; + void *buf = (void *)iocbpp[i]->aio_buf; uptr len = (uptr)iocbpp[i]->aio_nbytes; if (op == iocb_cmd_pwrite && buf && len) { PRE_READ(buf, len); } else if (op == iocb_cmd_pread && buf && len) { POST_WRITE(buf, len); } else if (op == iocb_cmd_pwritev) { - __sanitizer_iovec *iovec = (__sanitizer_iovec*)buf; + __sanitizer_iovec *iovec = (__sanitizer_iovec *)buf; for (uptr v = 0; v < len; v++) PRE_READ(iovec[v].iov_base, iovec[v].iov_len); } else if (op == iocb_cmd_preadv) { - __sanitizer_iovec *iovec = (__sanitizer_iovec*)buf; + __sanitizer_iovec *iovec = (__sanitizer_iovec *)buf; for (uptr v = 0; v < len; v++) POST_WRITE(iovec[v].iov_base, iovec[v].iov_len); } @@ -1336,19 +1439,18 @@ PRE_SYSCALL(io_submit)(long ctx_id, long nr, __sanitizer_iocb **iocbpp) { } } -POST_SYSCALL(io_submit)(long res, long ctx_id, long nr, - __sanitizer_iocb **iocbpp) {} +POST_SYSCALL(io_submit) +(long res, long ctx_id, long nr, __sanitizer_iocb **iocbpp) {} -PRE_SYSCALL(io_cancel)(long ctx_id, __sanitizer_iocb *iocb, - __sanitizer_io_event *result) { -} +PRE_SYSCALL(io_cancel) +(long ctx_id, __sanitizer_iocb *iocb, __sanitizer_io_event *result) {} -POST_SYSCALL(io_cancel)(long res, long ctx_id, __sanitizer_iocb *iocb, - __sanitizer_io_event *result) { +POST_SYSCALL(io_cancel) +(long res, long ctx_id, __sanitizer_iocb *iocb, __sanitizer_io_event *result) { if (res == 0) { if (result) { // See comment in io_getevents. - COMMON_SYSCALL_ACQUIRE((void*)result->data); + COMMON_SYSCALL_ACQUIRE((void *)result->data); POST_WRITE(result, sizeof(*result)); } if (iocb) @@ -1358,19 +1460,23 @@ POST_SYSCALL(io_cancel)(long res, long ctx_id, __sanitizer_iocb *iocb, PRE_SYSCALL(sendfile)(long out_fd, long in_fd, void *offset, long count) {} -POST_SYSCALL(sendfile)(long res, long out_fd, long in_fd, - __sanitizer___kernel_off_t *offset, long count) { +POST_SYSCALL(sendfile) +(long res, long out_fd, long in_fd, __sanitizer___kernel_off_t *offset, + long count) { if (res >= 0) { - if (offset) POST_WRITE(offset, sizeof(*offset)); + if (offset) + POST_WRITE(offset, sizeof(*offset)); } } PRE_SYSCALL(sendfile64)(long out_fd, long in_fd, void *offset, long count) {} -POST_SYSCALL(sendfile64)(long res, long out_fd, long in_fd, - __sanitizer___kernel_loff_t *offset, long count) { +POST_SYSCALL(sendfile64) +(long res, long out_fd, long in_fd, __sanitizer___kernel_loff_t *offset, + long count) { if (res >= 0) { - if (offset) POST_WRITE(offset, sizeof(*offset)); + if (offset) + POST_WRITE(offset, sizeof(*offset)); } } @@ -1402,9 +1508,7 @@ PRE_SYSCALL(open)(const void *filename, long flags, long mode) { POST_SYSCALL(open)(long res, const void *filename, long flags, long mode) {} -PRE_SYSCALL(close)(long fd) { - COMMON_SYSCALL_FD_CLOSE((int)fd); -} +PRE_SYSCALL(close)(long fd) { COMMON_SYSCALL_FD_CLOSE((int)fd); } POST_SYSCALL(close)(long res, long fd) {} @@ -1440,7 +1544,7 @@ PRE_SYSCALL(fchown)(long fd, long user, long group) {} POST_SYSCALL(fchown)(long res, long fd, long user, long group) {} -#if SANITIZER_USES_UID16_SYSCALLS +# if SANITIZER_USES_UID16_SYSCALLS PRE_SYSCALL(chown16)(const void *filename, long user, long group) { if (filename) PRE_READ(filename, @@ -1483,13 +1587,16 @@ POST_SYSCALL(setresuid16)(long res, long ruid, long euid, long suid) {} PRE_SYSCALL(getresuid16)(void *ruid, void *euid, void *suid) {} -POST_SYSCALL(getresuid16)(long res, __sanitizer___kernel_old_uid_t *ruid, - __sanitizer___kernel_old_uid_t *euid, - __sanitizer___kernel_old_uid_t *suid) { +POST_SYSCALL(getresuid16) +(long res, __sanitizer___kernel_old_uid_t *ruid, + __sanitizer___kernel_old_uid_t *euid, __sanitizer___kernel_old_uid_t *suid) { if (res >= 0) { - if (ruid) POST_WRITE(ruid, sizeof(*ruid)); - if (euid) POST_WRITE(euid, sizeof(*euid)); - if (suid) POST_WRITE(suid, sizeof(*suid)); + if (ruid) + POST_WRITE(ruid, sizeof(*ruid)); + if (euid) + POST_WRITE(euid, sizeof(*euid)); + if (suid) + POST_WRITE(suid, sizeof(*suid)); } } @@ -1499,13 +1606,16 @@ POST_SYSCALL(setresgid16)(long res, long rgid, long egid, long sgid) {} PRE_SYSCALL(getresgid16)(void *rgid, void *egid, void *sgid) {} -POST_SYSCALL(getresgid16)(long res, __sanitizer___kernel_old_gid_t *rgid, - __sanitizer___kernel_old_gid_t *egid, - __sanitizer___kernel_old_gid_t *sgid) { +POST_SYSCALL(getresgid16) +(long res, __sanitizer___kernel_old_gid_t *rgid, + __sanitizer___kernel_old_gid_t *egid, __sanitizer___kernel_old_gid_t *sgid) { if (res >= 0) { - if (rgid) POST_WRITE(rgid, sizeof(*rgid)); - if (egid) POST_WRITE(egid, sizeof(*egid)); - if (sgid) POST_WRITE(sgid, sizeof(*sgid)); + if (rgid) + POST_WRITE(rgid, sizeof(*rgid)); + if (egid) + POST_WRITE(egid, sizeof(*egid)); + if (sgid) + POST_WRITE(sgid, sizeof(*sgid)); } } @@ -1517,23 +1627,25 @@ PRE_SYSCALL(setfsgid16)(long gid) {} POST_SYSCALL(setfsgid16)(long res, long gid) {} -PRE_SYSCALL(getgroups16)(long gidsetsize, - __sanitizer___kernel_old_gid_t *grouplist) {} +PRE_SYSCALL(getgroups16) +(long gidsetsize, __sanitizer___kernel_old_gid_t *grouplist) {} -POST_SYSCALL(getgroups16)(long res, long gidsetsize, - __sanitizer___kernel_old_gid_t *grouplist) { +POST_SYSCALL(getgroups16) +(long res, long gidsetsize, __sanitizer___kernel_old_gid_t *grouplist) { if (res >= 0) { - if (grouplist) POST_WRITE(grouplist, res * sizeof(*grouplist)); + if (grouplist) + POST_WRITE(grouplist, res * sizeof(*grouplist)); } } -PRE_SYSCALL(setgroups16)(long gidsetsize, - __sanitizer___kernel_old_gid_t *grouplist) { - if (grouplist) POST_WRITE(grouplist, gidsetsize * sizeof(*grouplist)); +PRE_SYSCALL(setgroups16) +(long gidsetsize, __sanitizer___kernel_old_gid_t *grouplist) { + if (grouplist) + POST_WRITE(grouplist, gidsetsize * sizeof(*grouplist)); } -POST_SYSCALL(setgroups16)(long res, long gidsetsize, - __sanitizer___kernel_old_gid_t *grouplist) {} +POST_SYSCALL(setgroups16) +(long res, long gidsetsize, __sanitizer___kernel_old_gid_t *grouplist) {} PRE_SYSCALL(getuid16)() {} @@ -1550,7 +1662,7 @@ POST_SYSCALL(getgid16)(long res) {} PRE_SYSCALL(getegid16)() {} POST_SYSCALL(getegid16)(long res) {} -#endif // SANITIZER_USES_UID16_SYSCALLS +# endif // SANITIZER_USES_UID16_SYSCALLS PRE_SYSCALL(utime)(void *filename, void *times) {} @@ -1559,7 +1671,8 @@ POST_SYSCALL(utime)(long res, void *filename, void *times) { if (filename) POST_WRITE(filename, __sanitizer::internal_strlen((const char *)filename) + 1); - if (times) POST_WRITE(times, struct_utimbuf_sz); + if (times) + POST_WRITE(times, struct_utimbuf_sz); } } @@ -1570,7 +1683,8 @@ POST_SYSCALL(utimes)(long res, void *filename, void *utimes) { if (filename) POST_WRITE(filename, __sanitizer::internal_strlen((const char *)filename) + 1); - if (utimes) POST_WRITE(utimes, timeval_sz); + if (utimes) + POST_WRITE(utimes, timeval_sz); } } @@ -1578,91 +1692,104 @@ PRE_SYSCALL(lseek)(long fd, long offset, long origin) {} POST_SYSCALL(lseek)(long res, long fd, long offset, long origin) {} -PRE_SYSCALL(llseek)(long fd, long offset_high, long offset_low, void *result, - long origin) {} +PRE_SYSCALL(llseek) +(long fd, long offset_high, long offset_low, void *result, long origin) {} -POST_SYSCALL(llseek)(long res, long fd, long offset_high, long offset_low, - void *result, long origin) { +POST_SYSCALL(llseek) +(long res, long fd, long offset_high, long offset_low, void *result, + long origin) { if (res >= 0) { - if (result) POST_WRITE(result, sizeof(long long)); + if (result) + POST_WRITE(result, sizeof(long long)); } } PRE_SYSCALL(readv)(long fd, const __sanitizer_iovec *vec, long vlen) {} -POST_SYSCALL(readv)(long res, long fd, const __sanitizer_iovec *vec, - long vlen) { +POST_SYSCALL(readv) +(long res, long fd, const __sanitizer_iovec *vec, long vlen) { if (res >= 0) { - if (vec) kernel_write_iovec(vec, vlen, res); + if (vec) + kernel_write_iovec(vec, vlen, res); } } PRE_SYSCALL(write)(long fd, const void *buf, long count) { - if (buf) PRE_READ(buf, count); + if (buf) + PRE_READ(buf, count); } POST_SYSCALL(write)(long res, long fd, const void *buf, long count) {} PRE_SYSCALL(writev)(long fd, const __sanitizer_iovec *vec, long vlen) {} -POST_SYSCALL(writev)(long res, long fd, const __sanitizer_iovec *vec, - long vlen) { +POST_SYSCALL(writev) +(long res, long fd, const __sanitizer_iovec *vec, long vlen) { if (res >= 0) { - if (vec) kernel_read_iovec(vec, vlen, res); + if (vec) + kernel_read_iovec(vec, vlen, res); } } -#ifdef _LP64 +# ifdef _LP64 PRE_SYSCALL(pread64)(long fd, void *buf, long count, long pos) {} POST_SYSCALL(pread64)(long res, long fd, void *buf, long count, long pos) { if (res >= 0) { - if (buf) POST_WRITE(buf, res); + if (buf) + POST_WRITE(buf, res); } } PRE_SYSCALL(pwrite64)(long fd, const void *buf, long count, long pos) { - if (buf) PRE_READ(buf, count); + if (buf) + PRE_READ(buf, count); } -POST_SYSCALL(pwrite64)(long res, long fd, const void *buf, long count, - long pos) {} -#else +POST_SYSCALL(pwrite64) +(long res, long fd, const void *buf, long count, long pos) {} +# else PRE_SYSCALL(pread64)(long fd, void *buf, long count, long pos0, long pos1) {} -POST_SYSCALL(pread64)(long res, long fd, void *buf, long count, long pos0, - long pos1) { +POST_SYSCALL(pread64) +(long res, long fd, void *buf, long count, long pos0, long pos1) { if (res >= 0) { - if (buf) POST_WRITE(buf, res); + if (buf) + POST_WRITE(buf, res); } } -PRE_SYSCALL(pwrite64)(long fd, const void *buf, long count, long pos0, - long pos1) { - if (buf) PRE_READ(buf, count); +PRE_SYSCALL(pwrite64) +(long fd, const void *buf, long count, long pos0, long pos1) { + if (buf) + PRE_READ(buf, count); } -POST_SYSCALL(pwrite64)(long res, long fd, const void *buf, long count, - long pos0, long pos1) {} -#endif +POST_SYSCALL(pwrite64) +(long res, long fd, const void *buf, long count, long pos0, long pos1) {} +# endif -PRE_SYSCALL(preadv)(long fd, const __sanitizer_iovec *vec, long vlen, - long pos_l, long pos_h) {} +PRE_SYSCALL(preadv) +(long fd, const __sanitizer_iovec *vec, long vlen, long pos_l, long pos_h) {} -POST_SYSCALL(preadv)(long res, long fd, const __sanitizer_iovec *vec, long vlen, - long pos_l, long pos_h) { +POST_SYSCALL(preadv) +(long res, long fd, const __sanitizer_iovec *vec, long vlen, long pos_l, + long pos_h) { if (res >= 0) { - if (vec) kernel_write_iovec(vec, vlen, res); + if (vec) + kernel_write_iovec(vec, vlen, res); } } -PRE_SYSCALL(pwritev)(long fd, const __sanitizer_iovec *vec, long vlen, - long pos_l, long pos_h) {} +PRE_SYSCALL(pwritev) +(long fd, const __sanitizer_iovec *vec, long vlen, long pos_l, long pos_h) {} -POST_SYSCALL(pwritev)(long res, long fd, const __sanitizer_iovec *vec, - long vlen, long pos_l, long pos_h) { +POST_SYSCALL(pwritev) +(long res, long fd, const __sanitizer_iovec *vec, long vlen, long pos_l, + long pos_h) { if (res >= 0) { - if (vec) kernel_read_iovec(vec, vlen, res); + if (vec) + kernel_read_iovec(vec, vlen, res); } } @@ -1717,14 +1844,15 @@ PRE_SYSCALL(quotactl)(long cmd, const void *special, long id, void *addr) { PRE_READ(special, __sanitizer::internal_strlen((const char *)special) + 1); } -POST_SYSCALL(quotactl)(long res, long cmd, const void *special, long id, - void *addr) {} +POST_SYSCALL(quotactl) +(long res, long cmd, const void *special, long id, void *addr) {} PRE_SYSCALL(getdents)(long fd, void *dirent, long count) {} POST_SYSCALL(getdents)(long res, long fd, void *dirent, long count) { if (res >= 0) { - if (dirent) POST_WRITE(dirent, res); + if (dirent) + POST_WRITE(dirent, res); } } @@ -1732,15 +1860,16 @@ PRE_SYSCALL(getdents64)(long fd, void *dirent, long count) {} POST_SYSCALL(getdents64)(long res, long fd, void *dirent, long count) { if (res >= 0) { - if (dirent) POST_WRITE(dirent, res); + if (dirent) + POST_WRITE(dirent, res); } } -PRE_SYSCALL(setsockopt)(long fd, long level, long optname, void *optval, - long optlen) {} +PRE_SYSCALL(setsockopt) +(long fd, long level, long optname, void *optval, long optlen) {} -POST_SYSCALL(setsockopt)(long res, long fd, long level, long optname, - void *optval, long optlen) { +POST_SYSCALL(setsockopt) +(long res, long fd, long level, long optname, void *optval, long optlen) { if (res >= 0) { if (optval) POST_WRITE(optval, @@ -1748,77 +1877,88 @@ POST_SYSCALL(setsockopt)(long res, long fd, long level, long optname, } } -PRE_SYSCALL(getsockopt)(long fd, long level, long optname, void *optval, - void *optlen) {} +PRE_SYSCALL(getsockopt) +(long fd, long level, long optname, void *optval, void *optlen) {} -POST_SYSCALL(getsockopt)(long res, long fd, long level, long optname, - void *optval, void *optlen) { +POST_SYSCALL(getsockopt) +(long res, long fd, long level, long optname, void *optval, void *optlen) { if (res >= 0) { if (optval) POST_WRITE(optval, __sanitizer::internal_strlen((const char *)optval) + 1); - if (optlen) POST_WRITE(optlen, sizeof(int)); + if (optlen) + POST_WRITE(optlen, sizeof(int)); } } PRE_SYSCALL(bind)(long arg0, sanitizer_kernel_sockaddr *arg1, long arg2) {} -POST_SYSCALL(bind)(long res, long arg0, sanitizer_kernel_sockaddr *arg1, - long arg2) { +POST_SYSCALL(bind) +(long res, long arg0, sanitizer_kernel_sockaddr *arg1, long arg2) { if (res >= 0) { - if (arg1) POST_WRITE(arg1, sizeof(*arg1)); + if (arg1) + POST_WRITE(arg1, sizeof(*arg1)); } } PRE_SYSCALL(connect)(long arg0, sanitizer_kernel_sockaddr *arg1, long arg2) {} -POST_SYSCALL(connect)(long res, long arg0, sanitizer_kernel_sockaddr *arg1, - long arg2) { +POST_SYSCALL(connect) +(long res, long arg0, sanitizer_kernel_sockaddr *arg1, long arg2) { if (res >= 0) { - if (arg1) POST_WRITE(arg1, sizeof(*arg1)); + if (arg1) + POST_WRITE(arg1, sizeof(*arg1)); } } PRE_SYSCALL(accept)(long arg0, sanitizer_kernel_sockaddr *arg1, void *arg2) {} -POST_SYSCALL(accept)(long res, long arg0, sanitizer_kernel_sockaddr *arg1, - void *arg2) { +POST_SYSCALL(accept) +(long res, long arg0, sanitizer_kernel_sockaddr *arg1, void *arg2) { if (res >= 0) { - if (arg1) POST_WRITE(arg1, sizeof(*arg1)); - if (arg2) POST_WRITE(arg2, sizeof(unsigned)); + if (arg1) + POST_WRITE(arg1, sizeof(*arg1)); + if (arg2) + POST_WRITE(arg2, sizeof(unsigned)); } } -PRE_SYSCALL(accept4)(long arg0, sanitizer_kernel_sockaddr *arg1, void *arg2, - long arg3) {} +PRE_SYSCALL(accept4) +(long arg0, sanitizer_kernel_sockaddr *arg1, void *arg2, long arg3) {} -POST_SYSCALL(accept4)(long res, long arg0, sanitizer_kernel_sockaddr *arg1, - void *arg2, long arg3) { +POST_SYSCALL(accept4) +(long res, long arg0, sanitizer_kernel_sockaddr *arg1, void *arg2, long arg3) { if (res >= 0) { - if (arg1) POST_WRITE(arg1, sizeof(*arg1)); - if (arg2) POST_WRITE(arg2, sizeof(unsigned)); + if (arg1) + POST_WRITE(arg1, sizeof(*arg1)); + if (arg2) + POST_WRITE(arg2, sizeof(unsigned)); } } -PRE_SYSCALL(getsockname)(long arg0, sanitizer_kernel_sockaddr *arg1, - void *arg2) {} +PRE_SYSCALL(getsockname) +(long arg0, sanitizer_kernel_sockaddr *arg1, void *arg2) {} -POST_SYSCALL(getsockname)(long res, long arg0, sanitizer_kernel_sockaddr *arg1, - void *arg2) { +POST_SYSCALL(getsockname) +(long res, long arg0, sanitizer_kernel_sockaddr *arg1, void *arg2) { if (res >= 0) { - if (arg1) POST_WRITE(arg1, sizeof(*arg1)); - if (arg2) POST_WRITE(arg2, sizeof(unsigned)); + if (arg1) + POST_WRITE(arg1, sizeof(*arg1)); + if (arg2) + POST_WRITE(arg2, sizeof(unsigned)); } } -PRE_SYSCALL(getpeername)(long arg0, sanitizer_kernel_sockaddr *arg1, - void *arg2) {} +PRE_SYSCALL(getpeername) +(long arg0, sanitizer_kernel_sockaddr *arg1, void *arg2) {} -POST_SYSCALL(getpeername)(long res, long arg0, sanitizer_kernel_sockaddr *arg1, - void *arg2) { +POST_SYSCALL(getpeername) +(long res, long arg0, sanitizer_kernel_sockaddr *arg1, void *arg2) { if (res >= 0) { - if (arg1) POST_WRITE(arg1, sizeof(*arg1)); - if (arg2) POST_WRITE(arg2, sizeof(unsigned)); + if (arg1) + POST_WRITE(arg1, sizeof(*arg1)); + if (arg2) + POST_WRITE(arg2, sizeof(unsigned)); } } @@ -1826,18 +1966,23 @@ PRE_SYSCALL(send)(long arg0, void *arg1, long arg2, long arg3) {} POST_SYSCALL(send)(long res, long arg0, void *arg1, long arg2, long arg3) { if (res) { - if (arg1) POST_READ(arg1, res); + if (arg1) + POST_READ(arg1, res); } } -PRE_SYSCALL(sendto)(long arg0, void *arg1, long arg2, long arg3, - sanitizer_kernel_sockaddr *arg4, long arg5) {} +PRE_SYSCALL(sendto) +(long arg0, void *arg1, long arg2, long arg3, sanitizer_kernel_sockaddr *arg4, + long arg5) {} -POST_SYSCALL(sendto)(long res, long arg0, void *arg1, long arg2, long arg3, - sanitizer_kernel_sockaddr *arg4, long arg5) { +POST_SYSCALL(sendto) +(long res, long arg0, void *arg1, long arg2, long arg3, + sanitizer_kernel_sockaddr *arg4, long arg5) { if (res >= 0) { - if (arg1) POST_READ(arg1, res); - if (arg4) POST_WRITE(arg4, sizeof(*arg4)); + if (arg1) + POST_READ(arg1, res); + if (arg4) + POST_WRITE(arg4, sizeof(*arg4)); } } @@ -1857,19 +2002,25 @@ PRE_SYSCALL(recv)(long arg0, void *buf, long len, long flags) {} POST_SYSCALL(recv)(long res, void *buf, long len, long flags) { if (res >= 0) { - if (buf) POST_WRITE(buf, res); + if (buf) + POST_WRITE(buf, res); } } -PRE_SYSCALL(recvfrom)(long arg0, void *buf, long len, long flags, - sanitizer_kernel_sockaddr *arg4, void *arg5) {} +PRE_SYSCALL(recvfrom) +(long arg0, void *buf, long len, long flags, sanitizer_kernel_sockaddr *arg4, + void *arg5) {} -POST_SYSCALL(recvfrom)(long res, long arg0, void *buf, long len, long flags, - sanitizer_kernel_sockaddr *arg4, void *arg5) { +POST_SYSCALL(recvfrom) +(long res, long arg0, void *buf, long len, long flags, + sanitizer_kernel_sockaddr *arg4, void *arg5) { if (res >= 0) { - if (buf) POST_WRITE(buf, res); - if (arg4) POST_WRITE(arg4, sizeof(*arg4)); - if (arg5) POST_WRITE(arg5, sizeof(int)); + if (buf) + POST_WRITE(buf, res); + if (arg4) + POST_WRITE(arg4, sizeof(*arg4)); + if (arg5) + POST_WRITE(arg5, sizeof(int)); } } @@ -1881,14 +2032,16 @@ PRE_SYSCALL(socketpair)(long arg0, long arg1, long arg2, int *sv) {} POST_SYSCALL(socketpair)(long res, long arg0, long arg1, long arg2, int *sv) { if (res >= 0) - if (sv) POST_WRITE(sv, sizeof(int) * 2); + if (sv) + POST_WRITE(sv, sizeof(int) * 2); } PRE_SYSCALL(socketcall)(long call, void *args) {} POST_SYSCALL(socketcall)(long res, long call, void *args) { if (res >= 0) { - if (args) POST_WRITE(args, sizeof(long)); + if (args) + POST_WRITE(args, sizeof(long)); } } @@ -1898,25 +2051,31 @@ POST_SYSCALL(listen)(long res, long arg0, long arg1) {} PRE_SYSCALL(poll)(void *ufds, long nfds, long timeout) {} -POST_SYSCALL(poll)(long res, __sanitizer_pollfd *ufds, long nfds, - long timeout) { +POST_SYSCALL(poll) +(long res, __sanitizer_pollfd *ufds, long nfds, long timeout) { if (res >= 0) { - if (ufds) POST_WRITE(ufds, nfds * sizeof(*ufds)); + if (ufds) + POST_WRITE(ufds, nfds * sizeof(*ufds)); } } -PRE_SYSCALL(select)(long n, __sanitizer___kernel_fd_set *inp, - __sanitizer___kernel_fd_set *outp, - __sanitizer___kernel_fd_set *exp, void *tvp) {} +PRE_SYSCALL(select) +(long n, __sanitizer___kernel_fd_set *inp, __sanitizer___kernel_fd_set *outp, + __sanitizer___kernel_fd_set *exp, void *tvp) {} -POST_SYSCALL(select)(long res, long n, __sanitizer___kernel_fd_set *inp, - __sanitizer___kernel_fd_set *outp, - __sanitizer___kernel_fd_set *exp, void *tvp) { +POST_SYSCALL(select) +(long res, long n, __sanitizer___kernel_fd_set *inp, + __sanitizer___kernel_fd_set *outp, __sanitizer___kernel_fd_set *exp, + void *tvp) { if (res >= 0) { - if (inp) POST_WRITE(inp, sizeof(*inp)); - if (outp) POST_WRITE(outp, sizeof(*outp)); - if (exp) POST_WRITE(exp, sizeof(*exp)); - if (tvp) POST_WRITE(tvp, timeval_sz); + if (inp) + POST_WRITE(inp, sizeof(*inp)); + if (outp) + POST_WRITE(outp, sizeof(*outp)); + if (exp) + POST_WRITE(exp, sizeof(*exp)); + if (tvp) + POST_WRITE(tvp, timeval_sz); } } @@ -1936,29 +2095,55 @@ PRE_SYSCALL(epoll_ctl)(long epfd, long op, long fd, void *event) {} POST_SYSCALL(epoll_ctl)(long res, long epfd, long op, long fd, void *event) { if (res >= 0) { - if (event) POST_WRITE(event, struct_epoll_event_sz); + if (event) + POST_WRITE(event, struct_epoll_event_sz); } } -PRE_SYSCALL(epoll_wait)(long epfd, void *events, long maxevents, long timeout) { +PRE_SYSCALL(epoll_wait) +(long epfd, void *events, long maxevents, long timeout) {} + +POST_SYSCALL(epoll_wait) +(long res, long epfd, void *events, long maxevents, long timeout) { + if (res >= 0) { + if (events) + POST_WRITE(events, res * struct_epoll_event_sz); + } +} + +PRE_SYSCALL(epoll_pwait) +(long epfd, void *events, long maxevents, long timeout, + const kernel_sigset_t *sigmask, long sigsetsize) { + if (sigmask) + PRE_READ(sigmask, sigsetsize); } -POST_SYSCALL(epoll_wait)(long res, long epfd, void *events, long maxevents, - long timeout) { +POST_SYSCALL(epoll_pwait) +(long res, long epfd, void *events, long maxevents, long timeout, + const void *sigmask, long sigsetsize) { if (res >= 0) { - if (events) POST_WRITE(events, struct_epoll_event_sz); + if (events) + POST_WRITE(events, res * struct_epoll_event_sz); } } -PRE_SYSCALL(epoll_pwait)(long epfd, void *events, long maxevents, long timeout, - const kernel_sigset_t *sigmask, long sigsetsize) { - if (sigmask) PRE_READ(sigmask, sigsetsize); +PRE_SYSCALL(epoll_pwait2) +(long epfd, void *events, long maxevents, + const sanitizer_kernel_timespec *timeout, const kernel_sigset_t *sigmask, + long sigsetsize) { + if (timeout) + PRE_READ(timeout, sizeof(timeout)); + if (sigmask) + PRE_READ(sigmask, sigsetsize); } -POST_SYSCALL(epoll_pwait)(long res, long epfd, void *events, long maxevents, - long timeout, const void *sigmask, long sigsetsize) { +POST_SYSCALL(epoll_pwait2) +(long res, long epfd, void *events, long maxevents, + const sanitizer_kernel_timespec *timeout, const void *sigmask, + long sigsetsize) { if (res >= 0) { - if (events) POST_WRITE(events, struct_epoll_event_sz); + if (events) + POST_WRITE(events, res * struct_epoll_event_sz); } } @@ -1993,7 +2178,8 @@ PRE_SYSCALL(newuname)(void *name) {} POST_SYSCALL(newuname)(long res, void *name) { if (res >= 0) { - if (name) POST_WRITE(name, struct_new_utsname_sz); + if (name) + POST_WRITE(name, struct_new_utsname_sz); } } @@ -2001,7 +2187,8 @@ PRE_SYSCALL(uname)(void *arg0) {} POST_SYSCALL(uname)(long res, void *arg0) { if (res >= 0) { - if (arg0) POST_WRITE(arg0, struct_old_utsname_sz); + if (arg0) + POST_WRITE(arg0, struct_old_utsname_sz); } } @@ -2009,7 +2196,8 @@ PRE_SYSCALL(olduname)(void *arg0) {} POST_SYSCALL(olduname)(long res, void *arg0) { if (res >= 0) { - if (arg0) POST_WRITE(arg0, struct_oldold_utsname_sz); + if (arg0) + POST_WRITE(arg0, struct_oldold_utsname_sz); } } @@ -2017,7 +2205,8 @@ PRE_SYSCALL(getrlimit)(long resource, void *rlim) {} POST_SYSCALL(getrlimit)(long res, long resource, void *rlim) { if (res >= 0) { - if (rlim) POST_WRITE(rlim, struct_rlimit_sz); + if (rlim) + POST_WRITE(rlim, struct_rlimit_sz); } } @@ -2025,7 +2214,8 @@ PRE_SYSCALL(old_getrlimit)(long resource, void *rlim) {} POST_SYSCALL(old_getrlimit)(long res, long resource, void *rlim) { if (res >= 0) { - if (rlim) POST_WRITE(rlim, struct_rlimit_sz); + if (rlim) + POST_WRITE(rlim, struct_rlimit_sz); } } @@ -2033,29 +2223,33 @@ PRE_SYSCALL(setrlimit)(long resource, void *rlim) {} POST_SYSCALL(setrlimit)(long res, long resource, void *rlim) { if (res >= 0) { - if (rlim) POST_WRITE(rlim, struct_rlimit_sz); + if (rlim) + POST_WRITE(rlim, struct_rlimit_sz); } } -#if !SANITIZER_ANDROID -PRE_SYSCALL(prlimit64)(long pid, long resource, const void *new_rlim, - void *old_rlim) { - if (new_rlim) PRE_READ(new_rlim, struct_rlimit64_sz); +# if !SANITIZER_ANDROID +PRE_SYSCALL(prlimit64) +(long pid, long resource, const void *new_rlim, void *old_rlim) { + if (new_rlim) + PRE_READ(new_rlim, struct_rlimit64_sz); } -POST_SYSCALL(prlimit64)(long res, long pid, long resource, const void *new_rlim, - void *old_rlim) { +POST_SYSCALL(prlimit64) +(long res, long pid, long resource, const void *new_rlim, void *old_rlim) { if (res >= 0) { - if (old_rlim) POST_WRITE(old_rlim, struct_rlimit64_sz); + if (old_rlim) + POST_WRITE(old_rlim, struct_rlimit64_sz); } } -#endif +# endif PRE_SYSCALL(getrusage)(long who, void *ru) {} POST_SYSCALL(getrusage)(long res, long who, void *ru) { if (res >= 0) { - if (ru) POST_WRITE(ru, struct_rusage_sz); + if (ru) + POST_WRITE(ru, struct_rusage_sz); } } @@ -2068,31 +2262,34 @@ PRE_SYSCALL(msgget)(long key, long msgflg) {} POST_SYSCALL(msgget)(long res, long key, long msgflg) {} PRE_SYSCALL(msgsnd)(long msqid, void *msgp, long msgsz, long msgflg) { - if (msgp) PRE_READ(msgp, msgsz); + if (msgp) + PRE_READ(msgp, msgsz); } -POST_SYSCALL(msgsnd)(long res, long msqid, void *msgp, long msgsz, - long msgflg) {} +POST_SYSCALL(msgsnd) +(long res, long msqid, void *msgp, long msgsz, long msgflg) {} -PRE_SYSCALL(msgrcv)(long msqid, void *msgp, long msgsz, long msgtyp, - long msgflg) {} +PRE_SYSCALL(msgrcv) +(long msqid, void *msgp, long msgsz, long msgtyp, long msgflg) {} -POST_SYSCALL(msgrcv)(long res, long msqid, void *msgp, long msgsz, long msgtyp, - long msgflg) { +POST_SYSCALL(msgrcv) +(long res, long msqid, void *msgp, long msgsz, long msgtyp, long msgflg) { if (res >= 0) { - if (msgp) POST_WRITE(msgp, res); + if (msgp) + POST_WRITE(msgp, res); } } -#if !SANITIZER_ANDROID +# if !SANITIZER_ANDROID PRE_SYSCALL(msgctl)(long msqid, long cmd, void *buf) {} POST_SYSCALL(msgctl)(long res, long msqid, long cmd, void *buf) { if (res >= 0) { - if (buf) POST_WRITE(buf, struct_msqid_ds_sz); + if (buf) + POST_WRITE(buf, struct_msqid_ds_sz); } } -#endif +# endif PRE_SYSCALL(semget)(long key, long nsems, long semflg) {} @@ -2106,13 +2303,14 @@ PRE_SYSCALL(semctl)(long semid, long semnum, long cmd, void *arg) {} POST_SYSCALL(semctl)(long res, long semid, long semnum, long cmd, void *arg) {} -PRE_SYSCALL(semtimedop)(long semid, void *sops, long nsops, - const void *timeout) { - if (timeout) PRE_READ(timeout, struct_timespec_sz); +PRE_SYSCALL(semtimedop) +(long semid, void *sops, long nsops, const void *timeout) { + if (timeout) + PRE_READ(timeout, struct_timespec_sz); } -POST_SYSCALL(semtimedop)(long res, long semid, void *sops, long nsops, - const void *timeout) {} +POST_SYSCALL(semtimedop) +(long res, long semid, void *sops, long nsops, const void *timeout) {} PRE_SYSCALL(shmat)(long shmid, void *shmaddr, long shmflg) {} @@ -2138,18 +2336,20 @@ POST_SYSCALL(shmdt)(long res, void *shmaddr) { } } -PRE_SYSCALL(ipc)(long call, long first, long second, long third, void *ptr, - long fifth) {} +PRE_SYSCALL(ipc) +(long call, long first, long second, long third, void *ptr, long fifth) {} -POST_SYSCALL(ipc)(long res, long call, long first, long second, long third, - void *ptr, long fifth) {} +POST_SYSCALL(ipc) +(long res, long call, long first, long second, long third, void *ptr, + long fifth) {} -#if !SANITIZER_ANDROID +# if !SANITIZER_ANDROID PRE_SYSCALL(shmctl)(long shmid, long cmd, void *buf) {} POST_SYSCALL(shmctl)(long res, long shmid, long cmd, void *buf) { if (res >= 0) { - if (buf) POST_WRITE(buf, sizeof(__sanitizer_shmid_ds)); + if (buf) + POST_WRITE(buf, sizeof(__sanitizer_shmid_ds)); } } @@ -2158,10 +2358,11 @@ PRE_SYSCALL(mq_open)(const void *name, long oflag, long mode, void *attr) { PRE_READ(name, __sanitizer::internal_strlen((const char *)name) + 1); } -POST_SYSCALL(mq_open)(long res, const void *name, long oflag, long mode, - void *attr) { +POST_SYSCALL(mq_open) +(long res, const void *name, long oflag, long mode, void *attr) { if (res >= 0) { - if (attr) POST_WRITE(attr, struct_mq_attr_sz); + if (attr) + POST_WRITE(attr, struct_mq_attr_sz); } } @@ -2172,62 +2373,73 @@ PRE_SYSCALL(mq_unlink)(const void *name) { POST_SYSCALL(mq_unlink)(long res, const void *name) {} -PRE_SYSCALL(mq_timedsend)(long mqdes, const void *msg_ptr, long msg_len, - long msg_prio, const void *abs_timeout) { - if (msg_ptr) PRE_READ(msg_ptr, msg_len); - if (abs_timeout) PRE_READ(abs_timeout, struct_timespec_sz); +PRE_SYSCALL(mq_timedsend) +(long mqdes, const void *msg_ptr, long msg_len, long msg_prio, + const void *abs_timeout) { + if (msg_ptr) + PRE_READ(msg_ptr, msg_len); + if (abs_timeout) + PRE_READ(abs_timeout, struct_timespec_sz); } -POST_SYSCALL(mq_timedsend)(long res, long mqdes, const void *msg_ptr, - long msg_len, long msg_prio, - const void *abs_timeout) {} +POST_SYSCALL(mq_timedsend) +(long res, long mqdes, const void *msg_ptr, long msg_len, long msg_prio, + const void *abs_timeout) {} -PRE_SYSCALL(mq_timedreceive)(long mqdes, void *msg_ptr, long msg_len, - void *msg_prio, const void *abs_timeout) { - if (abs_timeout) PRE_READ(abs_timeout, struct_timespec_sz); +PRE_SYSCALL(mq_timedreceive) +(long mqdes, void *msg_ptr, long msg_len, void *msg_prio, + const void *abs_timeout) { + if (abs_timeout) + PRE_READ(abs_timeout, struct_timespec_sz); } -POST_SYSCALL(mq_timedreceive)(long res, long mqdes, void *msg_ptr, long msg_len, - int *msg_prio, const void *abs_timeout) { +POST_SYSCALL(mq_timedreceive) +(long res, long mqdes, void *msg_ptr, long msg_len, int *msg_prio, + const void *abs_timeout) { if (res >= 0) { - if (msg_ptr) POST_WRITE(msg_ptr, res); - if (msg_prio) POST_WRITE(msg_prio, sizeof(*msg_prio)); + if (msg_ptr) + POST_WRITE(msg_ptr, res); + if (msg_prio) + POST_WRITE(msg_prio, sizeof(*msg_prio)); } } PRE_SYSCALL(mq_notify)(long mqdes, const void *notification) { - if (notification) PRE_READ(notification, struct_sigevent_sz); + if (notification) + PRE_READ(notification, struct_sigevent_sz); } POST_SYSCALL(mq_notify)(long res, long mqdes, const void *notification) {} PRE_SYSCALL(mq_getsetattr)(long mqdes, const void *mqstat, void *omqstat) { - if (mqstat) PRE_READ(mqstat, struct_mq_attr_sz); + if (mqstat) + PRE_READ(mqstat, struct_mq_attr_sz); } -POST_SYSCALL(mq_getsetattr)(long res, long mqdes, const void *mqstat, - void *omqstat) { +POST_SYSCALL(mq_getsetattr) +(long res, long mqdes, const void *mqstat, void *omqstat) { if (res >= 0) { - if (omqstat) POST_WRITE(omqstat, struct_mq_attr_sz); + if (omqstat) + POST_WRITE(omqstat, struct_mq_attr_sz); } } -#endif // SANITIZER_ANDROID +# endif // SANITIZER_ANDROID PRE_SYSCALL(pciconfig_iobase)(long which, long bus, long devfn) {} POST_SYSCALL(pciconfig_iobase)(long res, long which, long bus, long devfn) {} -PRE_SYSCALL(pciconfig_read)(long bus, long dfn, long off, long len, void *buf) { -} +PRE_SYSCALL(pciconfig_read) +(long bus, long dfn, long off, long len, void *buf) {} -POST_SYSCALL(pciconfig_read)(long res, long bus, long dfn, long off, long len, - void *buf) {} +POST_SYSCALL(pciconfig_read) +(long res, long bus, long dfn, long off, long len, void *buf) {} -PRE_SYSCALL(pciconfig_write)(long bus, long dfn, long off, long len, - void *buf) {} +PRE_SYSCALL(pciconfig_write) +(long bus, long dfn, long off, long len, void *buf) {} -POST_SYSCALL(pciconfig_write)(long res, long bus, long dfn, long off, long len, - void *buf) {} +POST_SYSCALL(pciconfig_write) +(long res, long bus, long dfn, long off, long len, void *buf) {} PRE_SYSCALL(swapon)(const void *specialfile, long swap_flags) { if (specialfile) @@ -2247,8 +2459,10 @@ POST_SYSCALL(swapoff)(long res, const void *specialfile) {} PRE_SYSCALL(sysctl)(__sanitizer___sysctl_args *args) { if (args) { - if (args->name) PRE_READ(args->name, args->nlen * sizeof(*args->name)); - if (args->newval) PRE_READ(args->name, args->newlen); + if (args->name) + PRE_READ(args->name, args->nlen * sizeof(*args->name)); + if (args->newval) + PRE_READ(args->name, args->newlen); } } @@ -2265,7 +2479,8 @@ PRE_SYSCALL(sysinfo)(void *info) {} POST_SYSCALL(sysinfo)(long res, void *info) { if (res >= 0) { - if (info) POST_WRITE(info, struct_sysinfo_sz); + if (info) + POST_WRITE(info, struct_sysinfo_sz); } } @@ -2294,10 +2509,10 @@ PRE_SYSCALL(ni_syscall)() {} POST_SYSCALL(ni_syscall)(long res) {} PRE_SYSCALL(ptrace)(long request, long pid, long addr, long data) { -#if !SANITIZER_ANDROID && \ - (defined(__i386) || defined(__x86_64) || defined(__mips64) || \ - defined(__powerpc64__) || defined(__aarch64__) || defined(__s390__) || \ - SANITIZER_RISCV64) +# if !SANITIZER_ANDROID && \ + (defined(__i386) || defined(__x86_64) || defined(__mips64) || \ + defined(__powerpc64__) || defined(__aarch64__) || defined(__s390__) || \ + SANITIZER_RISCV64) if (data) { if (request == ptrace_setregs) { PRE_READ((void *)data, struct_user_regs_struct_sz); @@ -2312,14 +2527,14 @@ PRE_SYSCALL(ptrace)(long request, long pid, long addr, long data) { PRE_READ(iov->iov_base, iov->iov_len); } } -#endif +# endif } POST_SYSCALL(ptrace)(long res, long request, long pid, long addr, long data) { -#if !SANITIZER_ANDROID && \ - (defined(__i386) || defined(__x86_64) || defined(__mips64) || \ - defined(__powerpc64__) || defined(__aarch64__) || defined(__s390__) || \ - SANITIZER_RISCV64) +# if !SANITIZER_ANDROID && \ + (defined(__i386) || defined(__x86_64) || defined(__mips64) || \ + defined(__powerpc64__) || defined(__aarch64__) || defined(__s390__) || \ + SANITIZER_RISCV64) if (res >= 0 && data) { // Note that this is different from the interceptor in // sanitizer_common_interceptors.inc. @@ -2340,11 +2555,12 @@ POST_SYSCALL(ptrace)(long res, long request, long pid, long addr, long data) { POST_WRITE((void *)data, sizeof(void *)); } } -#endif +# endif } -PRE_SYSCALL(add_key)(const void *_type, const void *_description, - const void *_payload, long plen, long destringid) { +PRE_SYSCALL(add_key) +(const void *_type, const void *_description, const void *_payload, long plen, + long destringid) { if (_type) PRE_READ(_type, __sanitizer::internal_strlen((const char *)_type) + 1); if (_description) @@ -2352,11 +2568,13 @@ PRE_SYSCALL(add_key)(const void *_type, const void *_description, __sanitizer::internal_strlen((const char *)_description) + 1); } -POST_SYSCALL(add_key)(long res, const void *_type, const void *_description, - const void *_payload, long plen, long destringid) {} +POST_SYSCALL(add_key) +(long res, const void *_type, const void *_description, const void *_payload, + long plen, long destringid) {} -PRE_SYSCALL(request_key)(const void *_type, const void *_description, - const void *_callout_info, long destringid) { +PRE_SYSCALL(request_key) +(const void *_type, const void *_description, const void *_callout_info, + long destringid) { if (_type) PRE_READ(_type, __sanitizer::internal_strlen((const char *)_type) + 1); if (_description) @@ -2367,13 +2585,14 @@ PRE_SYSCALL(request_key)(const void *_type, const void *_description, __sanitizer::internal_strlen((const char *)_callout_info) + 1); } -POST_SYSCALL(request_key)(long res, const void *_type, const void *_description, - const void *_callout_info, long destringid) {} +POST_SYSCALL(request_key) +(long res, const void *_type, const void *_description, + const void *_callout_info, long destringid) {} PRE_SYSCALL(keyctl)(long cmd, long arg2, long arg3, long arg4, long arg5) {} -POST_SYSCALL(keyctl)(long res, long cmd, long arg2, long arg3, long arg4, - long arg5) {} +POST_SYSCALL(keyctl) +(long res, long cmd, long arg2, long arg3, long arg4, long arg5) {} PRE_SYSCALL(ioprio_set)(long which, long who, long ioprio) {} @@ -2387,50 +2606,62 @@ PRE_SYSCALL(set_mempolicy)(long mode, void *nmask, long maxnode) {} POST_SYSCALL(set_mempolicy)(long res, long mode, void *nmask, long maxnode) { if (res >= 0) { - if (nmask) POST_WRITE(nmask, sizeof(long)); + if (nmask) + POST_WRITE(nmask, sizeof(long)); } } -PRE_SYSCALL(migrate_pages)(long pid, long maxnode, const void *from, - const void *to) { - if (from) PRE_READ(from, sizeof(long)); - if (to) PRE_READ(to, sizeof(long)); +PRE_SYSCALL(migrate_pages) +(long pid, long maxnode, const void *from, const void *to) { + if (from) + PRE_READ(from, sizeof(long)); + if (to) + PRE_READ(to, sizeof(long)); } -POST_SYSCALL(migrate_pages)(long res, long pid, long maxnode, const void *from, - const void *to) {} +POST_SYSCALL(migrate_pages) +(long res, long pid, long maxnode, const void *from, const void *to) {} -PRE_SYSCALL(move_pages)(long pid, long nr_pages, const void **pages, - const int *nodes, int *status, long flags) { - if (pages) PRE_READ(pages, nr_pages * sizeof(*pages)); - if (nodes) PRE_READ(nodes, nr_pages * sizeof(*nodes)); +PRE_SYSCALL(move_pages) +(long pid, long nr_pages, const void **pages, const int *nodes, int *status, + long flags) { + if (pages) + PRE_READ(pages, nr_pages * sizeof(*pages)); + if (nodes) + PRE_READ(nodes, nr_pages * sizeof(*nodes)); } -POST_SYSCALL(move_pages)(long res, long pid, long nr_pages, const void **pages, - const int *nodes, int *status, long flags) { +POST_SYSCALL(move_pages) +(long res, long pid, long nr_pages, const void **pages, const int *nodes, + int *status, long flags) { if (res >= 0) { - if (status) POST_WRITE(status, nr_pages * sizeof(*status)); + if (status) + POST_WRITE(status, nr_pages * sizeof(*status)); } } -PRE_SYSCALL(mbind)(long start, long len, long mode, void *nmask, long maxnode, - long flags) {} +PRE_SYSCALL(mbind) +(long start, long len, long mode, void *nmask, long maxnode, long flags) {} -POST_SYSCALL(mbind)(long res, long start, long len, long mode, void *nmask, - long maxnode, long flags) { +POST_SYSCALL(mbind) +(long res, long start, long len, long mode, void *nmask, long maxnode, + long flags) { if (res >= 0) { - if (nmask) POST_WRITE(nmask, sizeof(long)); + if (nmask) + POST_WRITE(nmask, sizeof(long)); } } -PRE_SYSCALL(get_mempolicy)(void *policy, void *nmask, long maxnode, long addr, - long flags) {} +PRE_SYSCALL(get_mempolicy) +(void *policy, void *nmask, long maxnode, long addr, long flags) {} -POST_SYSCALL(get_mempolicy)(long res, void *policy, void *nmask, long maxnode, - long addr, long flags) { +POST_SYSCALL(get_mempolicy) +(long res, void *policy, void *nmask, long maxnode, long addr, long flags) { if (res >= 0) { - if (policy) POST_WRITE(policy, sizeof(int)); - if (nmask) POST_WRITE(nmask, sizeof(long)); + if (policy) + POST_WRITE(policy, sizeof(int)); + if (nmask) + POST_WRITE(nmask, sizeof(long)); } } @@ -2447,8 +2678,8 @@ PRE_SYSCALL(inotify_add_watch)(long fd, const void *path, long mask) { PRE_READ(path, __sanitizer::internal_strlen((const char *)path) + 1); } -POST_SYSCALL(inotify_add_watch)(long res, long fd, const void *path, - long mask) {} +POST_SYSCALL(inotify_add_watch) +(long res, long fd, const void *path, long mask) {} PRE_SYSCALL(inotify_rm_watch)(long fd, long wd) {} @@ -2458,8 +2689,10 @@ PRE_SYSCALL(spu_run)(long fd, void *unpc, void *ustatus) {} POST_SYSCALL(spu_run)(long res, long fd, unsigned *unpc, unsigned *ustatus) { if (res >= 0) { - if (unpc) POST_WRITE(unpc, sizeof(*unpc)); - if (ustatus) POST_WRITE(ustatus, sizeof(*ustatus)); + if (unpc) + POST_WRITE(unpc, sizeof(*unpc)); + if (ustatus) + POST_WRITE(ustatus, sizeof(*ustatus)); } } @@ -2468,8 +2701,8 @@ PRE_SYSCALL(spu_create)(const void *name, long flags, long mode, long fd) { PRE_READ(name, __sanitizer::internal_strlen((const char *)name) + 1); } -POST_SYSCALL(spu_create)(long res, const void *name, long flags, long mode, - long fd) {} +POST_SYSCALL(spu_create) +(long res, const void *name, long flags, long mode, long fd) {} PRE_SYSCALL(mknodat)(long dfd, const void *filename, long mode, long dev) { if (filename) @@ -2477,8 +2710,8 @@ PRE_SYSCALL(mknodat)(long dfd, const void *filename, long mode, long dev) { __sanitizer::internal_strlen((const char *)filename) + 1); } -POST_SYSCALL(mknodat)(long res, long dfd, const void *filename, long mode, - long dev) {} +POST_SYSCALL(mknodat) +(long res, long dfd, const void *filename, long mode, long dev) {} PRE_SYSCALL(mkdirat)(long dfd, const void *pathname, long mode) { if (pathname) @@ -2503,30 +2736,33 @@ PRE_SYSCALL(symlinkat)(const void *oldname, long newdfd, const void *newname) { PRE_READ(newname, __sanitizer::internal_strlen((const char *)newname) + 1); } -POST_SYSCALL(symlinkat)(long res, const void *oldname, long newdfd, - const void *newname) {} +POST_SYSCALL(symlinkat) +(long res, const void *oldname, long newdfd, const void *newname) {} -PRE_SYSCALL(linkat)(long olddfd, const void *oldname, long newdfd, - const void *newname, long flags) { +PRE_SYSCALL(linkat) +(long olddfd, const void *oldname, long newdfd, const void *newname, + long flags) { if (oldname) PRE_READ(oldname, __sanitizer::internal_strlen((const char *)oldname) + 1); if (newname) PRE_READ(newname, __sanitizer::internal_strlen((const char *)newname) + 1); } -POST_SYSCALL(linkat)(long res, long olddfd, const void *oldname, long newdfd, - const void *newname, long flags) {} +POST_SYSCALL(linkat) +(long res, long olddfd, const void *oldname, long newdfd, const void *newname, + long flags) {} -PRE_SYSCALL(renameat)(long olddfd, const void *oldname, long newdfd, - const void *newname) { +PRE_SYSCALL(renameat) +(long olddfd, const void *oldname, long newdfd, const void *newname) { if (oldname) PRE_READ(oldname, __sanitizer::internal_strlen((const char *)oldname) + 1); if (newname) PRE_READ(newname, __sanitizer::internal_strlen((const char *)newname) + 1); } -POST_SYSCALL(renameat)(long res, long olddfd, const void *oldname, long newdfd, - const void *newname) {} +POST_SYSCALL(renameat) +(long res, long olddfd, const void *oldname, long newdfd, const void *newname) { +} PRE_SYSCALL(futimesat)(long dfd, const void *filename, void *utimes) { if (filename) @@ -2534,10 +2770,11 @@ PRE_SYSCALL(futimesat)(long dfd, const void *filename, void *utimes) { __sanitizer::internal_strlen((const char *)filename) + 1); } -POST_SYSCALL(futimesat)(long res, long dfd, const void *filename, - void *utimes) { +POST_SYSCALL(futimesat) +(long res, long dfd, const void *filename, void *utimes) { if (res >= 0) { - if (utimes) POST_WRITE(utimes, timeval_sz); + if (utimes) + POST_WRITE(utimes, timeval_sz); } } @@ -2557,15 +2794,15 @@ PRE_SYSCALL(fchmodat)(long dfd, const void *filename, long mode) { POST_SYSCALL(fchmodat)(long res, long dfd, const void *filename, long mode) {} -PRE_SYSCALL(fchownat)(long dfd, const void *filename, long user, long group, - long flag) { +PRE_SYSCALL(fchownat) +(long dfd, const void *filename, long user, long group, long flag) { if (filename) PRE_READ(filename, __sanitizer::internal_strlen((const char *)filename) + 1); } -POST_SYSCALL(fchownat)(long res, long dfd, const void *filename, long user, - long group, long flag) {} +POST_SYSCALL(fchownat) +(long res, long dfd, const void *filename, long user, long group, long flag) {} PRE_SYSCALL(openat)(long dfd, const void *filename, long flags, long mode) { if (filename) @@ -2573,34 +2810,36 @@ PRE_SYSCALL(openat)(long dfd, const void *filename, long flags, long mode) { __sanitizer::internal_strlen((const char *)filename) + 1); } -POST_SYSCALL(openat)(long res, long dfd, const void *filename, long flags, - long mode) {} +POST_SYSCALL(openat) +(long res, long dfd, const void *filename, long flags, long mode) {} -PRE_SYSCALL(newfstatat)(long dfd, const void *filename, void *statbuf, - long flag) { +PRE_SYSCALL(newfstatat) +(long dfd, const void *filename, void *statbuf, long flag) { if (filename) PRE_READ(filename, __sanitizer::internal_strlen((const char *)filename) + 1); } -POST_SYSCALL(newfstatat)(long res, long dfd, const void *filename, - void *statbuf, long flag) { +POST_SYSCALL(newfstatat) +(long res, long dfd, const void *filename, void *statbuf, long flag) { if (res >= 0) { - if (statbuf) POST_WRITE(statbuf, struct_kernel_stat_sz); + if (statbuf) + POST_WRITE(statbuf, struct_kernel_stat_sz); } } -PRE_SYSCALL(fstatat64)(long dfd, const void *filename, void *statbuf, - long flag) { +PRE_SYSCALL(fstatat64) +(long dfd, const void *filename, void *statbuf, long flag) { if (filename) PRE_READ(filename, __sanitizer::internal_strlen((const char *)filename) + 1); } -POST_SYSCALL(fstatat64)(long res, long dfd, const void *filename, void *statbuf, - long flag) { +POST_SYSCALL(fstatat64) +(long res, long dfd, const void *filename, void *statbuf, long flag) { if (res >= 0) { - if (statbuf) POST_WRITE(statbuf, struct_kernel_stat64_sz); + if (statbuf) + POST_WRITE(statbuf, struct_kernel_stat64_sz); } } @@ -2609,25 +2848,26 @@ PRE_SYSCALL(readlinkat)(long dfd, const void *path, void *buf, long bufsiz) { PRE_READ(path, __sanitizer::internal_strlen((const char *)path) + 1); } -POST_SYSCALL(readlinkat)(long res, long dfd, const void *path, void *buf, - long bufsiz) { +POST_SYSCALL(readlinkat) +(long res, long dfd, const void *path, void *buf, long bufsiz) { if (res >= 0) { if (buf) POST_WRITE(buf, __sanitizer::internal_strlen((const char *)buf) + 1); } } -PRE_SYSCALL(utimensat)(long dfd, const void *filename, void *utimes, - long flags) { +PRE_SYSCALL(utimensat) +(long dfd, const void *filename, void *utimes, long flags) { if (filename) PRE_READ(filename, __sanitizer::internal_strlen((const char *)filename) + 1); } -POST_SYSCALL(utimensat)(long res, long dfd, const void *filename, void *utimes, - long flags) { +POST_SYSCALL(utimensat) +(long res, long dfd, const void *filename, void *utimes, long flags) { if (res >= 0) { - if (utimes) POST_WRITE(utimes, struct_timespec_sz); + if (utimes) + POST_WRITE(utimes, struct_timespec_sz); } } @@ -2635,24 +2875,28 @@ PRE_SYSCALL(unshare)(long unshare_flags) {} POST_SYSCALL(unshare)(long res, long unshare_flags) {} -PRE_SYSCALL(splice)(long fd_in, void *off_in, long fd_out, void *off_out, - long len, long flags) {} +PRE_SYSCALL(splice) +(long fd_in, void *off_in, long fd_out, void *off_out, long len, long flags) {} -POST_SYSCALL(splice)(long res, long fd_in, void *off_in, long fd_out, - void *off_out, long len, long flags) { +POST_SYSCALL(splice) +(long res, long fd_in, void *off_in, long fd_out, void *off_out, long len, + long flags) { if (res >= 0) { - if (off_in) POST_WRITE(off_in, sizeof(long long)); - if (off_out) POST_WRITE(off_out, sizeof(long long)); + if (off_in) + POST_WRITE(off_in, sizeof(long long)); + if (off_out) + POST_WRITE(off_out, sizeof(long long)); } } -PRE_SYSCALL(vmsplice)(long fd, const __sanitizer_iovec *iov, long nr_segs, - long flags) {} +PRE_SYSCALL(vmsplice) +(long fd, const __sanitizer_iovec *iov, long nr_segs, long flags) {} -POST_SYSCALL(vmsplice)(long res, long fd, const __sanitizer_iovec *iov, - long nr_segs, long flags) { +POST_SYSCALL(vmsplice) +(long res, long fd, const __sanitizer_iovec *iov, long nr_segs, long flags) { if (res >= 0) { - if (iov) kernel_read_iovec(iov, nr_segs, res); + if (iov) + kernel_read_iovec(iov, nr_segs, res); } } @@ -2662,8 +2906,8 @@ POST_SYSCALL(tee)(long res, long fdin, long fdout, long len, long flags) {} PRE_SYSCALL(get_robust_list)(long pid, void *head_ptr, void *len_ptr) {} -POST_SYSCALL(get_robust_list)(long res, long pid, void *head_ptr, - void *len_ptr) {} +POST_SYSCALL(get_robust_list) +(long res, long pid, void *head_ptr, void *len_ptr) {} PRE_SYSCALL(set_robust_list)(void *head, long len) {} @@ -2673,27 +2917,31 @@ PRE_SYSCALL(getcpu)(void *cpu, void *node, void *cache) {} POST_SYSCALL(getcpu)(long res, void *cpu, void *node, void *cache) { if (res >= 0) { - if (cpu) POST_WRITE(cpu, sizeof(unsigned)); - if (node) POST_WRITE(node, sizeof(unsigned)); + if (cpu) + POST_WRITE(cpu, sizeof(unsigned)); + if (node) + POST_WRITE(node, sizeof(unsigned)); // The third argument to this system call is nowadays unused. } } PRE_SYSCALL(signalfd)(long ufd, void *user_mask, long sizemask) {} -POST_SYSCALL(signalfd)(long res, long ufd, kernel_sigset_t *user_mask, - long sizemask) { +POST_SYSCALL(signalfd) +(long res, long ufd, kernel_sigset_t *user_mask, long sizemask) { if (res >= 0) { - if (user_mask) POST_WRITE(user_mask, sizemask); + if (user_mask) + POST_WRITE(user_mask, sizemask); } } PRE_SYSCALL(signalfd4)(long ufd, void *user_mask, long sizemask, long flags) {} -POST_SYSCALL(signalfd4)(long res, long ufd, kernel_sigset_t *user_mask, - long sizemask, long flags) { +POST_SYSCALL(signalfd4) +(long res, long ufd, kernel_sigset_t *user_mask, long sizemask, long flags) { if (res >= 0) { - if (user_mask) POST_WRITE(user_mask, sizemask); + if (user_mask) + POST_WRITE(user_mask, sizemask); } } @@ -2701,15 +2949,17 @@ PRE_SYSCALL(timerfd_create)(long clockid, long flags) {} POST_SYSCALL(timerfd_create)(long res, long clockid, long flags) {} -PRE_SYSCALL(timerfd_settime)(long ufd, long flags, const void *utmr, - void *otmr) { - if (utmr) PRE_READ(utmr, struct_itimerspec_sz); +PRE_SYSCALL(timerfd_settime) +(long ufd, long flags, const void *utmr, void *otmr) { + if (utmr) + PRE_READ(utmr, struct_itimerspec_sz); } -POST_SYSCALL(timerfd_settime)(long res, long ufd, long flags, const void *utmr, - void *otmr) { +POST_SYSCALL(timerfd_settime) +(long res, long ufd, long flags, const void *utmr, void *otmr) { if (res >= 0) { - if (otmr) POST_WRITE(otmr, struct_itimerspec_sz); + if (otmr) + POST_WRITE(otmr, struct_itimerspec_sz); } } @@ -2717,7 +2967,8 @@ PRE_SYSCALL(timerfd_gettime)(long ufd, void *otmr) {} POST_SYSCALL(timerfd_gettime)(long res, long ufd, void *otmr) { if (res >= 0) { - if (otmr) POST_WRITE(otmr, struct_itimerspec_sz); + if (otmr) + POST_WRITE(otmr, struct_itimerspec_sz); } } @@ -2735,33 +2986,42 @@ POST_SYSCALL(old_readdir)(long res, long arg0, void *arg1, long arg2) { // Missing definition of 'struct old_linux_dirent'. } -PRE_SYSCALL(pselect6)(long arg0, __sanitizer___kernel_fd_set *arg1, - __sanitizer___kernel_fd_set *arg2, - __sanitizer___kernel_fd_set *arg3, void *arg4, - void *arg5) {} +PRE_SYSCALL(pselect6) +(long arg0, __sanitizer___kernel_fd_set *arg1, + __sanitizer___kernel_fd_set *arg2, __sanitizer___kernel_fd_set *arg3, + void *arg4, void *arg5) {} -POST_SYSCALL(pselect6)(long res, long arg0, __sanitizer___kernel_fd_set *arg1, - __sanitizer___kernel_fd_set *arg2, - __sanitizer___kernel_fd_set *arg3, void *arg4, - void *arg5) { +POST_SYSCALL(pselect6) +(long res, long arg0, __sanitizer___kernel_fd_set *arg1, + __sanitizer___kernel_fd_set *arg2, __sanitizer___kernel_fd_set *arg3, + void *arg4, void *arg5) { if (res >= 0) { - if (arg1) POST_WRITE(arg1, sizeof(*arg1)); - if (arg2) POST_WRITE(arg2, sizeof(*arg2)); - if (arg3) POST_WRITE(arg3, sizeof(*arg3)); - if (arg4) POST_WRITE(arg4, struct_timespec_sz); + if (arg1) + POST_WRITE(arg1, sizeof(*arg1)); + if (arg2) + POST_WRITE(arg2, sizeof(*arg2)); + if (arg3) + POST_WRITE(arg3, sizeof(*arg3)); + if (arg4) + POST_WRITE(arg4, struct_timespec_sz); } } -PRE_SYSCALL(ppoll)(__sanitizer_pollfd *arg0, long arg1, void *arg2, - const kernel_sigset_t *arg3, long arg4) { - if (arg3) PRE_READ(arg3, arg4); +PRE_SYSCALL(ppoll) +(__sanitizer_pollfd *arg0, long arg1, void *arg2, const kernel_sigset_t *arg3, + long arg4) { + if (arg3) + PRE_READ(arg3, arg4); } -POST_SYSCALL(ppoll)(long res, __sanitizer_pollfd *arg0, long arg1, void *arg2, - const void *arg3, long arg4) { +POST_SYSCALL(ppoll) +(long res, __sanitizer_pollfd *arg0, long arg1, void *arg2, const void *arg3, + long arg4) { if (res >= 0) { - if (arg0) POST_WRITE(arg0, sizeof(*arg0)); - if (arg2) POST_WRITE(arg2, struct_timespec_sz); + if (arg0) + POST_WRITE(arg0, sizeof(*arg0)); + if (arg2) + POST_WRITE(arg2, struct_timespec_sz); } } @@ -2769,81 +3029,79 @@ PRE_SYSCALL(syncfs)(long fd) {} POST_SYSCALL(syncfs)(long res, long fd) {} -PRE_SYSCALL(perf_event_open)(__sanitizer_perf_event_attr *attr_uptr, long pid, - long cpu, long group_fd, long flags) { - if (attr_uptr) PRE_READ(attr_uptr, attr_uptr->size); +PRE_SYSCALL(perf_event_open) +(__sanitizer_perf_event_attr *attr_uptr, long pid, long cpu, long group_fd, + long flags) { + if (attr_uptr) + PRE_READ(attr_uptr, attr_uptr->size); } -POST_SYSCALL(perf_event_open)(long res, __sanitizer_perf_event_attr *attr_uptr, - long pid, long cpu, long group_fd, long flags) {} +POST_SYSCALL(perf_event_open) +(long res, __sanitizer_perf_event_attr *attr_uptr, long pid, long cpu, + long group_fd, long flags) {} -PRE_SYSCALL(mmap_pgoff)(long addr, long len, long prot, long flags, long fd, - long pgoff) {} +PRE_SYSCALL(mmap_pgoff) +(long addr, long len, long prot, long flags, long fd, long pgoff) {} -POST_SYSCALL(mmap_pgoff)(long res, long addr, long len, long prot, long flags, - long fd, long pgoff) {} +POST_SYSCALL(mmap_pgoff) +(long res, long addr, long len, long prot, long flags, long fd, long pgoff) {} PRE_SYSCALL(old_mmap)(void *arg) {} POST_SYSCALL(old_mmap)(long res, void *arg) {} -PRE_SYSCALL(name_to_handle_at)(long dfd, const void *name, void *handle, - void *mnt_id, long flag) {} +PRE_SYSCALL(name_to_handle_at) +(long dfd, const void *name, void *handle, void *mnt_id, long flag) {} -POST_SYSCALL(name_to_handle_at)(long res, long dfd, const void *name, - void *handle, void *mnt_id, long flag) {} +POST_SYSCALL(name_to_handle_at) +(long res, long dfd, const void *name, void *handle, void *mnt_id, long flag) {} PRE_SYSCALL(open_by_handle_at)(long mountdirfd, void *handle, long flags) {} -POST_SYSCALL(open_by_handle_at)(long res, long mountdirfd, void *handle, - long flags) {} +POST_SYSCALL(open_by_handle_at) +(long res, long mountdirfd, void *handle, long flags) {} PRE_SYSCALL(setns)(long fd, long nstype) {} POST_SYSCALL(setns)(long res, long fd, long nstype) {} -PRE_SYSCALL(process_vm_readv)(long pid, const __sanitizer_iovec *lvec, - long liovcnt, const void *rvec, long riovcnt, - long flags) {} +PRE_SYSCALL(process_vm_readv) +(long pid, const __sanitizer_iovec *lvec, long liovcnt, const void *rvec, + long riovcnt, long flags) {} -POST_SYSCALL(process_vm_readv)(long res, long pid, - const __sanitizer_iovec *lvec, long liovcnt, - const void *rvec, long riovcnt, long flags) { +POST_SYSCALL(process_vm_readv) +(long res, long pid, const __sanitizer_iovec *lvec, long liovcnt, + const void *rvec, long riovcnt, long flags) { if (res >= 0) { - if (lvec) kernel_write_iovec(lvec, liovcnt, res); + if (lvec) + kernel_write_iovec(lvec, liovcnt, res); } } -PRE_SYSCALL(process_vm_writev)(long pid, const __sanitizer_iovec *lvec, - long liovcnt, const void *rvec, long riovcnt, - long flags) {} +PRE_SYSCALL(process_vm_writev) +(long pid, const __sanitizer_iovec *lvec, long liovcnt, const void *rvec, + long riovcnt, long flags) {} -POST_SYSCALL(process_vm_writev)(long res, long pid, - const __sanitizer_iovec *lvec, long liovcnt, - const void *rvec, long riovcnt, long flags) { +POST_SYSCALL(process_vm_writev) +(long res, long pid, const __sanitizer_iovec *lvec, long liovcnt, + const void *rvec, long riovcnt, long flags) { if (res >= 0) { - if (lvec) kernel_read_iovec(lvec, liovcnt, res); + if (lvec) + kernel_read_iovec(lvec, liovcnt, res); } } -PRE_SYSCALL(fork)() { - COMMON_SYSCALL_PRE_FORK(); -} +PRE_SYSCALL(fork)() { COMMON_SYSCALL_PRE_FORK(); } -POST_SYSCALL(fork)(long res) { - COMMON_SYSCALL_POST_FORK(res); -} +POST_SYSCALL(fork)(long res) { COMMON_SYSCALL_POST_FORK(res); } -PRE_SYSCALL(vfork)() { - COMMON_SYSCALL_PRE_FORK(); -} +PRE_SYSCALL(vfork)() { COMMON_SYSCALL_PRE_FORK(); } -POST_SYSCALL(vfork)(long res) { - COMMON_SYSCALL_POST_FORK(res); -} +POST_SYSCALL(vfork)(long res) { COMMON_SYSCALL_POST_FORK(res); } -PRE_SYSCALL(sigaction)(long signum, const __sanitizer_kernel_sigaction_t *act, - __sanitizer_kernel_sigaction_t *oldact) { +PRE_SYSCALL(sigaction) +(long signum, const __sanitizer_kernel_sigaction_t *act, + __sanitizer_kernel_sigaction_t *oldact) { if (act) { PRE_READ(&act->sigaction, sizeof(act->sigaction)); PRE_READ(&act->sa_flags, sizeof(act->sa_flags)); @@ -2851,15 +3109,16 @@ PRE_SYSCALL(sigaction)(long signum, const __sanitizer_kernel_sigaction_t *act, } } -POST_SYSCALL(sigaction)(long res, long signum, - const __sanitizer_kernel_sigaction_t *act, - __sanitizer_kernel_sigaction_t *oldact) { - if (res >= 0 && oldact) POST_WRITE(oldact, sizeof(*oldact)); +POST_SYSCALL(sigaction) +(long res, long signum, const __sanitizer_kernel_sigaction_t *act, + __sanitizer_kernel_sigaction_t *oldact) { + if (res >= 0 && oldact) + POST_WRITE(oldact, sizeof(*oldact)); } -PRE_SYSCALL(rt_sigaction)(long signum, - const __sanitizer_kernel_sigaction_t *act, - __sanitizer_kernel_sigaction_t *oldact, SIZE_T sz) { +PRE_SYSCALL(rt_sigaction) +(long signum, const __sanitizer_kernel_sigaction_t *act, + __sanitizer_kernel_sigaction_t *oldact, SIZE_T sz) { if (act) { PRE_READ(&act->sigaction, sizeof(act->sigaction)); PRE_READ(&act->sa_flags, sizeof(act->sa_flags)); @@ -2867,9 +3126,9 @@ PRE_SYSCALL(rt_sigaction)(long signum, } } -POST_SYSCALL(rt_sigaction)(long res, long signum, - const __sanitizer_kernel_sigaction_t *act, - __sanitizer_kernel_sigaction_t *oldact, SIZE_T sz) { +POST_SYSCALL(rt_sigaction) +(long res, long signum, const __sanitizer_kernel_sigaction_t *act, + __sanitizer_kernel_sigaction_t *oldact, SIZE_T sz) { if (res >= 0 && oldact) { SIZE_T oldact_sz = ((char *)&oldact->sa_mask) - ((char *)oldact) + sz; POST_WRITE(oldact, oldact_sz); @@ -2906,11 +3165,11 @@ POST_SYSCALL(sigaltstack)(long res, void *ss, void *oss) { } } // extern "C" -#undef PRE_SYSCALL -#undef PRE_READ -#undef PRE_WRITE -#undef POST_SYSCALL -#undef POST_READ -#undef POST_WRITE +# undef PRE_SYSCALL +# undef PRE_READ +# undef PRE_WRITE +# undef POST_SYSCALL +# undef POST_READ +# undef POST_WRITE #endif // SANITIZER_LINUX diff --git a/libsanitizer/sanitizer_common/sanitizer_coverage_fuchsia.cpp b/libsanitizer/sanitizer_common/sanitizer_coverage_fuchsia.cpp index a52db08..1d0dbe5 100644 --- a/libsanitizer/sanitizer_common/sanitizer_coverage_fuchsia.cpp +++ b/libsanitizer/sanitizer_common/sanitizer_coverage_fuchsia.cpp @@ -51,6 +51,8 @@ constexpr const char kSancovSinkName[] = "sancov"; // This class relies on zero-initialization. class TracePcGuardController final { public: + constexpr TracePcGuardController() {} + // For each PC location being tracked, there is a u32 reserved in global // data called the "guard". At startup, we assign each guard slot a // unique index into the big results array. Later during runtime, the @@ -87,7 +89,7 @@ class TracePcGuardController final { } void Dump() { - BlockingMutexLock locked(&setup_lock_); + Lock locked(&setup_lock_); if (array_) { CHECK_NE(vmo_, ZX_HANDLE_INVALID); @@ -114,7 +116,7 @@ class TracePcGuardController final { // We can always spare the 32G of address space. static constexpr size_t MappingSize = sizeof(uptr) << 32; - BlockingMutex setup_lock_ = BlockingMutex(LINKER_INITIALIZED); + Mutex setup_lock_; uptr *array_ = nullptr; u32 next_index_ = 0; zx_handle_t vmo_ = {}; @@ -123,7 +125,7 @@ class TracePcGuardController final { size_t DataSize() const { return next_index_ * sizeof(uintptr_t); } u32 Setup(u32 num_guards) { - BlockingMutexLock locked(&setup_lock_); + Lock locked(&setup_lock_); DCHECK(common_flags()->coverage); if (next_index_ == 0) { diff --git a/libsanitizer/sanitizer_common/sanitizer_coverage_libcdep_new.cpp b/libsanitizer/sanitizer_common/sanitizer_coverage_libcdep_new.cpp index 73ebeb5..56220df 100644 --- a/libsanitizer/sanitizer_common/sanitizer_coverage_libcdep_new.cpp +++ b/libsanitizer/sanitizer_common/sanitizer_coverage_libcdep_new.cpp @@ -73,7 +73,7 @@ static void SanitizerDumpCoverage(const uptr* unsorted_pcs, uptr len) { if (!pc) continue; if (!__sanitizer_get_module_and_offset_for_pc(pc, nullptr, 0, &pcs[i])) { - Printf("ERROR: unknown pc 0x%x (may happen if dlclose is used)\n", pc); + Printf("ERROR: unknown pc 0x%zx (may happen if dlclose is used)\n", pc); continue; } uptr module_base = pc - pcs[i]; @@ -151,6 +151,55 @@ class TracePcGuardController { static TracePcGuardController pc_guard_controller; +// A basic default implementation of callbacks for +// -fsanitize-coverage=inline-8bit-counters,pc-table. +// Use TOOL_OPTIONS (UBSAN_OPTIONS, etc) to dump the coverage data: +// * cov_8bit_counters_out=PATH to dump the 8bit counters. +// * cov_pcs_out=PATH to dump the pc table. +// +// Most users will still need to define their own callbacks for greater +// flexibility. +namespace SingletonCounterCoverage { + +static char *counters_beg, *counters_end; +static const uptr *pcs_beg, *pcs_end; + +static void DumpCoverage() { + const char* file_path = common_flags()->cov_8bit_counters_out; + if (file_path && internal_strlen(file_path)) { + fd_t fd = OpenFile(file_path); + FileCloser file_closer(fd); + uptr size = counters_end - counters_beg; + WriteToFile(fd, counters_beg, size); + if (common_flags()->verbosity) + __sanitizer::Printf("cov_8bit_counters_out: written %zd bytes to %s\n", + size, file_path); + } + file_path = common_flags()->cov_pcs_out; + if (file_path && internal_strlen(file_path)) { + fd_t fd = OpenFile(file_path); + FileCloser file_closer(fd); + uptr size = (pcs_end - pcs_beg) * sizeof(uptr); + WriteToFile(fd, pcs_beg, size); + if (common_flags()->verbosity) + __sanitizer::Printf("cov_pcs_out: written %zd bytes to %s\n", size, + file_path); + } +} + +static void Cov8bitCountersInit(char* beg, char* end) { + counters_beg = beg; + counters_end = end; + Atexit(DumpCoverage); +} + +static void CovPcsInit(const uptr* beg, const uptr* end) { + pcs_beg = beg; + pcs_end = end; +} + +} // namespace SingletonCounterCoverage + } // namespace } // namespace __sancov @@ -191,7 +240,9 @@ SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_cov_dump() { SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_cov_reset() { __sancov::pc_guard_controller.Reset(); } -// Default empty implementations (weak). Users should redefine them. +// Default implementations (weak). +// Either empty or very simple. +// Most users should redefine them. SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_cov_trace_cmp, void) {} SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_cov_trace_cmp1, void) {} SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_cov_trace_cmp2, void) {} @@ -206,9 +257,15 @@ SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_cov_trace_div4, void) {} SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_cov_trace_div8, void) {} SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_cov_trace_gep, void) {} SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_cov_trace_pc_indir, void) {} -SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_cov_8bit_counters_init, void) {} +SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_cov_8bit_counters_init, + char* start, char* end) { + __sancov::SingletonCounterCoverage::Cov8bitCountersInit(start, end); +} SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_cov_bool_flag_init, void) {} -SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_cov_pcs_init, void) {} +SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_cov_pcs_init, const uptr* beg, + const uptr* end) { + __sancov::SingletonCounterCoverage::CovPcsInit(beg, end); +} } // extern "C" // Weak definition for code instrumented with -fsanitize-coverage=stack-depth // and later linked with code containing a strong definition. diff --git a/libsanitizer/sanitizer_common/sanitizer_file.cpp b/libsanitizer/sanitizer_common/sanitizer_file.cpp index 0b92dcc..5492560 100644 --- a/libsanitizer/sanitizer_common/sanitizer_file.cpp +++ b/libsanitizer/sanitizer_common/sanitizer_file.cpp @@ -75,6 +75,20 @@ void ReportFile::ReopenIfNecessary() { fd_pid = pid; } +static void RecursiveCreateParentDirs(char *path) { + if (path[0] == '\0') + return; + for (int i = 1; path[i] != '\0'; ++i) { + char save = path[i]; + if (!IsPathSeparator(path[i])) + continue; + path[i] = '\0'; + /* Some of these will fail, because the directory exists, ignore it. */ + CreateDir(path); + path[i] = save; + } +} + void ReportFile::SetReportPath(const char *path) { if (path) { uptr len = internal_strlen(path); @@ -95,6 +109,7 @@ void ReportFile::SetReportPath(const char *path) { fd = kStdoutFd; } else { internal_snprintf(path_prefix, kMaxPathLength, "%s", path); + RecursiveCreateParentDirs(path_prefix); } } diff --git a/libsanitizer/sanitizer_common/sanitizer_file.h b/libsanitizer/sanitizer_common/sanitizer_file.h index 08671ab..3d79161 100644 --- a/libsanitizer/sanitizer_common/sanitizer_file.h +++ b/libsanitizer/sanitizer_common/sanitizer_file.h @@ -81,6 +81,8 @@ bool FileExists(const char *filename); char *FindPathToBinary(const char *name); bool IsPathSeparator(const char c); bool IsAbsolutePath(const char *path); +// Returns true on success, false on failure. +bool CreateDir(const char *pathname); // Starts a subprocess and returs its pid. // If *_fd parameters are not kInvalidFd their corresponding input/output // streams will be redirect to the file. The files will always be closed diff --git a/libsanitizer/sanitizer_common/sanitizer_flag_parser.h b/libsanitizer/sanitizer_common/sanitizer_flag_parser.h index acc71cc..3ccc6a6 100644 --- a/libsanitizer/sanitizer_common/sanitizer_flag_parser.h +++ b/libsanitizer/sanitizer_common/sanitizer_flag_parser.h @@ -138,7 +138,7 @@ 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_); + uptr num_symbols_should_write = internal_snprintf(buffer, size, "0x%zx", *t_); return num_symbols_should_write < size; } diff --git a/libsanitizer/sanitizer_common/sanitizer_flags.inc b/libsanitizer/sanitizer_common/sanitizer_flags.inc index 3bc44c6..95da82b 100644 --- a/libsanitizer/sanitizer_common/sanitizer_flags.inc +++ b/libsanitizer/sanitizer_common/sanitizer_flags.inc @@ -160,6 +160,10 @@ COMMON_FLAG( COMMON_FLAG(const char *, coverage_dir, ".", "Target directory for coverage dumps. Defaults to the current " "directory.") +COMMON_FLAG(const char *, cov_8bit_counters_out, "", + "If non-empty, write 8bit counters to this file. ") +COMMON_FLAG(const char *, cov_pcs_out, "", + "If non-empty, write the coverage pc table to this file. ") COMMON_FLAG(bool, full_address_space, false, "Sanitize complete address space; " "by default kernel area on 32-bit platforms will not be sanitized") diff --git a/libsanitizer/sanitizer_common/sanitizer_fuchsia.cpp b/libsanitizer/sanitizer_common/sanitizer_fuchsia.cpp index 65bc398..de4c985 100644 --- a/libsanitizer/sanitizer_common/sanitizer_fuchsia.cpp +++ b/libsanitizer/sanitizer_common/sanitizer_fuchsia.cpp @@ -112,47 +112,6 @@ void FutexWake(atomic_uint32_t *p, u32 count) { CHECK_EQ(status, ZX_OK); } -enum MutexState : int { MtxUnlocked = 0, MtxLocked = 1, MtxSleeping = 2 }; - -BlockingMutex::BlockingMutex() { - // NOTE! It's important that this use internal_memset, because plain - // memset might be intercepted (e.g., actually be __asan_memset). - // Defining this so the compiler initializes each field, e.g.: - // BlockingMutex::BlockingMutex() : BlockingMutex(LINKER_INITIALIZED) {} - // might result in the compiler generating a call to memset, which would - // have the same problem. - internal_memset(this, 0, sizeof(*this)); -} - -void BlockingMutex::Lock() { - CHECK_EQ(owner_, 0); - atomic_uint32_t *m = reinterpret_cast<atomic_uint32_t *>(&opaque_storage_); - if (atomic_exchange(m, MtxLocked, memory_order_acquire) == MtxUnlocked) - return; - while (atomic_exchange(m, MtxSleeping, memory_order_acquire) != MtxUnlocked) { - zx_status_t status = - _zx_futex_wait(reinterpret_cast<zx_futex_t *>(m), MtxSleeping, - ZX_HANDLE_INVALID, ZX_TIME_INFINITE); - if (status != ZX_ERR_BAD_STATE) // Normal race. - CHECK_EQ(status, ZX_OK); - } -} - -void BlockingMutex::Unlock() { - atomic_uint32_t *m = reinterpret_cast<atomic_uint32_t *>(&opaque_storage_); - u32 v = atomic_exchange(m, MtxUnlocked, memory_order_release); - CHECK_NE(v, MtxUnlocked); - if (v == MtxSleeping) { - zx_status_t status = _zx_futex_wake(reinterpret_cast<zx_futex_t *>(m), 1); - CHECK_EQ(status, ZX_OK); - } -} - -void BlockingMutex::CheckLocked() const { - auto m = reinterpret_cast<atomic_uint32_t const *>(&opaque_storage_); - CHECK_NE(MtxUnlocked, atomic_load(m, memory_order_relaxed)); -} - uptr GetPageSize() { return _zx_system_get_page_size(); } uptr GetMmapGranularity() { return _zx_system_get_page_size(); } diff --git a/libsanitizer/sanitizer_common/sanitizer_interceptors_ioctl_netbsd.inc b/libsanitizer/sanitizer_common/sanitizer_interceptors_ioctl_netbsd.inc index 576807e..9683b97 100644 --- a/libsanitizer/sanitizer_common/sanitizer_interceptors_ioctl_netbsd.inc +++ b/libsanitizer/sanitizer_common/sanitizer_interceptors_ioctl_netbsd.inc @@ -1406,7 +1406,7 @@ static void ioctl_table_fill() { _(URIO_SEND_COMMAND, READWRITE, struct_urio_command_sz); _(URIO_RECV_COMMAND, READWRITE, struct_urio_command_sz); #undef _ -} // NOLINT +} static bool ioctl_initialized = false; diff --git a/libsanitizer/sanitizer_common/sanitizer_interface_internal.h b/libsanitizer/sanitizer_common/sanitizer_interface_internal.h index 0b001c1..1600d31 100644 --- a/libsanitizer/sanitizer_common/sanitizer_interface_internal.h +++ b/libsanitizer/sanitizer_common/sanitizer_interface_internal.h @@ -111,12 +111,13 @@ extern "C" { SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void __sanitizer_cov_trace_pc_guard_init(__sanitizer::u32*, __sanitizer::u32*); - SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE - void __sanitizer_cov_8bit_counters_init(); + SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void + __sanitizer_cov_8bit_counters_init(char *, char *); SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void __sanitizer_cov_bool_flag_init(); SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void - __sanitizer_cov_pcs_init(); + __sanitizer_cov_pcs_init(const __sanitizer::uptr *, + const __sanitizer::uptr *); } // extern "C" #endif // SANITIZER_INTERFACE_INTERNAL_H diff --git a/libsanitizer/sanitizer_common/sanitizer_internal_defs.h b/libsanitizer/sanitizer_common/sanitizer_internal_defs.h index 84053fe..e97cc9a 100644 --- a/libsanitizer/sanitizer_common/sanitizer_internal_defs.h +++ b/libsanitizer/sanitizer_common/sanitizer_internal_defs.h @@ -125,6 +125,10 @@ # define __has_attribute(x) 0 #endif +#if !defined(__has_cpp_attribute) +# define __has_cpp_attribute(x) 0 +#endif + // For portability reasons we do not include stddef.h, stdint.h or any other // system header, but we do need some basic types that are not defined // in a portable way by the language itself. @@ -135,8 +139,13 @@ namespace __sanitizer { typedef unsigned long long uptr; typedef signed long long sptr; #else +# if (SANITIZER_WORDSIZE == 64) || SANITIZER_MAC || SANITIZER_WINDOWS typedef unsigned long uptr; typedef signed long sptr; +# else +typedef unsigned int uptr; +typedef signed int sptr; +# endif #endif // defined(_WIN64) #if defined(__x86_64__) // Since x32 uses ILP32 data model in 64-bit hardware mode, we must use @@ -168,10 +177,9 @@ typedef long pid_t; typedef int pid_t; #endif -#if SANITIZER_FREEBSD || SANITIZER_NETBSD || \ - SANITIZER_MAC || \ +#if SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_MAC || \ (SANITIZER_SOLARIS && (defined(_LP64) || _FILE_OFFSET_BITS == 64)) || \ - (SANITIZER_LINUX && defined(__x86_64__)) + (SANITIZER_LINUX && (defined(__x86_64__) || defined(__hexagon__))) typedef u64 OFF_T; #else typedef uptr OFF_T; @@ -250,6 +258,12 @@ typedef u64 tid_t; # define NOEXCEPT throw() #endif +#if __has_cpp_attribute(clang::fallthrough) +# define FALLTHROUGH [[clang::fallthrough]] +#else +# define FALLTHROUGH +#endif + // Unaligned versions of basic types. typedef ALIGNED(1) u16 uu16; typedef ALIGNED(1) u32 uu32; @@ -277,14 +291,16 @@ void NORETURN CheckFailed(const char *file, int line, const char *cond, u64 v1, u64 v2); // Check macro -#define RAW_CHECK_MSG(expr, msg) do { \ - if (UNLIKELY(!(expr))) { \ - RawWrite(msg); \ - Die(); \ - } \ -} while (0) +#define RAW_CHECK_MSG(expr, msg, ...) \ + do { \ + if (UNLIKELY(!(expr))) { \ + const char* msgs[] = {msg, __VA_ARGS__}; \ + for (const char* m : msgs) RawWrite(m); \ + Die(); \ + } \ + } while (0) -#define RAW_CHECK(expr) RAW_CHECK_MSG(expr, #expr) +#define RAW_CHECK(expr, ...) RAW_CHECK_MSG(expr, #expr "\n", __VA_ARGS__) #define CHECK_IMPL(c1, op, c2) \ do { \ @@ -409,8 +425,14 @@ inline void Trap() { (void)enable_fp; \ } while (0) -constexpr u32 kInvalidTid = -1; -constexpr u32 kMainTid = 0; +// Internal thread identifier allocated by ThreadRegistry. +typedef u32 Tid; +constexpr Tid kInvalidTid = -1; +constexpr Tid kMainTid = 0; + +// Stack depot stack identifier. +typedef u32 StackID; +const StackID kInvalidStackID = 0; } // namespace __sanitizer diff --git a/libsanitizer/sanitizer_common/sanitizer_libc.cpp b/libsanitizer/sanitizer_common/sanitizer_libc.cpp index 4bc04b4..d3076f0 100644 --- a/libsanitizer/sanitizer_common/sanitizer_libc.cpp +++ b/libsanitizer/sanitizer_common/sanitizer_libc.cpp @@ -258,6 +258,18 @@ s64 internal_simple_strtoll(const char *nptr, const char **endptr, int base) { } } +uptr internal_wcslen(const wchar_t *s) { + uptr i = 0; + while (s[i]) i++; + return i; +} + +uptr internal_wcsnlen(const wchar_t *s, uptr maxlen) { + uptr i = 0; + while (i < maxlen && s[i]) i++; + return i; +} + bool mem_is_zero(const char *beg, uptr size) { CHECK_LE(size, 1ULL << FIRST_32_SECOND_64(30, 40)); // Sanity check. const char *end = beg + size; diff --git a/libsanitizer/sanitizer_common/sanitizer_libc.h b/libsanitizer/sanitizer_common/sanitizer_libc.h index bcb81eb..39a2126 100644 --- a/libsanitizer/sanitizer_common/sanitizer_libc.h +++ b/libsanitizer/sanitizer_common/sanitizer_libc.h @@ -49,7 +49,10 @@ char *internal_strrchr(const char *s, int c); char *internal_strstr(const char *haystack, const char *needle); // Works only for base=10 and doesn't set errno. s64 internal_simple_strtoll(const char *nptr, const char **endptr, int base); -int internal_snprintf(char *buffer, uptr length, const char *format, ...); +int internal_snprintf(char *buffer, uptr length, const char *format, ...) + FORMAT(3, 4); +uptr internal_wcslen(const wchar_t *s); +uptr internal_wcsnlen(const wchar_t *s, uptr maxlen); // Return true if all bytes in [mem, mem+size) are zero. // Optimized for the case when the result is true. diff --git a/libsanitizer/sanitizer_common/sanitizer_libignore.cpp b/libsanitizer/sanitizer_common/sanitizer_libignore.cpp index 431efc5..caaba31 100644 --- a/libsanitizer/sanitizer_common/sanitizer_libignore.cpp +++ b/libsanitizer/sanitizer_common/sanitizer_libignore.cpp @@ -22,9 +22,9 @@ LibIgnore::LibIgnore(LinkerInitialized) { } void LibIgnore::AddIgnoredLibrary(const char *name_templ) { - BlockingMutexLock lock(&mutex_); + Lock lock(&mutex_); if (count_ >= kMaxLibs) { - Report("%s: too many ignored libraries (max: %d)\n", SanitizerToolName, + Report("%s: too many ignored libraries (max: %zu)\n", SanitizerToolName, kMaxLibs); Die(); } @@ -36,7 +36,7 @@ void LibIgnore::AddIgnoredLibrary(const char *name_templ) { } void LibIgnore::OnLibraryLoaded(const char *name) { - BlockingMutexLock lock(&mutex_); + Lock lock(&mutex_); // Try to match suppressions with symlink target. InternalMmapVector<char> buf(kMaxPathLength); if (name && internal_readlink(name, buf.data(), buf.size() - 1) > 0 && @@ -84,7 +84,6 @@ void LibIgnore::OnLibraryLoaded(const char *name) { ignored_code_ranges_[idx].begin = range.beg; ignored_code_ranges_[idx].end = range.end; atomic_store(&ignored_ranges_count_, idx + 1, memory_order_release); - atomic_store(&enabled_, 1, memory_order_release); break; } } @@ -106,7 +105,7 @@ void LibIgnore::OnLibraryLoaded(const char *name) { continue; if (IsPcInstrumented(range.beg) && IsPcInstrumented(range.end - 1)) continue; - VReport(1, "Adding instrumented range %p-%p from library '%s'\n", + VReport(1, "Adding instrumented range 0x%zx-0x%zx from library '%s'\n", range.beg, range.end, mod.full_name()); const uptr idx = atomic_load(&instrumented_ranges_count_, memory_order_relaxed); @@ -115,7 +114,6 @@ void LibIgnore::OnLibraryLoaded(const char *name) { instrumented_code_ranges_[idx].end = range.end; atomic_store(&instrumented_ranges_count_, idx + 1, memory_order_release); - atomic_store(&enabled_, 1, memory_order_release); } } } @@ -125,29 +123,6 @@ void LibIgnore::OnLibraryUnloaded() { OnLibraryLoaded(nullptr); } -bool LibIgnore::IsIgnoredSlow(uptr pc, bool *pc_in_ignored_lib) const { - const uptr n = atomic_load(&ignored_ranges_count_, memory_order_acquire); - for (uptr i = 0; i < n; i++) { - if (IsInRange(pc, ignored_code_ranges_[i])) { - *pc_in_ignored_lib = true; - return true; - } - } - *pc_in_ignored_lib = false; - if (track_instrumented_libs_ && !IsPcInstrumented(pc)) - return true; - return false; -} - -bool LibIgnore::IsPcInstrumented(uptr pc) const { - const uptr n = atomic_load(&instrumented_ranges_count_, memory_order_acquire); - for (uptr i = 0; i < n; i++) { - if (IsInRange(pc, instrumented_code_ranges_[i])) - return true; - } - return false; -} - } // namespace __sanitizer #endif // SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_MAC || diff --git a/libsanitizer/sanitizer_common/sanitizer_libignore.h b/libsanitizer/sanitizer_common/sanitizer_libignore.h index 85452e5..18e4d83 100644 --- a/libsanitizer/sanitizer_common/sanitizer_libignore.h +++ b/libsanitizer/sanitizer_common/sanitizer_libignore.h @@ -45,6 +45,9 @@ class LibIgnore { // "pc_in_ignored_lib" if the PC is in an ignored library, false otherwise. bool IsIgnored(uptr pc, bool *pc_in_ignored_lib) const; + // Checks whether the provided PC belongs to an instrumented module. + bool IsPcInstrumented(uptr pc) const; + private: struct Lib { char *templ; @@ -58,10 +61,6 @@ class LibIgnore { uptr end; }; - // Checks whether the provided PC belongs to an instrumented module. - bool IsPcInstrumented(uptr pc) const; - bool IsIgnoredSlow(uptr pc, bool *pc_in_ignored_lib) const; - inline bool IsInRange(uptr pc, const LibCodeRange &range) const { return (pc >= range.begin && pc < range.end); } @@ -71,8 +70,6 @@ class LibIgnore { static const uptr kMaxLibs = 1024; // Hot part: - atomic_uintptr_t enabled_; - atomic_uintptr_t ignored_ranges_count_; LibCodeRange ignored_code_ranges_[kMaxIgnoredRanges]; @@ -80,7 +77,7 @@ class LibIgnore { LibCodeRange instrumented_code_ranges_[kMaxInstrumentedRanges]; // Cold part: - BlockingMutex mutex_; + Mutex mutex_; uptr count_; Lib libs_[kMaxLibs]; bool track_instrumented_libs_; @@ -90,11 +87,27 @@ class LibIgnore { void operator = (const LibIgnore&); // not implemented }; -ALWAYS_INLINE -bool LibIgnore::IsIgnored(uptr pc, bool *pc_in_ignored_lib) const { - if (LIKELY(atomic_load(&enabled_, memory_order_acquire) == 0)) - return false; - return IsIgnoredSlow(pc, pc_in_ignored_lib); +inline bool LibIgnore::IsIgnored(uptr pc, bool *pc_in_ignored_lib) const { + const uptr n = atomic_load(&ignored_ranges_count_, memory_order_acquire); + for (uptr i = 0; i < n; i++) { + if (IsInRange(pc, ignored_code_ranges_[i])) { + *pc_in_ignored_lib = true; + return true; + } + } + *pc_in_ignored_lib = false; + if (track_instrumented_libs_ && !IsPcInstrumented(pc)) + return true; + return false; +} + +inline bool LibIgnore::IsPcInstrumented(uptr pc) const { + const uptr n = atomic_load(&instrumented_ranges_count_, memory_order_acquire); + for (uptr i = 0; i < n; i++) { + if (IsInRange(pc, instrumented_code_ranges_[i])) + return true; + } + return false; } } // namespace __sanitizer diff --git a/libsanitizer/sanitizer_common/sanitizer_linux.cpp b/libsanitizer/sanitizer_common/sanitizer_linux.cpp index 9b7d87e..ea3e5bd 100644 --- a/libsanitizer/sanitizer_common/sanitizer_linux.cpp +++ b/libsanitizer/sanitizer_common/sanitizer_linux.cpp @@ -158,9 +158,11 @@ namespace __sanitizer { #include "sanitizer_syscall_linux_aarch64.inc" #elif SANITIZER_LINUX && defined(__arm__) #include "sanitizer_syscall_linux_arm.inc" -#else -#include "sanitizer_syscall_generic.inc" -#endif +# elif SANITIZER_LINUX && defined(__hexagon__) +# include "sanitizer_syscall_linux_hexagon.inc" +# else +# include "sanitizer_syscall_generic.inc" +# endif // --------------- sanitizer_libc.h #if !SANITIZER_SOLARIS && !SANITIZER_NETBSD @@ -415,7 +417,7 @@ uptr internal_unlink(const char *path) { } uptr internal_rename(const char *oldpath, const char *newpath) { -#if defined(__riscv) +#if defined(__riscv) && defined(__linux__) return internal_syscall(SYSCALL(renameat2), AT_FDCWD, (uptr)oldpath, AT_FDCWD, (uptr)newpath, 0); #elif SANITIZER_USES_CANONICAL_LINUX_SYSCALLS @@ -659,48 +661,6 @@ void FutexWake(atomic_uint32_t *p, u32 count) { # endif } -enum { MtxUnlocked = 0, MtxLocked = 1, MtxSleeping = 2 }; - -BlockingMutex::BlockingMutex() { - internal_memset(this, 0, sizeof(*this)); -} - -void BlockingMutex::Lock() { - CHECK_EQ(owner_, 0); - atomic_uint32_t *m = reinterpret_cast<atomic_uint32_t *>(&opaque_storage_); - if (atomic_exchange(m, MtxLocked, memory_order_acquire) == MtxUnlocked) - return; - while (atomic_exchange(m, MtxSleeping, memory_order_acquire) != MtxUnlocked) { -#if SANITIZER_FREEBSD - _umtx_op(m, UMTX_OP_WAIT_UINT, MtxSleeping, 0, 0); -#elif SANITIZER_NETBSD - sched_yield(); /* No userspace futex-like synchronization */ -#else - internal_syscall(SYSCALL(futex), (uptr)m, FUTEX_WAIT_PRIVATE, MtxSleeping, - 0, 0, 0); -#endif - } -} - -void BlockingMutex::Unlock() { - atomic_uint32_t *m = reinterpret_cast<atomic_uint32_t *>(&opaque_storage_); - u32 v = atomic_exchange(m, MtxUnlocked, memory_order_release); - CHECK_NE(v, MtxUnlocked); - if (v == MtxSleeping) { -#if SANITIZER_FREEBSD - _umtx_op(m, UMTX_OP_WAKE, 1, 0, 0); -#elif SANITIZER_NETBSD - /* No userspace futex-like synchronization */ -#else - internal_syscall(SYSCALL(futex), (uptr)m, FUTEX_WAKE_PRIVATE, 1, 0, 0, 0); -#endif - } -} - -void BlockingMutex::CheckLocked() const { - auto m = reinterpret_cast<atomic_uint32_t const *>(&opaque_storage_); - CHECK_NE(MtxUnlocked, atomic_load(m, memory_order_relaxed)); -} # endif // !SANITIZER_SOLARIS // ----------------- sanitizer_linux.h @@ -1217,7 +1177,8 @@ void ForEachMappedRegion(link_map *map, void (*cb)(const void *, uptr)) { } #endif -#if defined(__x86_64__) && SANITIZER_LINUX +#if SANITIZER_LINUX +#if defined(__x86_64__) // We cannot use glibc's clone wrapper, because it messes with the child // task's TLS. It writes the PID and TID of the child task to its thread // descriptor, but in our case the child task shares the thread descriptor with @@ -1556,7 +1517,7 @@ uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, : "cr0", "cr1", "memory", "ctr", "r0", "r27", "r28", "r29"); return res; } -#elif defined(__i386__) && SANITIZER_LINUX +#elif defined(__i386__) uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, int *parent_tidptr, void *newtls, int *child_tidptr) { int res; @@ -1621,7 +1582,7 @@ uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, : "memory"); return res; } -#elif defined(__arm__) && SANITIZER_LINUX +#elif defined(__arm__) uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, int *parent_tidptr, void *newtls, int *child_tidptr) { unsigned int res; @@ -1687,7 +1648,8 @@ uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, : "memory"); return res; } -#endif // defined(__x86_64__) && SANITIZER_LINUX +#endif +#endif // SANITIZER_LINUX #if SANITIZER_LINUX int internal_uname(struct utsname *buf) { @@ -1917,7 +1879,11 @@ SignalContext::WriteFlag SignalContext::GetWriteFlag() const { u32 instr = *(u32 *)pc; return (instr >> 21) & 1 ? WRITE: READ; #elif defined(__riscv) +#if SANITIZER_FREEBSD + unsigned long pc = ucontext->uc_mcontext.mc_gpregs.gp_sepc; +#else unsigned long pc = ucontext->uc_mcontext.__gregs[REG_PC]; +#endif unsigned faulty_instruction = *(uint16_t *)pc; #if defined(__riscv_compressed) @@ -2136,12 +2102,23 @@ static void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) { *sp = ucontext->uc_mcontext.gregs[15]; #elif defined(__riscv) ucontext_t *ucontext = (ucontext_t*)context; +# if SANITIZER_FREEBSD + *pc = ucontext->uc_mcontext.mc_gpregs.gp_sepc; + *bp = ucontext->uc_mcontext.mc_gpregs.gp_s[0]; + *sp = ucontext->uc_mcontext.mc_gpregs.gp_sp; +# else *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 +# endif +# elif defined(__hexagon__) + ucontext_t *ucontext = (ucontext_t *)context; + *pc = ucontext->uc_mcontext.pc; + *bp = ucontext->uc_mcontext.r30; + *sp = ucontext->uc_mcontext.r29; +# else +# error "Unsupported arch" +# endif } void SignalContext::InitPcSpBp() { GetPcSpBp(context, &pc, &sp, &bp); } diff --git a/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cpp b/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cpp index fc5619e..7ce9e25 100644 --- a/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cpp +++ b/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cpp @@ -759,13 +759,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_local_address_space_view.h b/libsanitizer/sanitizer_common/sanitizer_local_address_space_view.h index 0e19c4d..a47cfc9 100644 --- a/libsanitizer/sanitizer_common/sanitizer_local_address_space_view.h +++ b/libsanitizer/sanitizer_common/sanitizer_local_address_space_view.h @@ -17,7 +17,7 @@ // instantiated with the `LocalAddressSpaceView` type. This type is used to // load any pointers in instance methods. This implementation is effectively // a no-op. When an object is to be used in an out-of-process manner it is -// instansiated with the `RemoteAddressSpaceView` type. +// instantiated with the `RemoteAddressSpaceView` type. // // By making `AddressSpaceView` a template parameter of an object, it can // change its implementation at compile time which has no run time overhead. diff --git a/libsanitizer/sanitizer_common/sanitizer_mac.cpp b/libsanitizer/sanitizer_common/sanitizer_mac.cpp index 0aafbdb..b8839f1 100644 --- a/libsanitizer/sanitizer_common/sanitizer_mac.cpp +++ b/libsanitizer/sanitizer_common/sanitizer_mac.cpp @@ -37,7 +37,7 @@ extern char **environ; #endif -#if defined(__has_include) && __has_include(<os/trace.h>) && defined(__BLOCKS__) +#if defined(__has_include) && __has_include(<os/trace.h>) #define SANITIZER_OS_TRACE 1 #include <os/trace.h> #else @@ -70,15 +70,7 @@ extern "C" { #include <mach/mach_time.h> #include <mach/vm_statistics.h> #include <malloc/malloc.h> -#if defined(__has_builtin) && __has_builtin(__builtin_os_log_format) -# include <os/log.h> -#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 <os/log.h> #include <pthread.h> #include <sched.h> #include <signal.h> @@ -524,25 +516,6 @@ void FutexWait(atomic_uint32_t *p, u32 cmp) { void FutexWake(atomic_uint32_t *p, u32 count) {} -BlockingMutex::BlockingMutex() { - internal_memset(this, 0, sizeof(*this)); -} - -void BlockingMutex::Lock() { - CHECK(sizeof(OSSpinLock) <= sizeof(opaque_storage_)); - CHECK_EQ(OS_SPINLOCK_INIT, 0); - CHECK_EQ(owner_, 0); - OSSpinLockLock((OSSpinLock*)&opaque_storage_); -} - -void BlockingMutex::Unlock() { - OSSpinLockUnlock((OSSpinLock*)&opaque_storage_); -} - -void BlockingMutex::CheckLocked() const { - CHECK_NE(*(OSSpinLock*)&opaque_storage_, 0); -} - u64 NanoTime() { timeval tv; internal_memset(&tv, 0, sizeof(tv)); @@ -792,8 +765,8 @@ void *internal_start_thread(void *(*func)(void *arg), void *arg) { void internal_join_thread(void *th) { pthread_join((pthread_t)th, 0); } #if !SANITIZER_GO -static BlockingMutex syslog_lock(LINKER_INITIALIZED); -#endif +static Mutex syslog_lock; +# endif void WriteOneLineToSyslog(const char *s) { #if !SANITIZER_GO @@ -808,7 +781,7 @@ void WriteOneLineToSyslog(const char *s) { // buffer to store crash report application information static char crashreporter_info_buff[__sanitizer::kErrorMessageBufferSize] = {}; -static BlockingMutex crashreporter_info_mutex(LINKER_INITIALIZED); +static Mutex crashreporter_info_mutex; extern "C" { // Integrate with crash reporter libraries. @@ -838,7 +811,7 @@ asm(".desc ___crashreporter_info__, 0x10"); } // extern "C" static void CRAppendCrashLogMessage(const char *msg) { - BlockingMutexLock l(&crashreporter_info_mutex); + Lock l(&crashreporter_info_mutex); internal_strlcat(crashreporter_info_buff, msg, sizeof(crashreporter_info_buff)); #if HAVE_CRASHREPORTERCLIENT_H @@ -882,7 +855,7 @@ void LogFullErrorReport(const char *buffer) { // the reporting thread holds the thread registry mutex, and asl_log waits // for GCD to dispatch a new thread, the process will deadlock, because the // pthread_create wrapper needs to acquire the lock as well. - BlockingMutexLock l(&syslog_lock); + Lock l(&syslog_lock); if (common_flags()->log_to_syslog) WriteToSyslog(buffer); diff --git a/libsanitizer/sanitizer_common/sanitizer_mac.h b/libsanitizer/sanitizer_common/sanitizer_mac.h index 96a5986..0b6af5a 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_MAC #include "sanitizer_posix.h" diff --git a/libsanitizer/sanitizer_common/sanitizer_mutex.cpp b/libsanitizer/sanitizer_common/sanitizer_mutex.cpp index bc2d83c..1c177d8 100644 --- a/libsanitizer/sanitizer_common/sanitizer_mutex.cpp +++ b/libsanitizer/sanitizer_common/sanitizer_mutex.cpp @@ -16,6 +16,18 @@ namespace __sanitizer { +void StaticSpinMutex::LockSlow() { + for (int i = 0;; i++) { + if (i < 100) + proc_yield(1); + else + internal_sched_yield(); + if (atomic_load(&state_, memory_order_relaxed) == 0 && + atomic_exchange(&state_, 1, memory_order_acquire) == 0) + return; + } +} + void Semaphore::Wait() { u32 count = atomic_load(&state_, memory_order_relaxed); for (;;) { @@ -36,4 +48,178 @@ void Semaphore::Post(u32 count) { FutexWake(&state_, count); } +#if SANITIZER_CHECK_DEADLOCKS +// An empty mutex meta table, it effectively disables deadlock detection. +// Each tool can override the table to define own mutex hierarchy and +// enable deadlock detection. +// The table defines a static mutex type hierarchy (what mutex types can be locked +// under what mutex types). This table is checked to be acyclic and then +// actual mutex lock/unlock operations are checked to adhere to this hierarchy. +// The checking happens on mutex types rather than on individual mutex instances +// because doing it on mutex instances will both significantly complicate +// the implementation, worsen performance and memory overhead and is mostly +// unnecessary (we almost never lock multiple mutexes of the same type recursively). +static constexpr int kMutexTypeMax = 20; +SANITIZER_WEAK_ATTRIBUTE MutexMeta mutex_meta[kMutexTypeMax] = {}; +SANITIZER_WEAK_ATTRIBUTE void PrintMutexPC(uptr pc) {} +static StaticSpinMutex mutex_meta_mtx; +static int mutex_type_count = -1; +// Adjacency matrix of what mutexes can be locked under what mutexes. +static bool mutex_can_lock[kMutexTypeMax][kMutexTypeMax]; +// Mutex types with MutexMulti mark. +static bool mutex_multi[kMutexTypeMax]; + +void DebugMutexInit() { + // Build adjacency matrix. + bool leaf[kMutexTypeMax]; + internal_memset(&leaf, 0, sizeof(leaf)); + int cnt[kMutexTypeMax]; + internal_memset(&cnt, 0, sizeof(cnt)); + for (int t = 0; t < kMutexTypeMax; t++) { + mutex_type_count = t; + if (!mutex_meta[t].name) + break; + CHECK_EQ(t, mutex_meta[t].type); + for (uptr j = 0; j < ARRAY_SIZE(mutex_meta[t].can_lock); j++) { + MutexType z = mutex_meta[t].can_lock[j]; + if (z == MutexInvalid) + break; + if (z == MutexLeaf) { + CHECK(!leaf[t]); + leaf[t] = true; + continue; + } + if (z == MutexMulti) { + mutex_multi[t] = true; + continue; + } + CHECK_LT(z, kMutexTypeMax); + CHECK(!mutex_can_lock[t][z]); + mutex_can_lock[t][z] = true; + cnt[t]++; + } + } + // Indicates the array is not properly terminated. + CHECK_LT(mutex_type_count, kMutexTypeMax); + // Add leaf mutexes. + for (int t = 0; t < mutex_type_count; t++) { + if (!leaf[t]) + continue; + CHECK_EQ(cnt[t], 0); + for (int z = 0; z < mutex_type_count; z++) { + if (z == MutexInvalid || t == z || leaf[z]) + continue; + CHECK(!mutex_can_lock[z][t]); + mutex_can_lock[z][t] = true; + } + } + // Build the transitive closure and check that the graphs is acyclic. + u32 trans[kMutexTypeMax]; + static_assert(sizeof(trans[0]) * 8 >= kMutexTypeMax, + "kMutexTypeMax does not fit into u32, switch to u64"); + internal_memset(&trans, 0, sizeof(trans)); + for (int i = 0; i < mutex_type_count; i++) { + for (int j = 0; j < mutex_type_count; j++) + if (mutex_can_lock[i][j]) + trans[i] |= 1 << j; + } + for (int k = 0; k < mutex_type_count; k++) { + for (int i = 0; i < mutex_type_count; i++) { + if (trans[i] & (1 << k)) + trans[i] |= trans[k]; + } + } + for (int i = 0; i < mutex_type_count; i++) { + if (trans[i] & (1 << i)) { + Printf("Mutex %s participates in a cycle\n", mutex_meta[i].name); + Die(); + } + } +} + +struct InternalDeadlockDetector { + struct LockDesc { + u64 seq; + uptr pc; + int recursion; + }; + int initialized; + u64 sequence; + LockDesc locked[kMutexTypeMax]; + + void Lock(MutexType type, uptr pc) { + if (!Initialize(type)) + return; + CHECK_LT(type, mutex_type_count); + // Find the last locked mutex type. + // This is the type we will use for hierarchy checks. + u64 max_seq = 0; + MutexType max_idx = MutexInvalid; + for (int i = 0; i != mutex_type_count; i++) { + if (locked[i].seq == 0) + continue; + CHECK_NE(locked[i].seq, max_seq); + if (max_seq < locked[i].seq) { + max_seq = locked[i].seq; + max_idx = (MutexType)i; + } + } + if (max_idx == type && mutex_multi[type]) { + // Recursive lock of the same type. + CHECK_EQ(locked[type].seq, max_seq); + CHECK(locked[type].pc); + locked[type].recursion++; + return; + } + if (max_idx != MutexInvalid && !mutex_can_lock[max_idx][type]) { + Printf("%s: internal deadlock: can't lock %s under %s mutex\n", SanitizerToolName, + mutex_meta[type].name, mutex_meta[max_idx].name); + PrintMutexPC(pc); + CHECK(0); + } + locked[type].seq = ++sequence; + locked[type].pc = pc; + locked[type].recursion = 1; + } + + void Unlock(MutexType type) { + if (!Initialize(type)) + return; + CHECK_LT(type, mutex_type_count); + CHECK(locked[type].seq); + CHECK_GT(locked[type].recursion, 0); + if (--locked[type].recursion) + return; + locked[type].seq = 0; + locked[type].pc = 0; + } + + void CheckNoLocks() { + for (int i = 0; i < mutex_type_count; i++) CHECK_EQ(locked[i].recursion, 0); + } + + bool Initialize(MutexType type) { + if (type == MutexUnchecked || type == MutexInvalid) + return false; + CHECK_GT(type, MutexInvalid); + if (initialized != 0) + return initialized > 0; + initialized = -1; + SpinMutexLock lock(&mutex_meta_mtx); + if (mutex_type_count < 0) + DebugMutexInit(); + initialized = mutex_type_count ? 1 : -1; + return initialized > 0; + } +}; + +static THREADLOCAL InternalDeadlockDetector deadlock_detector; + +void CheckedMutex::LockImpl(uptr pc) { deadlock_detector.Lock(type_, pc); } + +void CheckedMutex::UnlockImpl() { deadlock_detector.Unlock(type_); } + +void CheckedMutex::CheckNoLocksImpl() { deadlock_detector.CheckNoLocks(); } +#endif + } // namespace __sanitizer diff --git a/libsanitizer/sanitizer_common/sanitizer_mutex.h b/libsanitizer/sanitizer_common/sanitizer_mutex.h index e3ff650..7479d35 100644 --- a/libsanitizer/sanitizer_common/sanitizer_mutex.h +++ b/libsanitizer/sanitizer_common/sanitizer_mutex.h @@ -27,7 +27,7 @@ class MUTEX StaticSpinMutex { } void Lock() ACQUIRE() { - if (TryLock()) + if (LIKELY(TryLock())) return; LockSlow(); } @@ -45,17 +45,7 @@ class MUTEX StaticSpinMutex { private: atomic_uint8_t state_; - void NOINLINE LockSlow() { - for (int i = 0;; i++) { - if (i < 10) - proc_yield(10); - else - internal_sched_yield(); - if (atomic_load(&state_, memory_order_relaxed) == 0 - && atomic_exchange(&state_, 1, memory_order_acquire) == 0) - return; - } - } + void LockSlow(); }; class MUTEX SpinMutex : public StaticSpinMutex { @@ -64,7 +54,6 @@ class MUTEX SpinMutex : public StaticSpinMutex { Init(); } - private: SpinMutex(const SpinMutex &) = delete; void operator=(const SpinMutex &) = delete; }; @@ -85,15 +74,94 @@ class Semaphore { atomic_uint32_t state_ = {0}; }; +typedef int MutexType; + +enum { + // Used as sentinel and to catch unassigned types + // (should not be used as real Mutex type). + MutexInvalid = 0, + MutexThreadRegistry, + // Each tool own mutexes must start at this number. + MutexLastCommon, + // Type for legacy mutexes that are not checked for deadlocks. + MutexUnchecked = -1, + // Special marks that can be used in MutexMeta::can_lock table. + // The leaf mutexes can be locked under any other non-leaf mutex, + // but no other mutex can be locked while under a leaf mutex. + MutexLeaf = -1, + // Multiple mutexes of this type can be locked at the same time. + MutexMulti = -3, +}; + +// Go linker does not support THREADLOCAL variables, +// so we can't use per-thread state. +#define SANITIZER_CHECK_DEADLOCKS \ + (SANITIZER_DEBUG && !SANITIZER_GO && SANITIZER_SUPPORTS_THREADLOCAL) + +#if SANITIZER_CHECK_DEADLOCKS +struct MutexMeta { + MutexType type; + const char *name; + // The table fixes what mutexes can be locked under what mutexes. + // If the entry for MutexTypeFoo contains MutexTypeBar, + // then Bar mutex can be locked while under Foo mutex. + // Can also contain the special MutexLeaf/MutexMulti marks. + MutexType can_lock[10]; +}; +#endif + +class CheckedMutex { + public: + explicit constexpr CheckedMutex(MutexType type) +#if SANITIZER_CHECK_DEADLOCKS + : type_(type) +#endif + { + } + + ALWAYS_INLINE void Lock() { +#if SANITIZER_CHECK_DEADLOCKS + LockImpl(GET_CALLER_PC()); +#endif + } + + ALWAYS_INLINE void Unlock() { +#if SANITIZER_CHECK_DEADLOCKS + UnlockImpl(); +#endif + } + + // Checks that the current thread does not hold any mutexes + // (e.g. when returning from a runtime function to user code). + static void CheckNoLocks() { +#if SANITIZER_CHECK_DEADLOCKS + CheckNoLocksImpl(); +#endif + } + + private: +#if SANITIZER_CHECK_DEADLOCKS + const MutexType type_; + + void LockImpl(uptr pc); + void UnlockImpl(); + static void CheckNoLocksImpl(); +#endif +}; + // Reader-writer mutex. -class MUTEX Mutex2 { +// Derive from CheckedMutex for the purposes of EBO. +// We could make it a field marked with [[no_unique_address]], +// but this attribute is not supported by some older compilers. +class MUTEX Mutex : CheckedMutex { public: - constexpr Mutex2() {} + explicit constexpr Mutex(MutexType type = MutexUnchecked) + : CheckedMutex(type) {} void Lock() ACQUIRE() { + CheckedMutex::Lock(); u64 reset_mask = ~0ull; u64 state = atomic_load_relaxed(&state_); - const uptr kMaxSpinIters = 1500; for (uptr spin_iters = 0;; spin_iters++) { u64 new_state; bool locked = (state & (kWriterLock | kReaderLockMask)) != 0; @@ -122,8 +190,6 @@ class MUTEX Mutex2 { // We've incremented waiting writers, so now block. writers_.Wait(); spin_iters = 0; - state = atomic_load(&state_, memory_order_relaxed); - DCHECK_NE(state & kWriterSpinWait, 0); } else { // We've set kWriterSpinWait, but we are still in active spinning. } @@ -132,10 +198,13 @@ class MUTEX Mutex2 { // Either way we need to reset kWriterSpinWait // next time we take the lock or block again. reset_mask = ~kWriterSpinWait; + state = atomic_load(&state_, memory_order_relaxed); + DCHECK_NE(state & kWriterSpinWait, 0); } } void Unlock() RELEASE() { + CheckedMutex::Unlock(); bool wake_writer; u64 wake_readers; u64 new_state; @@ -144,17 +213,16 @@ class MUTEX Mutex2 { DCHECK_NE(state & kWriterLock, 0); DCHECK_EQ(state & kReaderLockMask, 0); new_state = state & ~kWriterLock; - wake_writer = - (state & kWriterSpinWait) == 0 && (state & kWaitingWriterMask) != 0; + wake_writer = (state & (kWriterSpinWait | kReaderSpinWait)) == 0 && + (state & kWaitingWriterMask) != 0; if (wake_writer) new_state = (new_state - kWaitingWriterInc) | kWriterSpinWait; wake_readers = - (state & (kWriterSpinWait | kWaitingWriterMask)) != 0 + wake_writer || (state & kWriterSpinWait) != 0 ? 0 : ((state & kWaitingReaderMask) >> kWaitingReaderShift); if (wake_readers) - new_state = (new_state & ~kWaitingReaderMask) + - (wake_readers << kReaderLockShift); + new_state = (new_state & ~kWaitingReaderMask) | kReaderSpinWait; } while (UNLIKELY(!atomic_compare_exchange_weak(&state_, &state, new_state, memory_order_release))); if (UNLIKELY(wake_writer)) @@ -164,34 +232,53 @@ class MUTEX Mutex2 { } void ReadLock() ACQUIRE_SHARED() { - bool locked; - u64 new_state; + CheckedMutex::Lock(); + u64 reset_mask = ~0ull; u64 state = atomic_load_relaxed(&state_); - do { - locked = - (state & kReaderLockMask) == 0 && - (state & (kWriterLock | kWriterSpinWait | kWaitingWriterMask)) != 0; + for (uptr spin_iters = 0;; spin_iters++) { + bool locked = (state & kWriterLock) != 0; + u64 new_state; + if (LIKELY(!locked)) { + new_state = (state + kReaderLockInc) & reset_mask; + } else if (spin_iters > kMaxSpinIters) { + new_state = (state + kWaitingReaderInc) & reset_mask; + } else if ((state & kReaderSpinWait) == 0) { + // Active spinning, but denote our presence so that unlocking + // thread does not wake up other threads. + new_state = state | kReaderSpinWait; + } else { + // Active spinning. + state = atomic_load(&state_, memory_order_relaxed); + continue; + } + if (UNLIKELY(!atomic_compare_exchange_weak(&state_, &state, new_state, + memory_order_acquire))) + continue; if (LIKELY(!locked)) - new_state = state + kReaderLockInc; - else - new_state = state + kWaitingReaderInc; - } while (UNLIKELY(!atomic_compare_exchange_weak(&state_, &state, new_state, - memory_order_acquire))); - if (UNLIKELY(locked)) - readers_.Wait(); - DCHECK_EQ(atomic_load_relaxed(&state_) & kWriterLock, 0); - DCHECK_NE(atomic_load_relaxed(&state_) & kReaderLockMask, 0); + return; // We've locked the mutex. + if (spin_iters > kMaxSpinIters) { + // We've incremented waiting readers, so now block. + readers_.Wait(); + spin_iters = 0; + } else { + // We've set kReaderSpinWait, but we are still in active spinning. + } + reset_mask = ~kReaderSpinWait; + state = atomic_load(&state_, memory_order_relaxed); + } } void ReadUnlock() RELEASE_SHARED() { + CheckedMutex::Unlock(); bool wake; u64 new_state; u64 state = atomic_load_relaxed(&state_); do { DCHECK_NE(state & kReaderLockMask, 0); - DCHECK_EQ(state & (kWaitingReaderMask | kWriterLock), 0); + DCHECK_EQ(state & kWriterLock, 0); new_state = state - kReaderLockInc; - wake = (new_state & (kReaderLockMask | kWriterSpinWait)) == 0 && + wake = (new_state & + (kReaderLockMask | kWriterSpinWait | kReaderSpinWait)) == 0 && (new_state & kWaitingWriterMask) != 0; if (wake) new_state = (new_state - kWaitingWriterInc) | kWriterSpinWait; @@ -235,16 +322,14 @@ class MUTEX Mutex2 { // - a writer is awake and spin-waiting // the flag is used to prevent thundering herd problem // (new writers are not woken if this flag is set) + // - a reader is awake and spin-waiting // - // Writer support active spinning, readers does not. + // Both writers and readers use active spinning before blocking. // But readers are more aggressive and always take the mutex // if there are any other readers. - // Writers hand off the mutex to readers: after wake up readers - // already assume ownership of the mutex (don't need to do any - // state updates). But the mutex is not handed off to writers, - // after wake up writers compete to lock the mutex again. - // This is needed to allow repeated write locks even in presence - // of other blocked writers. + // After wake up both writers and readers compete to lock the + // mutex again. This is needed to allow repeated locks even in presence + // of other blocked threads. static constexpr u64 kCounterWidth = 20; static constexpr u64 kReaderLockShift = 0; static constexpr u64 kReaderLockInc = 1ull << kReaderLockShift; @@ -260,119 +345,18 @@ class MUTEX Mutex2 { << kWaitingWriterShift; static constexpr u64 kWriterLock = 1ull << (3 * kCounterWidth); static constexpr u64 kWriterSpinWait = 1ull << (3 * kCounterWidth + 1); + static constexpr u64 kReaderSpinWait = 1ull << (3 * kCounterWidth + 2); + + static constexpr uptr kMaxSpinIters = 1500; - Mutex2(const Mutex2 &) = delete; - void operator=(const Mutex2 &) = delete; + Mutex(LinkerInitialized) = delete; + Mutex(const Mutex &) = delete; + void operator=(const Mutex &) = delete; }; void FutexWait(atomic_uint32_t *p, u32 cmp); void FutexWake(atomic_uint32_t *p, u32 count); -class MUTEX BlockingMutex { - public: - explicit constexpr BlockingMutex(LinkerInitialized) - : opaque_storage_ {0, }, owner_ {0} {} - BlockingMutex(); - void Lock() ACQUIRE(); - void Unlock() RELEASE(); - - // This function does not guarantee an explicit check that the calling thread - // is the thread which owns the mutex. This behavior, while more strictly - // correct, causes problems in cases like StopTheWorld, where a parent thread - // owns the mutex but a child checks that it is locked. Rather than - // maintaining complex state to work around those situations, the check only - // checks that the mutex is owned, and assumes callers to be generally - // well-behaved. - void CheckLocked() const CHECK_LOCKED(); - - private: - // Solaris mutex_t has a member that requires 64-bit alignment. - ALIGNED(8) uptr opaque_storage_[10]; - uptr owner_; // for debugging -}; - -// Reader-writer spin mutex. -class MUTEX RWMutex { - public: - RWMutex() { - atomic_store(&state_, kUnlocked, memory_order_relaxed); - } - - ~RWMutex() { - CHECK_EQ(atomic_load(&state_, memory_order_relaxed), kUnlocked); - } - - void Lock() ACQUIRE() { - u32 cmp = kUnlocked; - if (atomic_compare_exchange_strong(&state_, &cmp, kWriteLock, - memory_order_acquire)) - return; - LockSlow(); - } - - void Unlock() RELEASE() { - u32 prev = atomic_fetch_sub(&state_, kWriteLock, memory_order_release); - DCHECK_NE(prev & kWriteLock, 0); - (void)prev; - } - - void ReadLock() ACQUIRE_SHARED() { - u32 prev = atomic_fetch_add(&state_, kReadLock, memory_order_acquire); - if ((prev & kWriteLock) == 0) - return; - ReadLockSlow(); - } - - void ReadUnlock() RELEASE_SHARED() { - u32 prev = atomic_fetch_sub(&state_, kReadLock, memory_order_release); - DCHECK_EQ(prev & kWriteLock, 0); - DCHECK_GT(prev & ~kWriteLock, 0); - (void)prev; - } - - void CheckLocked() const CHECK_LOCKED() { - CHECK_NE(atomic_load(&state_, memory_order_relaxed), kUnlocked); - } - - private: - atomic_uint32_t state_; - - enum { - kUnlocked = 0, - kWriteLock = 1, - kReadLock = 2 - }; - - void NOINLINE LockSlow() { - for (int i = 0;; i++) { - if (i < 10) - proc_yield(10); - else - internal_sched_yield(); - u32 cmp = atomic_load(&state_, memory_order_relaxed); - if (cmp == kUnlocked && - atomic_compare_exchange_weak(&state_, &cmp, kWriteLock, - memory_order_acquire)) - return; - } - } - - void NOINLINE ReadLockSlow() { - for (int i = 0;; i++) { - if (i < 10) - proc_yield(10); - else - internal_sched_yield(); - u32 prev = atomic_load(&state_, memory_order_acquire); - if ((prev & kWriteLock) == 0) - return; - } - } - - RWMutex(const RWMutex &) = delete; - void operator=(const RWMutex &) = delete; -}; - template <typename MutexType> class SCOPED_LOCK GenericScopedLock { public: @@ -405,10 +389,37 @@ class SCOPED_LOCK GenericScopedReadLock { void operator=(const GenericScopedReadLock &) = delete; }; +template <typename MutexType> +class SCOPED_LOCK GenericScopedRWLock { + public: + ALWAYS_INLINE explicit GenericScopedRWLock(MutexType *mu, bool write) + ACQUIRE(mu) + : mu_(mu), write_(write) { + if (write_) + mu_->Lock(); + else + mu_->ReadLock(); + } + + ALWAYS_INLINE ~GenericScopedRWLock() RELEASE() { + if (write_) + mu_->Unlock(); + else + mu_->ReadUnlock(); + } + + private: + MutexType *mu_; + bool write_; + + GenericScopedRWLock(const GenericScopedRWLock &) = delete; + void operator=(const GenericScopedRWLock &) = delete; +}; + typedef GenericScopedLock<StaticSpinMutex> SpinMutexLock; -typedef GenericScopedLock<BlockingMutex> BlockingMutexLock; -typedef GenericScopedLock<RWMutex> RWMutexLock; -typedef GenericScopedReadLock<RWMutex> RWMutexReadLock; +typedef GenericScopedLock<Mutex> Lock; +typedef GenericScopedReadLock<Mutex> ReadLock; +typedef GenericScopedRWLock<Mutex> RWLock; } // namespace __sanitizer diff --git a/libsanitizer/sanitizer_common/sanitizer_platform.h b/libsanitizer/sanitizer_common/sanitizer_platform.h index 4d3c088..3153de3 100644 --- a/libsanitizer/sanitizer_common/sanitizer_platform.h +++ b/libsanitizer/sanitizer_common/sanitizer_platform.h @@ -281,11 +281,12 @@ // 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__) || defined(__riscv)) && SANITIZER_LINUX -# define SANITIZER_USES_CANONICAL_LINUX_SYSCALLS 1 -# else -# define SANITIZER_USES_CANONICAL_LINUX_SYSCALLS 0 -# endif +# if (defined(__aarch64__) || defined(__riscv) || defined(__hexagon__)) && \ + SANITIZER_LINUX +# define SANITIZER_USES_CANONICAL_LINUX_SYSCALLS 1 +# else +# define SANITIZER_USES_CANONICAL_LINUX_SYSCALLS 0 +# endif #endif // udi16 syscalls can only be used when the following conditions are @@ -377,4 +378,18 @@ #define SANITIZER_SUPPORTS_INIT_FOR_DLOPEN 0 #endif +// SANITIZER_SUPPORTS_THREADLOCAL +// 1 - THREADLOCAL macro is supported by target +// 0 - THREADLOCAL macro is not supported by target +#ifndef __has_feature +// TODO: Support other compilers here +# define SANITIZER_SUPPORTS_THREADLOCAL 1 +#else +# if __has_feature(tls) +# define SANITIZER_SUPPORTS_THREADLOCAL 1 +# else +# define SANITIZER_SUPPORTS_THREADLOCAL 0 +# endif +#endif + #endif // SANITIZER_PLATFORM_H diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_interceptors.h b/libsanitizer/sanitizer_common/sanitizer_platform_interceptors.h index 5b710c2..02c51d9 100644 --- a/libsanitizer/sanitizer_common/sanitizer_platform_interceptors.h +++ b/libsanitizer/sanitizer_common/sanitizer_platform_interceptors.h @@ -229,7 +229,8 @@ (SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS) #define SANITIZER_INTERCEPT_CLOCK_GETTIME \ (SI_FREEBSD || SI_NETBSD || SI_LINUX || SI_SOLARIS) -#define SANITIZER_INTERCEPT_CLOCK_GETCPUCLOCKID SI_LINUX +#define SANITIZER_INTERCEPT_CLOCK_GETCPUCLOCKID \ + (SI_LINUX || SI_FREEBSD || SI_NETBSD) #define SANITIZER_INTERCEPT_GETITIMER SI_POSIX #define SANITIZER_INTERCEPT_TIME SI_POSIX #define SANITIZER_INTERCEPT_GLOB (SI_GLIBC || SI_SOLARIS) @@ -251,7 +252,8 @@ #define SANITIZER_INTERCEPT_GETHOSTENT_R (SI_FREEBSD || SI_GLIBC || SI_SOLARIS) #define SANITIZER_INTERCEPT_GETSOCKOPT SI_POSIX #define SANITIZER_INTERCEPT_ACCEPT SI_POSIX -#define SANITIZER_INTERCEPT_ACCEPT4 (SI_LINUX_NOT_ANDROID || SI_NETBSD) +#define SANITIZER_INTERCEPT_ACCEPT4 \ + (SI_LINUX_NOT_ANDROID || SI_NETBSD || SI_FREEBSD) #define SANITIZER_INTERCEPT_PACCEPT SI_NETBSD #define SANITIZER_INTERCEPT_MODF SI_POSIX #define SANITIZER_INTERCEPT_RECVMSG SI_POSIX @@ -309,7 +311,7 @@ #define SANITIZER_INTERCEPT_PPOLL SI_LINUX_NOT_ANDROID || SI_SOLARIS #define SANITIZER_INTERCEPT_WORDEXP \ (SI_FREEBSD || SI_NETBSD || (SI_MAC && !SI_IOS) || SI_LINUX_NOT_ANDROID || \ - SI_SOLARIS) // NOLINT + SI_SOLARIS) #define SANITIZER_INTERCEPT_SIGWAIT SI_POSIX #define SANITIZER_INTERCEPT_SIGWAITINFO SI_LINUX_NOT_ANDROID || SI_SOLARIS #define SANITIZER_INTERCEPT_SIGTIMEDWAIT SI_LINUX_NOT_ANDROID || SI_SOLARIS @@ -337,7 +339,7 @@ #define SANITIZER_INTERCEPT_ETHER_R (SI_FREEBSD || SI_LINUX_NOT_ANDROID) #define SANITIZER_INTERCEPT_SHMCTL \ (((SI_FREEBSD || SI_LINUX_NOT_ANDROID) && SANITIZER_WORDSIZE == 64) || \ - SI_NETBSD || SI_SOLARIS) // NOLINT + SI_NETBSD || SI_SOLARIS) #define SANITIZER_INTERCEPT_RANDOM_R SI_GLIBC #define SANITIZER_INTERCEPT_PTHREAD_ATTR_GET SI_POSIX #define SANITIZER_INTERCEPT_PTHREAD_ATTR_GETINHERITSCHED \ @@ -445,7 +447,8 @@ #define SANITIZER_INTERCEPT_SEM \ (SI_LINUX || SI_FREEBSD || SI_NETBSD || SI_SOLARIS) #define SANITIZER_INTERCEPT_PTHREAD_SETCANCEL SI_POSIX -#define SANITIZER_INTERCEPT_MINCORE (SI_LINUX || SI_NETBSD || SI_SOLARIS) +#define SANITIZER_INTERCEPT_MINCORE \ + (SI_LINUX || SI_NETBSD || SI_FREEBSD || SI_SOLARIS) #define SANITIZER_INTERCEPT_PROCESS_VM_READV SI_LINUX #define SANITIZER_INTERCEPT_CTERMID \ (SI_LINUX || SI_MAC || SI_FREEBSD || SI_NETBSD || SI_SOLARIS) @@ -496,7 +499,8 @@ #define SANITIZER_INTERCEPT_GID_FROM_GROUP SI_NETBSD #define SANITIZER_INTERCEPT_ACCESS (SI_NETBSD || SI_FREEBSD) #define SANITIZER_INTERCEPT_FACCESSAT (SI_NETBSD || SI_FREEBSD) -#define SANITIZER_INTERCEPT_GETGROUPLIST SI_NETBSD +#define SANITIZER_INTERCEPT_GETGROUPLIST \ + (SI_NETBSD || SI_FREEBSD || SI_LINUX) #define SANITIZER_INTERCEPT_STRLCPY \ (SI_NETBSD || SI_FREEBSD || SI_MAC || SI_ANDROID) @@ -517,10 +521,11 @@ #define SANITIZER_INTERCEPT_DEVNAME_R (SI_NETBSD || SI_FREEBSD) #define SANITIZER_INTERCEPT_FGETLN (SI_NETBSD || SI_FREEBSD) #define SANITIZER_INTERCEPT_STRMODE (SI_NETBSD || SI_FREEBSD) -#define SANITIZER_INTERCEPT_TTYENT SI_NETBSD -#define SANITIZER_INTERCEPT_PROTOENT (SI_NETBSD || SI_LINUX) +#define SANITIZER_INTERCEPT_TTYENT (SI_NETBSD || SI_FREEBSD) +#define SANITIZER_INTERCEPT_TTYENTPATH SI_NETBSD +#define SANITIZER_INTERCEPT_PROTOENT (SI_LINUX || SI_NETBSD || SI_FREEBSD) #define SANITIZER_INTERCEPT_PROTOENT_R SI_GLIBC -#define SANITIZER_INTERCEPT_NETENT SI_NETBSD +#define SANITIZER_INTERCEPT_NETENT (SI_LINUX || SI_NETBSD || SI_FREEBSD) #define SANITIZER_INTERCEPT_SETVBUF \ (SI_NETBSD || SI_FREEBSD || SI_LINUX || SI_MAC) #define SANITIZER_INTERCEPT_GETMNTINFO (SI_NETBSD || SI_FREEBSD || SI_MAC) @@ -536,7 +541,7 @@ #define SANITIZER_INTERCEPT_MODCTL SI_NETBSD #define SANITIZER_INTERCEPT_CAPSICUM SI_FREEBSD #define SANITIZER_INTERCEPT_STRTONUM (SI_NETBSD || SI_FREEBSD) -#define SANITIZER_INTERCEPT_FPARSELN SI_NETBSD +#define SANITIZER_INTERCEPT_FPARSELN (SI_NETBSD || SI_FREEBSD) #define SANITIZER_INTERCEPT_STATVFS1 SI_NETBSD #define SANITIZER_INTERCEPT_STRTOI SI_NETBSD #define SANITIZER_INTERCEPT_CAPSICUM SI_FREEBSD @@ -571,6 +576,8 @@ #define SANITIZER_INTERCEPT_QSORT \ (SI_POSIX && !SI_IOSSIM && !SI_WATCHOS && !SI_TVOS && !SI_ANDROID) #define SANITIZER_INTERCEPT_QSORT_R SI_GLIBC +#define SANITIZER_INTERCEPT_BSEARCH \ + (SI_POSIX && !SI_IOSSIM && !SI_WATCHOS && !SI_TVOS && !SI_ANDROID) // sigaltstack on i386 macOS cannot be intercepted due to setjmp() // calling it and assuming that it does not clobber registers. #define SANITIZER_INTERCEPT_SIGALTSTACK \ diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_limits_freebsd.cpp b/libsanitizer/sanitizer_common/sanitizer_platform_limits_freebsd.cpp index b5a45ae..bfe3eea 100644 --- a/libsanitizer/sanitizer_common/sanitizer_platform_limits_freebsd.cpp +++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_freebsd.cpp @@ -74,6 +74,7 @@ #include <term.h> #include <termios.h> #include <time.h> +#include <ttyent.h> #include <utime.h> #include <utmpx.h> #include <vis.h> @@ -170,9 +171,12 @@ uptr __sanitizer_in_addr_sz(int af) { unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr); int glob_nomatch = GLOB_NOMATCH; int glob_altdirfunc = GLOB_ALTDIRFUNC; +const int wordexp_wrde_dooffs = WRDE_DOOFFS; unsigned path_max = PATH_MAX; +int struct_ttyent_sz = sizeof(struct ttyent); + // ioctl arguments unsigned struct_ifreq_sz = sizeof(struct ifreq); unsigned struct_termios_sz = sizeof(struct termios); diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_limits_freebsd.h b/libsanitizer/sanitizer_common/sanitizer_platform_limits_freebsd.h index 5e0ca9c..89022ca 100644 --- a/libsanitizer/sanitizer_common/sanitizer_platform_limits_freebsd.h +++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_freebsd.h @@ -16,26 +16,26 @@ #if SANITIZER_FREEBSD -#include "sanitizer_internal_defs.h" -#include "sanitizer_platform.h" -#include "sanitizer_platform_limits_posix.h" +# include "sanitizer_internal_defs.h" +# include "sanitizer_platform.h" +# include "sanitizer_platform_limits_posix.h" // Get sys/_types.h, because that tells us whether 64-bit inodes are // used in struct dirent below. -#include <sys/_types.h> +# include <sys/_types.h> namespace __sanitizer { void *__sanitizer_get_link_map_by_dlopen_handle(void *handle); -#define GET_LINK_MAP_BY_DLOPEN_HANDLE(handle) \ - (link_map *)__sanitizer_get_link_map_by_dlopen_handle(handle) +# define GET_LINK_MAP_BY_DLOPEN_HANDLE(handle) \ + (link_map *)__sanitizer_get_link_map_by_dlopen_handle(handle) extern unsigned struct_utsname_sz; extern unsigned struct_stat_sz; -#if defined(__powerpc64__) +# if defined(__powerpc64__) const unsigned struct___old_kernel_stat_sz = 0; -#else +# else const unsigned struct___old_kernel_stat_sz = 32; -#endif +# endif extern unsigned struct_rusage_sz; extern unsigned siginfo_t_sz; extern unsigned struct_itimerval_sz; @@ -114,11 +114,24 @@ struct __sanitizer_ipc_perm { long key; }; -#if !defined(__i386__) +struct __sanitizer_protoent { + char *p_name; + char **p_aliases; + int p_proto; +}; + +struct __sanitizer_netent { + char *n_name; + char **n_aliases; + int n_addrtype; + u32 n_net; +}; + +# if !defined(__i386__) typedef long long __sanitizer_time_t; -#else +# else typedef long __sanitizer_time_t; -#endif +# endif struct __sanitizer_shmid_ds { __sanitizer_ipc_perm shm_perm; @@ -147,7 +160,7 @@ struct __sanitizer_ifaddrs { unsigned int ifa_flags; void *ifa_addr; // (struct sockaddr *) void *ifa_netmask; // (struct sockaddr *) -#undef ifa_dstaddr +# undef ifa_dstaddr void *ifa_dstaddr; // (struct sockaddr *) void *ifa_data; }; @@ -229,12 +242,12 @@ struct __sanitizer_cmsghdr { }; struct __sanitizer_dirent { -#if defined(__INO64) +# if defined(__INO64) unsigned long long d_fileno; unsigned long long d_off; -#else +# else unsigned int d_fileno; -#endif +# endif unsigned short d_reclen; // more fields that we don't care about }; @@ -243,23 +256,23 @@ struct __sanitizer_dirent { typedef int __sanitizer_clock_t; typedef int __sanitizer_clockid_t; -#if defined(_LP64) || defined(__x86_64__) || defined(__powerpc__) || \ - defined(__mips__) +# if defined(_LP64) || defined(__x86_64__) || defined(__powerpc__) || \ + defined(__mips__) typedef unsigned __sanitizer___kernel_uid_t; typedef unsigned __sanitizer___kernel_gid_t; -#else +# else typedef unsigned short __sanitizer___kernel_uid_t; typedef unsigned short __sanitizer___kernel_gid_t; -#endif +# endif typedef long long __sanitizer___kernel_off_t; -#if defined(__powerpc__) || defined(__mips__) +# if defined(__powerpc__) || defined(__mips__) typedef unsigned int __sanitizer___kernel_old_uid_t; typedef unsigned int __sanitizer___kernel_old_gid_t; -#else +# else typedef unsigned short __sanitizer___kernel_old_uid_t; typedef unsigned short __sanitizer___kernel_old_gid_t; -#endif +# endif typedef long long __sanitizer___kernel_loff_t; typedef struct { @@ -366,9 +379,12 @@ struct __sanitizer_glob_t { extern int glob_nomatch; extern int glob_altdirfunc; +extern const int wordexp_wrde_dooffs; extern unsigned path_max; +extern int struct_ttyent_sz; + struct __sanitizer_wordexp_t { uptr we_wordc; char **we_wordv; @@ -398,39 +414,49 @@ struct __sanitizer_ifconf { } ifc_ifcu; }; -#define IOC_NRBITS 8 -#define IOC_TYPEBITS 8 -#if defined(__powerpc__) || defined(__powerpc64__) || defined(__mips__) -#define IOC_SIZEBITS 13 -#define IOC_DIRBITS 3 -#define IOC_NONE 1U -#define IOC_WRITE 4U -#define IOC_READ 2U -#else -#define IOC_SIZEBITS 14 -#define IOC_DIRBITS 2 -#define IOC_NONE 0U -#define IOC_WRITE 1U -#define IOC_READ 2U -#endif -#define IOC_NRMASK ((1 << IOC_NRBITS) - 1) -#define IOC_TYPEMASK ((1 << IOC_TYPEBITS) - 1) -#define IOC_SIZEMASK ((1 << IOC_SIZEBITS) - 1) -#if defined(IOC_DIRMASK) -#undef IOC_DIRMASK -#endif -#define IOC_DIRMASK ((1 << IOC_DIRBITS) - 1) -#define IOC_NRSHIFT 0 -#define IOC_TYPESHIFT (IOC_NRSHIFT + IOC_NRBITS) -#define IOC_SIZESHIFT (IOC_TYPESHIFT + IOC_TYPEBITS) -#define IOC_DIRSHIFT (IOC_SIZESHIFT + IOC_SIZEBITS) -#define EVIOC_EV_MAX 0x1f -#define EVIOC_ABS_MAX 0x3f - -#define IOC_DIR(nr) (((nr) >> IOC_DIRSHIFT) & IOC_DIRMASK) -#define IOC_TYPE(nr) (((nr) >> IOC_TYPESHIFT) & IOC_TYPEMASK) -#define IOC_NR(nr) (((nr) >> IOC_NRSHIFT) & IOC_NRMASK) -#define IOC_SIZE(nr) (((nr) >> IOC_SIZESHIFT) & IOC_SIZEMASK) +struct __sanitizer__ttyent { + char *ty_name; + char *ty_getty; + char *ty_type; + int ty_status; + char *ty_window; + char *ty_comment; + char *ty_group; +}; + +# define IOC_NRBITS 8 +# define IOC_TYPEBITS 8 +# if defined(__powerpc__) || defined(__powerpc64__) || defined(__mips__) +# define IOC_SIZEBITS 13 +# define IOC_DIRBITS 3 +# define IOC_NONE 1U +# define IOC_WRITE 4U +# define IOC_READ 2U +# else +# define IOC_SIZEBITS 14 +# define IOC_DIRBITS 2 +# define IOC_NONE 0U +# define IOC_WRITE 1U +# define IOC_READ 2U +# endif +# define IOC_NRMASK ((1 << IOC_NRBITS) - 1) +# define IOC_TYPEMASK ((1 << IOC_TYPEBITS) - 1) +# define IOC_SIZEMASK ((1 << IOC_SIZEBITS) - 1) +# if defined(IOC_DIRMASK) +# undef IOC_DIRMASK +# endif +# define IOC_DIRMASK ((1 << IOC_DIRBITS) - 1) +# define IOC_NRSHIFT 0 +# define IOC_TYPESHIFT (IOC_NRSHIFT + IOC_NRBITS) +# define IOC_SIZESHIFT (IOC_TYPESHIFT + IOC_TYPEBITS) +# define IOC_DIRSHIFT (IOC_SIZESHIFT + IOC_SIZEBITS) +# define EVIOC_EV_MAX 0x1f +# define EVIOC_ABS_MAX 0x3f + +# define IOC_DIR(nr) (((nr) >> IOC_DIRSHIFT) & IOC_DIRMASK) +# define IOC_TYPE(nr) (((nr) >> IOC_TYPESHIFT) & IOC_TYPEMASK) +# define IOC_NR(nr) (((nr) >> IOC_NRSHIFT) & IOC_NRMASK) +# define IOC_SIZE(nr) (((nr) >> IOC_SIZESHIFT) & IOC_SIZEMASK) extern unsigned struct_ifreq_sz; extern unsigned struct_termios_sz; @@ -632,24 +658,24 @@ extern unsigned struct_fstab_sz; extern unsigned struct_StringList_sz; } // namespace __sanitizer -#define CHECK_TYPE_SIZE(TYPE) \ - COMPILER_CHECK(sizeof(__sanitizer_##TYPE) == sizeof(TYPE)) +# define CHECK_TYPE_SIZE(TYPE) \ + COMPILER_CHECK(sizeof(__sanitizer_##TYPE) == sizeof(TYPE)) -#define CHECK_SIZE_AND_OFFSET(CLASS, MEMBER) \ - COMPILER_CHECK(sizeof(((__sanitizer_##CLASS *)NULL)->MEMBER) == \ - sizeof(((CLASS *)NULL)->MEMBER)); \ - COMPILER_CHECK(offsetof(__sanitizer_##CLASS, MEMBER) == \ - offsetof(CLASS, MEMBER)) +# define CHECK_SIZE_AND_OFFSET(CLASS, MEMBER) \ + COMPILER_CHECK(sizeof(((__sanitizer_##CLASS *)NULL)->MEMBER) == \ + sizeof(((CLASS *)NULL)->MEMBER)); \ + COMPILER_CHECK(offsetof(__sanitizer_##CLASS, MEMBER) == \ + offsetof(CLASS, MEMBER)) // For sigaction, which is a function and struct at the same time, // and thus requires explicit "struct" in sizeof() expression. -#define CHECK_STRUCT_SIZE_AND_OFFSET(CLASS, MEMBER) \ - COMPILER_CHECK(sizeof(((struct __sanitizer_##CLASS *)NULL)->MEMBER) == \ - sizeof(((struct CLASS *)NULL)->MEMBER)); \ - COMPILER_CHECK(offsetof(struct __sanitizer_##CLASS, MEMBER) == \ - offsetof(struct CLASS, MEMBER)) +# define CHECK_STRUCT_SIZE_AND_OFFSET(CLASS, MEMBER) \ + COMPILER_CHECK(sizeof(((struct __sanitizer_##CLASS *)NULL)->MEMBER) == \ + sizeof(((struct CLASS *)NULL)->MEMBER)); \ + COMPILER_CHECK(offsetof(struct __sanitizer_##CLASS, MEMBER) == \ + offsetof(struct CLASS, MEMBER)) -#define SIGACTION_SYMNAME sigaction +# define SIGACTION_SYMNAME sigaction #endif diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_limits_linux.cpp b/libsanitizer/sanitizer_common/sanitizer_platform_limits_linux.cpp index f22f503..9d57757 100644 --- a/libsanitizer/sanitizer_common/sanitizer_platform_limits_linux.cpp +++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_linux.cpp @@ -26,37 +26,34 @@ // 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 <sys/stat.h>, struct stat -// takes the form of struct stat64 on 32-bit platforms if _FILE_OFFSET_BITS=64. -// Also, for some platforms (e.g. mips) there are additional members in the -// <sys/stat.h> struct stat:s. +// fine with newer headers, too. #include <linux/posix_types.h> -#if defined(__x86_64__) -#include <sys/stat.h> -#else -#define ino_t __kernel_ino_t -#define mode_t __kernel_mode_t -#define nlink_t __kernel_nlink_t -#define uid_t __kernel_uid_t -#define gid_t __kernel_gid_t -#define off_t __kernel_off_t -#define time_t __kernel_time_t +# if defined(__x86_64__) || defined(__mips__) || defined(__hexagon__) +# include <sys/stat.h> +# else +# define ino_t __kernel_ino_t +# define mode_t __kernel_mode_t +# define nlink_t __kernel_nlink_t +# define uid_t __kernel_uid_t +# define gid_t __kernel_gid_t +# define off_t __kernel_off_t +# define time_t __kernel_time_t // This header seems to contain the definitions of _kernel_ stat* structs. -#include <asm/stat.h> -#undef ino_t -#undef mode_t -#undef nlink_t -#undef uid_t -#undef gid_t -#undef off_t -#endif - -#include <linux/aio_abi.h> - -#if !SANITIZER_ANDROID -#include <sys/statfs.h> -#include <linux/perf_event.h> -#endif +# include <asm/stat.h> +# undef ino_t +# undef mode_t +# undef nlink_t +# undef uid_t +# undef gid_t +# undef off_t +# endif + +# include <linux/aio_abi.h> + +# if !SANITIZER_ANDROID +# include <sys/statfs.h> +# include <linux/perf_event.h> +# endif using namespace __sanitizer; @@ -66,9 +63,9 @@ namespace __sanitizer { #endif } // namespace __sanitizer -#if !defined(__powerpc64__) && !defined(__x86_64__) && !defined(__aarch64__)\ - && !defined(__mips__) && !defined(__s390__)\ - && !defined(__sparc__) && !defined(__riscv) +# if !defined(__powerpc64__) && !defined(__x86_64__) && \ + !defined(__aarch64__) && !defined(__mips__) && !defined(__s390__) && \ + !defined(__sparc__) && !defined(__riscv) && !defined(__hexagon__) COMPILER_CHECK(struct___old_kernel_stat_sz == sizeof(struct __old_kernel_stat)); #endif diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_limits_netbsd.cpp b/libsanitizer/sanitizer_common/sanitizer_platform_limits_netbsd.cpp index c8f2aa5..531e07f 100644 --- a/libsanitizer/sanitizer_common/sanitizer_platform_limits_netbsd.cpp +++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_netbsd.cpp @@ -666,6 +666,7 @@ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr); int glob_nomatch = GLOB_NOMATCH; int glob_altdirfunc = GLOB_ALTDIRFUNC; +const int wordexp_wrde_dooffs = WRDE_DOOFFS; unsigned path_max = PATH_MAX; diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_limits_netbsd.h b/libsanitizer/sanitizer_common/sanitizer_platform_limits_netbsd.h index 9e28dcf..9407803 100644 --- a/libsanitizer/sanitizer_common/sanitizer_platform_limits_netbsd.h +++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_netbsd.h @@ -394,6 +394,7 @@ struct __sanitizer_glob_t { extern int glob_nomatch; extern int glob_altdirfunc; +extern const int wordexp_wrde_dooffs; extern unsigned path_max; diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cpp b/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cpp index 6e5c330..a1c4528 100644 --- a/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cpp +++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cpp @@ -91,10 +91,10 @@ #if SANITIZER_LINUX # include <utime.h> # include <sys/ptrace.h> -#if defined(__mips64) || defined(__aarch64__) || defined(__arm__) || \ - SANITIZER_RISCV64 -# include <asm/ptrace.h> -# ifdef __arm__ +# if defined(__mips64) || defined(__aarch64__) || defined(__arm__) || \ + defined(__hexagon__) || SANITIZER_RISCV64 +# include <asm/ptrace.h> +# ifdef __arm__ typedef struct user_fpregs elf_fpregset_t; # define ARM_VFPREGS_SIZE_ASAN (32 * 8 /*fpregs*/ + 4 /*fpscr*/) # if !defined(ARM_VFPREGS_SIZE) @@ -242,12 +242,13 @@ namespace __sanitizer { defined(__powerpc64__) || defined(__arch64__) || defined(__sparcv9) || \ defined(__x86_64__) || SANITIZER_RISCV64 #define SIZEOF_STRUCT_USTAT 32 -#elif defined(__arm__) || defined(__i386__) || defined(__mips__) \ - || defined(__powerpc__) || defined(__s390__) || defined(__sparc__) -#define SIZEOF_STRUCT_USTAT 20 -#else -#error Unknown size of struct ustat -#endif +# elif defined(__arm__) || defined(__i386__) || defined(__mips__) || \ + defined(__powerpc__) || defined(__s390__) || defined(__sparc__) || \ + defined(__hexagon__) +# define SIZEOF_STRUCT_USTAT 20 +# else +# error Unknown size of struct ustat +# endif unsigned struct_ustat_sz = SIZEOF_STRUCT_USTAT; unsigned struct_rlimit64_sz = sizeof(struct rlimit64); unsigned struct_statvfs64_sz = sizeof(struct statvfs64); @@ -312,6 +313,10 @@ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr); int glob_altdirfunc = GLOB_ALTDIRFUNC; #endif +# if !SANITIZER_ANDROID + const int wordexp_wrde_dooffs = WRDE_DOOFFS; +# endif // !SANITIZER_ANDROID + #if SANITIZER_LINUX && !SANITIZER_ANDROID && \ (defined(__i386) || defined(__x86_64) || defined(__mips64) || \ defined(__powerpc64__) || defined(__aarch64__) || defined(__arm__) || \ diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h b/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h index 07c7a93..d69b344 100644 --- a/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h +++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h @@ -83,7 +83,7 @@ const unsigned struct_kernel_stat64_sz = 104; #elif defined(__mips__) const unsigned struct_kernel_stat_sz = SANITIZER_ANDROID ? FIRST_32_SECOND_64(104, 128) - : FIRST_32_SECOND_64(144, 216); + : FIRST_32_SECOND_64(160, 216); const unsigned struct_kernel_stat64_sz = 104; #elif defined(__s390__) && !defined(__s390x__) const unsigned struct_kernel_stat_sz = 64; @@ -102,7 +102,10 @@ const unsigned struct_kernel_stat64_sz = 104; #elif SANITIZER_RISCV64 const unsigned struct_kernel_stat_sz = 128; const unsigned struct_kernel_stat64_sz = 0; // RISCV64 does not use stat64 -#endif +# elif defined(__hexagon__) +const unsigned struct_kernel_stat_sz = 128; +const unsigned struct_kernel_stat64_sz = 0; +# endif struct __sanitizer_perf_event_attr { unsigned type; unsigned size; @@ -367,7 +370,7 @@ struct __sanitizer_group { char **gr_mem; }; -#if defined(__x86_64__) && !defined(_LP64) +# if (defined(__x86_64__) && !defined(_LP64)) || defined(__hexagon__) typedef long long __sanitizer_time_t; #else typedef long __sanitizer_time_t; @@ -475,23 +478,23 @@ struct __sanitizer_dirent { unsigned short d_reclen; // more fields that we don't care about }; -#elif SANITIZER_ANDROID || defined(__x86_64__) +# elif SANITIZER_ANDROID || defined(__x86_64__) || defined(__hexagon__) struct __sanitizer_dirent { unsigned long long d_ino; unsigned long long d_off; unsigned short d_reclen; // more fields that we don't care about }; -#else +# else struct __sanitizer_dirent { uptr d_ino; uptr d_off; unsigned short d_reclen; // more fields that we don't care about }; -#endif +# endif -#if SANITIZER_LINUX && !SANITIZER_ANDROID +# if SANITIZER_LINUX && !SANITIZER_ANDROID struct __sanitizer_dirent64 { unsigned long long d_ino; unsigned long long d_off; @@ -511,8 +514,8 @@ typedef int __sanitizer_clockid_t; #endif #if SANITIZER_LINUX -#if defined(_LP64) || defined(__x86_64__) || defined(__powerpc__) || \ - defined(__mips__) +# if defined(_LP64) || defined(__x86_64__) || defined(__powerpc__) || \ + defined(__mips__) || defined(__hexagon__) typedef unsigned __sanitizer___kernel_uid_t; typedef unsigned __sanitizer___kernel_gid_t; #else @@ -712,6 +715,13 @@ struct __sanitizer_protoent { int p_proto; }; +struct __sanitizer_netent { + char *n_name; + char **n_aliases; + int n_addrtype; + u32 n_net; +}; + struct __sanitizer_addrinfo { int ai_flags; int ai_family; @@ -773,6 +783,10 @@ extern int glob_altdirfunc; extern unsigned path_max; +# if !SANITIZER_ANDROID +extern const int wordexp_wrde_dooffs; +# endif // !SANITIZER_ANDROID + struct __sanitizer_wordexp_t { uptr we_wordc; char **we_wordv; diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_limits_solaris.cpp b/libsanitizer/sanitizer_common/sanitizer_platform_limits_solaris.cpp index 565b31f..a113cb0 100644 --- a/libsanitizer/sanitizer_common/sanitizer_platform_limits_solaris.cpp +++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_solaris.cpp @@ -123,6 +123,7 @@ namespace __sanitizer { unsigned struct_ElfW_Phdr_sz = sizeof(ElfW(Phdr)); int glob_nomatch = GLOB_NOMATCH; + const int wordexp_wrde_dooffs = WRDE_DOOFFS; unsigned path_max = PATH_MAX; diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_limits_solaris.h b/libsanitizer/sanitizer_common/sanitizer_platform_limits_solaris.h index 85995e7..cbab577 100644 --- a/libsanitizer/sanitizer_common/sanitizer_platform_limits_solaris.h +++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_solaris.h @@ -341,6 +341,7 @@ struct __sanitizer_glob_t { extern int glob_nomatch; extern int glob_altdirfunc; +extern const int wordexp_wrde_dooffs; extern unsigned path_max; diff --git a/libsanitizer/sanitizer_common/sanitizer_posix.h b/libsanitizer/sanitizer_common/sanitizer_posix.h index b65dae6..f91e26e 100644 --- a/libsanitizer/sanitizer_common/sanitizer_posix.h +++ b/libsanitizer/sanitizer_common/sanitizer_posix.h @@ -20,10 +20,7 @@ #include "sanitizer_platform_limits_posix.h" #include "sanitizer_platform_limits_solaris.h" -#if !SANITIZER_POSIX -// Make it hard to accidentally use any of functions declared in this file: -#error This file should only be included on POSIX -#endif +#if SANITIZER_POSIX namespace __sanitizer { @@ -126,4 +123,6 @@ void DecorateMapping(uptr addr, uptr size, const char *name); } // namespace __sanitizer +#endif // SANITIZER_POSIX + #endif // SANITIZER_POSIX_H diff --git a/libsanitizer/sanitizer_common/sanitizer_posix_libcdep.cpp b/libsanitizer/sanitizer_common/sanitizer_posix_libcdep.cpp index ddf6844..eed02ce 100644 --- a/libsanitizer/sanitizer_common/sanitizer_posix_libcdep.cpp +++ b/libsanitizer/sanitizer_common/sanitizer_posix_libcdep.cpp @@ -151,6 +151,8 @@ int Atexit(void (*function)(void)) { #endif } +bool CreateDir(const char *pathname) { return mkdir(pathname, 0755) == 0; } + bool SupportsColoredOutput(fd_t fd) { return isatty(fd) != 0; } diff --git a/libsanitizer/sanitizer_common/sanitizer_printf.cpp b/libsanitizer/sanitizer_common/sanitizer_printf.cpp index b913c92..79aee8b 100644 --- a/libsanitizer/sanitizer_common/sanitizer_printf.cpp +++ b/libsanitizer/sanitizer_common/sanitizer_printf.cpp @@ -20,10 +20,6 @@ #include <stdio.h> #include <stdarg.h> -#if defined(__x86_64__) -# include <emmintrin.h> -#endif - #if SANITIZER_WINDOWS && defined(_MSC_VER) && _MSC_VER < 1800 && \ !defined(va_copy) # define va_copy(dst, src) ((dst) = (src)) @@ -132,8 +128,8 @@ static int AppendPointer(char **buff, const char *buff_end, u64 ptr_value) { int VSNPrintf(char *buff, int buff_length, const char *format, va_list args) { static const char *kPrintfFormatsHelp = - "Supported Printf formats: %([0-9]*)?(z|ll)?{d,u,x,X,V}; %p; " - "%[-]([0-9]*)?(\\.\\*)?s; %c\n"; + "Supported Printf formats: %([0-9]*)?(z|l|ll)?{d,u,x,X}; %p; " + "%[-]([0-9]*)?(\\.\\*)?s; %c\nProvided format: "; RAW_CHECK(format); RAW_CHECK(buff_length > 0); const char *buff_end = &buff[buff_length - 1]; @@ -164,9 +160,11 @@ int VSNPrintf(char *buff, int buff_length, } bool have_z = (*cur == 'z'); cur += have_z; - bool have_ll = !have_z && (cur[0] == 'l' && cur[1] == 'l'); + bool have_l = cur[0] == 'l' && cur[1] != 'l'; + cur += have_l; + bool have_ll = cur[0] == 'l' && cur[1] == 'l'; cur += have_ll * 2; - const bool have_length = have_z || have_ll; + const bool have_length = have_z || have_l || have_ll; const bool have_flags = have_width || have_length; // At the moment only %s supports precision and left-justification. CHECK(!((precision >= 0 || left_justified) && *cur != 's')); @@ -174,6 +172,7 @@ int VSNPrintf(char *buff, int buff_length, case 'd': { s64 dval = have_ll ? va_arg(args, s64) : have_z ? va_arg(args, sptr) + : have_l ? va_arg(args, long) : va_arg(args, int); result += AppendSignedDecimal(&buff, buff_end, dval, width, pad_with_zero); @@ -184,26 +183,20 @@ int VSNPrintf(char *buff, int buff_length, case 'X': { u64 uval = have_ll ? va_arg(args, u64) : have_z ? va_arg(args, uptr) + : have_l ? va_arg(args, unsigned long) : va_arg(args, unsigned); bool uppercase = (*cur == 'X'); result += AppendUnsigned(&buff, buff_end, uval, (*cur == 'u') ? 10 : 16, width, pad_with_zero, uppercase); break; } - case 'V': { - for (uptr i = 0; i < 16; i++) { - unsigned x = va_arg(args, unsigned); - result += AppendUnsigned(&buff, buff_end, x, 16, 2, true, false); - } - break; - } case 'p': { - RAW_CHECK_MSG(!have_flags, kPrintfFormatsHelp); + RAW_CHECK(!have_flags, kPrintfFormatsHelp, format); result += AppendPointer(&buff, buff_end, va_arg(args, uptr)); break; } case 's': { - RAW_CHECK_MSG(!have_length, kPrintfFormatsHelp); + RAW_CHECK(!have_length, kPrintfFormatsHelp, format); // Only left-justified width is supported. CHECK(!have_width || left_justified); result += AppendString(&buff, buff_end, left_justified ? -width : width, @@ -211,17 +204,17 @@ int VSNPrintf(char *buff, int buff_length, break; } case 'c': { - RAW_CHECK_MSG(!have_flags, kPrintfFormatsHelp); + RAW_CHECK(!have_flags, kPrintfFormatsHelp, format); result += AppendChar(&buff, buff_end, va_arg(args, int)); break; } case '%' : { - RAW_CHECK_MSG(!have_flags, kPrintfFormatsHelp); + RAW_CHECK(!have_flags, kPrintfFormatsHelp, format); result += AppendChar(&buff, buff_end, '%'); break; } default: { - RAW_CHECK_MSG(false, kPrintfFormatsHelp); + RAW_CHECK(false, kPrintfFormatsHelp, format); } } } @@ -317,7 +310,6 @@ static void NOINLINE SharedPrintfCode(bool append_pid, const char *format, format, args); } -FORMAT(1, 2) void Printf(const char *format, ...) { va_list args; va_start(args, format); @@ -326,7 +318,6 @@ void Printf(const char *format, ...) { } // Like Printf, but prints the current PID before the output string. -FORMAT(1, 2) void Report(const char *format, ...) { va_list args; va_start(args, format); @@ -338,7 +329,6 @@ void Report(const char *format, ...) { // Returns the number of symbols that should have been written to buffer // (not including trailing '\0'). Thus, the string is truncated // iff return value is not less than "length". -FORMAT(3, 4) int internal_snprintf(char *buffer, uptr length, const char *format, ...) { va_list args; va_start(args, format); @@ -347,7 +337,6 @@ int internal_snprintf(char *buffer, uptr length, const char *format, ...) { return needed_length; } -FORMAT(2, 3) void InternalScopedString::append(const char *format, ...) { uptr prev_len = length(); diff --git a/libsanitizer/sanitizer_common/sanitizer_signal_interceptors.inc b/libsanitizer/sanitizer_common/sanitizer_signal_interceptors.inc index cefb870..475e577 100644 --- a/libsanitizer/sanitizer_common/sanitizer_signal_interceptors.inc +++ b/libsanitizer/sanitizer_common/sanitizer_signal_interceptors.inc @@ -29,8 +29,16 @@ using namespace __sanitizer; #endif #ifndef SIGNAL_INTERCEPTOR_SIGACTION_IMPL -#define SIGNAL_INTERCEPTOR_SIGACTION_IMPL(signum, act, oldact) \ - { return REAL(sigaction_symname)(signum, act, oldact); } +# define SIGNAL_INTERCEPTOR_SIGACTION_IMPL(signum, act, oldact) \ + { \ + if (!REAL(sigaction_symname)) { \ + Printf( \ + "Warning: REAL(sigaction_symname) == nullptr. This may happen " \ + "if you link with ubsan statically. Sigaction will not work.\n"); \ + return -1; \ + } \ + return REAL(sigaction_symname)(signum, act, oldact); \ + } #endif #if SANITIZER_INTERCEPT_BSD_SIGNAL diff --git a/libsanitizer/sanitizer_common/sanitizer_solaris.cpp b/libsanitizer/sanitizer_common/sanitizer_solaris.cpp index cb53eab..62c40af 100644 --- a/libsanitizer/sanitizer_common/sanitizer_solaris.cpp +++ b/libsanitizer/sanitizer_common/sanitizer_solaris.cpp @@ -225,28 +225,6 @@ void FutexWait(atomic_uint32_t *p, u32 cmp) { void FutexWake(atomic_uint32_t *p, u32 count) {} -BlockingMutex::BlockingMutex() { - CHECK(sizeof(mutex_t) <= sizeof(opaque_storage_)); - internal_memset(this, 0, sizeof(*this)); - CHECK_EQ(mutex_init((mutex_t *)&opaque_storage_, USYNC_THREAD, NULL), 0); -} - -void BlockingMutex::Lock() { - CHECK(sizeof(mutex_t) <= sizeof(opaque_storage_)); - CHECK_NE(owner_, (uptr)thr_self()); - CHECK_EQ(mutex_lock((mutex_t *)&opaque_storage_), 0); - CHECK(!owner_); - owner_ = (uptr)thr_self(); -} - -void BlockingMutex::Unlock() { - CHECK(owner_ == (uptr)thr_self()); - owner_ = 0; - CHECK_EQ(mutex_unlock((mutex_t *)&opaque_storage_), 0); -} - -void BlockingMutex::CheckLocked() const { CHECK_EQ((uptr)thr_self(), owner_); } - } // namespace __sanitizer #endif // SANITIZER_SOLARIS diff --git a/libsanitizer/sanitizer_common/sanitizer_stacktrace.cpp b/libsanitizer/sanitizer_common/sanitizer_stacktrace.cpp index 515dedd..4707c6c 100644 --- a/libsanitizer/sanitizer_common/sanitizer_stacktrace.cpp +++ b/libsanitizer/sanitizer_common/sanitizer_stacktrace.cpp @@ -22,7 +22,8 @@ namespace __sanitizer { uptr StackTrace::GetNextInstructionPc(uptr pc) { #if defined(__sparc__) || defined(__mips__) return pc + 8; -#elif defined(__powerpc__) || defined(__arm__) || defined(__aarch64__) +#elif defined(__powerpc__) || defined(__arm__) || defined(__aarch64__) || \ + defined(__hexagon__) return pc + 4; #elif SANITIZER_RISCV64 // Current check order is 4 -> 2 -> 6 -> 8 @@ -64,7 +65,7 @@ void BufferedStackTrace::Init(const uptr *pcs, uptr cnt, uptr extra_top_pc) { top_frame_bp = 0; } -// Sparc implemention is in its own file. +// Sparc implementation is in its own file. #if !defined(__sparc__) // In GCC on ARM bp points to saved lr, not fp, so we should check the next @@ -85,8 +86,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 @@ -109,21 +110,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(__riscv) diff --git a/libsanitizer/sanitizer_common/sanitizer_stacktrace_libcdep.cpp b/libsanitizer/sanitizer_common/sanitizer_stacktrace_libcdep.cpp index f60ea77..2d1c03f 100644 --- a/libsanitizer/sanitizer_common/sanitizer_stacktrace_libcdep.cpp +++ b/libsanitizer/sanitizer_common/sanitizer_stacktrace_libcdep.cpp @@ -64,7 +64,7 @@ class StackTraceTextPrinter { if (dedup_token_->length()) dedup_token_->append("--"); if (stack->info.function != nullptr) - dedup_token_->append(stack->info.function); + dedup_token_->append("%s", stack->info.function); } } diff --git a/libsanitizer/sanitizer_common/sanitizer_stacktrace_printer.cpp b/libsanitizer/sanitizer_common/sanitizer_stacktrace_printer.cpp index c998322..ad638a8 100644 --- a/libsanitizer/sanitizer_common/sanitizer_stacktrace_printer.cpp +++ b/libsanitizer/sanitizer_common/sanitizer_stacktrace_printer.cpp @@ -129,7 +129,7 @@ void RenderFrame(InternalScopedString *buffer, const char *format, int frame_no, break; // Frame number and all fields of AddressInfo structure. case 'n': - buffer->append("%zu", frame_no); + buffer->append("%u", frame_no); break; case 'p': buffer->append("0x%zx", address); @@ -198,8 +198,7 @@ void RenderFrame(InternalScopedString *buffer, const char *format, int frame_no, } break; default: - Report("Unsupported specifier in stack frame format: %c (0x%zx)!\n", *p, - *p); + Report("Unsupported specifier in stack frame format: %c (%p)!\n", *p, p); Die(); } } @@ -244,14 +243,14 @@ void RenderData(InternalScopedString *buffer, const char *format, buffer->append("%s", StripPathPrefix(DI->file, strip_path_prefix)); break; case 'l': - buffer->append("%d", DI->line); + buffer->append("%zu", DI->line); break; case 'g': buffer->append("%s", DI->name); break; default: - Report("Unsupported specifier in stack frame format: %c (0x%zx)!\n", *p, - *p); + Report("Unsupported specifier in stack frame format: %c (%p)!\n", *p, + p); Die(); } } diff --git a/libsanitizer/sanitizer_common/sanitizer_stacktrace_sparc.cpp b/libsanitizer/sanitizer_common/sanitizer_stacktrace_sparc.cpp index 34190fb..1e635a6 100644 --- a/libsanitizer/sanitizer_common/sanitizer_stacktrace_sparc.cpp +++ b/libsanitizer/sanitizer_common/sanitizer_stacktrace_sparc.cpp @@ -9,7 +9,7 @@ // This file is shared between AddressSanitizer and ThreadSanitizer // run-time libraries. // -// Implemention of fast stack unwinding for Sparc. +// Implementation of fast stack unwinding for Sparc. //===----------------------------------------------------------------------===// #if defined(__sparc__) diff --git a/libsanitizer/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp b/libsanitizer/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp index 53cfddc..403bda1 100644 --- a/libsanitizer/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp +++ b/libsanitizer/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp @@ -108,7 +108,7 @@ struct TracerThreadArgument { void *callback_argument; // The tracer thread waits on this mutex while the parent finishes its // preparations. - BlockingMutex mutex; + Mutex mutex; // Tracer thread signals its completion by setting done. atomic_uintptr_t done; uptr parent_pid; diff --git a/libsanitizer/sanitizer_common/sanitizer_stoptheworld_netbsd_libcdep.cpp b/libsanitizer/sanitizer_common/sanitizer_stoptheworld_netbsd_libcdep.cpp index 9c7cd64..701db72 100644 --- a/libsanitizer/sanitizer_common/sanitizer_stoptheworld_netbsd_libcdep.cpp +++ b/libsanitizer/sanitizer_common/sanitizer_stoptheworld_netbsd_libcdep.cpp @@ -68,7 +68,7 @@ class SuspendedThreadsListNetBSD final : public SuspendedThreadsList { struct TracerThreadArgument { StopTheWorldCallback callback; void *callback_argument; - BlockingMutex mutex; + Mutex mutex; atomic_uintptr_t done; uptr parent_pid; }; diff --git a/libsanitizer/sanitizer_common/sanitizer_symbolizer.h b/libsanitizer/sanitizer_common/sanitizer_symbolizer.h index 2476b0e..42bd157 100644 --- a/libsanitizer/sanitizer_common/sanitizer_symbolizer.h +++ b/libsanitizer/sanitizer_common/sanitizer_symbolizer.h @@ -158,7 +158,7 @@ class Symbolizer final { // its method should be protected by |mu_|. class ModuleNameOwner { public: - explicit ModuleNameOwner(BlockingMutex *synchronized_by) + explicit ModuleNameOwner(Mutex *synchronized_by) : last_match_(nullptr), mu_(synchronized_by) { storage_.reserve(kInitialCapacity); } @@ -169,7 +169,7 @@ class Symbolizer final { InternalMmapVector<const char*> storage_; const char *last_match_; - BlockingMutex *mu_; + Mutex *mu_; } module_names_; /// Platform-specific function for creating a Symbolizer object. @@ -192,7 +192,7 @@ class Symbolizer final { // Mutex locked from public methods of |Symbolizer|, so that the internals // (including individual symbolizer tools and platform-specific methods) are // always synchronized. - BlockingMutex mu_; + Mutex mu_; IntrusiveList<SymbolizerTool> tools_; diff --git a/libsanitizer/sanitizer_common/sanitizer_symbolizer_internal.h b/libsanitizer/sanitizer_common/sanitizer_symbolizer_internal.h index 71de175..b867094 100644 --- a/libsanitizer/sanitizer_common/sanitizer_symbolizer_internal.h +++ b/libsanitizer/sanitizer_common/sanitizer_symbolizer_internal.h @@ -21,7 +21,7 @@ namespace __sanitizer { // Parsing helpers, 'str' is searched for delimiter(s) and a string or uptr // is extracted. When extracting a string, a newly allocated (using -// InternalAlloc) and null-terminataed buffer is returned. They return a pointer +// InternalAlloc) and null-terminated buffer is returned. They return a pointer // to the next characted after the found delimiter. const char *ExtractToken(const char *str, const char *delims, char **result); const char *ExtractInt(const char *str, const char *delims, int *result); diff --git a/libsanitizer/sanitizer_common/sanitizer_symbolizer_libcdep.cpp b/libsanitizer/sanitizer_common/sanitizer_symbolizer_libcdep.cpp index 98418b4..3fc994f 100644 --- a/libsanitizer/sanitizer_common/sanitizer_symbolizer_libcdep.cpp +++ b/libsanitizer/sanitizer_common/sanitizer_symbolizer_libcdep.cpp @@ -83,7 +83,7 @@ const char *ExtractTokenUpToDelimiter(const char *str, const char *delimiter, } SymbolizedStack *Symbolizer::SymbolizePC(uptr addr) { - BlockingMutexLock l(&mu_); + Lock l(&mu_); const char *module_name = nullptr; uptr module_offset; ModuleArch arch; @@ -103,7 +103,7 @@ SymbolizedStack *Symbolizer::SymbolizePC(uptr addr) { } bool Symbolizer::SymbolizeData(uptr addr, DataInfo *info) { - BlockingMutexLock l(&mu_); + Lock l(&mu_); const char *module_name = nullptr; uptr module_offset; ModuleArch arch; @@ -124,7 +124,7 @@ bool Symbolizer::SymbolizeData(uptr addr, DataInfo *info) { } bool Symbolizer::SymbolizeFrame(uptr addr, FrameInfo *info) { - BlockingMutexLock l(&mu_); + Lock l(&mu_); const char *module_name = nullptr; if (!FindModuleNameAndOffsetForAddress( addr, &module_name, &info->module_offset, &info->module_arch)) @@ -141,7 +141,7 @@ bool Symbolizer::SymbolizeFrame(uptr addr, FrameInfo *info) { bool Symbolizer::GetModuleNameAndOffsetForPC(uptr pc, const char **module_name, uptr *module_address) { - BlockingMutexLock l(&mu_); + Lock l(&mu_); const char *internal_module_name = nullptr; ModuleArch arch; if (!FindModuleNameAndOffsetForAddress(pc, &internal_module_name, @@ -154,7 +154,7 @@ bool Symbolizer::GetModuleNameAndOffsetForPC(uptr pc, const char **module_name, } void Symbolizer::Flush() { - BlockingMutexLock l(&mu_); + Lock l(&mu_); for (auto &tool : tools_) { SymbolizerScope sym_scope(this); tool.Flush(); @@ -162,7 +162,7 @@ void Symbolizer::Flush() { } const char *Symbolizer::Demangle(const char *name) { - BlockingMutexLock l(&mu_); + Lock l(&mu_); for (auto &tool : tools_) { SymbolizerScope sym_scope(this); if (const char *demangled = tool.Demangle(name)) diff --git a/libsanitizer/sanitizer_common/sanitizer_syscall_linux_hexagon.inc b/libsanitizer/sanitizer_common/sanitizer_syscall_linux_hexagon.inc new file mode 100644 index 0000000..553bff7 --- /dev/null +++ b/libsanitizer/sanitizer_common/sanitizer_syscall_linux_hexagon.inc @@ -0,0 +1,131 @@ +//===-- sanitizer_syscall_linux_hexagon.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 +// +//===----------------------------------------------------------------------===// +// +// Implementations of internal_syscall and internal_iserror for Linux/hexagon. +// +//===----------------------------------------------------------------------===// + +#define SYSCALL(name) __NR_##name + +#define __internal_syscall_LL_E(x) \ + ((union { \ + long long ll; \ + long l[2]; \ + }){.ll = x}) \ + .l[0], \ + ((union { \ + long long ll; \ + long l[2]; \ + }){.ll = x}) \ + .l[1] +#define __internal_syscall_LL_O(x) 0, __SYSCALL_LL_E((x)) + +#define __asm_syscall(...) \ + do { \ + __asm__ __volatile__("trap0(#1)" : "=r"(r0) : __VA_ARGS__ : "memory"); \ + return r0; \ + } while (0) + +#define __internal_syscall0(n) (__internal_syscall)(n) + +static uptr __internal_syscall(long n) { + register u32 r6 __asm__("r6") = n; + register u32 r0 __asm__("r0"); + __asm_syscall("r"(r6)); +} + +#define __internal_syscall1(n, a1) (__internal_syscall)(n, (long)(a1)) + +static uptr __internal_syscall(long n, long a) { + register u32 r6 __asm__("r6") = n; + register u32 r0 __asm__("r0") = a; + __asm_syscall("r"(r6), "0"(r0)); +} + +#define __internal_syscall2(n, a1, a2) \ + (__internal_syscall)(n, (long)(a1), (long)(a2)) + +static uptr __internal_syscall(long n, long a, long b) { + register u32 r6 __asm__("r6") = n; + register u32 r0 __asm__("r0") = a; + register u32 r1 __asm__("r1") = b; + __asm_syscall("r"(r6), "0"(r0), "r"(r1)); +} + +#define __internal_syscall3(n, a1, a2, a3) \ + (__internal_syscall)(n, (long)(a1), (long)(a2), (long)(a3)) + +static uptr __internal_syscall(long n, long a, long b, long c) { + register u32 r6 __asm__("r6") = n; + register u32 r0 __asm__("r0") = a; + register u32 r1 __asm__("r1") = b; + register u32 r2 __asm__("r2") = c; + __asm_syscall("r"(r6), "0"(r0), "r"(r1), "r"(r2)); +} + +#define __internal_syscall4(n, a1, a2, a3, a4) \ + (__internal_syscall)(n, (long)(a1), (long)(a2), (long)(a3), (long)(a4)) + +static uptr __internal_syscall(long n, long a, long b, long c, long d) { + register u32 r6 __asm__("r6") = n; + register u32 r0 __asm__("r0") = a; + register u32 r1 __asm__("r1") = b; + register u32 r2 __asm__("r2") = c; + register u32 r3 __asm__("r3") = d; + __asm_syscall("r"(r6), "0"(r0), "r"(r1), "r"(r2), "r"(r3)); +} + +#define __internal_syscall5(n, a1, a2, a3, a4, a5) \ + (__internal_syscall)(n, (long)(a1), (long)(a2), (long)(a3), (long)(a4), \ + (long)(a5)) + +static uptr __internal_syscall(long n, long a, long b, long c, long d, long e) { + register u32 r6 __asm__("r6") = n; + register u32 r0 __asm__("r0") = a; + register u32 r1 __asm__("r1") = b; + register u32 r2 __asm__("r2") = c; + register u32 r3 __asm__("r3") = d; + register u32 r4 __asm__("r4") = e; + __asm_syscall("r"(r6), "0"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4)); +} + +#define __internal_syscall6(n, a1, a2, a3, a4, a5, a6) \ + (__internal_syscall)(n, (long)(a1), (long)(a2), (long)(a3), (long)(a4), \ + (long)(a5), (long)(a6)) + +static uptr __internal_syscall(long n, long a, long b, long c, long d, long e, + long f) { + register u32 r6 __asm__("r6") = n; + register u32 r0 __asm__("r0") = a; + register u32 r1 __asm__("r1") = b; + register u32 r2 __asm__("r2") = c; + register u32 r3 __asm__("r3") = d; + register u32 r4 __asm__("r4") = e; + register u32 r5 __asm__("r5") = f; + __asm_syscall("r"(r6), "0"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4), "r"(r5)); +} + +#define __SYSCALL_NARGS_X(a1, a2, a3, a4, a5, a6, a7, a8, n, ...) n +#define __SYSCALL_NARGS(...) \ + __SYSCALL_NARGS_X(__VA_ARGS__, 7, 6, 5, 4, 3, 2, 1, 0, ) +#define __SYSCALL_CONCAT_X(a, b) a##b +#define __SYSCALL_CONCAT(a, b) __SYSCALL_CONCAT_X(a, b) +#define __SYSCALL_DISP(b, ...) \ + __SYSCALL_CONCAT(b, __SYSCALL_NARGS(__VA_ARGS__))(__VA_ARGS__) + +#define internal_syscall(...) __SYSCALL_DISP(__internal_syscall, __VA_ARGS__) + +// Helper function used to avoid clobbering of errno. +bool internal_iserror(uptr retval, int *rverrno) { + if (retval >= (uptr)-4095) { + if (rverrno) + *rverrno = -retval; + return true; + } + return false; +} diff --git a/libsanitizer/sanitizer_common/sanitizer_thread_registry.cpp b/libsanitizer/sanitizer_common/sanitizer_thread_registry.cpp index 745fbf7..a34b8c1 100644 --- a/libsanitizer/sanitizer_common/sanitizer_thread_registry.cpp +++ b/libsanitizer/sanitizer_common/sanitizer_thread_registry.cpp @@ -119,7 +119,7 @@ ThreadRegistry::ThreadRegistry(ThreadContextFactory factory, u32 max_threads, void ThreadRegistry::GetNumberOfThreads(uptr *total, uptr *running, uptr *alive) { - BlockingMutexLock l(&mtx_); + ThreadRegistryLock l(this); if (total) *total = threads_.size(); if (running) *running = running_threads_; @@ -127,13 +127,13 @@ void ThreadRegistry::GetNumberOfThreads(uptr *total, uptr *running, } uptr ThreadRegistry::GetMaxAliveThreads() { - BlockingMutexLock l(&mtx_); + ThreadRegistryLock l(this); return max_alive_threads_; } u32 ThreadRegistry::CreateThread(uptr user_id, bool detached, u32 parent_tid, void *arg) { - BlockingMutexLock l(&mtx_); + ThreadRegistryLock l(this); u32 tid = kInvalidTid; ThreadContextBase *tctx = QuarantinePop(); if (tctx) { @@ -179,7 +179,7 @@ void ThreadRegistry::RunCallbackForEachThreadLocked(ThreadCallback cb, } u32 ThreadRegistry::FindThread(FindThreadCallback cb, void *arg) { - BlockingMutexLock l(&mtx_); + ThreadRegistryLock l(this); for (u32 tid = 0; tid < threads_.size(); tid++) { ThreadContextBase *tctx = threads_[tid]; if (tctx != 0 && cb(tctx, arg)) @@ -211,7 +211,7 @@ ThreadContextBase *ThreadRegistry::FindThreadContextByOsIDLocked(tid_t os_id) { } void ThreadRegistry::SetThreadName(u32 tid, const char *name) { - BlockingMutexLock l(&mtx_); + ThreadRegistryLock l(this); ThreadContextBase *tctx = threads_[tid]; CHECK_NE(tctx, 0); CHECK_EQ(SANITIZER_FUCHSIA ? ThreadStatusCreated : ThreadStatusRunning, @@ -220,7 +220,7 @@ void ThreadRegistry::SetThreadName(u32 tid, const char *name) { } void ThreadRegistry::SetThreadNameByUserId(uptr user_id, const char *name) { - BlockingMutexLock l(&mtx_); + ThreadRegistryLock l(this); for (u32 tid = 0; tid < threads_.size(); tid++) { ThreadContextBase *tctx = threads_[tid]; if (tctx != 0 && tctx->user_id == user_id && @@ -232,7 +232,7 @@ void ThreadRegistry::SetThreadNameByUserId(uptr user_id, const char *name) { } void ThreadRegistry::DetachThread(u32 tid, void *arg) { - BlockingMutexLock l(&mtx_); + ThreadRegistryLock l(this); ThreadContextBase *tctx = threads_[tid]; CHECK_NE(tctx, 0); if (tctx->status == ThreadStatusInvalid) { @@ -252,7 +252,7 @@ void ThreadRegistry::JoinThread(u32 tid, void *arg) { bool destroyed = false; do { { - BlockingMutexLock l(&mtx_); + ThreadRegistryLock l(this); ThreadContextBase *tctx = threads_[tid]; CHECK_NE(tctx, 0); if (tctx->status == ThreadStatusInvalid) { @@ -275,7 +275,7 @@ void ThreadRegistry::JoinThread(u32 tid, void *arg) { // thread before trying to create it, and then failed to actually // create it, and so never called StartThread. ThreadStatus ThreadRegistry::FinishThread(u32 tid) { - BlockingMutexLock l(&mtx_); + ThreadRegistryLock l(this); CHECK_GT(alive_threads_, 0); alive_threads_--; ThreadContextBase *tctx = threads_[tid]; @@ -301,7 +301,7 @@ ThreadStatus ThreadRegistry::FinishThread(u32 tid) { void ThreadRegistry::StartThread(u32 tid, tid_t os_id, ThreadType thread_type, void *arg) { - BlockingMutexLock l(&mtx_); + ThreadRegistryLock l(this); running_threads_++; ThreadContextBase *tctx = threads_[tid]; CHECK_NE(tctx, 0); @@ -334,7 +334,7 @@ ThreadContextBase *ThreadRegistry::QuarantinePop() { } void ThreadRegistry::SetThreadUserId(u32 tid, uptr user_id) { - BlockingMutexLock l(&mtx_); + ThreadRegistryLock l(this); ThreadContextBase *tctx = threads_[tid]; CHECK_NE(tctx, 0); CHECK_NE(tctx->status, ThreadStatusInvalid); diff --git a/libsanitizer/sanitizer_common/sanitizer_thread_registry.h b/libsanitizer/sanitizer_common/sanitizer_thread_registry.h index 0b28bbe..a8a4d4d 100644 --- a/libsanitizer/sanitizer_common/sanitizer_thread_registry.h +++ b/libsanitizer/sanitizer_common/sanitizer_thread_registry.h @@ -135,7 +135,7 @@ class MUTEX ThreadRegistry { const u32 thread_quarantine_size_; const u32 max_reuse_; - BlockingMutex mtx_; + Mutex mtx_; u64 total_threads_; // Total number of created threads. May be greater than // max_threads_ if contexts were reused. diff --git a/libsanitizer/sanitizer_common/sanitizer_tls_get_addr.cpp b/libsanitizer/sanitizer_common/sanitizer_tls_get_addr.cpp index 1f664b6..ce5e85d 100644 --- a/libsanitizer/sanitizer_common/sanitizer_tls_get_addr.cpp +++ b/libsanitizer/sanitizer_common/sanitizer_tls_get_addr.cpp @@ -44,7 +44,7 @@ static atomic_uintptr_t number_of_live_dtls; static const uptr kDestroyedThread = -1; static void DTLS_Deallocate(DTLS::DTVBlock *block) { - VReport(2, "__tls_get_addr: DTLS_Deallocate %p %zd\n", block); + VReport(2, "__tls_get_addr: DTLS_Deallocate %p\n", block); UnmapOrDie(block, sizeof(DTLS::DTVBlock)); atomic_fetch_sub(&number_of_live_dtls, 1, memory_order_relaxed); } @@ -117,26 +117,27 @@ DTLS::DTV *DTLS_on_tls_get_addr(void *arg_void, void *res, return 0; uptr tls_size = 0; uptr tls_beg = reinterpret_cast<uptr>(res) - arg->offset - kDtvOffset; - VReport(2, "__tls_get_addr: %p {%p,%p} => %p; tls_beg: %p; sp: %p " - "num_live_dtls %zd\n", + VReport(2, + "__tls_get_addr: %p {0x%zx,0x%zx} => %p; tls_beg: 0x%zx; sp: %p " + "num_live_dtls %zd\n", arg, arg->dso_id, arg->offset, res, tls_beg, &tls_beg, atomic_load(&number_of_live_dtls, memory_order_relaxed)); if (dtls.last_memalign_ptr == tls_beg) { tls_size = dtls.last_memalign_size; - VReport(2, "__tls_get_addr: glibc <=2.18 suspected; tls={%p,%p}\n", - tls_beg, tls_size); + VReport(2, "__tls_get_addr: glibc <=2.18 suspected; tls={0x%zx,0x%zx}\n", + tls_beg, tls_size); } else if (tls_beg >= static_tls_begin && tls_beg < static_tls_end) { // This is the static TLS block which was initialized / unpoisoned at thread // creation. - VReport(2, "__tls_get_addr: static tls: %p\n", tls_beg); + VReport(2, "__tls_get_addr: static tls: 0x%zx\n", tls_beg); tls_size = 0; } else if ((tls_beg % 4096) == sizeof(Glibc_2_19_tls_header)) { // We may want to check gnu_get_libc_version(). Glibc_2_19_tls_header *header = (Glibc_2_19_tls_header *)tls_beg - 1; tls_size = header->size; tls_beg = header->start; - VReport(2, "__tls_get_addr: glibc >=2.19 suspected; tls={%p %p}\n", - tls_beg, tls_size); + VReport(2, "__tls_get_addr: glibc >=2.19 suspected; tls={0x%zx 0x%zx}\n", + tls_beg, tls_size); } else { VReport(2, "__tls_get_addr: Can't guess glibc version\n"); // This may happen inside the DTOR of main thread, so just ignore it. @@ -149,7 +150,7 @@ DTLS::DTV *DTLS_on_tls_get_addr(void *arg_void, void *res, void DTLS_on_libc_memalign(void *ptr, uptr size) { if (!common_flags()->intercept_tls_get_addr) return; - VReport(2, "DTLS_on_libc_memalign: %p %p\n", ptr, size); + VReport(2, "DTLS_on_libc_memalign: %p 0x%zx\n", ptr, size); dtls.last_memalign_ptr = reinterpret_cast<uptr>(ptr); dtls.last_memalign_size = size; } diff --git a/libsanitizer/sanitizer_common/sanitizer_win.cpp b/libsanitizer/sanitizer_common/sanitizer_win.cpp index dddd885..811aa49 100644 --- a/libsanitizer/sanitizer_common/sanitizer_win.cpp +++ b/libsanitizer/sanitizer_common/sanitizer_win.cpp @@ -16,6 +16,7 @@ #define WIN32_LEAN_AND_MEAN #define NOGDI +#include <direct.h> #include <windows.h> #include <io.h> #include <psapi.h> @@ -565,6 +566,8 @@ void Abort() { internal__exit(3); } +bool CreateDir(const char *pathname) { return _mkdir(pathname) == 0; } + #if !SANITIZER_GO // Read the file to extract the ImageBase field from the PE header. If ASLR is // disabled and this virtual address is available, the loader will typically @@ -827,27 +830,6 @@ void FutexWake(atomic_uint32_t *p, u32 count) { WakeByAddressAll(p); } -// ---------------------- BlockingMutex ---------------- {{{1 - -BlockingMutex::BlockingMutex() { - CHECK(sizeof(SRWLOCK) <= sizeof(opaque_storage_)); - internal_memset(this, 0, sizeof(*this)); -} - -void BlockingMutex::Lock() { - AcquireSRWLockExclusive((PSRWLOCK)opaque_storage_); - CHECK_EQ(owner_, 0); - owner_ = GetThreadSelf(); -} - -void BlockingMutex::Unlock() { - CheckLocked(); - owner_ = 0; - ReleaseSRWLockExclusive((PSRWLOCK)opaque_storage_); -} - -void BlockingMutex::CheckLocked() const { CHECK_EQ(owner_, GetThreadSelf()); } - uptr GetTlsSize() { return 0; } |