diff --git a/compiler-rt/lib/dfsan/dfsan.h b/compiler-rt/lib/dfsan/dfsan.h --- a/compiler-rt/lib/dfsan/dfsan.h +++ b/compiler-rt/lib/dfsan/dfsan.h @@ -46,6 +46,10 @@ // Copy or move the origins of the len bytes from src to dst. void dfsan_mem_origin_transfer(const void *dst, const void *src, uptr len); + +// Copy shadow bytes from src to dst. +// Note this preserves distinct taint labls at specific offsets. +void dfsan_mem_shadow_transfer(void *dst, const void *src, uptr len); } // extern "C" template diff --git a/compiler-rt/lib/dfsan/dfsan.cpp b/compiler-rt/lib/dfsan/dfsan.cpp --- a/compiler-rt/lib/dfsan/dfsan.cpp +++ b/compiler-rt/lib/dfsan/dfsan.cpp @@ -401,12 +401,18 @@ MoveOrigin(dst, src, len, &stack); } -SANITIZER_INTERFACE_ATTRIBUTE void dfsan_mem_origin_transfer(const void *dst, - const void *src, - uptr len) { +extern "C" SANITIZER_INTERFACE_ATTRIBUTE void dfsan_mem_origin_transfer( + const void *dst, const void *src, uptr len) { __dfsan_mem_origin_transfer(dst, src, len); } +extern "C" SANITIZER_INTERFACE_ATTRIBUTE void dfsan_mem_shadow_transfer( + void *dst, const void *src, uptr len) { + internal_memcpy((void *)__dfsan::shadow_for(dst), + (const void *)__dfsan::shadow_for(src), + len * sizeof(dfsan_label)); +} + namespace __dfsan { bool dfsan_inited = false; @@ -414,8 +420,7 @@ void dfsan_copy_memory(void *dst, const void *src, uptr size) { internal_memcpy(dst, src, size); - internal_memcpy((void *)shadow_for(dst), (const void *)shadow_for(src), - size * sizeof(dfsan_label)); + dfsan_mem_shadow_transfer(dst, src, size); if (dfsan_get_track_origins()) dfsan_mem_origin_transfer(dst, src, size); } 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 @@ -497,9 +497,7 @@ } static void *dfsan_memcpy(void *dest, const void *src, size_t n) { - dfsan_label *sdest = shadow_for(dest); - const dfsan_label *ssrc = shadow_for(src); - internal_memcpy((void *)sdest, (const void *)ssrc, n * sizeof(dfsan_label)); + dfsan_mem_shadow_transfer(dest, src, n); return internal_memcpy(dest, src, n); } @@ -584,10 +582,7 @@ dfsan_label *ret_label) { size_t dest_len = strlen(dest); char *ret = strcat(dest, src); - dfsan_label *sdest = shadow_for(dest + dest_len); - const dfsan_label *ssrc = shadow_for(src); - internal_memcpy((void *)sdest, (const void *)ssrc, - strlen(src) * sizeof(dfsan_label)); + dfsan_mem_shadow_transfer(dest + dest_len, src, strlen(src)); *ret_label = dest_label; return ret; } @@ -598,12 +593,9 @@ dfsan_origin *ret_origin) { size_t dest_len = strlen(dest); char *ret = strcat(dest, src); - dfsan_label *sdest = shadow_for(dest + dest_len); - const dfsan_label *ssrc = shadow_for(src); size_t src_len = strlen(src); dfsan_mem_origin_transfer(dest + dest_len, src, src_len); - internal_memcpy((void *)sdest, (const void *)ssrc, - src_len * sizeof(dfsan_label)); + dfsan_mem_shadow_transfer(dest + dest_len, src, src_len); *ret_label = dest_label; *ret_origin = dest_origin; return ret; @@ -1120,8 +1112,7 @@ dfsan_label src_label, dfsan_label *ret_label) { char *ret = strcpy(dest, src); if (ret) { - internal_memcpy(shadow_for(dest), shadow_for(src), - sizeof(dfsan_label) * (strlen(src) + 1)); + dfsan_mem_shadow_transfer(dest, src, strlen(src) + 1); } *ret_label = dst_label; return ret; @@ -1136,8 +1127,7 @@ if (ret) { size_t str_len = strlen(src) + 1; dfsan_mem_origin_transfer(dest, src, str_len); - internal_memcpy(shadow_for(dest), shadow_for(src), - sizeof(dfsan_label) * str_len); + dfsan_mem_shadow_transfer(dest, src, str_len); } *ret_label = dst_label; *ret_origin = dst_origin; @@ -2369,9 +2359,8 @@ formatter.num_written_bytes(retval)); } va_labels++; - internal_memcpy(shadow_for(formatter.str_cur()), shadow_for(arg), - sizeof(dfsan_label) * - formatter.num_written_bytes(retval)); + dfsan_mem_shadow_transfer(formatter.str_cur(), arg, + formatter.num_written_bytes(retval)); end_fmt = true; break; }