[compiler-rt] r286708 - [asan] Fix strncmp and strncasecmp interceptors

Reid Kleckner via llvm-commits llvm-commits at lists.llvm.org
Mon Nov 14 09:46:59 PST 2016


Windows doesn't have strncasecmp. I have a hack to make the test pass, but
maybe it would be better to split the test into strncmp and strncasecmp and
XFAIL the strncasecmp one.

On Fri, Nov 11, 2016 at 8:32 PM, Vitaly Buka via llvm-commits <
llvm-commits at lists.llvm.org> wrote:

> Author: vitalybuka
> Date: Fri Nov 11 22:32:31 2016
> New Revision: 286708
>
> URL: http://llvm.org/viewvc/llvm-project?rev=286708&view=rev
> Log:
> [asan] Fix strncmp and strncasecmp interceptors
>
> Summary:
> In non-strict mode we will check memory access for both strings from
> beginning
> to either:
>   1. 0-char
>   2. size
>   3. different chars
>
> In strict mode we will check from beginning to either:
>   1. 0-char
>   2. size
>
> Previously in strict mode we always checked up to the 0-char.
>
> Reviewers: kcc, eugenis
>
> Subscribers: llvm-commits, kubabrecka
>
> Differential Revision: https://reviews.llvm.org/D26574
>
> Modified:
>     compiler-rt/trunk/lib/sanitizer_common/sanitizer_
> common_interceptors.inc
>     compiler-rt/trunk/test/asan/TestCases/strncmp_strict.c
>
> Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_
> common_interceptors.inc
> URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/
> sanitizer_common/sanitizer_common_interceptors.inc?rev=
> 286708&r1=286707&r2=286708&view=diff
> ============================================================
> ==================
> --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc
> (original)
> +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc
> Fri Nov 11 22:32:31 2016
> @@ -304,8 +304,14 @@ INTERCEPTOR(int, strncmp, const char *s1
>      c2 = (unsigned char)s2[i];
>      if (c1 != c2 || c1 == '\0') break;
>    }
> -  COMMON_INTERCEPTOR_READ_STRING(ctx, s1, Min(i + 1, size));
> -  COMMON_INTERCEPTOR_READ_STRING(ctx, s2, Min(i + 1, size));
> +  uptr i1 = i;
> +  uptr i2 = i;
> +  if (common_flags()->strict_string_checks) {
> +    for (; i1 < size && s1[i1]; i1++) {}
> +    for (; i2 < size && s2[i2]; i2++) {}
> +  }
> +  COMMON_INTERCEPTOR_READ_RANGE((ctx), (s1), Min(i1 + 1, size));
> +  COMMON_INTERCEPTOR_READ_RANGE((ctx), (s2), Min(i2 + 1, size));
>    int result = CharCmpX(c1, c2);
>    CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strncmp,
> GET_CALLER_PC(), s1,
>                               s2, size, result);
> @@ -348,24 +354,30 @@ INTERCEPTOR(int, strcasecmp, const char
>  }
>
>  DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strncasecmp, uptr
> called_pc,
> -                              const char *s1, const char *s2, uptr n,
> +                              const char *s1, const char *s2, uptr size,
>                                int result)
>
> -INTERCEPTOR(int, strncasecmp, const char *s1, const char *s2, SIZE_T n) {
> +INTERCEPTOR(int, strncasecmp, const char *s1, const char *s2, SIZE_T
> size) {
>    void *ctx;
> -  COMMON_INTERCEPTOR_ENTER(ctx, strncasecmp, s1, s2, n);
> +  COMMON_INTERCEPTOR_ENTER(ctx, strncasecmp, s1, s2, size);
>    unsigned char c1 = 0, c2 = 0;
>    uptr i;
> -  for (i = 0; i < n; i++) {
> +  for (i = 0; i < size; i++) {
>      c1 = (unsigned char)s1[i];
>      c2 = (unsigned char)s2[i];
>      if (CharCaseCmp(c1, c2) != 0 || c1 == '\0') break;
>    }
> -  COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, Min(i + 1, n));
> -  COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, Min(i + 1, n));
> +  uptr i1 = i;
> +  uptr i2 = i;
> +  if (common_flags()->strict_string_checks) {
> +    for (; i1 < size && s1[i1]; i1++) {}
> +    for (; i2 < size && s2[i2]; i2++) {}
> +  }
> +  COMMON_INTERCEPTOR_READ_RANGE((ctx), (s1), Min(i1 + 1, size));
> +  COMMON_INTERCEPTOR_READ_RANGE((ctx), (s2), Min(i2 + 1, size));
>    int result = CharCaseCmp(c1, c2);
>    CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strncasecmp,
> GET_CALLER_PC(),
> -                             s1, s2, n, result);
> +                             s1, s2, size, result);
>    return result;
>  }
>
>
> Modified: compiler-rt/trunk/test/asan/TestCases/strncmp_strict.c
> URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/
> test/asan/TestCases/strncmp_strict.c?rev=286708&r1=286707&
> r2=286708&view=diff
> ============================================================
> ==================
> --- compiler-rt/trunk/test/asan/TestCases/strncmp_strict.c (original)
> +++ compiler-rt/trunk/test/asan/TestCases/strncmp_strict.c Fri Nov 11
> 22:32:31 2016
> @@ -1,26 +1,81 @@
>  // Test strict_string_checks option in strncmp function
> -// RUN: %clang_asan %s -o %t && %run %t 2>&1
> -// RUN: %env_asan_opts=strict_string_checks=false %run %t 2>&1
> -// RUN: %env_asan_opts=strict_string_checks=true not %run %t 2>&1 |
> FileCheck %s
> +// RUN: %clang_asan %s -o %t
> +
> +// RUN: %env_asan_opts=strict_string_checks=false %run %t a 2>&1
> +// RUN: %env_asan_opts=strict_string_checks=true %run %t a 2>&1
> +// RUN: not %run %t b 2>&1 | FileCheck %s
> +// RUN: not %run %t c 2>&1 | FileCheck %s
> +// RUN: not %run %t d 2>&1 | FileCheck %s
> +// RUN: not %run %t e 2>&1 | FileCheck %s
> +// RUN: not %run %t f 2>&1 | FileCheck %s
> +// RUN: not %run %t g 2>&1 | FileCheck %s
> +// RUN: %env_asan_opts=strict_string_checks=false %run %t h 2>&1
> +// RUN: %env_asan_opts=strict_string_checks=true not %run %t h 2>&1 |
> FileCheck %s
> +// RUN: %env_asan_opts=strict_string_checks=false %run %t i 2>&1
> +// RUN: %env_asan_opts=strict_string_checks=true not %run %t i 2>&1 |
> FileCheck %s
> +
> +// RUN: %env_asan_opts=strict_string_checks=false %run %t A 2>&1
> +// RUN: %env_asan_opts=strict_string_checks=true %run %t A 2>&1
> +// RUN: not %run %t B 2>&1 | FileCheck %s
> +// RUN: not %run %t C 2>&1 | FileCheck %s
> +// RUN: not %run %t D 2>&1 | FileCheck %s
> +// RUN: not %run %t E 2>&1 | FileCheck %s
> +// RUN: not %run %t F 2>&1 | FileCheck %s
> +// RUN: not %run %t G 2>&1 | FileCheck %s
> +// RUN: %env_asan_opts=strict_string_checks=false %run %t H 2>&1
> +// RUN: %env_asan_opts=strict_string_checks=true not %run %t H 2>&1 |
> FileCheck %s
> +// RUN: %env_asan_opts=strict_string_checks=false %run %t I 2>&1
> +// RUN: %env_asan_opts=strict_string_checks=true not %run %t I 2>&1 |
> FileCheck %s
>
>  #include <assert.h>
>  #include <stdlib.h>
> +#include <stdio.h>
>  #include <string.h>
> +#include <ctype.h>
>
>  int main(int argc, char **argv) {
> -  size_t size = 100;
> +  assert(argc >= 2);
> +  const size_t size = 100;
>    char fill = 'o';
> -  char *s1 = (char*)malloc(size);
> +  char s1[size];
> +  char s2[size];
>    memset(s1, fill, size);
> -  char *s2 = (char*)malloc(size);
>    memset(s2, fill, size);
> -  s1[size - 1] = 'z';
> -  s2[size - 1] = 'x';
> -  int r = strncmp(s1, s2, size + 1);
> -  // CHECK: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}}
> -  // CHECK: READ of size 101
> -  assert(r == 1);
> -  free(s1);
> -  free(s2);
> +
> +  int (*cmp_fn)(const char *, const char *, size_t);
> +  cmp_fn = islower(argv[1][0]) ? &strncmp : &strncasecmp;
> +
> +  switch(tolower(argv[1][0])) {
> +    case 'a':
> +      s1[size - 1] = 'z';
> +      s2[size - 1] = 'x';
> +      for (int i = 0; i <= size; ++i)
> +        assert((cmp_fn(s1, s2, i) == 0) == (i < size));
> +      s1[size - 1] = '\0';
> +      s2[size - 1] = '\0';
> +      assert(cmp_fn(s1, s2, 2*size) == 0);
> +      break;
> +    case 'b':
> +      return cmp_fn(s1-1, s2, 1);
> +    case 'c':
> +      return cmp_fn(s1, s2-1, 1);
> +    case 'd':
> +      return cmp_fn(s1+size, s2, 1);
> +    case 'e':
> +      return cmp_fn(s1, s2+size, 1);
> +    case 'f':
> +      return cmp_fn(s1+1, s2, size);
> +    case 'g':
> +      return cmp_fn(s1, s2+1, size);
> +    case 'h':
> +      s1[size - 1] = '\0';
> +      assert(cmp_fn(s1, s2, 2*size) != 0);
> +      break;
> +    case 'i':
> +      s2[size - 1] = '\0';
> +      assert(cmp_fn(s1, s2, 2*size) != 0);
> +      break;
> +    // CHECK: {{.*}}ERROR: AddressSanitizer:
> stack-buffer-{{ov|und}}erflow on address
> +  }
>    return 0;
>  }
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20161114/ac013be2/attachment.html>


More information about the llvm-commits mailing list