Index: compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc =================================================================== --- compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc +++ compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc @@ -588,6 +588,9 @@ const char *s1, const char *s2, char *result) INTERCEPTOR(char*, strstr, const char *s1, const char *s2) { + // Handling empty NEEDLE special case. + if (s2[0] == '\0') + return (char *)s1; if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) return internal_strstr(s1, s2); void *ctx; Index: compiler-rt/lib/sanitizer_common/sanitizer_libc.cpp =================================================================== --- compiler-rt/lib/sanitizer_common/sanitizer_libc.cpp +++ compiler-rt/lib/sanitizer_common/sanitizer_libc.cpp @@ -217,6 +217,9 @@ char *internal_strstr(const char *haystack, const char *needle) { // This is O(N^2), but we are not using it in hot places. + //Handling empty needle special case + if (needle[0] == '\0') + return (char *)haystack; uptr len1 = internal_strlen(haystack); uptr len2 = internal_strlen(needle); if (len1 < len2) return nullptr; Index: compiler-rt/test/sanitizer_common/TestCases/strstr.c =================================================================== --- compiler-rt/test/sanitizer_common/TestCases/strstr.c +++ compiler-rt/test/sanitizer_common/TestCases/strstr.c @@ -1,4 +1,5 @@ // RUN: %clang %s -o %t && %run %t 2>&1 +// RUN: %clang %s -g -fsanitize=thread -o %t && %run %t 2>&1 #include #include @@ -8,5 +9,9 @@ char s2[] = "b"; r = strstr(s1, s2); assert(r == s1 + 1); + char *s3 = NULL; + char *s4 = ""; + char *p = strstr(s3, s4); + assert(p == NULL); return 0; }