<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On 21 October 2016 at 16:52, Kostya Serebryany via llvm-commits <span dir="ltr"><<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Author: kcc<br>
Date: Fri Oct 21 18:52:26 2016<br>
New Revision: 284901<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=284901&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project?rev=284901&view=rev</a><br>
Log:<br>
[sanitizers] support strict_string_checks for strncmp<br>
<br>
Added:<br>
    compiler-rt/trunk/test/asan/<wbr>TestCases/strncmp_strict.c<br>
Modified:<br>
    compiler-rt/trunk/lib/<wbr>sanitizer_common/sanitizer_<wbr>common_interceptors.inc<br>
<br>
Modified: compiler-rt/trunk/lib/<wbr>sanitizer_common/sanitizer_<wbr>common_interceptors.inc<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc?rev=284901&r1=284900&r2=284901&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/compiler-rt/trunk/lib/<wbr>sanitizer_common/sanitizer_<wbr>common_interceptors.inc?rev=<wbr>284901&r1=284900&r2=284901&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- compiler-rt/trunk/lib/<wbr>sanitizer_common/sanitizer_<wbr>common_interceptors.inc (original)<br>
+++ compiler-rt/trunk/lib/<wbr>sanitizer_common/sanitizer_<wbr>common_interceptors.inc Fri Oct 21 18:52:26 2016<br>
@@ -304,8 +304,8 @@ INTERCEPTOR(int, strncmp, const char *s1<br>
     c2 = (unsigned char)s2[i];<br>
     if (c1 != c2 || c1 == '\0') break;<br>
   }<br>
-  COMMON_INTERCEPTOR_READ_RANGE(<wbr>ctx, s1, Min(i + 1, size));<br>
-  COMMON_INTERCEPTOR_READ_RANGE(<wbr>ctx, s2, Min(i + 1, size));<br>
+  COMMON_INTERCEPTOR_READ_<wbr>STRING(ctx, s1, Min(i + 1, size));<br>
+  COMMON_INTERCEPTOR_READ_<wbr>STRING(ctx, s2, Min(i + 1, size));<br></blockquote><div><br></div><div>I think this change is wrong, but please double check my analysis. I think arguments to strncmp don't need to be NUL terminated like arguments to strcmp do.</div><div><br></div><div>C99 7.1.1 defines: "A string is a contiguous sequence of characters terminated by and including the first null character." Then strcmp is defined as a function which "compares the strings" in 7.21.4.2 while strncmp is defined to operate over two "possibly null-terminated array"s in 7.21.4.4. The bug manifests in COMMON_INTERCEPTOR_READ_STRING calling REAL(strlen) on these arguments which aren't guaranteed to be NUL terminated.</div><div><br></div><div>What do you think?</div><div><br></div><div>Nick</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
   int result = CharCmpX(c1, c2);<br>
   CALL_WEAK_INTERCEPTOR_HOOK(__<wbr>sanitizer_weak_hook_strncmp, GET_CALLER_PC(), s1,<br>
                              s2, size, result);<br>
<br>
Added: compiler-rt/trunk/test/asan/<wbr>TestCases/strncmp_strict.c<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/TestCases/strncmp_strict.c?rev=284901&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/compiler-rt/trunk/<wbr>test/asan/TestCases/strncmp_<wbr>strict.c?rev=284901&view=auto</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- compiler-rt/trunk/test/asan/<wbr>TestCases/strncmp_strict.c (added)<br>
+++ compiler-rt/trunk/test/asan/<wbr>TestCases/strncmp_strict.c Fri Oct 21 18:52:26 2016<br>
@@ -0,0 +1,26 @@<br>
+// Test strict_string_checks option in strncmp function<br>
+// RUN: %clang_asan %s -o %t && %run %t 2>&1<br>
+// RUN: %env_asan_opts=strict_string_<wbr>checks=false %run %t 2>&1<br>
+// RUN: %env_asan_opts=strict_string_<wbr>checks=true not %run %t 2>&1 | FileCheck %s<br>
+<br>
+#include <assert.h><br>
+#include <stdlib.h><br>
+#include <string.h><br>
+<br>
+int main(int argc, char **argv) {<br>
+  size_t size = 100;<br>
+  char fill = 'o';<br>
+  char *s1 = (char*)malloc(size);<br>
+  memset(s1, fill, size);<br>
+  char *s2 = (char*)malloc(size);<br>
+  memset(s2, fill, size);<br>
+  s1[size - 1] = 'z';<br>
+  s2[size - 1] = 'x';<br>
+  int r = strncmp(s1, s2, size + 1);<br>
+  // CHECK: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}}<br>
+  // CHECK: READ of size 101<br>
+  assert(r == 1);<br>
+  free(s1);<br>
+  free(s2);<br>
+  return 0;<br>
+}<br>
<br>
<br>
______________________________<wbr>_________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div></div>