<html>
<head>
<base href="https://bugs.llvm.org/">
</head>
<body><table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Bug ID</th>
<td><a class="bz_bug_link
bz_status_NEW "
title="NEW - __dfsw_strncasecmp is implemented incorrectly"
href="https://bugs.llvm.org/show_bug.cgi?id=38369">38369</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>__dfsw_strncasecmp is implemented incorrectly
</td>
</tr>
<tr>
<th>Product</th>
<td>compiler-rt
</td>
</tr>
<tr>
<th>Version</th>
<td>6.0
</td>
</tr>
<tr>
<th>Hardware</th>
<td>PC
</td>
</tr>
<tr>
<th>OS</th>
<td>Linux
</td>
</tr>
<tr>
<th>Status</th>
<td>NEW
</td>
</tr>
<tr>
<th>Severity</th>
<td>normal
</td>
</tr>
<tr>
<th>Priority</th>
<td>P
</td>
</tr>
<tr>
<th>Component</th>
<td>dfsan
</td>
</tr>
<tr>
<th>Assignee</th>
<td>unassignedbugs@nondot.org
</td>
</tr>
<tr>
<th>Reporter</th>
<td>huhong789@gmail.com
</td>
</tr>
<tr>
<th>CC</th>
<td>llvm-bugs@lists.llvm.org
</td>
</tr></table>
<p>
<div>
<pre>The implementation of __dfsw_strncasecmp in
compiler-rt/lib/dfsan/dfsan_custom.cc has a bug.
Here is the test code.
/* test.c */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main() {
char * s1 = "ABC";
char * s2 = "abc";
size_t n = 2;
if (strncasecmp(s1, s2, n)) {
printf("%s != %s for first %lu bytes\n", s1, s2, n);
} else {
printf("%s == %s for first %lu bytes\n", s1, s2, n);
}
return 0;
}
First compile with clang
$ clang test.c -o test-clang
$ ./test-clang
ABC == abc for first 2 bytes
Then compile with clang + dfsan
$ clang test.c -fsanitize=dataflow -o test-dfsan
$ ./test-dfsan
ABC != abc for first 2 bytes
The source code of __dfsw_strncasecmp is as follows:
200 SANITIZER_INTERFACE_ATTRIBUTE int
201 __dfsw_strncasecmp(const char *s1, const char *s2, size_t n,
202 dfsan_label s1_label, dfsan_label s2_label,
203 dfsan_label n_label, dfsan_label *ret_label) {
204 if (n == 0) {
205 *ret_label = 0;
206 return 0;
207 }
208
209 for (size_t i = 0;; ++i) {
210 if (tolower(s1[i]) != tolower(s2[i]) || s1[i] == 0 || s2[i] == 0 ||
211 i == n-1) {
212 if (flags().strict_data_dependencies) {
213 *ret_label = 0;
214 } else {
215 *ret_label = dfsan_union(dfsan_read_label(s1, i + 1),
216 dfsan_read_label(s2, i + 1));
217 }
218 return s1[i] - s2[i];
219 }
220 }
221 return 0;
222 }
When i == 1, condition in line 211 is matched. The execution finally reaches
line 218, which only compares s1[1] and s2[1], instead of tolower(s1[1])
tolower(s2[1]).
Possible fix:
Use tolower in line 218.</pre>
</div>
</p>
<hr>
<span>You are receiving this mail because:</span>
<ul>
<li>You are on the CC list for the bug.</li>
</ul>
</body>
</html>