Skip to content

Commit 5becf54

Browse files
tkuchtabrowneee
authored andcommitted
[DFSAN] Add support for strnlen
This patch adds a support for the libc strnlen() function in DFSAN Reviewed by: browneee Differential Revision: https://reviews.llvm.org/D149459
1 parent aa6cb0f commit 5becf54

File tree

3 files changed

+60
-0
lines changed

3 files changed

+60
-0
lines changed

compiler-rt/lib/dfsan/dfsan_custom.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -535,6 +535,36 @@ SANITIZER_INTERFACE_ATTRIBUTE size_t __dfso_strlen(const char *s,
535535
return ret;
536536
}
537537

538+
SANITIZER_INTERFACE_ATTRIBUTE size_t __dfsw_strnlen(const char *s,
539+
size_t maxlen,
540+
dfsan_label s_label,
541+
dfsan_label maxlen_label,
542+
dfsan_label *ret_label) {
543+
size_t ret = strnlen(s, maxlen);
544+
if (flags().strict_data_dependencies) {
545+
*ret_label = 0;
546+
} else {
547+
size_t full_len = strlen(s);
548+
size_t covered_len = maxlen > (full_len + 1) ? (full_len + 1) : maxlen;
549+
*ret_label = dfsan_union(maxlen_label, dfsan_read_label(s, covered_len));
550+
}
551+
return ret;
552+
}
553+
554+
SANITIZER_INTERFACE_ATTRIBUTE size_t __dfso_strnlen(
555+
const char *s, size_t maxlen, dfsan_label s_label, dfsan_label maxlen_label,
556+
dfsan_label *ret_label, dfsan_origin s_origin, dfsan_origin maxlen_origin,
557+
dfsan_origin *ret_origin) {
558+
size_t ret = __dfsw_strnlen(s, maxlen, s_label, maxlen_label, ret_label);
559+
if (!flags().strict_data_dependencies) {
560+
size_t full_len = strlen(s);
561+
size_t covered_len = maxlen > (full_len + 1) ? (full_len + 1) : maxlen;
562+
dfsan_origin o = dfsan_read_origin_of_first_taint(s, covered_len);
563+
*ret_origin = o ? o : maxlen_origin;
564+
}
565+
return ret;
566+
}
567+
538568
static void *dfsan_memmove(void *dest, const void *src, size_t n) {
539569
dfsan_label *sdest = shadow_for(dest);
540570
const dfsan_label *ssrc = shadow_for(src);

compiler-rt/lib/dfsan/done_abilist.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,7 @@ fun:strcasecmp=custom
278278
fun:strchr=custom
279279
fun:strcmp=custom
280280
fun:strlen=custom
281+
fun:strnlen=custom
281282
fun:strncasecmp=custom
282283
fun:strncmp=custom
283284
fun:strpbrk=custom

compiler-rt/test/dfsan/custom.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,34 @@ void test_strlen() {
381381
#endif
382382
}
383383

384+
void test_strnlen() {
385+
char str1[] = "str1";
386+
dfsan_set_label(i_label, &str1[3], 1);
387+
388+
int maxlen = 4;
389+
dfsan_set_label(j_label, &maxlen, sizeof(maxlen));
390+
391+
int rv = strnlen(str1, maxlen);
392+
assert(rv == 4);
393+
#ifdef STRICT_DATA_DEPENDENCIES
394+
ASSERT_ZERO_LABEL(rv);
395+
#else
396+
ASSERT_LABEL(rv, dfsan_union(i_label, j_label));
397+
ASSERT_EQ_ORIGIN(rv, str1[3]);
398+
#endif
399+
400+
maxlen = 2;
401+
dfsan_set_label(j_label, &maxlen, sizeof(maxlen));
402+
rv = strnlen(str1, maxlen);
403+
assert(rv == 2);
404+
#ifdef STRICT_DATA_DEPENDENCIES
405+
ASSERT_ZERO_LABEL(rv);
406+
#else
407+
ASSERT_LABEL(rv, j_label);
408+
ASSERT_EQ_ORIGIN(rv, maxlen);
409+
#endif
410+
}
411+
384412
void test_strdup() {
385413
char str1[] = "str1";
386414
dfsan_set_label(i_label, &str1[3], 1);
@@ -2085,6 +2113,7 @@ int main(void) {
20852113
test_strcpy();
20862114
test_strdup();
20872115
test_strlen();
2116+
test_strnlen();
20882117
test_strncasecmp();
20892118
test_strncmp();
20902119
test_strncpy();

0 commit comments

Comments
 (0)