[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
This commit is contained in:
Jianzhou Zhao 2021-03-17 16:22:01 +00:00
parent fb4f6057a6
commit 1fe042041c
4 changed files with 337 additions and 28 deletions

View File

@ -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];

View File

@ -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"

View File

@ -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) {

View File

@ -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();