diff mbox

[ASan] Add new tests for string interceptors.

Message ID 5630817A.20402@partner.samsung.com
State New
Headers show

Commit Message

max Oct. 28, 2015, 8:04 a.m. UTC
Hi,

since the last libsanitizer merge happened, we have new string 
interceptors in libasan: strstr, strcasestr, strspn, strcspn and 
strpbrk. This patch migrates corresponding tests for them from LLVM. 
Also, asan_intercepted_p predicate is updated to handle corresponding 
builtin codes.

Regtested and bootstrapped on x86_64-unknown-linux-gnu, OK to apply?

-Maxim
diff mbox

Patch

gcc/ChangeLog:

2015-10-28  Maxim Ostapenko  <m.ostapenko@partner.samsung.com>

	* asan.h (asan_intercepted_p): Handle BUILT_IN_STRCSPN,
	BUILT_IN_STRPBRK, BUILT_IN_STRSPN and BUILT_IN_STRSTR.

gcc/testsuite/ChangeLog:

2015-10-28  Maxim Ostapenko  <m.ostapenko@partner.samsung.com>

	* c-c++-common/asan/strcasestr-1.c: New test.
	* c-c++-common/asan/strcasestr-2.c: Likewise.
	* c-c++-common/asan/strcspn-1.c: Likewise.
	* c-c++-common/asan/strcspn-2.c: Likewise.
	* c-c++-common/asan/strpbrk-1.c: Likewise.
	* c-c++-common/asan/strpbrk-2.c: Likewise.
	* c-c++-common/asan/strspn-1.c: Likewise.
	* c-c++-common/asan/strspn-2.c: Likewise.
	* c-c++-common/asan/strstr-1.c: Likewise.
	* c-c++-common/asan/strstr-2.c: Likewise.

Index: gcc/asan.h
===================================================================
--- gcc/asan.h	(revision 229169)
+++ gcc/asan.h	(working copy)
@@ -103,6 +103,10 @@ 
 	 || fcode == BUILT_IN_STRNCASECMP
 	 || fcode == BUILT_IN_STRNCAT
 	 || fcode == BUILT_IN_STRNCMP
+	 || fcode == BUILT_IN_STRCSPN
+	 || fcode == BUILT_IN_STRPBRK
+	 || fcode == BUILT_IN_STRSPN
+	 || fcode == BUILT_IN_STRSTR
 	 || fcode == BUILT_IN_STRNCPY;
 }
 #endif /* TREE_ASAN */
Index: gcc/testsuite/c-c++-common/asan/strcasestr-1.c
===================================================================
--- gcc/testsuite/c-c++-common/asan/strcasestr-1.c	(revision 0)
+++ gcc/testsuite/c-c++-common/asan/strcasestr-1.c	(working copy)
@@ -0,0 +1,29 @@ 
+/* { dg-do run } */
+/* { dg-set-target-env-var ASAN_OPTIONS "strict_string_checks=true" } */
+/* { dg-shouldfail "asan" } */
+
+#include <assert.h>
+#include <sanitizer/asan_interface.h>
+
+#ifndef __cplusplus
+#define _GNU_SOURCE
+#else
+extern "C"
+#endif
+char *
+strcasestr(const char *haystack, const char *needle);
+
+int main(int argc, char **argv) {
+  char *r = 0;
+  char s2[] = "c";
+  char s1[4] = "abC";
+  __asan_poison_memory_region ((char *)&s1[2], 2);
+  r = strcasestr(s1, s2);
+  assert(r == s1 + 2);
+  return 0;
+}
+
+/* { dg-output "READ of size 4 at .* thread T0.*" } */
+/* { dg-output ".*(main)?.*strcasestr-1.(c:21)?.*" } */
+/* { dg-output "is located in stack of thread T0 at offset.*" } */
+/* { dg-output "\'s1\' <== Memory access at offset \[0-9\]+ partially overflows this variable" } */
Index: gcc/testsuite/c-c++-common/asan/strcasestr-2.c
===================================================================
--- gcc/testsuite/c-c++-common/asan/strcasestr-2.c	(revision 0)
+++ gcc/testsuite/c-c++-common/asan/strcasestr-2.c	(working copy)
@@ -0,0 +1,30 @@ 
+/* { dg-do run } */
+/* { dg-set-target-env-var ASAN_OPTIONS "strict_string_checks=true" } */
+/* { dg-shouldfail "asan" } */
+
+#include <assert.h>
+#include <sanitizer/asan_interface.h>
+
+#ifndef __cplusplus
+#define _GNU_SOURCE
+#else
+extern "C"
+#endif
+char *
+strcasestr(const char *haystack, const char *needle);
+
+int main(int argc, char **argv) {
+  char *r = 0;
+  char s1[] = "ab";
+  char s2[4] = "cba";
+  __asan_poison_memory_region ((char *)&s2[2], 2);
+  r = strcasestr(s1, s2);
+  assert(r == 0);
+  return 0;
+}
+
+/* { dg-output "READ of size 4 at .* thread T0.*" } */
+/* { dg-output ".*(main)?.*strcasestr-2.(c:21)?.*" } */
+/* { dg-output "is located in stack of thread T0 at offset.*" } */
+/* { dg-output "\'s2\' <== Memory access at offset \[0-9\]+ partially overflows this variable" } */
Index: gcc/testsuite/c-c++-common/asan/strcspn-1.c
===================================================================
--- gcc/testsuite/c-c++-common/asan/strcspn-1.c	(revision 0)
+++ gcc/testsuite/c-c++-common/asan/strcspn-1.c	(working copy)
@@ -0,0 +1,26 @@ 
+/* { dg-do run } */
+/* { dg-set-target-env-var ASAN_OPTIONS "strict_string_checks=true" } */
+/* { dg-shouldfail "asan" } */
+
+#include <assert.h>
+#include <sanitizer/asan_interface.h>
+#ifdef __cplusplus
+extern "C"
+#endif
+__SIZE_TYPE__
+strcspn (const char *s, const char *reject);
+
+int main(int argc, char **argv) {
+  __SIZE_TYPE__ r;
+  char s2[] = "ab";
+  char s1[4] = "caB";
+  __asan_poison_memory_region ((char *)&s1[2], 2);
+  r = strcspn(s1, s2);
+  assert(r == 1);
+  return 0;
+}
+
+/* { dg-output "READ of size 4 at .* thread T0.*" } */
+/* { dg-output ".*(main)?.*strcspn-1.(c:18)?.*" } */
+/* { dg-output "is located in stack of thread T0 at offset.*" } */
+/* { dg-output "\'s1\' <== Memory access at offset \[0-9\]+ partially overflows this variable" } */
Index: gcc/testsuite/c-c++-common/asan/strcspn-2.c
===================================================================
--- gcc/testsuite/c-c++-common/asan/strcspn-2.c	(revision 0)
+++ gcc/testsuite/c-c++-common/asan/strcspn-2.c	(working copy)
@@ -0,0 +1,26 @@ 
+/* { dg-do run } */
+/* { dg-set-target-env-var ASAN_OPTIONS "strict_string_checks=true" } */
+/* { dg-shouldfail "asan" } */
+
+#include <assert.h>
+#include <sanitizer/asan_interface.h>
+#ifdef __cplusplus
+extern "C"
+#endif
+__SIZE_TYPE__
+strcspn (const char *s, const char *reject);
+
+int main(int argc, char **argv) {
+  __SIZE_TYPE__ r;
+  char s1[] = "ab";
+  char s2[4] = "abc";
+  __asan_poison_memory_region ((char *)&s2[2], 2);
+  r = strcspn(s1, s2);
+  assert(r == 0);
+  return 0;
+}
+
+/* { dg-output "READ of size 4 at .* thread T0.*" } */
+/* { dg-output ".*(main)?.*strcspn-2.(c:18)?.*" } */
+/* { dg-output "is located in stack of thread T0 at offset.*" } */
+/* { dg-output "\'s2\' <== Memory access at offset \[0-9\]+ partially overflows this variable" } */
Index: gcc/testsuite/c-c++-common/asan/strpbrk-1.c
===================================================================
--- gcc/testsuite/c-c++-common/asan/strpbrk-1.c	(revision 0)
+++ gcc/testsuite/c-c++-common/asan/strpbrk-1.c	(working copy)
@@ -0,0 +1,26 @@ 
+/* { dg-do run } */
+/* { dg-set-target-env-var ASAN_OPTIONS "strict_string_checks=true" } */
+/* { dg-shouldfail "asan" } */
+
+#include <assert.h>
+#include <sanitizer/asan_interface.h>
+#ifdef __cplusplus
+extern "C"
+#endif
+char *
+strpbrk(const char *s, const char *accept);
+
+int main(int argc, char **argv) {
+  char *r;
+  char s2[] = "ab";
+  char s1[4] = "cab";
+  __asan_poison_memory_region ((char *)&s1[2], 2);
+  r = strpbrk(s1, s2);
+  assert(r == s1 + 1);
+  return 0;
+}
+
+/* { dg-output "READ of size 4 at .* thread T0.*" } */
+/* { dg-output ".*(main)?.*strpbrk-1.(c:18)?.*" } */
+/* { dg-output "is located in stack of thread T0 at offset.*" } */
+/* { dg-output "\'s1\' <== Memory access at offset \[0-9\]+ partially overflows this variable" } */
Index: gcc/testsuite/c-c++-common/asan/strpbrk-2.c
===================================================================
--- gcc/testsuite/c-c++-common/asan/strpbrk-2.c	(revision 0)
+++ gcc/testsuite/c-c++-common/asan/strpbrk-2.c	(working copy)
@@ -0,0 +1,26 @@ 
+/* { dg-do run } */
+/* { dg-set-target-env-var ASAN_OPTIONS "strict_string_checks=true" } */
+/* { dg-shouldfail "asan" } */
+
+#include <assert.h>
+#include <sanitizer/asan_interface.h>
+#ifdef __cplusplus
+extern "C"
+#endif
+char *
+strpbrk(const char *s, const char *accept);
+
+int main(int argc, char **argv) {
+  char *r;
+  char s1[] = "c";
+  char s2[4] = "bca";
+  __asan_poison_memory_region ((char *)&s2[2], 2);
+  r = strpbrk(s1, s2);
+  assert(r == s1);
+  return 0;
+}
+
+/* { dg-output "READ of size 4 at .* thread T0.*" } */
+/* { dg-output ".*(main)?.*strpbrk-2.(c:18)?.*" } */
+/* { dg-output "is located in stack of thread T0 at offset.*" } */
+/* { dg-output "\'s2\' <== Memory access at offset \[0-9\]+ partially overflows this variable" } */
Index: gcc/testsuite/c-c++-common/asan/strspn-1.c
===================================================================
--- gcc/testsuite/c-c++-common/asan/strspn-1.c	(revision 0)
+++ gcc/testsuite/c-c++-common/asan/strspn-1.c	(working copy)
@@ -0,0 +1,26 @@ 
+/* { dg-do run } */
+/* { dg-set-target-env-var ASAN_OPTIONS "strict_string_checks=true" } */
+/* { dg-shouldfail "asan" } */
+
+#include <assert.h>
+#include <sanitizer/asan_interface.h>
+#ifdef __cplusplus
+extern "C"
+#endif
+__SIZE_TYPE__
+strspn (const char *s, const char *reject);
+
+int main(int argc, char **argv) {
+  __SIZE_TYPE__ r;
+  char s2[] = "ab";
+  char s1[4] = "acb";
+  __asan_poison_memory_region ((char *)&s1[2], 2);
+  r = strspn(s1, s2);
+  assert(r == 1);
+  return 0;
+}
+
+/* { dg-output "READ of size 4 at .* thread T0.*" } */
+/* { dg-output ".*(main)?.*strspn-1.(c:18)?.*" } */
+/* { dg-output "is located in stack of thread T0 at offset.*" } */
+/* { dg-output "\'s1\' <== Memory access at offset \[0-9\]+ partially overflows this variable" } */
Index: gcc/testsuite/c-c++-common/asan/strspn-2.c
===================================================================
--- gcc/testsuite/c-c++-common/asan/strspn-2.c	(revision 0)
+++ gcc/testsuite/c-c++-common/asan/strspn-2.c	(working copy)
@@ -0,0 +1,26 @@ 
+/* { dg-do run } */
+/* { dg-set-target-env-var ASAN_OPTIONS "strict_string_checks=true" } */
+/* { dg-shouldfail "asan" } */
+
+#include <assert.h>
+#include <sanitizer/asan_interface.h>
+#ifdef __cplusplus
+extern "C"
+#endif
+__SIZE_TYPE__
+strspn (const char *s, const char *reject);
+
+int main(int argc, char **argv) {
+  size_t r;
+  char s1[] = "bbc";
+  char s2[5] = "abcd";
+  __asan_poison_memory_region ((char *)&s2[3], 2);
+  r = strspn(s1, s2);
+  assert(r >= 2);
+  return 0;
+}
+
+/* { dg-output "READ of size 5 at .* thread T0.*" } */
+/* { dg-output ".*(main)?.*strspn-2.(c:18)?.*" } */
+/* { dg-output "is located in stack of thread T0 at offset.*" } */
+/* { dg-output "\'s2\' <== Memory access at offset \[0-9\]+ partially overflows this variable" } */
Index: gcc/testsuite/c-c++-common/asan/strstr-1.c
===================================================================
--- gcc/testsuite/c-c++-common/asan/strstr-1.c	(revision 0)
+++ gcc/testsuite/c-c++-common/asan/strstr-1.c	(working copy)
@@ -0,0 +1,27 @@ 
+/* { dg-do run } */
+/* { dg-set-target-env-var ASAN_OPTIONS "strict_string_checks=true" } */
+/* { dg-shouldfail "asan" } */
+
+#include <assert.h>
+#include <sanitizer/asan_interface.h>
+
+#ifdef __cplusplus
+extern "C"
+#endif
+char *
+strstr(const char *haystack, const char *needle);
+
+int main(int argc, char **argv) {
+  char *r = 0;
+  char s2[] = "c";
+  char s1[4] = "acb";
+  __asan_poison_memory_region ((char *)&s1[2], 2);
+  r = strstr(s1, s2);
+  assert(r == s1 + 1);
+  return 0;
+}
+
+/* { dg-output "READ of size 4 at .* thread T0.*" } */
+/* { dg-output ".*(main)?.*strstr-1.(c:19)?.*" } */
+/* { dg-output "is located in stack of thread T0 at offset.*" } */
+/* { dg-output "\'s1\' <== Memory access at offset \[0-9\]+ partially overflows this variable" } */
Index: gcc/testsuite/c-c++-common/asan/strstr-2.c
===================================================================
--- gcc/testsuite/c-c++-common/asan/strstr-2.c	(revision 0)
+++ gcc/testsuite/c-c++-common/asan/strstr-2.c	(working copy)
@@ -0,0 +1,27 @@ 
+/* { dg-do run } */
+/* { dg-set-target-env-var ASAN_OPTIONS "strict_string_checks=true" } */
+/* { dg-shouldfail "asan" } */
+
+#include <assert.h>
+#include <sanitizer/asan_interface.h>
+
+#ifdef __cplusplus
+extern "C"
+#endif
+char *
+strstr(const char *haystack, const char *needle);
+
+int main(int argc, char **argv) {
+  char *r = 0;
+  char s1[] = "ab";
+  char s2[4] = "cab";
+  __asan_poison_memory_region ((char *)&s2[2], 2);
+  r = strstr(s1, s2);
+  assert(r == 0);
+  return 0;
+}
+
+/* { dg-output "READ of size 4 at .* thread T0.*" } */
+/* { dg-output ".*(main)?.*strstr-2.(c:19)?.*" } */
+/* { dg-output "is located in stack of thread T0 at offset.*" } */
+/* { dg-output "\'s2\' <== Memory access at offset \[0-9\]+ partially overflows this variable" } */