forked from OSchip/llvm-project
[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:
parent
fb4f6057a6
commit
1fe042041c
|
@ -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];
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue