Index: lib/dfsan/dfsan_custom.cc =================================================================== --- lib/dfsan/dfsan_custom.cc +++ lib/dfsan/dfsan_custom.cc @@ -70,7 +70,8 @@ if (flags().strict_data_dependencies) { *ret_label = s_label; } else { - *ret_label = dfsan_union(dfsan_read_label(s, i + 1), c_label); + *ret_label = dfsan_union(dfsan_read_label(s, i + 1), + dfsan_union(s_label, c_label)); } return s[i] == 0 ? 0 : const_cast(s+i); } @@ -258,7 +259,7 @@ dfsan_memcpy(s1, s2, n); } - *ret_label = 0; + *ret_label = s1_label; return s1; } @@ -720,4 +721,83 @@ *ret_label = 0; return ret; } + +SANITIZER_INTERFACE_ATTRIBUTE void *__dfsw_memchr(void *s, int c, size_t n, + dfsan_label s_label, + dfsan_label c_label, + dfsan_label n_label, + dfsan_label *ret_label) { + void *ret = memchr(s, c, n); + if (flags().strict_data_dependencies) { + *ret_label = ret ? s_label : 0; + } else { + size_t len = + ret ? reinterpret_cast(ret) - reinterpret_cast(s) + 1 + : n; + *ret_label = + dfsan_union(dfsan_read_label(s, len), dfsan_union(s_label, c_label)); + } + return ret; +} + +SANITIZER_INTERFACE_ATTRIBUTE char *__dfsw_strrchr(char *s, int c, + dfsan_label s_label, + dfsan_label c_label, + dfsan_label *ret_label) { + char *ret = strrchr(s, c); + if (flags().strict_data_dependencies) { + *ret_label = ret ? s_label : 0; + } else { + size_t len = ret ? ret - s + 1 : strlen(s) + 1; + *ret_label = + dfsan_union(dfsan_read_label(s, len), dfsan_union(s_label, c_label)); + } + + return ret; +} + +SANITIZER_INTERFACE_ATTRIBUTE char *__dfsw_strstr(char *haystack, char *needle, + dfsan_label haystack_label, + dfsan_label needle_label, + dfsan_label *ret_label) { + char *ret = strstr(haystack, needle); + if (flags().strict_data_dependencies) { + *ret_label = ret ? haystack_label : 0; + } else { + size_t len = ret ? ret + strlen(needle) - haystack : strlen(haystack) + 1; + *ret_label = + dfsan_union(dfsan_read_label(haystack, len), + dfsan_union(dfsan_read_label(needle, strlen(needle) + 1), + dfsan_union(haystack_label, needle_label))); + } + + return ret; +} + +SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_nanosleep(const struct timespec *req, + struct timespec *rem, + dfsan_label req_label, + dfsan_label rem_label, + dfsan_label *ret_label) { + int ret = nanosleep(req, rem); + *ret_label = 0; + if (ret == -1) { + // Interrupted by a signal, rem is filled with the remaining time. + dfsan_set_label(0, rem, sizeof(struct timespec)); + } + return ret; +} + +SANITIZER_INTERFACE_ATTRIBUTE int +__dfsw_socketpair(int domain, int type, int protocol, int sv[2], + dfsan_label domain_label, dfsan_label type_label, + dfsan_label protocol_label, dfsan_label sv_label, + dfsan_label *ret_label) { + int ret = socketpair(domain, type, protocol, sv); + *ret_label = 0; + if (ret == 0) { + dfsan_set_label(0, sv, sizeof(sv)); + } + return ret; +} } Index: lib/dfsan/done_abilist.txt =================================================================== --- lib/dfsan/done_abilist.txt +++ lib/dfsan/done_abilist.txt @@ -154,8 +154,10 @@ fun:gethostname=custom fun:getrlimit=custom fun:getrusage=custom +fun:nanosleep=custom fun:pread=custom fun:read=custom +fun:socketpair=custom fun:stat=custom fun:time=custom @@ -177,6 +179,7 @@ # Functions that produce an output that is computed from the input, but is not # necessarily data dependent. +fun:memchr=custom fun:memcmp=custom fun:strcasecmp=custom fun:strchr=custom @@ -184,6 +187,8 @@ fun:strlen=custom fun:strncasecmp=custom fun:strncmp=custom +fun:strrchr=custom +fun:strstr=custom # Functions that take a callback (wrap the callback manually). fun:dl_iterate_phdr=custom Index: lib/dfsan/lit_tests/custom.c =================================================================== --- lib/dfsan/lit_tests/custom.c +++ lib/dfsan/lit_tests/custom.c @@ -605,6 +605,107 @@ dl_iterate_phdr(dl_iterate_phdr_test_cb, (void *)3); } +void test_strrchr() { + char str1[] = "str1str1"; + dfsan_set_label(i_label, &str1[7], 1); + + char *rv = strrchr(str1, 'r'); + assert(rv == &str1[6]); + ASSERT_ZERO_LABEL(rv); + + rv = strrchr(str1, '1'); + assert(rv == &str1[7]); +#ifdef STRICT_DATA_DEPENDENCIES + ASSERT_ZERO_LABEL(rv); +#else + ASSERT_LABEL(rv, i_label); +#endif +} + +void test_strstr() { + char str1[] = "str1str1"; + dfsan_set_label(i_label, &str1[3], 1); + dfsan_set_label(j_label, &str1[5], 1); + + char *rv = strstr(str1, "1s"); + assert(rv == &str1[3]); +#ifdef STRICT_DATA_DEPENDENCIES + ASSERT_ZERO_LABEL(rv); +#else + ASSERT_LABEL(rv, i_label); +#endif + + rv = strstr(str1, "2s"); + assert(rv == NULL); +#ifdef STRICT_DATA_DEPENDENCIES + ASSERT_ZERO_LABEL(rv); +#else + ASSERT_LABEL(rv, i_j_label); +#endif +} + +void test_memchr() { + char str1[] = "str1"; + dfsan_set_label(i_label, &str1[3], 1); + dfsan_set_label(j_label, &str1[4], 1); + + char *crv = memchr(str1, 'r', sizeof(str1)); + assert(crv == &str1[2]); + ASSERT_ZERO_LABEL(crv); + + crv = memchr(str1, '1', sizeof(str1)); + assert(crv == &str1[3]); +#ifdef STRICT_DATA_DEPENDENCIES + ASSERT_ZERO_LABEL(crv); +#else + ASSERT_LABEL(crv, i_label); +#endif + + crv = memchr(str1, 'x', sizeof(str1)); + assert(!crv); +#ifdef STRICT_DATA_DEPENDENCIES + ASSERT_ZERO_LABEL(crv); +#else + ASSERT_LABEL(crv, i_j_label); +#endif +} + +void alarm_handler(int unused) { + ; +} + +void test_nanosleep() { + struct timespec req, rem; + req.tv_sec = 1; + req.tv_nsec = 0; + dfsan_set_label(i_label, &rem, sizeof(rem)); + + // non interrupted + int rv = nanosleep(&req, &rem); + assert(rv == 0); + ASSERT_ZERO_LABEL(rv); + ASSERT_READ_LABEL(&rem, 1, i_label); + + // interrupted by an alarm + signal(SIGALRM, alarm_handler); + req.tv_sec = 3; + alarm(1); + rv = nanosleep(&req, &rem); + assert(rv == -1); + ASSERT_ZERO_LABEL(rv); + ASSERT_READ_ZERO_LABEL(&rem, sizeof(rem)); +} + +void test_socketpair() { + int fd[2]; + + dfsan_set_label(i_label, fd, sizeof(fd)); + int rv = socketpair(PF_LOCAL, SOCK_STREAM, 0, fd); + assert(rv == 0); + ASSERT_ZERO_LABEL(rv); + ASSERT_READ_ZERO_LABEL(fd, sizeof(fd)); +} + int main(void) { i_label = dfsan_create_label("i", 0); j_label = dfsan_create_label("j", 0); @@ -612,47 +713,50 @@ test_calloc(); test_clock_gettime(); + test_ctime_r(); + test_dl_iterate_phdr(); test_dlopen(); + test_fgets(); test_fstat(); + test_get_current_dir_name(); + test_getcwd(); + test_gethostname(); + test_getpwuid_r(); + test_getrlimit(); + test_getrusage(); + test_gettimeofday(); + test_inet_pton(); + test_localtime_r(); + test_memchr(); test_memcmp(); test_memcpy(); test_memset(); + test_nanosleep(); + test_poll(); test_pread(); + test_pthread_create(); test_read(); + test_sched_getaffinity(); + test_select(); + test_sigaction(); + test_sigemptyset(); + test_socketpair(); test_stat(); test_strcasecmp(); test_strchr(); test_strcmp(); + test_strcpy(); test_strdup(); test_strlen(); test_strncasecmp(); test_strncmp(); test_strncpy(); - - test_ctime_r(); - test_fgets(); - test_getcwd(); - test_get_current_dir_name(); - test_gethostname(); - test_getrlimit(); - test_getrusage(); - test_strcpy(); + test_strrchr(); + test_strstr(); + test_strtod(); test_strtol(); test_strtoll(); - test_strtod(); test_strtoul(); test_strtoull(); test_time(); - test_inet_pton(); - test_localtime_r(); - test_getpwuid_r(); - test_poll(); - test_select(); - test_sched_getaffinity(); - test_sigemptyset(); - test_sigaction(); - test_gettimeofday(); - - test_pthread_create(); - test_dl_iterate_phdr(); }