From 4950695eba6dc1b50f0f9c8359b4e74317d7dff4 Mon Sep 17 00:00:00 2001 From: Jianzhou Zhao Date: Fri, 19 Mar 2021 17:25:42 +0000 Subject: [PATCH] [dfsan] Add Origin ABI Wrappers Supported ctime_r, fgets, getcwd, get_current_dir_name, gethostname, getrlimit, getrusage, strcpy, time, inet_pton, localtime_r, getpwuid_r, epoll_wait, poll, select, sched_getaffinity Most of them work as calling their non-origin verision directly. This is a part of https://reviews.llvm.org/D95835. Reviewed By: morehouse Differential Revision: https://reviews.llvm.org/D98966 --- compiler-rt/lib/dfsan/dfsan_custom.cpp | 202 ++++++++++++++++++++++++++++++--- compiler-rt/test/dfsan/custom.cpp | 132 ++++++++++++++++----- 2 files changed, 291 insertions(+), 43 deletions(-) diff --git a/compiler-rt/lib/dfsan/dfsan_custom.cpp b/compiler-rt/lib/dfsan/dfsan_custom.cpp index 604dd5d..8c3af25 100644 --- a/compiler-rt/lib/dfsan/dfsan_custom.cpp +++ b/compiler-rt/lib/dfsan/dfsan_custom.cpp @@ -644,7 +644,6 @@ SANITIZER_INTERFACE_ATTRIBUTE char *__dfso_strdup(const char *s, void *p = malloc(len + 1); dfsan_memcpy_with_origin(p, s, len + 1); *ret_label = 0; - *ret_origin = 0; return static_cast(p); } @@ -700,9 +699,8 @@ SANITIZER_INTERFACE_ATTRIBUTE ssize_t __dfso_pread( dfsan_label *ret_label, dfsan_origin fd_origin, dfsan_origin buf_origin, dfsan_origin count_origin, dfsan_label offset_origin, dfsan_origin *ret_origin) { - ssize_t ret = __dfsw_pread(fd, buf, count, offset, fd_label, buf_label, - count_label, offset_label, ret_label); - return ret; + return __dfsw_pread(fd, buf, count, offset, fd_label, buf_label, count_label, + offset_label, ret_label); } SANITIZER_INTERFACE_ATTRIBUTE ssize_t @@ -722,9 +720,8 @@ SANITIZER_INTERFACE_ATTRIBUTE ssize_t __dfso_read( dfsan_label buf_label, dfsan_label count_label, dfsan_label *ret_label, dfsan_origin fd_origin, dfsan_origin buf_origin, dfsan_origin count_origin, dfsan_origin *ret_origin) { - ssize_t ret = - __dfsw_read(fd, buf, count, fd_label, buf_label, count_label, ret_label); - return ret; + return __dfsw_read(fd, buf, count, fd_label, buf_label, count_label, + ret_label); } SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_clock_gettime(clockid_t clk_id, @@ -743,8 +740,7 @@ SANITIZER_INTERFACE_ATTRIBUTE int __dfso_clock_gettime( clockid_t clk_id, struct timespec *tp, dfsan_label clk_id_label, dfsan_label tp_label, dfsan_label *ret_label, dfsan_origin clk_id_origin, dfsan_origin tp_origin, dfsan_origin *ret_origin) { - int ret = __dfsw_clock_gettime(clk_id, tp, clk_id_label, tp_label, ret_label); - return ret; + return __dfsw_clock_gettime(clk_id, tp, clk_id_label, tp_label, ret_label); } static void dfsan_set_zero_label(const void *ptr, uptr size) { @@ -770,9 +766,7 @@ SANITIZER_INTERFACE_ATTRIBUTE void *__dfso_dlopen( dfsan_label flag_label, dfsan_label *ret_label, dfsan_origin filename_origin, dfsan_origin flag_origin, dfsan_origin *ret_origin) { - void *handle = - __dfsw_dlopen(filename, flag, filename_label, flag_label, ret_label); - return handle; + return __dfsw_dlopen(filename, flag, filename_label, flag_label, ret_label); } static void *DFsanThreadStartFunc(void *arg) { @@ -965,6 +959,25 @@ char *__dfsw_ctime_r(const time_t *timep, char *buf, dfsan_label timep_label, } SANITIZER_INTERFACE_ATTRIBUTE +char *__dfso_ctime_r(const time_t *timep, char *buf, dfsan_label timep_label, + dfsan_label buf_label, dfsan_label *ret_label, + dfsan_origin timep_origin, dfsan_origin buf_origin, + dfsan_origin *ret_origin) { + char *ret = ctime_r(timep, buf); + if (ret) { + dfsan_set_label_origin( + dfsan_read_label(timep, sizeof(time_t)), + dfsan_read_origin_of_first_taint(timep, sizeof(time_t)), buf, + strlen(buf) + 1); + *ret_label = buf_label; + *ret_origin = buf_origin; + } else { + *ret_label = 0; + } + return ret; +} + +SANITIZER_INTERFACE_ATTRIBUTE char *__dfsw_fgets(char *s, int size, FILE *stream, dfsan_label s_label, dfsan_label size_label, dfsan_label stream_label, dfsan_label *ret_label) { @@ -979,6 +992,19 @@ char *__dfsw_fgets(char *s, int size, FILE *stream, dfsan_label s_label, } SANITIZER_INTERFACE_ATTRIBUTE +char *__dfso_fgets(char *s, int size, FILE *stream, dfsan_label s_label, + dfsan_label size_label, dfsan_label stream_label, + dfsan_label *ret_label, dfsan_origin s_origin, + dfsan_origin size_origin, dfsan_origin stream_origin, + dfsan_origin *ret_origin) { + char *ret = __dfsw_fgets(s, size, stream, s_label, size_label, stream_label, + ret_label); + if (ret) + *ret_origin = s_origin; + return ret; +} + +SANITIZER_INTERFACE_ATTRIBUTE char *__dfsw_getcwd(char *buf, size_t size, dfsan_label buf_label, dfsan_label size_label, dfsan_label *ret_label) { char *ret = getcwd(buf, size); @@ -992,16 +1018,32 @@ char *__dfsw_getcwd(char *buf, size_t size, dfsan_label buf_label, } SANITIZER_INTERFACE_ATTRIBUTE +char *__dfso_getcwd(char *buf, size_t size, dfsan_label buf_label, + dfsan_label size_label, dfsan_label *ret_label, + dfsan_origin buf_origin, dfsan_origin size_origin, + dfsan_origin *ret_origin) { + char *ret = __dfsw_getcwd(buf, size, buf_label, size_label, ret_label); + if (ret) + *ret_origin = buf_origin; + return ret; +} + +SANITIZER_INTERFACE_ATTRIBUTE char *__dfsw_get_current_dir_name(dfsan_label *ret_label) { char *ret = get_current_dir_name(); - if (ret) { + if (ret) dfsan_set_label(0, ret, strlen(ret) + 1); - } *ret_label = 0; return ret; } SANITIZER_INTERFACE_ATTRIBUTE +char *__dfso_get_current_dir_name(dfsan_label *ret_label, + dfsan_origin *ret_origin) { + return __dfsw_get_current_dir_name(ret_label); +} + +SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_gethostname(char *name, size_t len, dfsan_label name_label, dfsan_label len_label, dfsan_label *ret_label) { int ret = gethostname(name, len); @@ -1013,6 +1055,14 @@ int __dfsw_gethostname(char *name, size_t len, dfsan_label name_label, } SANITIZER_INTERFACE_ATTRIBUTE +int __dfso_gethostname(char *name, size_t len, dfsan_label name_label, + dfsan_label len_label, dfsan_label *ret_label, + dfsan_origin name_origin, dfsan_origin len_origin, + dfsan_label *ret_origin) { + return __dfsw_gethostname(name, len, name_label, len_label, ret_label); +} + +SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_getrlimit(int resource, struct rlimit *rlim, dfsan_label resource_label, dfsan_label rlim_label, dfsan_label *ret_label) { @@ -1025,6 +1075,15 @@ int __dfsw_getrlimit(int resource, struct rlimit *rlim, } SANITIZER_INTERFACE_ATTRIBUTE +int __dfso_getrlimit(int resource, struct rlimit *rlim, + dfsan_label resource_label, dfsan_label rlim_label, + dfsan_label *ret_label, dfsan_origin resource_origin, + dfsan_origin rlim_origin, dfsan_origin *ret_origin) { + return __dfsw_getrlimit(resource, rlim, resource_label, rlim_label, + ret_label); +} + +SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_getrusage(int who, struct rusage *usage, dfsan_label who_label, dfsan_label usage_label, dfsan_label *ret_label) { int ret = getrusage(who, usage); @@ -1036,6 +1095,14 @@ int __dfsw_getrusage(int who, struct rusage *usage, dfsan_label who_label, } SANITIZER_INTERFACE_ATTRIBUTE +int __dfso_getrusage(int who, struct rusage *usage, dfsan_label who_label, + dfsan_label usage_label, dfsan_label *ret_label, + dfsan_origin who_origin, dfsan_origin usage_origin, + dfsan_label *ret_origin) { + return __dfsw_getrusage(who, usage, who_label, usage_label, ret_label); +} + +SANITIZER_INTERFACE_ATTRIBUTE char *__dfsw_strcpy(char *dest, const char *src, dfsan_label dst_label, dfsan_label src_label, dfsan_label *ret_label) { char *ret = strcpy(dest, src); // NOLINT @@ -1287,6 +1354,12 @@ time_t __dfsw_time(time_t *t, dfsan_label t_label, dfsan_label *ret_label) { } SANITIZER_INTERFACE_ATTRIBUTE +time_t __dfso_time(time_t *t, dfsan_label t_label, dfsan_label *ret_label, + dfsan_origin t_origin, dfsan_origin *ret_origin) { + return __dfsw_time(t, t_label, ret_label); +} + +SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_inet_pton(int af, const char *src, void *dst, dfsan_label af_label, dfsan_label src_label, dfsan_label dst_label, dfsan_label *ret_label) { @@ -1300,6 +1373,24 @@ int __dfsw_inet_pton(int af, const char *src, void *dst, dfsan_label af_label, } SANITIZER_INTERFACE_ATTRIBUTE +int __dfso_inet_pton(int af, const char *src, void *dst, dfsan_label af_label, + dfsan_label src_label, dfsan_label dst_label, + dfsan_label *ret_label, dfsan_origin af_origin, + dfsan_origin src_origin, dfsan_origin dst_origin, + dfsan_origin *ret_origin) { + int ret = inet_pton(af, src, dst); + if (ret == 1) { + int src_len = strlen(src) + 1; + dfsan_set_label_origin( + dfsan_read_label(src, src_len), + dfsan_read_origin_of_first_taint(src, src_len), dst, + af == AF_INET ? sizeof(struct in_addr) : sizeof(in6_addr)); + } + *ret_label = 0; + return ret; +} + +SANITIZER_INTERFACE_ATTRIBUTE struct tm *__dfsw_localtime_r(const time_t *timep, struct tm *result, dfsan_label timep_label, dfsan_label result_label, dfsan_label *ret_label) { @@ -1315,6 +1406,26 @@ struct tm *__dfsw_localtime_r(const time_t *timep, struct tm *result, } SANITIZER_INTERFACE_ATTRIBUTE +struct tm *__dfso_localtime_r(const time_t *timep, struct tm *result, + dfsan_label timep_label, dfsan_label result_label, + dfsan_label *ret_label, dfsan_origin timep_origin, + dfsan_origin result_origin, + dfsan_origin *ret_origin) { + struct tm *ret = localtime_r(timep, result); + if (ret) { + dfsan_set_label_origin( + dfsan_read_label(timep, sizeof(time_t)), + dfsan_read_origin_of_first_taint(timep, sizeof(time_t)), result, + sizeof(struct tm)); + *ret_label = result_label; + *ret_origin = result_origin; + } else { + *ret_label = 0; + } + return ret; +} + +SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_getpwuid_r(id_t uid, struct passwd *pwd, char *buf, size_t buflen, struct passwd **result, dfsan_label uid_label, dfsan_label pwd_label, @@ -1333,6 +1444,19 @@ int __dfsw_getpwuid_r(id_t uid, struct passwd *pwd, } SANITIZER_INTERFACE_ATTRIBUTE +int __dfso_getpwuid_r(id_t uid, struct passwd *pwd, char *buf, size_t buflen, + struct passwd **result, dfsan_label uid_label, + dfsan_label pwd_label, dfsan_label buf_label, + dfsan_label buflen_label, dfsan_label result_label, + dfsan_label *ret_label, dfsan_origin uid_origin, + dfsan_origin pwd_origin, dfsan_origin buf_origin, + dfsan_origin buflen_origin, dfsan_origin result_origin, + dfsan_origin *ret_origin) { + return __dfsw_getpwuid_r(uid, pwd, buf, buflen, result, uid_label, pwd_label, + buf_label, buflen_label, result_label, ret_label); +} + +SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout, dfsan_label epfd_label, dfsan_label events_label, dfsan_label maxevents_label, @@ -1345,6 +1469,19 @@ int __dfsw_epoll_wait(int epfd, struct epoll_event *events, int maxevents, } SANITIZER_INTERFACE_ATTRIBUTE +int __dfso_epoll_wait(int epfd, struct epoll_event *events, int maxevents, + int timeout, dfsan_label epfd_label, + dfsan_label events_label, dfsan_label maxevents_label, + dfsan_label timeout_label, dfsan_label *ret_label, + dfsan_origin epfd_origin, dfsan_origin events_origin, + dfsan_origin maxevents_origin, + dfsan_origin timeout_origin, dfsan_origin *ret_origin) { + return __dfsw_epoll_wait(epfd, events, maxevents, timeout, epfd_label, + events_label, maxevents_label, timeout_label, + ret_label); +} + +SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_poll(struct pollfd *fds, nfds_t nfds, int timeout, dfsan_label dfs_label, dfsan_label nfds_label, dfsan_label timeout_label, dfsan_label *ret_label) { @@ -1359,6 +1496,16 @@ int __dfsw_poll(struct pollfd *fds, nfds_t nfds, int timeout, } SANITIZER_INTERFACE_ATTRIBUTE +int __dfso_poll(struct pollfd *fds, nfds_t nfds, int timeout, + dfsan_label dfs_label, dfsan_label nfds_label, + dfsan_label timeout_label, dfsan_label *ret_label, + dfsan_origin dfs_origin, dfsan_origin nfds_origin, + dfsan_origin timeout_origin, dfsan_origin *ret_origin) { + return __dfsw_poll(fds, nfds, timeout, dfs_label, nfds_label, timeout_label, + ret_label); +} + +SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout, dfsan_label nfds_label, dfsan_label readfds_label, @@ -1382,6 +1529,20 @@ int __dfsw_select(int nfds, fd_set *readfds, fd_set *writefds, } SANITIZER_INTERFACE_ATTRIBUTE +int __dfso_select(int nfds, fd_set *readfds, fd_set *writefds, + fd_set *exceptfds, struct timeval *timeout, + dfsan_label nfds_label, dfsan_label readfds_label, + dfsan_label writefds_label, dfsan_label exceptfds_label, + dfsan_label timeout_label, dfsan_label *ret_label, + dfsan_origin nfds_origin, dfsan_origin readfds_origin, + dfsan_origin writefds_origin, dfsan_origin exceptfds_origin, + dfsan_origin timeout_origin, dfsan_origin *ret_origin) { + return __dfsw_select(nfds, readfds, writefds, exceptfds, timeout, nfds_label, + readfds_label, writefds_label, exceptfds_label, + timeout_label, ret_label); +} + +SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_sched_getaffinity(pid_t pid, size_t cpusetsize, cpu_set_t *mask, dfsan_label pid_label, dfsan_label cpusetsize_label, @@ -1395,6 +1556,19 @@ int __dfsw_sched_getaffinity(pid_t pid, size_t cpusetsize, cpu_set_t *mask, } SANITIZER_INTERFACE_ATTRIBUTE +int __dfso_sched_getaffinity(pid_t pid, size_t cpusetsize, cpu_set_t *mask, + dfsan_label pid_label, + dfsan_label cpusetsize_label, + dfsan_label mask_label, dfsan_label *ret_label, + dfsan_origin pid_origin, + dfsan_origin cpusetsize_origin, + dfsan_origin mask_origin, + dfsan_origin *ret_origin) { + return __dfsw_sched_getaffinity(pid, cpusetsize, mask, pid_label, + cpusetsize_label, mask_label, ret_label); +} + +SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_sigemptyset(sigset_t *set, dfsan_label set_label, dfsan_label *ret_label) { int ret = sigemptyset(set); diff --git a/compiler-rt/test/dfsan/custom.cpp b/compiler-rt/test/dfsan/custom.cpp index 2084e3a..63fa438 100644 --- a/compiler-rt/test/dfsan/custom.cpp +++ b/compiler-rt/test/dfsan/custom.cpp @@ -142,6 +142,23 @@ dfsan_label i_j_label = 0; #define ASSERT_SAVED_ORIGINS(val) #endif +#ifdef ORIGIN_TRACKING +#define DEFINE_AND_SAVE_N_ORIGINS(val, n) \ + dfsan_origin val##_o[n]; \ + for (int i = 0; i < n; ++i) \ + val##_o[i] = dfsan_get_origin((long)(val[i])); +#else +#define DEFINE_AND_SAVE_N_ORIGINS(val, n) +#endif + +#ifdef ORIGIN_TRACKING +#define ASSERT_SAVED_N_ORIGINS(val, n) \ + for (int i = 0; i < n; ++i) \ + ASSERT_ORIGIN(val[i], val##_o[i]); +#else +#define ASSERT_SAVED_N_ORIGINS(val, n) +#endif + void test_stat() { int i = 1; dfsan_set_label(i_label, &i, sizeof(i)); @@ -762,28 +779,37 @@ void test_clock_gettime() { ASSERT_ORIGIN(((char *)&tp)[3], origin); } -#if !defined(ORIGIN_TRACKING) void test_ctime_r() { char *buf = (char*) malloc(64); time_t t = 0; + DEFINE_AND_SAVE_ORIGINS(buf) + dfsan_origin t_o = dfsan_get_origin((long)t); + char *ret = ctime_r(&t, buf); ASSERT_ZERO_LABEL(ret); assert(buf == ret); ASSERT_READ_ZERO_LABEL(buf, strlen(buf) + 1); + ASSERT_SAVED_ORIGINS(buf) dfsan_set_label(i_label, &t, sizeof(t)); + t_o = dfsan_get_origin((long)t); ret = ctime_r(&t, buf); ASSERT_ZERO_LABEL(ret); ASSERT_READ_LABEL(buf, strlen(buf) + 1, i_label); + for (int i = 0; i < strlen(buf) + 1; ++i) + ASSERT_ORIGIN(buf[i], t_o); t = 0; dfsan_set_label(j_label, &buf, sizeof(&buf)); + dfsan_origin buf_ptr_o = dfsan_get_origin((long)buf); ret = ctime_r(&t, buf); ASSERT_LABEL(ret, j_label); + ASSERT_ORIGIN(ret, buf_ptr_o); ASSERT_READ_ZERO_LABEL(buf, strlen(buf) + 1); + for (int i = 0; i < strlen(buf) + 1; ++i) + ASSERT_ORIGIN(buf[i], t_o); } -#endif // !defined(ORIGIN_TRACKING) static int write_callback_count = 0; static int last_fd; @@ -860,32 +886,48 @@ void test_dfsan_set_write_callback() { dfsan_set_write_callback(NULL); } -#if !defined(ORIGIN_TRACKING) void test_fgets() { char *buf = (char*) malloc(128); FILE *f = fopen("/etc/passwd", "r"); dfsan_set_label(j_label, buf, 1); + DEFINE_AND_SAVE_N_ORIGINS(buf, 128) + char *ret = fgets(buf, sizeof(buf), f); assert(ret == buf); ASSERT_ZERO_LABEL(ret); + ASSERT_EQ_ORIGIN(ret, buf); ASSERT_READ_ZERO_LABEL(buf, 128); + ASSERT_SAVED_N_ORIGINS(buf, 128) + dfsan_set_label(j_label, &buf, sizeof(&buf)); ret = fgets(buf, sizeof(buf), f); ASSERT_LABEL(ret, j_label); + ASSERT_EQ_ORIGIN(ret, buf); + ASSERT_SAVED_N_ORIGINS(buf, 128) + fclose(f); + free(buf); } void test_getcwd() { char buf[1024]; char *ptr = buf; dfsan_set_label(i_label, buf + 2, 2); + DEFINE_AND_SAVE_ORIGINS(buf) + char* ret = getcwd(buf, sizeof(buf)); assert(ret == buf); assert(ret[0] == '/'); + ASSERT_ZERO_LABEL(ret); + ASSERT_EQ_ORIGIN(ret, buf); ASSERT_READ_ZERO_LABEL(buf + 2, 2); + ASSERT_SAVED_ORIGINS(buf) + dfsan_set_label(i_label, &ptr, sizeof(ptr)); ret = getcwd(ptr, sizeof(buf)); ASSERT_LABEL(ret, i_label); + ASSERT_EQ_ORIGIN(ret, ptr); + ASSERT_SAVED_ORIGINS(buf) } void test_get_current_dir_name() { @@ -893,44 +935,62 @@ void test_get_current_dir_name() { assert(ret); assert(ret[0] == '/'); ASSERT_READ_ZERO_LABEL(ret, strlen(ret) + 1); + ASSERT_ZERO_LABEL(ret); } void test_gethostname() { char buf[1024]; dfsan_set_label(i_label, buf + 2, 2); - assert(gethostname(buf, sizeof(buf)) == 0); + DEFINE_AND_SAVE_ORIGINS(buf) + int ret = gethostname(buf, sizeof(buf)); + assert(ret == 0); + ASSERT_ZERO_LABEL(ret); ASSERT_READ_ZERO_LABEL(buf + 2, 2); + ASSERT_SAVED_ORIGINS(buf) } void test_getrlimit() { struct rlimit rlim; dfsan_set_label(i_label, &rlim, sizeof(rlim)); - assert(getrlimit(RLIMIT_CPU, &rlim) == 0); + DEFINE_AND_SAVE_ORIGINS(rlim); + int ret = getrlimit(RLIMIT_CPU, &rlim); + assert(ret == 0); + ASSERT_ZERO_LABEL(ret); ASSERT_READ_ZERO_LABEL(&rlim, sizeof(rlim)); + ASSERT_SAVED_ORIGINS(rlim) } void test_getrusage() { struct rusage usage; dfsan_set_label(i_label, &usage, sizeof(usage)); - assert(getrusage(RUSAGE_SELF, &usage) == 0); + DEFINE_AND_SAVE_ORIGINS(usage); + int ret = getrusage(RUSAGE_SELF, &usage); + assert(ret == 0); + ASSERT_ZERO_LABEL(ret); ASSERT_READ_ZERO_LABEL(&usage, sizeof(usage)); + ASSERT_SAVED_ORIGINS(usage) } -#endif // !defined(ORIGIN_TRACKING) void test_strcpy() { char src[] = "hello world"; char dst[sizeof(src) + 2]; + char *p_dst = dst; dfsan_set_label(0, src, sizeof(src)); dfsan_set_label(0, dst, sizeof(dst)); + dfsan_set_label(k_label, &p_dst, sizeof(p_dst)); dfsan_set_label(i_label, src + 2, 1); dfsan_set_label(j_label, src + 3, 1); dfsan_set_label(j_label, dst + 4, 1); dfsan_set_label(i_label, dst + 12, 1); - char *ret = strcpy(dst, src); + char *ret = strcpy(p_dst, src); assert(ret == dst); assert(strcmp(src, dst) == 0); + ASSERT_LABEL(ret, k_label); + ASSERT_EQ_ORIGIN(ret, p_dst); for (int i = 0; i < strlen(src) + 1; ++i) { assert(dfsan_get_label(dst[i]) == dfsan_get_label(src[i])); + if (dfsan_get_label(dst[i])) + assert(dfsan_get_init_origin(&dst[i]) == dfsan_get_origin(src[i])); } // Note: if strlen(src) + 1 were used instead to compute the first untouched // byte of dest, the label would be I|J. This is because strlen() might @@ -1061,14 +1121,16 @@ void test_strtod() { ASSERT_EQ_ORIGIN(ret, buf[1]); } -#if !defined(ORIGIN_TRACKING) void test_time() { time_t t = 0; dfsan_set_label(i_label, &t, 1); + DEFINE_AND_SAVE_ORIGINS(t) time_t ret = time(&t); assert(ret == t); assert(ret > 0); + ASSERT_ZERO_LABEL(ret); ASSERT_ZERO_LABEL(t); + ASSERT_SAVED_ORIGINS(t) } void test_inet_pton() { @@ -1077,7 +1139,9 @@ void test_inet_pton() { struct in_addr in4; int ret4 = inet_pton(AF_INET, addr4, &in4); assert(ret4 == 1); + ASSERT_ZERO_LABEL(ret4); ASSERT_READ_LABEL(&in4, sizeof(in4), i_label); + ASSERT_ORIGINS(&in4, sizeof(in4), dfsan_get_origin((long)(addr4[3]))) assert(in4.s_addr == htonl(0x7f000001)); char addr6[] = "::1"; @@ -1085,17 +1149,27 @@ void test_inet_pton() { struct in6_addr in6; int ret6 = inet_pton(AF_INET6, addr6, &in6); assert(ret6 == 1); + ASSERT_ZERO_LABEL(ret6); ASSERT_READ_LABEL(((char *) &in6) + sizeof(in6) - 1, 1, j_label); + ASSERT_ORIGINS(&in6, sizeof(in6), dfsan_get_origin((long)(addr6[3]))) } void test_localtime_r() { time_t t0 = 1384800998; struct tm t1; dfsan_set_label(i_label, &t0, sizeof(t0)); - struct tm* ret = localtime_r(&t0, &t1); + dfsan_origin t0_o = dfsan_get_origin((long)t0); + struct tm *pt1 = &t1; + dfsan_set_label(j_label, &pt1, sizeof(pt1)); + dfsan_origin pt1_o = dfsan_get_origin((long)pt1); + struct tm *ret = localtime_r(&t0, pt1); assert(ret == &t1); assert(t1.tm_min == 56); + ASSERT_LABEL(ret, j_label); + ASSERT_INIT_ORIGIN(&ret, pt1_o); + ASSERT_READ_LABEL(&ret, sizeof(ret), j_label); ASSERT_LABEL(t1.tm_mon, i_label); + ASSERT_ORIGIN(t1.tm_mon, t0_o); } void test_getpwuid_r() { @@ -1104,11 +1178,16 @@ void test_getpwuid_r() { struct passwd *result; dfsan_set_label(i_label, &pwd, 4); + DEFINE_AND_SAVE_ORIGINS(pwd) + DEFINE_AND_SAVE_ORIGINS(buf) int ret = getpwuid_r(0, &pwd, buf, sizeof(buf), &result); assert(ret == 0); assert(strcmp(pwd.pw_name, "root") == 0); assert(result == &pwd); + ASSERT_ZERO_LABEL(ret); ASSERT_READ_ZERO_LABEL(&pwd, 4); + ASSERT_SAVED_ORIGINS(pwd) + ASSERT_SAVED_ORIGINS(buf) } void test_epoll_wait() { @@ -1129,12 +1208,14 @@ void test_epoll_wait() { // Test epoll_wait when no events have occurred. event = {}; dfsan_set_label(i_label, &event, sizeof(event)); + DEFINE_AND_SAVE_ORIGINS(event) ret = epoll_wait(epfd, &event, /*maxevents=*/1, /*timeout=*/0); assert(ret == 0); assert(event.events == 0); assert(event.data.fd == 0); ASSERT_ZERO_LABEL(ret); ASSERT_READ_LABEL(&event, sizeof(event), i_label); + ASSERT_SAVED_ORIGINS(event) // Test epoll_wait when an event occurs. write(pipe_fds[1], "x", 1); @@ -1144,6 +1225,7 @@ void test_epoll_wait() { assert(event.data.fd == pipe_fds[0]); ASSERT_ZERO_LABEL(ret); ASSERT_READ_ZERO_LABEL(&event, sizeof(event)); + ASSERT_SAVED_ORIGINS(event) // Clean up. close(epfd); @@ -1156,8 +1238,11 @@ void test_poll() { fd.fd = 0; fd.events = POLLIN; dfsan_set_label(i_label, &fd.revents, sizeof(fd.revents)); + DEFINE_AND_SAVE_ORIGINS(fd) int ret = poll(&fd, 1, 1); + ASSERT_ZERO_LABEL(ret); ASSERT_ZERO_LABEL(fd.revents); + ASSERT_SAVED_ORIGINS(fd) assert(ret >= 0); } @@ -1168,20 +1253,27 @@ void test_select() { FD_SET(0, &fds); dfsan_set_label(i_label, &fds, sizeof(fds)); dfsan_set_label(j_label, &t, sizeof(t)); + DEFINE_AND_SAVE_ORIGINS(fds) + DEFINE_AND_SAVE_ORIGINS(t) int ret = select(1, &fds, NULL, NULL, &t); assert(ret >= 0); + ASSERT_ZERO_LABEL(ret); ASSERT_ZERO_LABEL(t.tv_sec); ASSERT_READ_ZERO_LABEL(&fds, sizeof(fds)); + ASSERT_SAVED_ORIGINS(fds) + ASSERT_SAVED_ORIGINS(t) } void test_sched_getaffinity() { cpu_set_t mask; dfsan_set_label(j_label, &mask, 1); + DEFINE_AND_SAVE_ORIGINS(mask) int ret = sched_getaffinity(0, sizeof(mask), &mask); assert(ret == 0); + ASSERT_ZERO_LABEL(ret); ASSERT_READ_ZERO_LABEL(&mask, sizeof(mask)); + ASSERT_SAVED_ORIGINS(mask) } -#endif // !defined(ORIGIN_TRACKING) void test_sigemptyset() { sigset_t set; @@ -1845,55 +1937,41 @@ int main(void) { test_bcmp(); test_calloc(); test_clock_gettime(); -#if !defined(ORIGIN_TRACKING) test_ctime_r(); -#endif // !defined(ORIGIN_TRACKING) test_dfsan_set_write_callback(); test_dl_iterate_phdr(); test_dlopen(); -#if !defined(ORIGIN_TRACKING) test_epoll_wait(); test_fgets(); -#endif // !defined(ORIGIN_TRACKING) test_fork(); test_fstat(); -#if !defined(ORIGIN_TRACKING) test_get_current_dir_name(); test_getcwd(); test_gethostname(); -#endif // !defined(ORIGIN_TRACKING) test_getpeername(); -#if !defined(ORIGIN_TRACKING) test_getpwuid_r(); test_getrlimit(); test_getrusage(); -#endif // !defined(ORIGIN_TRACKING) test_getsockname(); test_getsockopt(); test_gettimeofday(); -#if !defined(ORIGIN_TRACKING) test_inet_pton(); test_localtime_r(); -#endif // !defined(ORIGIN_TRACKING) test_memchr(); test_memcmp(); test_memcpy(); test_memmove(); test_memset(); test_nanosleep(); -#if !defined(ORIGIN_TRACKING) test_poll(); -#endif // !defined(ORIGIN_TRACKING) test_pread(); test_pthread_create(); test_pthread_join(); test_read(); test_recvmmsg(); test_recvmsg(); -#if !defined(ORIGIN_TRACKING) test_sched_getaffinity(); test_select(); -#endif // !defined(ORIGIN_TRACKING) test_sigaction(); test_signal(); test_sigaltstack(); @@ -1906,9 +1984,7 @@ int main(void) { test_strchr(); test_strcmp(); test_strcat(); -#if !defined(ORIGIN_TRACKING) test_strcpy(); -#endif // !defined(ORIGIN_TRACKING) test_strdup(); test_strlen(); test_strncasecmp(); @@ -1922,8 +1998,6 @@ int main(void) { test_strtoll(); test_strtoul(); test_strtoull(); -#if !defined(ORIGIN_TRACKING) test_time(); -#endif // !defined(ORIGIN_TRACKING) test_write(); } -- 2.7.4