[compiler-rt] r341438 - [hwasan] print thread IDs when reporting a bug (also had to fix pthread_create on Linux)
Matt Morehouse via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 5 09:17:24 PDT 2018
Kostya, this is making thread-uaf.c flaky on the buildbot. Please take a
look.
http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux/builds/15270/steps/test%20standalone%20compiler-rt%20with%20symbolizer/logs/stdio
FAIL: HWAddressSanitizer-x86_64 :: TestCases/thread-uaf.c (3067 of 6725)
******************** TEST 'HWAddressSanitizer-x86_64 ::
TestCases/thread-uaf.c' FAILED ********************Script:
--
: 'RUN: at line 3';
/b/sanitizer-x86_64-linux/build/llvm_build64/bin/clang
-fsanitize=hwaddress -mllvm -hwasan-generate-tags-with-calls -m64
-gline-tables-only
/b/sanitizer-x86_64-linux/build/llvm/projects/compiler-rt/test/hwasan/TestCases/thread-uaf.c
-o /b/sanitizer-x86_64-linux/build/compiler_rt_build/test/hwasan/X86_64/TestCases/Output/thread-uaf.c.tmp
&& not /b/sanitizer-x86_64-linux/build/compiler_rt_build/test/hwasan/X86_64/TestCases/Output/thread-uaf.c.tmp
2>&1 | FileCheck
/b/sanitizer-x86_64-linux/build/llvm/projects/compiler-rt/test/hwasan/TestCases/thread-uaf.c
--
Exit Code: 1
Command Output (stderr):
--
/b/sanitizer-x86_64-linux/build/llvm/projects/compiler-rt/test/hwasan/TestCases/thread-uaf.c:33:12:
error: CHECK: expected string not found in input
// CHECK: WRITE of size 1 {{.*}} in thread T3
^
<stdin>:1:61: note: scanning from here
==24433==ERROR: HWAddressSanitizer: tag-mismatch on address
0x77867e8003d5 at pc 0x5588d4c102ae
^
<stdin>:2:1: note: possible intended match here
WRITE of size 1 at 0x77867e8003d5 tags: 04/02 (ptr/mem) in thread T2
^
On Tue, Sep 4, 2018 at 6:17 PM Kostya Serebryany via llvm-commits <
llvm-commits at lists.llvm.org> wrote:
> Author: kcc
> Date: Tue Sep 4 18:16:50 2018
> New Revision: 341438
>
> URL: http://llvm.org/viewvc/llvm-project?rev=341438&view=rev
> Log:
> [hwasan] print thread IDs when reporting a bug (also had to fix
> pthread_create on Linux)
>
> Modified:
> compiler-rt/trunk/lib/hwasan/hwasan_interceptors.cc
> compiler-rt/trunk/lib/hwasan/hwasan_report.cc
> compiler-rt/trunk/lib/hwasan/hwasan_thread.cc
> compiler-rt/trunk/lib/hwasan/hwasan_thread.h
> compiler-rt/trunk/test/hwasan/TestCases/many-threads-uaf.c
> compiler-rt/trunk/test/hwasan/TestCases/thread-uaf.c
>
> Modified: compiler-rt/trunk/lib/hwasan/hwasan_interceptors.cc
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/hwasan/hwasan_interceptors.cc?rev=341438&r1=341437&r2=341438&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/hwasan/hwasan_interceptors.cc (original)
> +++ compiler-rt/trunk/lib/hwasan/hwasan_interceptors.cc Tue Sep 4
> 18:16:50 2018
> @@ -292,16 +292,23 @@ INTERCEPTOR(void *, malloc, SIZE_T size)
> extern "C" int pthread_attr_init(void *attr);
> extern "C" int pthread_attr_destroy(void *attr);
>
> +struct ThreadStartArg {
> + thread_callback_t callback;
> + void *param;
> +};
> +
> static void *HwasanThreadStartFunc(void *arg) {
> __hwasan_thread_enter();
> - ThreadStartArg *A = reinterpret_cast<ThreadStartArg*>(arg);
> - return A->callback(A->param);
> + ThreadStartArg A = *reinterpret_cast<ThreadStartArg*>(arg);
> + UnmapOrDie(arg, GetPageSizeCached());
> + return A.callback(A.param);
> }
>
> INTERCEPTOR(int, pthread_create, void *th, void *attr, void
> *(*callback)(void*),
> void * param) {
> ScopedTaggingDisabler disabler;
> - ThreadStartArg *A = GetCurrentThread()->thread_start_arg();
> + ThreadStartArg *A = reinterpret_cast<ThreadStartArg *> (MmapOrDie(
> + GetPageSizeCached(), "pthread_create"));
> *A = {callback, param};
> int res = REAL(pthread_create)(UntagPtr(th), UntagPtr(attr),
> &HwasanThreadStartFunc, A);
>
> Modified: compiler-rt/trunk/lib/hwasan/hwasan_report.cc
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/hwasan/hwasan_report.cc?rev=341438&r1=341437&r2=341438&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/hwasan/hwasan_report.cc (original)
> +++ compiler-rt/trunk/lib/hwasan/hwasan_report.cc Tue Sep 4 18:16:50 2018
> @@ -43,6 +43,7 @@ class Decorator: public __sanitizer::San
> const char *Origin() const { return Magenta(); }
> const char *Name() const { return Green(); }
> const char *Location() { return Green(); }
> + const char *Thread() { return Green(); }
> };
>
> bool FindHeapAllocation(HeapAllocationsRingBuffer *rb,
> @@ -116,7 +117,7 @@ void PrintAddressDescription(uptr tagged
> har.requested_size, UntagAddr(har.tagged_addr),
> UntagAddr(har.tagged_addr) + har.requested_size);
> Printf("%s", d.Allocation());
> - Printf("freed by thread %p here:\n", t);
> + Printf("freed by thread T%zd here:\n", t->unique_id());
> Printf("%s", d.Default());
> GetStackTraceFromId(har.free_context_id).Print();
>
> @@ -124,6 +125,7 @@ void PrintAddressDescription(uptr tagged
> Printf("previously allocated here:\n", t);
> Printf("%s", d.Default());
> GetStackTraceFromId(har.alloc_context_id).Print();
> + t->Announce();
>
> num_descriptions_printed++;
> }
> @@ -131,8 +133,10 @@ void PrintAddressDescription(uptr tagged
> // Very basic check for stack memory.
> if (t->AddrIsInStack(untagged_addr)) {
> Printf("%s", d.Location());
> - Printf("Address %p is located in stack of thread %p\n",
> untagged_addr, t);
> - Printf("%s", d.Default());
> + Printf("Address %p is located in stack of thread T%zd\n",
> untagged_addr,
> + t->unique_id());
> + t->Announce();
> +
> num_descriptions_printed++;
> }
> });
> @@ -230,18 +234,21 @@ void ReportTagMismatch(StackTrace *stack
> Report("ERROR: %s: %s on address %p at pc %p\n", SanitizerToolName,
> bug_type,
> untagged_addr, pc);
>
> + Thread *t = GetCurrentThread();
> +
> tag_t ptr_tag = GetTagFromPointer(tagged_addr);
> tag_t *tag_ptr = reinterpret_cast<tag_t*>(MemToShadow(untagged_addr));
> tag_t mem_tag = *tag_ptr;
> Printf("%s", d.Access());
> - Printf("%s of size %zu at %p tags: %02x/%02x (ptr/mem)\n",
> + Printf("%s of size %zu at %p tags: %02x/%02x (ptr/mem) in thread
> T%zd\n",
> is_store ? "WRITE" : "READ", access_size, untagged_addr, ptr_tag,
> - mem_tag);
> + mem_tag, t->unique_id());
> Printf("%s", d.Default());
>
> stack->Print();
>
> PrintAddressDescription(tagged_addr, access_size);
> + t->Announce();
>
> PrintTagsAroundAddr(tag_ptr);
>
>
> Modified: compiler-rt/trunk/lib/hwasan/hwasan_thread.cc
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/hwasan/hwasan_thread.cc?rev=341438&r1=341437&r2=341438&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/hwasan/hwasan_thread.cc (original)
> +++ compiler-rt/trunk/lib/hwasan/hwasan_thread.cc Tue Sep 4 18:16:50 2018
> @@ -63,10 +63,11 @@ void Thread::Create() {
> uptr size = RoundUpTo(sizeof(Thread), PageSize);
> Thread *thread = (Thread*)MmapOrDie(size, __func__);
> thread->destructor_iterations_ = GetPthreadDestructorIterations();
> - thread->random_state_ = flags()->random_tags ? RandomSeed() : 0;
> + thread->unique_id_ = unique_id++;
> + thread->random_state_ =
> + flags()->random_tags ? RandomSeed() : thread->unique_id_;
> if (auto sz = flags()->heap_history_size)
> thread->heap_allocations_ = RingBuffer<HeapAllocationRecord>::New(sz);
> - thread->unique_id_ = unique_id++;
> InsertIntoThreadList(thread);
> SetCurrentThread(thread);
> thread->Init();
> @@ -100,7 +101,7 @@ void Thread::Init() {
> CHECK(MemIsApp(stack_top_ - 1));
> }
> if (flags()->verbose_threads)
> - Print("Creating ");
> + Print("Creating : ");
> }
>
> void Thread::ClearShadowForThreadStackAndTLS() {
> @@ -112,7 +113,7 @@ void Thread::ClearShadowForThreadStackAn
>
> void Thread::Destroy() {
> if (flags()->verbose_threads)
> - Print("Destroying");
> + Print("Destroying: ");
> malloc_storage().CommitBack();
> ClearShadowForThreadStackAndTLS();
> RemoveFromThreadList(this);
> @@ -124,8 +125,8 @@ void Thread::Destroy() {
> }
>
> void Thread::Print(const char *Prefix) {
> - Printf("%s: thread %p id: %zd stack: [%p,%p) sz: %zd tls: [%p,%p)\n",
> Prefix,
> - this, unique_id_, stack_bottom(), stack_top(),
> + Printf("%sT%zd %p stack: [%p,%p) sz: %zd tls: [%p,%p)\n", Prefix,
> + unique_id_, this, stack_bottom(), stack_top(),
> stack_top() - stack_bottom(),
> tls_begin(), tls_end());
> }
>
> Modified: compiler-rt/trunk/lib/hwasan/hwasan_thread.h
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/hwasan/hwasan_thread.h?rev=341438&r1=341437&r2=341438&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/hwasan/hwasan_thread.h (original)
> +++ compiler-rt/trunk/lib/hwasan/hwasan_thread.h Tue Sep 4 18:16:50 2018
> @@ -19,11 +19,6 @@
>
> namespace __hwasan {
>
> -struct ThreadStartArg {
> - thread_callback_t callback;
> - void *param;
> -};
> -
> class Thread {
> public:
> static void Create(); // Must be called from the thread itself.
> @@ -73,9 +68,12 @@ class Thread {
> }
> }
>
> - // Return a scratch ThreadStartArg object to be used in
> - // pthread_create interceptor.
> - ThreadStartArg *thread_start_arg() { return &thread_start_arg_; }
> + u64 unique_id() const { return unique_id_; }
> + void Announce() {
> + if (announced_) return;
> + announced_ = true;
> + Print("Thread: ");
> + }
>
> private:
> // NOTE: There is no Thread constructor. It is allocated
> @@ -108,7 +106,7 @@ class Thread {
>
> u32 tagging_disabled_; // if non-zero, malloc uses zero tag in this
> thread.
>
> - ThreadStartArg thread_start_arg_;
> + bool announced_;
> };
>
> Thread *GetCurrentThread();
>
> Modified: compiler-rt/trunk/test/hwasan/TestCases/many-threads-uaf.c
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/hwasan/TestCases/many-threads-uaf.c?rev=341438&r1=341437&r2=341438&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/test/hwasan/TestCases/many-threads-uaf.c (original)
> +++ compiler-rt/trunk/test/hwasan/TestCases/many-threads-uaf.c Tue Sep 4
> 18:16:50 2018
> @@ -14,12 +14,12 @@ void *BoringThread(void *arg) {
> return NULL;
> }
>
> -// CHECK: Creating : thread {{.*}} id: 0
> -// CHECK: Creating : thread {{.*}} id: 1
> -// CHECK: Destroying: thread {{.*}} id: 1
> -// CHECK: Creating : thread {{.*}} id: 1100
> -// CHECK: Destroying: thread {{.*}} id: 1100
> -// CHECK: Creating : thread {{.*}} id: 1101
> +// CHECK: Creating : T0
> +// CHECK: Creating : T1
> +// CHECK: Destroying: T1
> +// CHECK: Creating : T1100
> +// CHECK: Destroying: T1100
> +// CHECK: Creating : T1101
>
> void *UAFThread(void *arg) {
> char * volatile x = (char*)malloc(10);
> @@ -29,6 +29,7 @@ void *UAFThread(void *arg) {
> // CHECK: ERROR: HWAddressSanitizer: tag-mismatch on address
> // CHECK: WRITE of size 1
> // CHECK: many-threads-uaf.c:[[@LINE-3]]
> + // CHECK: Thread: T1101
> return NULL;
> }
>
>
> Modified: compiler-rt/trunk/test/hwasan/TestCases/thread-uaf.c
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/hwasan/TestCases/thread-uaf.c?rev=341438&r1=341437&r2=341438&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/test/hwasan/TestCases/thread-uaf.c (original)
> +++ compiler-rt/trunk/test/hwasan/TestCases/thread-uaf.c Tue Sep 4
> 18:16:50 2018
> @@ -1,3 +1,5 @@
> +// Tests UAF detection where Allocate/Deallocate/Use
> +// happen in separate threads.
> // RUN: %clang_hwasan %s -o %t && not %run %t 2>&1 | FileCheck %s
> // REQUIRES: stable-runtime
>
> @@ -7,20 +9,48 @@
>
> #include <sanitizer/hwasan_interface.h>
>
> -void *Thread(void *arg) {
> - char * volatile x = (char*)malloc(10);
> - fprintf(stderr, "ZZZ %p\n", x);
> +char *volatile x;
> +int state;
> +
> +void *Allocate(void *arg) {
> + x = (char*)malloc(10);
> + __sync_fetch_and_add(&state, 1);
> + while (__sync_fetch_and_add(&state, 0) != 3) {}
> + return NULL;
> +}
> +void *Deallocate(void *arg) {
> + while (__sync_fetch_and_add(&state, 0) != 1) {}
> free(x);
> + __sync_fetch_and_add(&state, 1);
> + while (__sync_fetch_and_add(&state, 0) != 3) {}
> + return NULL;
> +}
> +
> +void *Use(void *arg) {
> + while (__sync_fetch_and_add(&state, 0) != 2) {}
> x[5] = 42;
> // CHECK: ERROR: HWAddressSanitizer: tag-mismatch on address
> - // CHECK: WRITE of size 1
> + // CHECK: WRITE of size 1 {{.*}} in thread T3
> // CHECK: thread-uaf.c:[[@LINE-3]]
> + // CHECK: freed by thread T2 here
> + // CHECK: in Deallocate
> + // CHECK: previously allocated here:
> + // CHECK: in Allocate
> + // CHECK: Thread: T2 0x
> + // CHECK: Thread: T3 0x
> + __sync_fetch_and_add(&state, 1);
> return NULL;
> }
>
> int main() {
> __hwasan_enable_allocator_tagging();
> - pthread_t t;
> - pthread_create(&t, NULL, Thread, NULL);
> - pthread_join(t, NULL);
> + pthread_t t1, t2, t3;
> +
> + pthread_create(&t1, NULL, Allocate, NULL);
> + pthread_create(&t2, NULL, Deallocate, NULL);
> + pthread_create(&t3, NULL, Use, NULL);
> +
> + pthread_join(t1, NULL);
> + pthread_join(t2, NULL);
> + pthread_join(t3, NULL);
> }
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180905/31b1007a/attachment.html>
More information about the llvm-commits
mailing list