diff --git a/compiler-rt/lib/dfsan/dfsan_custom.cpp b/compiler-rt/lib/dfsan/dfsan_custom.cpp --- a/compiler-rt/lib/dfsan/dfsan_custom.cpp +++ b/compiler-rt/lib/dfsan/dfsan_custom.cpp @@ -427,6 +427,18 @@ return rv; } +SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_pthread_join(pthread_t thread, + void **retval, + dfsan_label thread_label, + dfsan_label retval_label, + dfsan_label *ret_label) { + int ret = pthread_join(thread, retval); + if (ret == 0 && retval) + dfsan_set_label(0, retval, sizeof(*retval)); + *ret_label = 0; + return ret; +} + struct dl_iterate_phdr_info { int (*callback_trampoline)(void *callback, struct dl_phdr_info *info, size_t size, void *data, dfsan_label info_label, diff --git a/compiler-rt/lib/dfsan/done_abilist.txt b/compiler-rt/lib/dfsan/done_abilist.txt --- a/compiler-rt/lib/dfsan/done_abilist.txt +++ b/compiler-rt/lib/dfsan/done_abilist.txt @@ -319,6 +319,10 @@ # Functions that take a callback (wrap the callback manually). fun:pthread_create=custom +# Functions that produce output does not depend on the input (need to zero the +# shadow manually). +fun:pthread_join=custom + ############################################################################### # libffi/libgo ############################################################################### diff --git a/compiler-rt/test/dfsan/custom.cpp b/compiler-rt/test/dfsan/custom.cpp --- a/compiler-rt/test/dfsan/custom.cpp +++ b/compiler-rt/test/dfsan/custom.cpp @@ -792,8 +792,12 @@ pthread_t pt; pthread_create(&pt, 0, pthread_create_test_cb, (void *)1); void *cbrv; - pthread_join(pt, &cbrv); + dfsan_set_label(i_label, &cbrv, sizeof(cbrv)); + int ret = pthread_join(pt, &cbrv); + assert(ret == 0); assert(cbrv == (void *)2); + ASSERT_ZERO_LABEL(ret); + ASSERT_ZERO_LABEL(cbrv); } int dl_iterate_phdr_test_cb(struct dl_phdr_info *info, size_t size,