[compiler-rt] 1fe0420 - [dfsan] Add origin ABI wrappers
Jianzhou Zhao via llvm-commits
llvm-commits at lists.llvm.org
Fri Mar 19 09:23:48 PDT 2021
Author: Jianzhou Zhao
Date: 2021-03-19T16:23:25Z
New Revision: 1fe042041c451760437d3e4285820f4581f0b744
URL: https://github.com/llvm/llvm-project/commit/1fe042041c451760437d3e4285820f4581f0b744
DIFF: https://github.com/llvm/llvm-project/commit/1fe042041c451760437d3e4285820f4581f0b744.diff
LOG: [dfsan] Add origin ABI wrappers
supported: dl_get_tls_static_info, calloc, clock_gettime,
dfsan_set_write_callback, dl_iterato_phdr, dlopen, memcpy,
memmove, memset, pread, read, strcat, strdup, strncpy
This is a part of https://reviews.llvm.org/D95835.
Reviewed By: morehouse
Differential Revision: https://reviews.llvm.org/D98790
Added:
Modified:
compiler-rt/lib/dfsan/dfsan.cpp
compiler-rt/lib/dfsan/dfsan.h
compiler-rt/lib/dfsan/dfsan_custom.cpp
compiler-rt/test/dfsan/custom.cpp
Removed:
################################################################################
diff --git a/compiler-rt/lib/dfsan/dfsan.cpp b/compiler-rt/lib/dfsan/dfsan.cpp
index 5a9620aa417e..2aff8869d2cf 100644
--- a/compiler-rt/lib/dfsan/dfsan.cpp
+++ b/compiler-rt/lib/dfsan/dfsan.cpp
@@ -736,6 +736,13 @@ dfsan_read_origin_of_first_taint(const void *addr, uptr size) {
return GetOriginIfTainted((uptr)addr, size);
}
+SANITIZER_INTERFACE_ATTRIBUTE void dfsan_set_label_origin(dfsan_label label,
+ dfsan_origin origin,
+ void *addr,
+ uptr size) {
+ __dfsan_set_label(label, origin, addr, size);
+}
+
extern "C" SANITIZER_INTERFACE_ATTRIBUTE
const struct dfsan_label_info *dfsan_get_label_info(dfsan_label label) {
return &__dfsan_label_info[label];
diff --git a/compiler-rt/lib/dfsan/dfsan.h b/compiler-rt/lib/dfsan/dfsan.h
index c2f173f079ff..73b4e4dcd297 100644
--- a/compiler-rt/lib/dfsan/dfsan.h
+++ b/compiler-rt/lib/dfsan/dfsan.h
@@ -48,6 +48,10 @@ void dfsan_clear_thread_local_state();
// from the address addr.
dfsan_origin dfsan_read_origin_of_first_taint(const void *addr, uptr size);
+// Set the data within [addr, addr+size) with label and origin.
+void dfsan_set_label_origin(dfsan_label label, dfsan_origin origin, void *addr,
+ uptr size);
+
// Copy or move the origins of the len bytes from src to dst.
void dfsan_mem_origin_transfer(const void *dst, const void *src, uptr len);
} // extern "C"
diff --git a/compiler-rt/lib/dfsan/dfsan_custom.cpp b/compiler-rt/lib/dfsan/dfsan_custom.cpp
index 804c57bd3c35..96b7668db90c 100644
--- a/compiler-rt/lib/dfsan/dfsan_custom.cpp
+++ b/compiler-rt/lib/dfsan/dfsan_custom.cpp
@@ -470,6 +470,15 @@ SANITIZER_INTERFACE_ATTRIBUTE void *__dfsw_calloc(size_t nmemb, size_t size,
return p;
}
+SANITIZER_INTERFACE_ATTRIBUTE void *__dfso_calloc(
+ size_t nmemb, size_t size, dfsan_label nmemb_label, dfsan_label size_label,
+ dfsan_label *ret_label, dfsan_origin nmemb_origin, dfsan_origin size_origin,
+ dfsan_origin *ret_origin) {
+ void *p = __dfsw_calloc(nmemb, size, nmemb_label, size_label, ret_label);
+ *ret_origin = 0;
+ return p;
+}
+
SANITIZER_INTERFACE_ATTRIBUTE size_t
__dfsw_strlen(const char *s, dfsan_label s_label, dfsan_label *ret_label) {
size_t ret = strlen(s);
@@ -499,6 +508,11 @@ static void *dfsan_memmove(void *dest, const void *src, size_t n) {
return internal_memmove(dest, src, n);
}
+static void *dfsan_memmove_with_origin(void *dest, const void *src, size_t n) {
+ dfsan_mem_origin_transfer(dest, src, n);
+ return dfsan_memmove(dest, src, n);
+}
+
static void *dfsan_memcpy(void *dest, const void *src, size_t n) {
dfsan_label *sdest = shadow_for(dest);
const dfsan_label *ssrc = shadow_for(src);
@@ -506,11 +520,22 @@ static void *dfsan_memcpy(void *dest, const void *src, size_t n) {
return internal_memcpy(dest, src, n);
}
+static void *dfsan_memcpy_with_origin(void *dest, const void *src, size_t n) {
+ dfsan_mem_origin_transfer(dest, src, n);
+ return dfsan_memcpy(dest, src, n);
+}
+
static void dfsan_memset(void *s, int c, dfsan_label c_label, size_t n) {
internal_memset(s, c, n);
dfsan_set_label(c_label, s, n);
}
+static void dfsan_memset_with_origin(void *s, int c, dfsan_label c_label,
+ dfsan_origin c_origin, size_t n) {
+ internal_memset(s, c, n);
+ dfsan_set_label_origin(c_label, c_origin, s, n);
+}
+
SANITIZER_INTERFACE_ATTRIBUTE
void *__dfsw_memcpy(void *dest, const void *src, size_t n,
dfsan_label dest_label, dfsan_label src_label,
@@ -519,6 +544,17 @@ void *__dfsw_memcpy(void *dest, const void *src, size_t n,
return dfsan_memcpy(dest, src, n);
}
+SANITIZER_INTERFACE_ATTRIBUTE
+void *__dfso_memcpy(void *dest, const void *src, size_t n,
+ dfsan_label dest_label, dfsan_label src_label,
+ dfsan_label n_label, dfsan_label *ret_label,
+ dfsan_origin dest_origin, dfsan_origin src_origin,
+ dfsan_origin n_origin, dfsan_origin *ret_origin) {
+ *ret_label = dest_label;
+ *ret_origin = dest_origin;
+ return dfsan_memcpy_with_origin(dest, src, n);
+}
+
SANITIZER_INTERFACE_ATTRIBUTE
void *__dfsw_memmove(void *dest, const void *src, size_t n,
dfsan_label dest_label, dfsan_label src_label,
@@ -527,6 +563,17 @@ void *__dfsw_memmove(void *dest, const void *src, size_t n,
return dfsan_memmove(dest, src, n);
}
+SANITIZER_INTERFACE_ATTRIBUTE
+void *__dfso_memmove(void *dest, const void *src, size_t n,
+ dfsan_label dest_label, dfsan_label src_label,
+ dfsan_label n_label, dfsan_label *ret_label,
+ dfsan_origin dest_origin, dfsan_origin src_origin,
+ dfsan_origin n_origin, dfsan_origin *ret_origin) {
+ *ret_label = dest_label;
+ *ret_origin = dest_origin;
+ return dfsan_memmove_with_origin(dest, src, n);
+}
+
SANITIZER_INTERFACE_ATTRIBUTE
void *__dfsw_memset(void *s, int c, size_t n,
dfsan_label s_label, dfsan_label c_label,
@@ -536,6 +583,18 @@ void *__dfsw_memset(void *s, int c, size_t n,
return s;
}
+SANITIZER_INTERFACE_ATTRIBUTE
+void *__dfso_memset(void *s, int c, size_t n, dfsan_label s_label,
+ dfsan_label c_label, dfsan_label n_label,
+ dfsan_label *ret_label, dfsan_origin s_origin,
+ dfsan_origin c_origin, dfsan_origin n_origin,
+ dfsan_origin *ret_origin) {
+ dfsan_memset_with_origin(s, c, c_label, c_origin, n);
+ *ret_label = s_label;
+ *ret_origin = s_origin;
+ return s;
+}
+
SANITIZER_INTERFACE_ATTRIBUTE char *__dfsw_strcat(char *dest, const char *src,
dfsan_label dest_label,
dfsan_label src_label,
@@ -550,6 +609,23 @@ SANITIZER_INTERFACE_ATTRIBUTE char *__dfsw_strcat(char *dest, const char *src,
return ret;
}
+SANITIZER_INTERFACE_ATTRIBUTE char *__dfso_strcat(
+ char *dest, const char *src, dfsan_label dest_label, dfsan_label src_label,
+ dfsan_label *ret_label, dfsan_origin dest_origin, dfsan_origin src_origin,
+ dfsan_origin *ret_origin) {
+ size_t dest_len = strlen(dest);
+ char *ret = strcat(dest, src); // NOLINT
+ dfsan_label *sdest = shadow_for(dest + dest_len);
+ const dfsan_label *ssrc = shadow_for(src);
+ size_t src_len = strlen(src);
+ dfsan_mem_origin_transfer(dest + dest_len, src, src_len);
+ internal_memcpy((void *)sdest, (const void *)ssrc,
+ src_len * sizeof(dfsan_label));
+ *ret_label = dest_label;
+ *ret_origin = dest_origin;
+ return ret;
+}
+
SANITIZER_INTERFACE_ATTRIBUTE char *
__dfsw_strdup(const char *s, dfsan_label s_label, dfsan_label *ret_label) {
size_t len = strlen(s);
@@ -559,6 +635,19 @@ __dfsw_strdup(const char *s, dfsan_label s_label, dfsan_label *ret_label) {
return static_cast<char *>(p);
}
+SANITIZER_INTERFACE_ATTRIBUTE char *__dfso_strdup(const char *s,
+ dfsan_label s_label,
+ dfsan_label *ret_label,
+ dfsan_origin s_origin,
+ dfsan_origin *ret_origin) {
+ size_t len = strlen(s);
+ void *p = malloc(len + 1);
+ dfsan_memcpy_with_origin(p, s, len + 1);
+ *ret_label = 0;
+ *ret_origin = 0;
+ return static_cast<char *>(p);
+}
+
SANITIZER_INTERFACE_ATTRIBUTE char *
__dfsw_strncpy(char *s1, const char *s2, size_t n, dfsan_label s1_label,
dfsan_label s2_label, dfsan_label n_label,
@@ -575,6 +664,24 @@ __dfsw_strncpy(char *s1, const char *s2, size_t n, dfsan_label s1_label,
return s1;
}
+SANITIZER_INTERFACE_ATTRIBUTE char *__dfso_strncpy(
+ char *s1, const char *s2, size_t n, dfsan_label s1_label,
+ dfsan_label s2_label, dfsan_label n_label, dfsan_label *ret_label,
+ dfsan_origin s1_origin, dfsan_origin s2_origin, dfsan_origin n_origin,
+ dfsan_origin *ret_origin) {
+ size_t len = strlen(s2);
+ if (len < n) {
+ dfsan_memcpy_with_origin(s1, s2, len + 1);
+ dfsan_memset_with_origin(s1 + len + 1, 0, 0, 0, n - len - 1);
+ } else {
+ dfsan_memcpy_with_origin(s1, s2, n);
+ }
+
+ *ret_label = s1_label;
+ *ret_origin = s1_origin;
+ return s1;
+}
+
SANITIZER_INTERFACE_ATTRIBUTE ssize_t
__dfsw_pread(int fd, void *buf, size_t count, off_t offset,
dfsan_label fd_label, dfsan_label buf_label,
@@ -587,6 +694,17 @@ __dfsw_pread(int fd, void *buf, size_t count, off_t offset,
return ret;
}
+SANITIZER_INTERFACE_ATTRIBUTE ssize_t __dfso_pread(
+ int fd, void *buf, size_t count, off_t offset, dfsan_label fd_label,
+ dfsan_label buf_label, dfsan_label count_label, dfsan_label offset_label,
+ 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;
+}
+
SANITIZER_INTERFACE_ATTRIBUTE ssize_t
__dfsw_read(int fd, void *buf, size_t count,
dfsan_label fd_label, dfsan_label buf_label,
@@ -599,6 +717,16 @@ __dfsw_read(int fd, void *buf, size_t count,
return ret;
}
+SANITIZER_INTERFACE_ATTRIBUTE ssize_t __dfso_read(
+ int fd, void *buf, size_t count, dfsan_label fd_label,
+ 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;
+}
+
SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_clock_gettime(clockid_t clk_id,
struct timespec *tp,
dfsan_label clk_id_label,
@@ -611,7 +739,15 @@ SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_clock_gettime(clockid_t clk_id,
return ret;
}
-static void unpoison(const void *ptr, uptr size) {
+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;
+}
+
+static void dfsan_set_zero_label(const void *ptr, uptr size) {
dfsan_set_label(0, const_cast<void *>(ptr), size);
}
@@ -624,11 +760,21 @@ __dfsw_dlopen(const char *filename, int flag, dfsan_label filename_label,
void *handle = dlopen(filename, flag);
link_map *map = GET_LINK_MAP_BY_DLOPEN_HANDLE(handle);
if (map)
- ForEachMappedRegion(map, unpoison);
+ ForEachMappedRegion(map, dfsan_set_zero_label);
*ret_label = 0;
return handle;
}
+SANITIZER_INTERFACE_ATTRIBUTE void *__dfso_dlopen(
+ const char *filename, int flag, dfsan_label filename_label,
+ 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;
+}
+
static void *DFsanThreadStartFunc(void *arg) {
DFsanThread *t = (DFsanThread *)arg;
SetCurrentThread(t);
@@ -715,6 +861,17 @@ struct dl_iterate_phdr_info {
void *data;
};
+struct dl_iterate_phdr_origin_info {
+ int (*callback_trampoline)(void *callback, struct dl_phdr_info *info,
+ size_t size, void *data, dfsan_label info_label,
+ dfsan_label size_label, dfsan_label data_label,
+ dfsan_label *ret_label, dfsan_origin info_origin,
+ dfsan_origin size_origin, dfsan_origin data_origin,
+ dfsan_origin *ret_origin);
+ void *callback;
+ void *data;
+};
+
int dl_iterate_phdr_cb(struct dl_phdr_info *info, size_t size, void *data) {
dl_iterate_phdr_info *dipi = (dl_iterate_phdr_info *)data;
dfsan_set_label(0, *info);
@@ -728,6 +885,21 @@ int dl_iterate_phdr_cb(struct dl_phdr_info *info, size_t size, void *data) {
0, &ret_label);
}
+int dl_iterate_phdr_origin_cb(struct dl_phdr_info *info, size_t size,
+ void *data) {
+ dl_iterate_phdr_origin_info *dipi = (dl_iterate_phdr_origin_info *)data;
+ dfsan_set_label(0, *info);
+ dfsan_set_label(0, const_cast<char *>(info->dlpi_name),
+ strlen(info->dlpi_name) + 1);
+ dfsan_set_label(
+ 0, const_cast<char *>(reinterpret_cast<const char *>(info->dlpi_phdr)),
+ sizeof(*info->dlpi_phdr) * info->dlpi_phnum);
+ dfsan_label ret_label;
+ dfsan_origin ret_origin;
+ return dipi->callback_trampoline(dipi->callback, info, size, dipi->data, 0, 0,
+ 0, &ret_label, 0, 0, 0, &ret_origin);
+}
+
SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_dl_iterate_phdr(
int (*callback_trampoline)(void *callback, struct dl_phdr_info *info,
size_t size, void *data, dfsan_label info_label,
@@ -740,6 +912,23 @@ SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_dl_iterate_phdr(
return dl_iterate_phdr(dl_iterate_phdr_cb, &dipi);
}
+SANITIZER_INTERFACE_ATTRIBUTE int __dfso_dl_iterate_phdr(
+ int (*callback_trampoline)(void *callback, struct dl_phdr_info *info,
+ size_t size, void *data, dfsan_label info_label,
+ dfsan_label size_label, dfsan_label data_label,
+ dfsan_label *ret_label, dfsan_origin info_origin,
+ dfsan_origin size_origin,
+ dfsan_origin data_origin,
+ dfsan_origin *ret_origin),
+ void *callback, void *data, dfsan_label callback_label,
+ dfsan_label data_label, dfsan_label *ret_label,
+ dfsan_origin callback_origin, dfsan_origin data_origin,
+ dfsan_origin *ret_origin) {
+ dl_iterate_phdr_origin_info dipi = {callback_trampoline, callback, data};
+ *ret_label = 0;
+ return dl_iterate_phdr(dl_iterate_phdr_origin_cb, &dipi);
+}
+
// This function is only available for glibc 2.27 or newer. Mark it weak so
// linking succeeds with older glibcs.
SANITIZER_WEAK_ATTRIBUTE void _dl_get_tls_static_info(size_t *sizep,
@@ -754,6 +943,13 @@ SANITIZER_INTERFACE_ATTRIBUTE void __dfsw__dl_get_tls_static_info(
dfsan_set_label(0, alignp, sizeof(*alignp));
}
+SANITIZER_INTERFACE_ATTRIBUTE void __dfso__dl_get_tls_static_info(
+ size_t *sizep, size_t *alignp, dfsan_label sizep_label,
+ dfsan_label alignp_label, dfsan_origin sizep_origin,
+ dfsan_origin alignp_origin) {
+ __dfsw__dl_get_tls_static_info(sizep, alignp, sizep_label, alignp_label);
+}
+
SANITIZER_INTERFACE_ATTRIBUTE
char *__dfsw_ctime_r(const time_t *timep, char *buf, dfsan_label timep_label,
dfsan_label buf_label, dfsan_label *ret_label) {
diff --git a/compiler-rt/test/dfsan/custom.cpp b/compiler-rt/test/dfsan/custom.cpp
index 7825f7aa8f32..1498c104160e 100644
--- a/compiler-rt/test/dfsan/custom.cpp
+++ b/compiler-rt/test/dfsan/custom.cpp
@@ -217,41 +217,68 @@ void test_bcmp() {
ASSERT_ZERO_LABEL(rv);
}
-#if !defined(ORIGIN_TRACKING)
void test_memcpy() {
char str1[] = "str1";
char str2[sizeof(str1)];
dfsan_set_label(i_label, &str1[3], 1);
- ASSERT_ZERO_LABEL(memcpy(str2, str1, sizeof(str1)));
+ DEFINE_AND_SAVE_ORIGINS(str1)
+
+ char *ptr2 = str2;
+ dfsan_set_label(j_label, &ptr2, sizeof(ptr2));
+
+ void *r = memcpy(ptr2, str1, sizeof(str1));
+ ASSERT_LABEL(r, j_label);
+ ASSERT_EQ_ORIGIN(r, ptr2);
assert(0 == memcmp(str2, str1, sizeof(str1)));
ASSERT_ZERO_LABEL(str2[0]);
ASSERT_LABEL(str2[3], i_label);
+
+ for (int i = 0; i < sizeof(str2); ++i) {
+ if (!dfsan_get_label(str2[i]))
+ continue;
+ ASSERT_INIT_ORIGIN(&(str2[i]), str1_o[i]);
+ }
}
void test_memmove() {
char str[] = "str1xx";
dfsan_set_label(i_label, &str[3], 1);
- ASSERT_ZERO_LABEL(memmove(str + 2, str, 4));
+ DEFINE_AND_SAVE_ORIGINS(str)
+
+ char *ptr = str + 2;
+ dfsan_set_label(j_label, &ptr, sizeof(ptr));
+
+ void *r = memmove(ptr, str, 4);
+ ASSERT_LABEL(r, j_label);
+ ASSERT_EQ_ORIGIN(r, ptr);
assert(0 == memcmp(str + 2, "str1", 4));
- for (int i = 0; i <= 4; ++i)
- ASSERT_ZERO_LABEL(str[i]);
+ ASSERT_ZERO_LABEL(str[4]);
ASSERT_LABEL(str[5], i_label);
+
+ for (int i = 0; i < 4; ++i) {
+ if (!dfsan_get_label(ptr[i]))
+ continue;
+ ASSERT_INIT_ORIGIN(&(ptr[i]), str_o[i]);
+ }
}
void test_memset() {
char buf[8];
int j = 'a';
+ char *ptr = buf;
dfsan_set_label(j_label, &j, sizeof(j));
-
- ASSERT_ZERO_LABEL(memset(&buf, j, sizeof(buf)));
+ dfsan_set_label(k_label, &ptr, sizeof(ptr));
+ void *ret = memset(ptr, j, sizeof(buf));
+ ASSERT_LABEL(ret, k_label);
+ ASSERT_EQ_ORIGIN(ret, ptr);
for (int i = 0; i < 8; ++i) {
ASSERT_LABEL(buf[i], j_label);
+ ASSERT_EQ_ORIGIN(buf[i], j);
assert(buf[i] == 'a');
}
}
-#endif // !defined(ORIGIN_TRACKING)
void test_strcmp() {
char str1[] = "str1", str2[] = "str2";
@@ -278,18 +305,34 @@ void test_strcmp() {
#endif
}
-#if !defined(ORIGIN_TRACKING)
void test_strcat() {
char src[] = "world";
+ int volatile x = 0; // buffer to ensure src and dst do not share origins
char dst[] = "hello \0 ";
+ int volatile y = 0; // buffer to ensure dst and p do not share origins
char *p = dst;
dfsan_set_label(k_label, &p, sizeof(p));
dfsan_set_label(i_label, src, sizeof(src));
dfsan_set_label(j_label, dst, sizeof(dst));
+ dfsan_origin dst_o = dfsan_get_origin((long)dst[0]);
char *ret = strcat(p, src);
ASSERT_LABEL(ret, k_label);
+ ASSERT_EQ_ORIGIN(ret, p);
assert(ret == dst);
assert(strcmp(src, dst + 6) == 0);
+ // Origins are assigned for every 4 contiguous 4-aligned bytes. After
+ // appending src to dst, origins of src can overwrite origins of dst if their
+ // application adddresses are within [start_aligned_down, end_aligned_up).
+ // Other origins are not changed.
+ char *start_aligned_down = (char *)(((size_t)(dst + 6)) & ~3UL);
+ char *end_aligned_up = (char *)(((size_t)(dst + 11 + 4)) & ~3UL);
+ for (int i = 0; i < 12; ++i) {
+ if (dst + i < start_aligned_down || dst + i >= end_aligned_up) {
+ ASSERT_INIT_ORIGIN(&dst[i], dst_o);
+ } else {
+ ASSERT_INIT_ORIGIN_EQ_ORIGIN(&dst[i], src[0]);
+ }
+ }
for (int i = 0; i < 6; ++i) {
ASSERT_LABEL(dst[i], j_label);
}
@@ -299,7 +342,6 @@ void test_strcat() {
}
ASSERT_LABEL(dst[11], j_label);
}
-#endif // !defined(ORIGIN_TRACKING)
void test_strlen() {
char str1[] = "str1";
@@ -315,14 +357,22 @@ void test_strlen() {
#endif
}
-#if !defined(ORIGIN_TRACKING)
void test_strdup() {
char str1[] = "str1";
dfsan_set_label(i_label, &str1[3], 1);
+ DEFINE_AND_SAVE_ORIGINS(str1)
char *strd = strdup(str1);
+ ASSERT_ZERO_LABEL(strd);
ASSERT_ZERO_LABEL(strd[0]);
ASSERT_LABEL(strd[3], i_label);
+
+ for (int i = 0; i < strlen(strd); ++i) {
+ if (!dfsan_get_label(strd[i]))
+ continue;
+ ASSERT_INIT_ORIGIN(&(strd[i]), str1_o[i]);
+ }
+
free(strd);
}
@@ -339,16 +389,29 @@ void test_strncpy() {
ASSERT_ZERO_LABEL(strd[1]);
ASSERT_ZERO_LABEL(strd[2]);
ASSERT_LABEL(strd[3], i_label);
+ ASSERT_INIT_ORIGIN_EQ_ORIGIN(&(strd[3]), str1[3]);
- strd = strncpy(str2, str1, 3);
+ char *p2 = str2;
+ dfsan_set_label(j_label, &p2, sizeof(p2));
+ strd = strncpy(p2, str1, 3);
assert(strd == str2);
assert(strncmp(str1, str2, 3) == 0);
- ASSERT_ZERO_LABEL(strd);
+ ASSERT_LABEL(strd, j_label);
+ ASSERT_EQ_ORIGIN(strd, p2);
+ // When -dfsan-combine-pointer-labels-on-load is on, strd's label propagates
+ // to strd[i]'s label. When ORIGIN_TRACKING is defined,
+ // -dfsan-combine-pointer-labels-on-load is always off, otherwise the flag
+ // is on by default.
+#if defined(ORIGIN_TRACKING)
ASSERT_ZERO_LABEL(strd[0]);
ASSERT_ZERO_LABEL(strd[1]);
ASSERT_ZERO_LABEL(strd[2]);
+#else
+ ASSERT_LABEL(strd[0], j_label);
+ ASSERT_LABEL(strd[1], j_label);
+ ASSERT_LABEL(strd[2], j_label);
+#endif
}
-#endif // !defined(ORIGIN_TRACKING)
void test_strncmp() {
char str1[] = "str1", str2[] = "str2";
@@ -523,7 +586,6 @@ void test_strchr() {
#endif
}
-#if !defined(ORIGIN_TRACKING)
void test_calloc() {
// With any luck this sequence of calls will cause calloc to return the same
// pointer both times. This is probably the best we can do to test this
@@ -538,6 +600,7 @@ void test_calloc() {
free(crv);
}
+#if !defined(ORIGIN_TRACKING)
void test_recvmmsg() {
int sockfds[2];
int ret = socketpair(AF_UNIX, SOCK_DGRAM, 0, sockfds);
@@ -630,12 +693,14 @@ void test_recvmsg() {
close(sockfds[0]);
close(sockfds[1]);
}
+#endif // !defined(ORIGIN_TRACKING)
void test_read() {
char buf[16];
dfsan_set_label(i_label, buf, 1);
dfsan_set_label(j_label, buf + 15, 1);
+ DEFINE_AND_SAVE_ORIGINS(buf)
ASSERT_LABEL(buf[0], i_label);
ASSERT_LABEL(buf[15], j_label);
@@ -645,6 +710,7 @@ void test_read() {
ASSERT_ZERO_LABEL(rv);
ASSERT_ZERO_LABEL(buf[0]);
ASSERT_ZERO_LABEL(buf[15]);
+ ASSERT_SAVED_ORIGINS(buf)
close(fd);
}
@@ -653,6 +719,7 @@ void test_pread() {
dfsan_set_label(i_label, buf, 1);
dfsan_set_label(j_label, buf + 15, 1);
+ DEFINE_AND_SAVE_ORIGINS(buf)
ASSERT_LABEL(buf[0], i_label);
ASSERT_LABEL(buf[15], j_label);
@@ -662,6 +729,7 @@ void test_pread() {
ASSERT_ZERO_LABEL(rv);
ASSERT_ZERO_LABEL(buf[0]);
ASSERT_ZERO_LABEL(buf[15]);
+ ASSERT_SAVED_ORIGINS(buf)
close(fd);
}
@@ -678,12 +746,15 @@ void test_dlopen() {
void test_clock_gettime() {
struct timespec tp;
dfsan_set_label(j_label, ((char *)&tp) + 3, 1);
+ dfsan_origin origin = dfsan_get_origin((long)(((char *)&tp)[3]));
int t = clock_gettime(CLOCK_REALTIME, &tp);
assert(t == 0);
ASSERT_ZERO_LABEL(t);
ASSERT_ZERO_LABEL(((char *)&tp)[3]);
+ ASSERT_ORIGIN(((char *)&tp)[3], origin);
}
+#if !defined(ORIGIN_TRACKING)
void test_ctime_r() {
char *buf = (char*) malloc(64);
time_t t = 0;
@@ -704,6 +775,7 @@ void test_ctime_r() {
ASSERT_LABEL(ret, j_label);
ASSERT_READ_ZERO_LABEL(buf, strlen(buf) + 1);
}
+#endif // !defined(ORIGIN_TRACKING)
static int write_callback_count = 0;
static int last_fd;
@@ -728,6 +800,8 @@ void test_dfsan_set_write_callback() {
write_callback_count = 0;
+ DEFINE_AND_SAVE_ORIGINS(buf)
+
// Callback should be invoked on every call to write().
int res = write(fd, buf, buf_len);
assert(write_callback_count == 1);
@@ -736,12 +810,21 @@ void test_dfsan_set_write_callback() {
ASSERT_READ_ZERO_LABEL(last_buf, sizeof(last_buf));
ASSERT_READ_ZERO_LABEL(&last_count, sizeof(last_count));
+ for (int i = 0; i < buf_len; ++i)
+ ASSERT_ORIGIN(last_buf[i], buf_o[i]);
+
+ ASSERT_ZERO_ORIGINS(&last_count, sizeof(last_count));
+
// Add a label to write() arguments. Check that the labels are readable from
// the values passed to the callback.
dfsan_set_label(i_label, &fd, sizeof(fd));
dfsan_set_label(j_label, &(buf[3]), 1);
dfsan_set_label(k_label, &buf_len, sizeof(buf_len));
+ dfsan_origin fd_o = dfsan_get_origin((long)fd);
+ dfsan_origin buf3_o = dfsan_get_origin((long)(buf[3]));
+ dfsan_origin buf_len_o = dfsan_get_origin((long)buf_len);
+
res = write(fd, buf, buf_len);
assert(write_callback_count == 2);
ASSERT_READ_ZERO_LABEL(&res, sizeof(res));
@@ -749,10 +832,27 @@ void test_dfsan_set_write_callback() {
ASSERT_READ_LABEL(&last_buf[3], sizeof(last_buf[3]), j_label);
ASSERT_READ_LABEL(last_buf, sizeof(last_buf), j_label);
ASSERT_READ_LABEL(&last_count, sizeof(last_count), k_label);
+ ASSERT_ZERO_ORIGINS(&res, sizeof(res));
+ ASSERT_INIT_ORIGINS(&last_fd, sizeof(last_fd), fd_o);
+ ASSERT_INIT_ORIGINS(&last_buf[3], sizeof(last_buf[3]), buf3_o);
+
+ // Origins are assigned for every 4 contiguous 4-aligned bytes. After
+ // appending src to dst, origins of src can overwrite origins of dst if their
+ // application adddresses are within an aligned range. Other origins are not
+ // changed.
+ for (int i = 0; i < buf_len; ++i) {
+ size_t i_addr = size_t(&last_buf[i]);
+ if (((size_t(&last_buf[3]) & ~3UL) > i_addr) ||
+ (((size_t(&last_buf[3]) + 4) & ~3UL) <= i_addr))
+ ASSERT_ORIGIN(last_buf[i], buf_o[i]);
+ }
+
+ ASSERT_INIT_ORIGINS(&last_count, sizeof(last_count), buf_len_o);
dfsan_set_write_callback(NULL);
}
+#if !defined(ORIGIN_TRACKING)
void test_fgets() {
char *buf = (char*) malloc(128);
FILE *f = fopen("/etc/passwd", "r");
@@ -1126,7 +1226,6 @@ void test_pthread_create() {
// check-wrappers script.
void test_pthread_join() {}
-#if !defined(ORIGIN_TRACKING)
int dl_iterate_phdr_test_cb(struct dl_phdr_info *info, size_t size,
void *data) {
assert(data == (void *)3);
@@ -1151,11 +1250,16 @@ void test__dl_get_tls_static_info() {
size_t sizep = 0, alignp = 0;
dfsan_set_label(i_label, &sizep, sizeof(sizep));
dfsan_set_label(i_label, &alignp, sizeof(alignp));
+ dfsan_origin sizep_o = dfsan_get_origin(sizep);
+ dfsan_origin alignp_o = dfsan_get_origin(alignp);
_dl_get_tls_static_info(&sizep, &alignp);
ASSERT_ZERO_LABEL(sizep);
ASSERT_ZERO_LABEL(alignp);
+ ASSERT_ORIGIN(sizep, sizep_o);
+ ASSERT_ORIGIN(alignp, alignp_o);
}
+#if !defined(ORIGIN_TRACKING)
void test_strrchr() {
char str1[] = "str1str1";
dfsan_set_label(i_label, &str1[7], 1);
@@ -1559,17 +1663,17 @@ int main(void) {
assert(i_j_label != j_label);
assert(i_j_label != k_label);
-#if !defined(ORIGIN_TRACKING)
test__dl_get_tls_static_info();
-#endif // !defined(ORIGIN_TRACKING)
test_bcmp();
-#if !defined(ORIGIN_TRACKING)
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)
@@ -1591,18 +1695,18 @@ int main(void) {
test_memchr();
#endif // !defined(ORIGIN_TRACKING)
test_memcmp();
-#if !defined(ORIGIN_TRACKING)
test_memcpy();
test_memmove();
test_memset();
+#if !defined(ORIGIN_TRACKING)
test_nanosleep();
test_poll();
- test_pread();
#endif // !defined(ORIGIN_TRACKING)
+ test_pread();
test_pthread_create();
test_pthread_join();
-#if !defined(ORIGIN_TRACKING)
test_read();
+#if !defined(ORIGIN_TRACKING)
test_recvmmsg();
test_recvmsg();
test_sched_getaffinity();
@@ -1621,17 +1725,15 @@ int main(void) {
test_strcasecmp();
test_strchr();
test_strcmp();
-#if !defined(ORIGIN_TRACKING)
test_strcat();
+#if !defined(ORIGIN_TRACKING)
test_strcpy();
- test_strdup();
#endif // !defined(ORIGIN_TRACKING)
+ test_strdup();
test_strlen();
test_strncasecmp();
test_strncmp();
-#if !defined(ORIGIN_TRACKING)
test_strncpy();
-#endif // !defined(ORIGIN_TRACKING)
test_strpbrk();
#if !defined(ORIGIN_TRACKING)
test_strrchr();
More information about the llvm-commits
mailing list