diff --git a/clang/docs/AddressSanitizer.rst b/clang/docs/AddressSanitizer.rst index 6c1cb2865329..c11d470d1def 100644 --- a/clang/docs/AddressSanitizer.rst +++ b/clang/docs/AddressSanitizer.rst @@ -269,37 +269,40 @@ Interaction of Inlining with Disabling Sanitizer Instrumentation #define ALWAYS_INLINE_IF_UNINSTRUMENTED __attribute__((always_inline)) #endif -Conditional Sanitizer Checks with ``__builtin_allow_sanitize_check`` --------------------------------------------------------------------- +Explicit Sanitizer Checks with ``__builtin_allow_sanitize_check`` +----------------------------------------------------------------- The ``__builtin_allow_sanitize_check("address")`` builtin can be used to -conditionally execute code only when AddressSanitizer is active for the current -function (after inlining). This is particularly useful for inserting explicit, -sanitizer-specific checks around operations like syscalls or inline assembly, -which might otherwise be unchecked by the sanitizer. +conditionally execute code depending on whether AddressSanitizer checks are +enabled and permitted by the current policy (after inlining). This is +particularly useful for inserting explicit, sanitizer-specific checks around +operations like syscalls or inline assembly, which might otherwise be unchecked +by the sanitizer. Example: .. code-block:: c + void __asan_load8(void *); + inline __attribute__((always_inline)) - void copy_to_device(void *addr, size_t size) { - if (__builtin_allow_sanitize_check("address")) { - // Custom checks that address range is valid. - } - // ... actual device memory copy logic, potentially a syscall ... + void my_helper(void *addr) { + if (__builtin_allow_sanitize_check("address")) + __asan_load8(addr); + // ... actual logic, e.g. inline assembly ... + asm volatile ("..." : : "r" (addr) : "memory"); } void instrumented_function() { ... - copy_to_device(buf, sizeof(buf)); // checks are active + my_helper(buf); // checks are active ... } __attribute__((no_sanitize("address"))) void uninstrumented_function() { ... - copy_to_device(buf, sizeof(buf)); // checks are skipped + my_helper(buf); // checks are skipped ... } diff --git a/clang/docs/MemorySanitizer.rst b/clang/docs/MemorySanitizer.rst index 0ebfed78abba..f69eeb40ef21 100644 --- a/clang/docs/MemorySanitizer.rst +++ b/clang/docs/MemorySanitizer.rst @@ -117,37 +117,40 @@ Interaction of Inlining with Disabling Sanitizer Instrumentation #define ALWAYS_INLINE_IF_UNINSTRUMENTED __attribute__((always_inline)) #endif -Conditional Sanitizer Checks with ``__builtin_allow_sanitize_check`` --------------------------------------------------------------------- +Explicit Sanitizer Checks with ``__builtin_allow_sanitize_check`` +----------------------------------------------------------------- The ``__builtin_allow_sanitize_check("memory")`` builtin can be used to -conditionally execute code only when MemorySanitizer is active for the current -function (after inlining). This is particularly useful for inserting explicit, -sanitizer-specific checks around operations like syscalls or inline assembly, -which might otherwise be unchecked by the sanitizer. +conditionally execute code depending on whether MemorySanitizer checks are +enabled and permitted by the current policy (after inlining). This is +particularly useful for inserting explicit, sanitizer-specific checks around +operations like syscalls or inline assembly, which might otherwise be unchecked +by the sanitizer. Example: .. code-block:: c + void __msan_check_mem_is_initialized(const void *, size_t); + inline __attribute__((always_inline)) - void copy_to_device(void *addr, size_t size) { - if (__builtin_allow_sanitize_check("memory")) { - // Custom checks if `data` is initialized. - } - // ... actual device memory copy logic, potentially a syscall ... + void my_send(void *addr, size_t size) { + if (__builtin_allow_sanitize_check("memory")) + __msan_check_mem_is_initialized(addr, size); + // ... syscall or other logic where MSan may not see the access ... + send(addr, size); } void instrumented_function() { ... - copy_to_device(buf, sizeof(buf)); // checks are active + my_send(buf, sizeof(buf)); // checks are active ... } __attribute__((no_sanitize("memory"))) void uninstrumented_function() { ... - copy_to_device(buf, sizeof(buf)); // checks are skipped + my_send(buf, sizeof(buf)); // checks are skipped ... } diff --git a/clang/docs/ThreadSanitizer.rst b/clang/docs/ThreadSanitizer.rst index 06c0cdbdd7e8..86dc2600626b 100644 --- a/clang/docs/ThreadSanitizer.rst +++ b/clang/docs/ThreadSanitizer.rst @@ -126,37 +126,40 @@ Interaction of Inlining with Disabling Sanitizer Instrumentation #define ALWAYS_INLINE_IF_UNINSTRUMENTED __attribute__((always_inline)) #endif -Conditional Sanitizer Checks with ``__builtin_allow_sanitize_check`` --------------------------------------------------------------------- +Explicit Sanitizer Checks with ``__builtin_allow_sanitize_check`` +----------------------------------------------------------------- The ``__builtin_allow_sanitize_check("thread")`` builtin can be used to -conditionally execute code only when ThreadSanitizer is active for the current -function (after inlining). This is particularly useful for inserting explicit, -sanitizer-specific checks around operations like syscalls or inline assembly, -which might otherwise be unchecked by the sanitizer. +conditionally execute code depending on whether ThreadSanitizer checks are +enabled and permitted by the current policy (after inlining). This is +particularly useful for inserting explicit, sanitizer-specific checks around +operations like syscalls or inline assembly, which might otherwise be unchecked +by the sanitizer. Example: .. code-block:: c + void __tsan_read8(void *); + inline __attribute__((always_inline)) - void copy_to_device(void *addr, size_t size) { - if (__builtin_allow_sanitize_check("thread")) { - // Custom checks that `data` is not concurrently modified. - } - // ... actual device memory copy logic, potentially a syscall ... + void my_helper(void *addr) { + if (__builtin_allow_sanitize_check("thread")) + __tsan_read8(addr); + // ... actual logic, e.g. inline assembly ... + asm volatile ("..." : : "r" (addr) : "memory"); } void instrumented_function() { ... - copy_to_device(&shared_data, size); // checks are active + my_helper(&shared_data); // checks are active ... } __attribute__((no_sanitize("thread"))) void uninstrumented_function() { ... - copy_to_device(&shared_data, size); // checks are skipped + my_helper(&shared_data); // checks are skipped ... }