104 lines · c
1// RUN: %clang_asan %s -o %t2 3// Test overflows with strict_string_checks4 5// RUN: %env_asan_opts=strict_string_checks=true not %run %t test1 2>&1 | \6// RUN: FileCheck %s --check-prefix=CHECK17// RUN: %env_asan_opts=intercept_strtok=false %run %t test1 2>&18// RUN: %env_asan_opts=strict_string_checks=true not %run %t test2 2>&1 | \9// RUN: FileCheck %s --check-prefix=CHECK210// RUN: %env_asan_opts=intercept_strtok=false %run %t test2 2>&111// RUN: %env_asan_opts=strict_string_checks=true not %run %t test3 2>&1 | \12// RUN: FileCheck %s --check-prefix=CHECK313// RUN: %env_asan_opts=intercept_strtok=false %run %t test3 2>&114// RUN: %env_asan_opts=strict_string_checks=true %run %t test4 2>&115// RUN: %env_asan_opts=intercept_strtok=false %run %t test4 2>&116 17// Test overflows with !strict_string_checks18// RUN: %env_asan_opts=strict_string_checks=false not %run %t test5 2>&1 | \19// RUN: FileCheck %s --check-prefix=CHECK520// RUN: %env_asan_opts=intercept_strtok=false %run %t test5 2>&121// RUN: %env_asan_opts=strict_string_checks=false not %run %t test6 2>&1 | \22// RUN: FileCheck %s --check-prefix=CHECK623// RUN: %env_asan_opts=intercept_strtok=false %run %t test6 2>&124 25 26#include <assert.h>27#include <string.h>28#include <sanitizer/asan_interface.h>29 30// Check that we find overflows in the delimiters on the first call31// with strict_string_checks.32void test1() {33 char *token;34 char s[4] = "abc";35 char token_delimiter[2] = "b";36 __asan_poison_memory_region ((char *)&token_delimiter[1], 2);37 token = strtok(s, token_delimiter);38 // CHECK1: 'token_delimiter'{{.*}} <== Memory access at offset {{[0-9]+}} partially overflows this variable39}40 41// Check that we find overflows in the delimiters on the second call (str == NULL)42// with strict_string_checks.43void test2() {44 char *token;45 char s[4] = "abc";46 char token_delimiter[2] = "b";47 token = strtok(s, token_delimiter);48 assert(strcmp(token, "a") == 0);49 __asan_poison_memory_region ((char *)&token_delimiter[1], 2);50 token = strtok(NULL, token_delimiter);51 // CHECK2: 'token_delimiter'{{.*}} <== Memory access at offset {{[0-9]+}} partially overflows this variable52}53 54// Check that we find overflows in the string (only on the first call) with strict_string_checks.55void test3() {56 char *token;57 char s[4] = "abc";58 char token_delimiter[2] = "b";59 __asan_poison_memory_region ((char *)&s[3], 2);60 token = strtok(s, token_delimiter);61 // CHECK3: 's'{{.*}} <== Memory access at offset {{[0-9]+}} partially overflows this variable62}63 64// Check that we do not crash when strtok returns NULL with strict_string_checks.65void test4() {66 char *token;67 char s[] = "";68 char token_delimiter[] = "a";69 token = strtok(s, token_delimiter);70 assert(token == NULL);71}72 73// Check that we find overflows in the string (only on the first call) with !strict_string_checks.74void test5() {75 char *token;76 char s[4] = "abc";77 char token_delimiter[2] = "d";78 __asan_poison_memory_region ((char *)&s[2], 2);79 __asan_poison_memory_region ((char *)&token_delimiter[1], 2);80 token = strtok(s, token_delimiter);81 // CHECK5: 's'{{.*}} <== Memory access at offset {{[0-9]+}} partially overflows this variable82}83 84// Check that we find overflows in the delimiters (only on the first call) with !strict_string_checks.85void test6() {86 char *token;87 char s[4] = "abc";88 char token_delimiter[1] = {'d'};89 __asan_poison_memory_region ((char *)&token_delimiter[1], 2);90 token = strtok(s, &token_delimiter[1]);91 // CHECK6: 'token_delimiter'{{.*}} <== Memory access at offset {{[0-9]+}} overflows this variable92}93 94int main(int argc, char **argv) {95 if (argc != 2) return 1;96 if (!strcmp(argv[1], "test1")) test1();97 if (!strcmp(argv[1], "test2")) test2();98 if (!strcmp(argv[1], "test3")) test3();99 if (!strcmp(argv[1], "test4")) test4();100 if (!strcmp(argv[1], "test5")) test5();101 if (!strcmp(argv[1], "test6")) test6();102 return 0;103}104