提交 253f3e23 编写于 作者: D dhy308

Fix code review issues.

Issue: I6A9R5
Test: libc-test pass
Signed-off-by: Ndhy308 <tony.gan@huawei.com>
上级 06dc6a9e
......@@ -21,15 +21,14 @@
#include "functionalext.h"
#define LIB_PATH "/data/tests/libc-test/src/libldso_cfi_test_lib.so"
#define BAD_LIB_PATH "/data/tests/libc-test/src/libldso_cfi_test_bad_lib.so"
struct dso {
char *mock;
char *mock;
unsigned char *map;
size_t map_len;
size_t map_len;
};
extern int init_cfi_shadow(struct dso *dso_list);
extern int init_cfi_shadow(struct dso *dso_list, struct dso *ldso);
extern int map_dso_to_cfi_shadow(struct dso *dso);
extern void unmap_dso_from_cfi_shadow(struct dso *dso);
extern void __cfi_slowpath(uint64_t CallSiteTypeId, void *Ptr);
......@@ -62,7 +61,7 @@ static void test_func() {}
void cfi_init_test_0001(void)
{
printf("["__FILE__"][Line: %d][%s]: entry\n", __LINE__, __func__);
EXPECT_EQ("cfi_init_test_0001", init_cfi_shadow(NULL), 0);
EXPECT_EQ("cfi_init_test_0001", init_cfi_shadow(NULL, NULL), 0);
}
/**
......@@ -88,7 +87,7 @@ void cfi_init_test_0003(void)
}
/**
* @tc.name : cfi_slowpath_function_test_0001
* @tc.name : cfi_slowpath_function_test_0002
* @tc.desc : Loading a dso that contains __cfi_check() symbol, call the __cfi_slowpath() function with
* address inside the DSO, the __cfi_check() function is called.
* @tc.level : Level 1
......@@ -96,6 +95,7 @@ void cfi_init_test_0003(void)
void cfi_slowpath_function_test_0002(void)
{
printf("["__FILE__"][Line: %d][%s]: entry\n", __LINE__, __func__);
uint64_t expected_call_site_type_id = 20;
void* handle = dlopen(LIB_PATH, RTLD_LAZY);
EXPECT_PTRNE("cfi_slowpath_function_test_0002", handle, NULL);
......@@ -107,8 +107,8 @@ void cfi_slowpath_function_test_0002(void)
size_t count = (*get_count)();
__cfi_slowpath(20, (*get_global_address)());
EXPECT_EQ("cfi_slowpath_function_test_0002", 20, (*get_type_id)());
__cfi_slowpath(expected_call_site_type_id, (*get_global_address)());
EXPECT_EQ("cfi_slowpath_function_test_0002", expected_call_site_type_id, (*get_type_id)());
EXPECT_EQ("cfi_slowpath_function_test_0002", (*get_global_address)(), (*get_address)());
EXPECT_EQ("cfi_slowpath_function_test_0002", NULL, (*get_diag)());
EXPECT_EQ("cfi_slowpath_function_test_0002", ++count, (*get_count)());
......@@ -127,6 +127,8 @@ void cfi_slowpath_function_test_0002(void)
void cfi_slowpath_function_test_0003(void)
{
printf("["__FILE__"][Line: %d][%s]: entry\n", __LINE__, __func__);
uint64_t expected_call_site_type_id = 30;
uint64_t unexpected_call_site_type_id = 40;
void* handle = dlopen(LIB_PATH, RTLD_LAZY);
EXPECT_PTRNE("cfi_slowpath_function_test_0003", handle, NULL);
......@@ -136,10 +138,10 @@ void cfi_slowpath_function_test_0003(void)
*(void **)(&get_diag) = dlsym(handle, "get_diag");
*(void **)(&get_global_address) = dlsym(handle, "get_global_address");
__cfi_slowpath(30, (*get_global_address)());
__cfi_slowpath(expected_call_site_type_id, (*get_global_address)());
size_t count = (*get_count)();
__cfi_slowpath(40, (void*)(&test_func));
EXPECT_EQ("cfi_slowpath_function_test_0003", 30, (*get_type_id)());
__cfi_slowpath(unexpected_call_site_type_id, (void*)(&test_func));
EXPECT_EQ("cfi_slowpath_function_test_0003", expected_call_site_type_id, (*get_type_id)());
EXPECT_EQ("cfi_slowpath_function_test_0003", (*get_global_address)(), (*get_address)());
EXPECT_EQ("cfi_slowpath_function_test_0003", NULL, (*get_diag)());
EXPECT_EQ("cfi_slowpath_function_test_0003", count, (*get_count)());
......@@ -156,13 +158,14 @@ void cfi_slowpath_function_test_0003(void)
void cfi_slowpath_function_test_0004(void)
{
printf("["__FILE__"][Line: %d][%s]: entry\n", __LINE__, __func__);
uint64_t call_site_type_id = 30;
void* handle = dlopen(LIB_PATH, RTLD_LAZY);
EXPECT_PTRNE("cfi_slowpath_function_test_0004", handle, NULL);
*(void **)(&get_count) = dlsym(handle, "get_count");
size_t count = (*get_count)();
__cfi_slowpath(30, NULL);
__cfi_slowpath(call_site_type_id, NULL);
EXPECT_EQ("cfi_slowpath_function_test_0004", count, (*get_count)());
dlclose(handle);
......@@ -173,12 +176,12 @@ void cfi_slowpath_function_test_0004(void)
* @tc.name : cfi_slowpath_function_test_0005
* @tc.desc : Loading a dso that contains __cfi_check() symbol, call the __cfi_slowpath() function with
* invalid address, coredump happened.
* not called.
* @tc.level : Level 2
*/
void cfi_slowpath_function_test_0005(void)
{
printf("["__FILE__"][Line: %d][%s]: entry\n", __LINE__, __func__);
uint64_t call_site_type_id = 30;
void* handle = dlopen(LIB_PATH, RTLD_LAZY);
EXPECT_PTRNE("cfi_slowpath_function_test_0005", handle, NULL);
......@@ -192,12 +195,12 @@ void cfi_slowpath_function_test_0005(void)
int status;
pid_t pid;
pid = fork();
if(pid > 0) {
if (pid > 0) {
printf("["__FILE__"][Line: %d][%s]: parent process pid = %d\n", __LINE__, __func__, getppid());
wait(&status);
} else if(pid == 0) {
} else if (pid == 0) {
printf("["__FILE__"][Line: %d][%s]: child pid = %d\n", __LINE__, __func__, pid);
__cfi_slowpath(30, (void*)&count);
__cfi_slowpath(call_site_type_id, (void*)&count);
} else {
printf("["__FILE__"][Line: %d][%s]: fork failed!\n", __LINE__, __func__);
}
......@@ -214,6 +217,7 @@ void cfi_slowpath_function_test_0005(void)
void cfi_slowpath_function_test_0006(void)
{
printf("["__FILE__"][Line: %d][%s]: entry\n", __LINE__, __func__);
uint64_t call_site_type_id = 50;
void* handle = dlopen(LIB_PATH, RTLD_LAZY);
EXPECT_PTRNE("cfi_slowpath_function_test_0006", handle, NULL);
......@@ -224,7 +228,7 @@ void cfi_slowpath_function_test_0006(void)
const size_t bss_size = 1024 * 1024;
for (size_t i = 0; i < bss_size; ++i) {
__cfi_slowpath(50, (char*)buf_check + i);
__cfi_slowpath(call_site_type_id, (char*)buf_check + i);
EXPECT_EQ("cfi_slowpath_function_test_0006", ++count, (*get_count)());
}
......@@ -240,12 +244,14 @@ void cfi_slowpath_function_test_0006(void)
void cfi_slowpath_function_test_0007(void)
{
printf("["__FILE__"][Line: %d][%s]: entry\n", __LINE__, __func__);
uint64_t call_site_type_id1 = 10;
uint64_t call_site_type_id2 = 20;
void* handle = dlopen(LIB_PATH, RTLD_LAZY);
EXPECT_PTRNE("cfi_slowpath_function_test_0007", handle, NULL);
*(void **)(&get_count) = dlsym(handle, "get_count");
*(void **)(&get_global_address) = dlsym(handle, "get_global_address");
__cfi_slowpath(10, (*get_global_address)());
__cfi_slowpath(call_site_type_id1, (*get_global_address)());
void* handle2 = dlopen(LIB_PATH, RTLD_LAZY);
EXPECT_PTREQ("cfi_slowpath_function_test_0007", handle, handle2);
......@@ -256,10 +262,10 @@ void cfi_slowpath_function_test_0007(void)
*(void **)(&get_global_address) = dlsym(handle2, "get_global_address");
size_t count = (*get_count)();
__cfi_slowpath(20, (*get_global_address)());
EXPECT_EQ("cfi_slowpath_function_test_0002", 20, (*get_type_id)());
EXPECT_EQ("cfi_slowpath_function_test_0002", (*get_global_address)(), (*get_address)());
EXPECT_EQ("cfi_slowpath_function_test_0002", ++count, (*get_count)());
__cfi_slowpath(call_site_type_id2, (*get_global_address)());
EXPECT_EQ("cfi_slowpath_function_test_0007", call_site_type_id2, (*get_type_id)());
EXPECT_EQ("cfi_slowpath_function_test_0007", (*get_global_address)(), (*get_address)());
EXPECT_EQ("cfi_slowpath_function_test_0007", ++count, (*get_count)());
dlclose(handle);
dlclose(handle2);
......@@ -274,6 +280,7 @@ void cfi_slowpath_function_test_0007(void)
void cfi_slowpath_function_test_0008(void)
{
printf("["__FILE__"][Line: %d][%s]: entry\n", __LINE__, __func__);
uint64_t call_site_type_id = 30;
void* handle = dlopen(LIB_PATH, RTLD_LAZY);
EXPECT_PTRNE("cfi_slowpath_function_test_0008", handle, NULL);
*(void **)(&get_global_address) = dlsym(handle, "get_global_address");
......@@ -282,12 +289,12 @@ void cfi_slowpath_function_test_0008(void)
int status;
pid_t pid;
pid = fork();
if(pid > 0) {
if (pid > 0) {
printf("["__FILE__"][Line: %d][%s]: parent process pid = %d\n", __LINE__, __func__, getppid());
wait(&status);
} else if(pid == 0) {
} else if (pid == 0) {
printf("["__FILE__"][Line: %d][%s]: child pid = %d\n", __LINE__, __func__, pid);
__cfi_slowpath(30, (*get_global_address)());
__cfi_slowpath(call_site_type_id, (*get_global_address)());
} else {
printf("["__FILE__"][Line: %d][%s]: fork failed!\n", __LINE__, __func__);
}
......@@ -303,20 +310,25 @@ void cfi_slowpath_function_test_0008(void)
void cfi_slowpath_diag_function_test_0001(void)
{
printf("["__FILE__"][Line: %d][%s]: entry\n", __LINE__, __func__);
uint64_t call_site_type_id = 10;
uint64_t diag_info = 0;
void* handle = dlopen(LIB_PATH, RTLD_LAZY);
EXPECT_PTRNE("cfi_slowpath_diag_function_test_0002", handle, NULL);
EXPECT_PTRNE("cfi_slowpath_diag_function_test_0001", handle, NULL);
*(void **)(&get_count) = dlsym(handle, "get_count");
*(void **)(&get_type_id) = dlsym(handle, "get_type_id");
*(void **)(&get_diag) = dlsym(handle, "get_diag");
*(void **)(&get_global_address) = dlsym(handle, "get_global_address");
size_t count = (*get_count)();
void* diag_ptr = (void*)(5678);
__cfi_slowpath_diag(10, NULL, diag_ptr);
EXPECT_EQ("cfi_slowpath_diag_function_test_0002", count, (*get_count)());
__cfi_slowpath_diag(call_site_type_id, NULL, &diag_info);
EXPECT_EQ("cfi_slowpath_diag_function_test_0001", count, (*get_count)());
__cfi_slowpath_diag(10, (*get_global_address)(), NULL);
EXPECT_EQ("cfi_slowpath_diag_function_test_0002", ++count, (*get_count)());
__cfi_slowpath_diag(call_site_type_id, (*get_global_address)(), &diag_info);
EXPECT_EQ("cfi_slowpath_diag_function_test_0001", ++count, (*get_count)());
EXPECT_EQ("cfi_slowpath_diag_function_test_0001", call_site_type_id, (*get_type_id)());
EXPECT_EQ("cfi_slowpath_diag_function_test_0001", (*get_diag)(), &diag_info);
dlclose(handle);
printf("["__FILE__"][Line: %d][%s]: end\n", __LINE__, __func__);
......@@ -372,7 +384,7 @@ TEST_FUN G_Fun_Array[] = {
int main(void)
{
printf("["__FILE__"][Line: %d][%s]: entry\n", __LINE__, __func__);
int num = sizeof(G_Fun_Array)/sizeof(TEST_FUN);
int num = sizeof(G_Fun_Array) / sizeof(TEST_FUN);
for (int pos = 0; pos < num; ++pos) {
G_Fun_Array[pos]();
}
......
......@@ -27,13 +27,13 @@ static void *g_diag = NULL;
char buf[1024 * 1024];
// Mock a CFI-enabled library without relying on the compiler.
__attribute__((aligned(4096))) void __cfi_check(uint64_t CallSiteTypeId,
void *TargetAddr, void *Diag) {
__attribute__((aligned(4096))) void __cfi_check(uint64_t call_site_type_id,
void *target_addr, void *diag) {
printf("["__FILE__"][Line: %d][%s]: entry\n", __LINE__, __func__);
++g_count;
g_type_id = CallSiteTypeId;
g_address = TargetAddr;
g_diag = Diag;
g_type_id = call_site_type_id;
g_address = target_addr;
g_diag = diag;
}
size_t get_count() {
......
......@@ -63,8 +63,7 @@
* - First align up the target addr with LIBRARY_ALIGNMENT to locate the corresponding shadow value.
* - Then calculate the __cfi_check addr.
*
* In order for the algorithm to work well, the start addr of each dso should be aligned with LIBRARY_ALIGNMENT.
*/
* In order for the algorithm to work well, the start addr of each dso should be aligned with LIBRARY_ALIGNMENT. */
#define MAX(a,b) (((a) > (b)) ? (a) : (b))
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
......@@ -87,23 +86,20 @@ static uintptr_t shadow_size = 0;
static char *cfi_shadow_start = NULL;
/* List head of all the DSOs loaded by the process */
static struct dso *dso_list_head = NULL;
static char* ldso_name = NULL;
static struct dso *pldso = NULL;
/* Shadow value */
/* The related shadow value(s) will be set to `sv_invalid` when:
* - init CFI shadow.
* - removing a dso.
*/
* - removing a dso. */
static const uint16_t sv_invalid = 0;
/* The related shadow value(s) will be set to `sv_uncheck` if:
* - the DSO does not enable CFI Cross-Dso.
* - the DSO enabled CFI Cross-Dso, but this DSO is larger than 16G, for the part of the dso that exceeds 16G,
* its shadow value will be set to `sv_uncheck`.
*/
* its shadow value will be set to `sv_uncheck`. */
static const uint16_t sv_uncheck = 1;
/* If a DSO enabled CFI Cross-Dso, the DSO's shadow value should be valid. Because of the defination of `sv_invalid`
* and `sv_unchecked`, the valid shadow value should be at least 2.
*/
* and `sv_unchecked`, the valid shadow value should be at least 2. */
static const uint16_t sv_valid_min = 2;
#if defined(__LP64__)
......@@ -126,52 +122,81 @@ void __cfi_slowpath_diag(uint64_t call_site_type_id, void *func_ptr, void *diag_
static inline uintptr_t addr_to_offset(uintptr_t addr, int bits)
{
/* Convert addr to CFI shadow offset.
* Shift left 1 bit because the shadow value is uint16_t.
*/
* Shift left 1 bit because the shadow value is uint16_t. */
return (addr >> bits) << 1;
}
static struct symdef find_cfi_check_sym(struct dso *p)
{
LD_LOGD("[%{public}s] start!\n", __FUNCTION__);
LD_LOGD("[CFI] [%{public}s] start!\n", __FUNCTION__);
struct verinfo verinfo = { .s = "__cfi_check", .v = "", .use_vna_hash = false };
struct sym_info_pair s_info_p = gnu_hash(verinfo.s);
return find_sym_impl(p, &verinfo, s_info_p, 0, p->namespace);
}
static int is_addr_in_ldso(size_t a)
{
size_t i = 0;
if (DL_FDPIC) {
i = count_syms(pldso);
if (a - (size_t)pldso->funcdescs < i * sizeof(*pldso->funcdescs))
return 1;
}
if (DL_FDPIC && pldso->loadmap) {
for (i = 0; i < pldso->loadmap->nsegs; i++) {
if (a-pldso->loadmap->segs[i].p_vaddr
< pldso->loadmap->segs[i].p_memsz)
return 1;
}
} else {
Phdr *ph = pldso->phdr;
size_t phcnt = pldso->phnum;
size_t entsz = pldso->phentsize;
size_t base = (size_t)pldso->base;
for (; phcnt--; ph = (void *)((char *)ph + entsz)) {
if (ph->p_type != PT_LOAD) continue;
if (a - base - ph->p_vaddr < ph->p_memsz)
return 1;
}
if (a - (size_t)pldso->map < pldso->map_len)
return 0;
}
return 0;
}
static uintptr_t get_cfi_check_addr(uint16_t value, void* func_ptr)
{
LD_LOGD("[%{public}s] start!\n", __FUNCTION__);
LD_LOGD("[CFI] [%{public}s] start!\n", __FUNCTION__);
uintptr_t addr = (uintptr_t)func_ptr;
uintptr_t aligned_addr = ALIGN_DOWN(addr, shadow_alignment) + shadow_alignment;
uintptr_t cfi_check_func_addr = aligned_addr - ((uintptr_t)(value - sv_valid_min) << cfi_check_granularity);
#ifdef __arm__
LD_LOGD("[%{public}s] __arm__ defined!\n", __FUNCTION__);
LD_LOGD("[CFI] [%{public}s] __arm__ defined!\n", __FUNCTION__);
cfi_check_func_addr++;
#endif
LD_LOGI("[%{public}s] the cfi_check_func_addr is %{public}p!\n", __FUNCTION__, cfi_check_func_addr);
LD_LOGI("[CFI] [%{public}s] the cfi_check_func_addr is %{public}p!\n", __FUNCTION__, cfi_check_func_addr);
return cfi_check_func_addr;
}
static inline void cfi_slowpath_common(uint64_t call_site_type_id, void *func_ptr, void *diag_data)
{
LD_LOGI("[%{public}s] func_ptr[%{public}p] !\n", __FUNCTION__, func_ptr);
LD_LOGI("[CFI] [%{public}s] func_ptr[%{public}p] !\n", __FUNCTION__, func_ptr);
uint16_t value = sv_invalid;
if (func_ptr == NULL) {
LD_LOGE("[%{public}s] func_ptr is NULL!\n", __FUNCTION__);
LD_LOGE("[CFI] [%{public}s] func_ptr is NULL!\n", __FUNCTION__);
return;
}
#if defined(__aarch64__)
LD_LOGD("[%{public}s] __aarch64__ defined!\n", __FUNCTION__);
LD_LOGD("[CFI] [%{public}s] __aarch64__ defined!\n", __FUNCTION__);
uintptr_t addr = (uintptr_t)func_ptr & ((1ULL << 56) - 1);
#else
LD_LOGD("[%{public}s] __aarch64__ not defined!\n", __FUNCTION__);
LD_LOGD("[CFI] [%{public}s] __aarch64__ not defined!\n", __FUNCTION__);
uintptr_t addr = func_ptr;
#endif
......@@ -179,7 +204,7 @@ static inline void cfi_slowpath_common(uint64_t call_site_type_id, void *func_pt
uintptr_t offset = addr_to_offset(addr, shadow_granularity);
if (cfi_shadow_start == NULL) {
LD_LOGE("[%{public}s] the cfi_shadow_start is null!\n", __FUNCTION__);
LD_LOGE("[CFI] [%{public}s] the cfi_shadow_start is null!\n", __FUNCTION__);
__builtin_trap();
}
......@@ -188,33 +213,32 @@ static inline void cfi_slowpath_common(uint64_t call_site_type_id, void *func_pt
} else {
value = *((uint16_t*)(cfi_shadow_start + offset));
}
LD_LOGI("[%{public}s] the value is 0x%{public}x!\n", __FUNCTION__, value);
LD_LOGI("[CFI] [%{public}s] the value is 0x%{public}x!\n", __FUNCTION__, value);
struct dso *dso = NULL;
switch (value)
{
case sv_invalid:
/* The ldso is an exception because it is loaded by kernel and is not mapped to the CFI shadow.
* Do not check it. */
if (is_addr_in_ldso((size_t)func_ptr)) {
LD_LOGI("[CFI] [%{public}s] uncheck for ldso\n", __FUNCTION__);
return;
}
dso = (struct dso *)addr2dso((size_t)__builtin_return_address(0));
if (dso == NULL) {
LD_LOGE("[%{public}s] can not find the dso!\n", __FUNCTION__);
LD_LOGE("[CFI] [%{public}s] can not find the dso!\n", __FUNCTION__);
__builtin_trap();
}
LD_LOGI("[%{public}s] dso name[%{public}s]!\n", __FUNCTION__, dso->name);
/* The ldso is an exception because it is loaded by kernel and is not mapped to the CFI shadow.
* Do not check it.
*/
if (strcmp(ldso_name, dso->name) == 0) {
LD_LOGI("[%{public}s] uncheck for ldso\n", __FUNCTION__);
return;
}
LD_LOGI("[CFI] [%{public}s] dso name[%{public}s]!\n", __FUNCTION__, dso->name);
struct symdef cfi_check_sym = find_cfi_check_sym(dso);
if (!cfi_check_sym.sym) {
LD_LOGE("[%{public}s] can not find the __cfi_check in the dso!\n", __FUNCTION__);
LD_LOGE("[CFI] [%{public}s] can not find the __cfi_check in the dso!\n", __FUNCTION__);
__builtin_trap();
}
LD_LOGD("[%{public}s] cfi_check addr[%{public}p]!\n", __FUNCTION__,
LD_LOGD("[CFI] [%{public}s] cfi_check addr[%{public}p]!\n", __FUNCTION__,
LADDR(cfi_check_sym.dso, cfi_check_sym.sym->st_value));
((cfi_check_t)LADDR(cfi_check_sym.dso, cfi_check_sym.sym->st_value))(call_site_type_id, func_ptr, diag_data);
break;
......@@ -228,56 +252,56 @@ static inline void cfi_slowpath_common(uint64_t call_site_type_id, void *func_pt
return;
}
int init_cfi_shadow(struct dso *dso_list, char *so_name)
int init_cfi_shadow(struct dso *dso_list, struct dso *ldso)
{
LD_LOGI("[%{public}s] start!\n", __FUNCTION__);
LD_LOGI("[CFI] [%{public}s] start!\n", __FUNCTION__);
if (dso_list == NULL) {
LD_LOGW("[%{public}s] has null param!\n", __FUNCTION__);
LD_LOGW("[CFI] [%{public}s] has null param!\n", __FUNCTION__);
return CFI_SUCCESS;
}
/* Save the head node of dso list */
dso_list_head = dso_list;
ldso_name = so_name;
pldso = ldso;
return map_dso_to_cfi_shadow(dso_list);
}
int map_dso_to_cfi_shadow(struct dso *dso)
{
LD_LOGI("[%{public}s] start!\n", __FUNCTION__);
LD_LOGI("[CFI] [%{public}s] start!\n", __FUNCTION__);
bool has_cfi_check = false;
if (dso == NULL) {
LD_LOGW("[%{public}s] has null param!\n", __FUNCTION__);
LD_LOGW("[CFI] [%{public}s] has null param!\n", __FUNCTION__);
return CFI_SUCCESS;
}
/* Find __cfi_check symbol in dso list */
for (struct dso *p = dso; p; p = p->next) {
if (find_cfi_check_sym(p).sym) {
LD_LOGI("[%{public}s] find __cfi_check function in dso %{public}s!\n", __FUNCTION__, p->name);
has_cfi_check = true;
break;
}
}
/* If the cfi shadow does not exist, create it and map all the dsos and its dependents to it. */
if (cfi_shadow_start == NULL) {
/* Find __cfi_check symbol in dso list */
for (struct dso *p = dso; p; p = p->next) {
if (find_cfi_check_sym(p).sym) {
LD_LOGI("[CFI] [%{public}s] find __cfi_check function in dso %{public}s!\n", __FUNCTION__, p->name);
has_cfi_check = true;
break;
}
}
if (has_cfi_check) {
if (create_cfi_shadow() == CFI_FAILED) {
LD_LOGE("[%{public}s] create cfi shadow failed!\n", __FUNCTION__);
LD_LOGE("[CFI] [%{public}s] create cfi shadow failed!\n", __FUNCTION__);
return CFI_FAILED;
}
LD_LOGD("[%{public}s] add_dso_to_cfi_shadow with dso_list_head!\n", __FUNCTION__);
LD_LOGD("[CFI] [%{public}s] add_dso_to_cfi_shadow with dso_list_head!\n", __FUNCTION__);
add_dso_to_cfi_shadow(dso_list_head);
prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, cfi_shadow_start, shadow_size, "cfi_shadow:musl");
}
/* If the cfi shadow exists, map the current dso and its dependents to it. */
} else {
LD_LOGD("[%{public}s] add_dso_to_cfi_shadow with dso!\n", __FUNCTION__);
LD_LOGD("[CFI] [%{public}s] add_dso_to_cfi_shadow with dso!\n", __FUNCTION__);
add_dso_to_cfi_shadow(dso);
prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, cfi_shadow_start, shadow_size, "cfi_shadow:musl");
}
......@@ -287,14 +311,14 @@ int map_dso_to_cfi_shadow(struct dso *dso)
void unmap_dso_from_cfi_shadow(struct dso *dso)
{
LD_LOGD("[%{public}s] start!\n", __FUNCTION__);
LD_LOGD("[CFI] [%{public}s] start!\n", __FUNCTION__);
if (dso == NULL) {
LD_LOGE("[%{public}s] has null param!\n", __FUNCTION__);
LD_LOGE("[CFI] [%{public}s] has null param!\n", __FUNCTION__);
return;
}
LD_LOGI("[%{public}s] unmap dso %{public}s from shadow!\n", __FUNCTION__, dso->name);
LD_LOGI("[CFI] [%{public}s] unmap dso %{public}s from shadow!\n", __FUNCTION__, dso->name);
if (cfi_shadow_start == NULL)
return;
......@@ -315,68 +339,67 @@ void unmap_dso_from_cfi_shadow(struct dso *dso)
static int create_cfi_shadow(void)
{
LD_LOGD("[%{public}s] start!\n", __FUNCTION__);
LD_LOGD("[CFI] [%{public}s] start!\n", __FUNCTION__);
/* Each process can load up to (max_target_addr >> shadow_granularity) dsos. Shift left 1 bit because the shadow
* value is uint16_t. The size passed to mmap() should be aligned with 4096, so shadow_size should be aligned.
*/
* value is uint16_t. The size passed to mmap() should be aligned with 4096, so shadow_size should be aligned. */
shadow_size = ALIGN_UP(((max_target_addr >> shadow_granularity) << 1), PAGE_SIZE);
uintptr_t *mmap_addr = mmap(NULL, shadow_size, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, -1, 0);
if (mmap_addr == MAP_FAILED) {
LD_LOGE("[%{public}s] mmap failed!\n", __FUNCTION__);
LD_LOGE("[CFI] [%{public}s] mmap failed!\n", __FUNCTION__);
return CFI_FAILED;
}
cfi_shadow_start = (char*)mmap_addr;
LD_LOGI("[%{public}s] the cfi_shadow_start addr is %{public}p!\n", __FUNCTION__, cfi_shadow_start);
LD_LOGI("[CFI] [%{public}s] the cfi_shadow_start addr is %{public}p!\n", __FUNCTION__, cfi_shadow_start);
return CFI_SUCCESS;
}
static int add_dso_to_cfi_shadow(struct dso *dso)
{
LD_LOGI("[%{public}s] start!\n", __FUNCTION__);
LD_LOGI("[CFI] [%{public}s] start!\n", __FUNCTION__);
for (struct dso *p = dso; p; p = p->next) {
LD_LOGI("[%{public}s] start to deal with dso %{public}s!\n", __FUNCTION__, p->name);
LD_LOGI("[CFI] [%{public}s] start to deal with dso %{public}s!\n", __FUNCTION__, p->name);
if (p->map == 0 || p->map_len == 0) {
LD_LOGW("[%{public}s] the dso has no data! map[%{public}p] map_len[0x%{public}x]\n",
LD_LOGW("[CFI] [%{public}s] the dso has no data! map[%{public}p] map_len[0x%{public}x]\n",
__FUNCTION__, p->map, p->map_len);
continue;
}
if (p->is_mapped_to_shadow == true) {
LD_LOGW("[%{public}s] the dso is already in shadow!\n", __FUNCTION__);
LD_LOGW("[CFI] [%{public}s] the dso is already in shadow!\n", __FUNCTION__);
continue;
}
struct symdef cfi_check_sym = find_cfi_check_sym(p);
/* If the dso doesn't have __cfi_check(), set it's shadow value unchecked. */
if (!cfi_check_sym.sym) {
LD_LOGI("[%{public}s] the dso has no __cfi_check()!\n", __FUNCTION__);
LD_LOGI("[CFI] [%{public}s] the dso has no __cfi_check()!\n", __FUNCTION__);
if (fill_shadow_value_to_shadow(p->map, p->map + p->map_len, 0, sv_uncheck) == CFI_FAILED) {
LD_LOGE("[%{public}s] add dso to cfi shadow failed!\n", __FUNCTION__);
LD_LOGE("[CFI] [%{public}s] add dso to cfi shadow failed!\n", __FUNCTION__);
return CFI_FAILED;
}
/* If the dso has __cfi_check(), set it's shadow value valid. */
} else {
LD_LOGI("[%{public}s] the dso has __cfi_check()!\n", __FUNCTION__);
LD_LOGI("[CFI] [%{public}s] the dso has __cfi_check()!\n", __FUNCTION__);
uintptr_t end = p->map + p->map_len;
uintptr_t cfi_check = LADDR(cfi_check_sym.dso, cfi_check_sym.sym->st_value);
if (cfi_check == 0) {
LD_LOGE("[%{public}s] the dso has null cfi_check func!\n", __FUNCTION__);
LD_LOGE("[CFI] [%{public}s] the dso has null cfi_check func!\n", __FUNCTION__);
return CFI_FAILED;
}
if (fill_shadow_value_to_shadow(p->map, end, cfi_check, sv_valid_min) == CFI_FAILED) {
LD_LOGE("[%{public}s] add dso to cfi shadow failed!\n", __FUNCTION__);
LD_LOGE("[CFI] [%{public}s] add dso to cfi shadow failed!\n", __FUNCTION__);
return CFI_FAILED;
}
}
p->is_mapped_to_shadow = true;
LD_LOGI("[%{public}s] finish to deal with dso %{public}s!\n", __FUNCTION__, p->name);
LD_LOGI("[CFI] [%{public}s] finish to deal with dso %{public}s!\n", __FUNCTION__, p->name);
}
return CFI_SUCCESS;
......@@ -384,11 +407,11 @@ static int add_dso_to_cfi_shadow(struct dso *dso)
static int fill_shadow_value_to_shadow(uintptr_t begin, uintptr_t end, uintptr_t cfi_check, uint16_t type)
{
LD_LOGI("[%{public}s] begin[%{public}x] end[%{public}x] cfi_check[%{public}x] type[%{public}x]!\n",
LD_LOGI("[CFI] [%{public}s] begin[%{public}x] end[%{public}x] cfi_check[%{public}x] type[%{public}x]!\n",
__FUNCTION__, begin, end, cfi_check, type);
/* To ensure the atomicity of the CFI shadow operation, we create a temp_shadow, write the shadow value to
* the temp_shadow, and then write it back to the CFI shadow by mremap().*/
* the temp_shadow, and then write it back to the CFI shadow by mremap(). */
begin = ALIGN_DOWN(MAX(begin, cfi_check), shadow_alignment);
char* shadow_begin = cfi_shadow_start + addr_to_offset(begin, LIBRARY_ALIGNMENT_BITS);
char* shadow_end = (char*)(((uint16_t*)(cfi_shadow_start + addr_to_offset(end - 1, LIBRARY_ALIGNMENT_BITS))) + 1);
......@@ -403,11 +426,11 @@ static int fill_shadow_value_to_shadow(uintptr_t begin, uintptr_t end, uintptr_t
PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (tmp_shadow_start == MAP_FAILED) {
LD_LOGE("[%{public}s] mmap failed!\n", __FUNCTION__);
LD_LOGE("[CFI] [%{public}s] mmap failed!\n", __FUNCTION__);
return CFI_FAILED;
}
LD_LOGD("[%{public}s] tmp_shadow_start is %{public}p\t tmp_shadow_size is 0x%{public}x!\n",
LD_LOGD("[CFI] [%{public}s] tmp_shadow_start is %{public}p\t tmp_shadow_size is 0x%{public}x!\n",
__FUNCTION__, tmp_shadow_start, tmp_shadow_size);
memcpy(tmp_shadow_start, aligned_shadow_begin, offset_begin);
memcpy(tmp_shadow_start + offset_end, shadow_end, aligned_shadow_end - shadow_end);
......@@ -421,7 +444,7 @@ static int fill_shadow_value_to_shadow(uintptr_t begin, uintptr_t end, uintptr_t
uint16_t shadow_value_begin = ((begin + shadow_alignment - cfi_check)
>> cfi_check_granularity) + sv_valid_min;
#endif
LD_LOGI("[%{public}s] shadow_value_begin is 0x%{public}x!\n", __FUNCTION__, shadow_value_begin);
LD_LOGI("[CFI] [%{public}s] shadow_value_begin is 0x%{public}x!\n", __FUNCTION__, shadow_value_begin);
uint16_t shadow_value_step = 1 << (shadow_granularity - cfi_check_granularity);
uint16_t shadow_value = shadow_value_begin;
......@@ -429,8 +452,7 @@ static int fill_shadow_value_to_shadow(uintptr_t begin, uintptr_t end, uintptr_t
for (uint16_t *shadow_addr = tmp_shadow_start + offset_begin;
shadow_addr != tmp_shadow_start + offset_end; shadow_addr++) {
/* If a dso is larger than 16G( = max_shadow_value * shadow_alignment / 1G),
* the excess is not checked.
*/
* the excess is not checked. */
if (shadow_value < shadow_value_begin) {
*shadow_addr = sv_uncheck;
continue;
......@@ -446,7 +468,7 @@ static int fill_shadow_value_to_shadow(uintptr_t begin, uintptr_t end, uintptr_t
*shadow_addr = type;
}
} else {
LD_LOGE("[%{public}s] has error param!\n", __FUNCTION__);
LD_LOGE("[CFI] [%{public}s] has error param!\n", __FUNCTION__);
munmap(tmp_shadow_start, tmp_shadow_size);
return CFI_FAILED;
}
......@@ -457,18 +479,18 @@ static int fill_shadow_value_to_shadow(uintptr_t begin, uintptr_t end, uintptr_t
MREMAP_MAYMOVE | MREMAP_FIXED, aligned_shadow_begin);
if (mremap_addr == MAP_FAILED) {
LD_LOGE("[%{public}s] mremap failed!\n", __FUNCTION__);
LD_LOGE("[CFI] [%{public}s] mremap failed!\n", __FUNCTION__);
munmap(tmp_shadow_start, tmp_shadow_size);
return CFI_FAILED;
}
LD_LOGD("[%{public}s] fill completed!\n", __FUNCTION__);
LD_LOGD("[CFI] [%{public}s] fill completed!\n", __FUNCTION__);
return CFI_SUCCESS;
}
void __cfi_slowpath(uint64_t call_site_type_id, void *func_ptr)
{
LD_LOGD("[%{public}s] start!\n", __FUNCTION__);
LD_LOGD("[CFI] [%{public}s] start!\n", __FUNCTION__);
cfi_slowpath_common(call_site_type_id, func_ptr, NULL);
......@@ -477,7 +499,7 @@ void __cfi_slowpath(uint64_t call_site_type_id, void *func_ptr)
void __cfi_slowpath_diag(uint64_t call_site_type_id, void *func_ptr, void *diag_data)
{
LD_LOGD("[%{public}s] start!\n", __FUNCTION__);
LD_LOGD("[CFI] [%{public}s] start!\n", __FUNCTION__);
cfi_slowpath_common(call_site_type_id, func_ptr, diag_data);
......
......@@ -25,7 +25,7 @@
#define LIBRARY_ALIGNMENT (1UL << LIBRARY_ALIGNMENT_BITS)
/* map all the dso and the dependents to cfi shadow */
int init_cfi_shadow(struct dso *dso_list, char *so_name);
int init_cfi_shadow(struct dso *dso_list, struct dso *ldso);
/* map a dso and the dependents to cfi shadow */
int map_dso_to_cfi_shadow(struct dso *dso);
/* unmap a dso from cfi shadow */
......
......@@ -1345,7 +1345,7 @@ static void *map_library(int fd, struct dso *dso, struct reserved_address_params
/* we will find a LIBRARY_ALIGNMENT aligned address as the start of dso
* so we need a tmp_map_len as map_len + LIBRARY_ALIGNMENT to make sure
* we have enough space to shift the dso to the correct location*/
* we have enough space to shift the dso to the correct location. */
size_t tmp_map_len = ALIGN(map_len, LIBRARY_ALIGNMENT) + LIBRARY_ALIGNMENT - PAGE_SIZE;
/* if reserved_params exists, we should use start_addr as prefered result to do the mmap operation */
......@@ -1574,7 +1574,7 @@ static void decode_dyn(struct dso *p)
p->verneed = laddr(p, *dyn);
}
static size_t count_syms(struct dso *p)
size_t count_syms(struct dso *p)
{
if (p->hashtab) return p->hashtab[1];
......@@ -2897,7 +2897,7 @@ void __dls3(size_t *sp, size_t *auxv)
libc.tls_size = tmp_tls_size;
}
if (init_cfi_shadow(head, ldso.name) == CFI_FAILED) {
if (init_cfi_shadow(head, &ldso) == CFI_FAILED) {
error("[%s] init_cfi_shadow failed: %m", __FUNCTION__);
}
......@@ -4389,7 +4389,7 @@ static bool task_map_library(struct loadtask *task, struct reserved_address_para
/* we will find a LIBRARY_ALIGNMENT aligned address as the start of dso
* so we need a tmp_map_len as map_len + LIBRARY_ALIGNMENT to make sure
* we have enough space to shift the dso to the correct location*/
* we have enough space to shift the dso to the correct location. */
size_t tmp_map_len = ALIGN(map_len, LIBRARY_ALIGNMENT) + LIBRARY_ALIGNMENT - PAGE_SIZE;
/* if reserved_params exists, we should use start_addr as prefered result to do the mmap operation */
......
......@@ -228,6 +228,7 @@ void *laddr(const struct dso *p, size_t v);
#endif
void *addr2dso(size_t a);
size_t count_syms(struct dso *p);
struct sym_info_pair gnu_hash(const char *s0);
struct symdef find_sym_impl(
struct dso *dso, struct verinfo *verinfo, struct sym_info_pair s_info_p, int need_def, ns_t *ns);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册