Skip to content

Commit 5f0f497

Browse files
authored
[libc] Unify and extend no_sanitize attributes for strlen. (#161316)
Fast strlen implementations (naive wide-reads, SIMD-based, and x86_64/aarch64-optimized versions) all may perform technically-out-of-bound reads, which leads to reports under ASan, HWASan (on ARM machines), and also TSan (which also has the capability to detect heap out-of-bound reads). So, we need to explicitly disable instrumentation in all three cases. Tragically, Clang didn't support `[[gnu::no_sanitize]]` syntax until recently, and since we're supporting both GCC and Clang, we have to revert to `__attribute__` syntax.
1 parent ed1d954 commit 5f0f497

File tree

7 files changed

+18
-6
lines changed

7 files changed

+18
-6
lines changed

libc/src/__support/macros/attributes.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,4 +81,14 @@ LIBC_THREAD_MODE_EXTERNAL.
8181
#define LIBC_HAS_VECTOR_TYPE 0
8282
#endif
8383

84+
#if __has_attribute(no_sanitize)
85+
// Disable regular and hardware-supported ASan for functions that may
86+
// intentionally make out-of-bounds access. Disable TSan as well, as it detects
87+
// out-of-bounds accesses to heap memory.
88+
#define LIBC_NO_SANITIZE_OOB_ACCESS \
89+
__attribute__((no_sanitize("address", "hwaddress", "thread")))
90+
#else
91+
#define LIBC_NO_SANITIZE_OOB_ACCESS
92+
#endif
93+
8494
#endif // LLVM_LIBC_SRC___SUPPORT_MACROS_ATTRIBUTES_H

libc/src/string/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ add_header_library(
2222
libc.src.__support.CPP.type_traits
2323
libc.src.__support.CPP.simd
2424
libc.src.__support.common
25+
libc.src.__support.macros.attributes
2526
libc.src.string.memory_utils.inline_memcpy
2627
${string_config_options}
2728
)

libc/src/string/memory_utils/aarch64/inline_strlen.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
namespace LIBC_NAMESPACE_DECL {
1818

1919
namespace neon {
20-
[[gnu::no_sanitize_address]] [[maybe_unused]] LIBC_INLINE static size_t
20+
[[maybe_unused]] LIBC_NO_SANITIZE_OOB_ACCESS LIBC_INLINE static size_t
2121
string_length(const char *src) {
2222
using Vector __attribute__((may_alias)) = uint8x8_t;
2323

libc/src/string/memory_utils/generic/inline_strlen.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,7 @@ LIBC_INLINE constexpr cpp::simd_mask<char> shift_mask(cpp::simd_mask<char> m,
2424
return cpp::bit_cast<cpp::simd_mask<char>>(r);
2525
}
2626

27-
[[clang::no_sanitize("address")]] LIBC_INLINE size_t
28-
string_length(const char *src) {
27+
LIBC_NO_SANITIZE_OOB_ACCESS LIBC_INLINE size_t string_length(const char *src) {
2928
constexpr cpp::simd<char> null_byte = cpp::splat('\0');
3029

3130
size_t alignment = alignof(cpp::simd<char>);

libc/src/string/memory_utils/x86_64/inline_strlen.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,12 @@ namespace LIBC_NAMESPACE_DECL {
1818
namespace string_length_internal {
1919
// Return a bit-mask with the nth bit set if the nth-byte in block_ptr is zero.
2020
template <typename Vector, typename Mask>
21-
[[gnu::no_sanitize_address]] LIBC_INLINE static Mask
21+
LIBC_NO_SANITIZE_OOB_ACCESS LIBC_INLINE static Mask
2222
compare_and_mask(const Vector *block_ptr);
2323

2424
template <typename Vector, typename Mask,
2525
decltype(compare_and_mask<Vector, Mask>)>
26-
[[gnu::no_sanitize_address]] LIBC_INLINE static size_t
26+
LIBC_NO_SANITIZE_OOB_ACCESS LIBC_INLINE static size_t
2727
string_length_vector(const char *src) {
2828
uintptr_t misalign_bytes = reinterpret_cast<uintptr_t>(src) % sizeof(Vector);
2929

libc/src/string/string_utils.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "hdr/types/size_t.h"
2020
#include "src/__support/CPP/bitset.h"
2121
#include "src/__support/CPP/type_traits.h" // cpp::is_same_v
22+
#include "src/__support/macros/attributes.h"
2223
#include "src/__support/macros/config.h"
2324
#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
2425
#include "src/string/memory_utils/inline_memcpy.h"
@@ -119,7 +120,7 @@ template <typename T> LIBC_INLINE size_t string_length(const T *src) {
119120
}
120121

121122
template <typename Word>
122-
[[gnu::no_sanitize_address]] LIBC_INLINE void *
123+
LIBC_NO_SANITIZE_OOB_ACCESS LIBC_INLINE void *
123124
find_first_character_wide_read(const unsigned char *src, unsigned char ch,
124125
size_t n) {
125126
const unsigned char *char_ptr = src;

utils/bazel/llvm-project-overlay/libc/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5336,6 +5336,7 @@ libc_support_library(
53365336
":__support_common",
53375337
":__support_cpp_bitset",
53385338
":__support_cpp_type_traits",
5339+
":__support_macros_attributes",
53395340
":__support_macros_optimization",
53405341
":hdr_limits_macros",
53415342
":llvm_libc_types_size_t",

0 commit comments

Comments
 (0)