Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle AARCH64_TLS_TPREL relas #29

Merged
merged 1 commit into from
Jun 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions include/compartment.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ struct LibRelaMapping
char *rela_name;
void *rela_address; // address of relocation in compartment
void *target_func_address; // address of actual function
unsigned short rela_type; // type of relocation
unsigned short rela_sym_type; // type of underlying symbol
unsigned short rela_sym_bind; // bind of underlying symbol
};
Expand Down
35 changes: 20 additions & 15 deletions src/compartment.c
Original file line number Diff line number Diff line change
Expand Up @@ -664,7 +664,7 @@ parse_lib_rela(Elf64_Shdr *rela_shdr, Elf64_Ehdr *lib_ehdr, int lib_fd,
// Prepare TLS look-up function relocation (will be copied for each TLS
// relocation entry
static struct LibRelaMapping tls_lrm
= { NULL, 0x0, 0x0, STT_FUNC, STB_GLOBAL };
= { NULL, 0x0, 0x0, -1, STT_FUNC, STB_GLOBAL };

// Log symbols that will need to be relocated eagerly at maptime
Elf64_Rela curr_rela;
Expand All @@ -675,7 +675,7 @@ parse_lib_rela(Elf64_Shdr *rela_shdr, Elf64_Ehdr *lib_ehdr, int lib_fd,
size_t curr_rela_sym_idx = ELF64_R_SYM(curr_rela.r_info);
size_t curr_rela_type = ELF64_R_TYPE(curr_rela.r_info);

struct LibRelaMapping lrm = { NULL, 0x0, 0x0, -1, -1 };
struct LibRelaMapping lrm = { NULL, 0x0, 0x0, curr_rela_type, -1, -1 };

// XXX We handle `TLS` symbols differently. It seems the way
// AARCH64 handles TLS variables is preferentially via
Expand Down Expand Up @@ -736,11 +736,12 @@ parse_lib_rela(Elf64_Shdr *rela_shdr, Elf64_Ehdr *lib_ehdr, int lib_fd,
// function relocation
lrm.rela_address = curr_rela.r_offset
+ (char *) lib_dep->lib_mem_base + sizeof(void *);
memcpy(
new_relas + actual_relas, &lrm, sizeof(struct LibRelaMapping));

actual_relas += 1;
continue;
}
else if (curr_rela_type == R_AARCH64_TLS_TPREL64)
{
lrm.target_func_address = (char *) curr_rela.r_addend;
lrm.rela_address
= curr_rela.r_offset + (char *) lib_dep->lib_mem_base;
}
else
{
Expand Down Expand Up @@ -796,13 +797,9 @@ parse_lib_rela(Elf64_Shdr *rela_shdr, Elf64_Ehdr *lib_ehdr, int lib_fd,
}
lrm.rela_address
= curr_rela.r_offset + (char *) lib_dep->lib_mem_base;
memcpy(
new_relas + actual_relas, &lrm, sizeof(struct LibRelaMapping));

actual_relas += 1;
continue;
}
errx(1, "Unhandled relocation\n");
memcpy(new_relas + actual_relas, &lrm, sizeof(struct LibRelaMapping));
actual_relas += 1;
}
lib_dep->rela_maps = realloc(lib_dep->rela_maps,
(lib_dep->rela_maps_count + actual_relas)
Expand Down Expand Up @@ -890,12 +887,14 @@ resolve_rela_syms(struct Compartment *new_comp)
continue;
}

if (curr_rela_map->target_func_address != 0)
if (curr_rela_map->target_func_address != 0
|| curr_rela_map->rela_type == R_AARCH64_TLS_TPREL64)
{
continue;
}

if (!strcmp(curr_rela_map->rela_name, tls_rtld_dropin))
if (curr_rela_map->rela_name
&& !strcmp(curr_rela_map->rela_name, tls_rtld_dropin))
{
curr_rela_map->target_func_address = new_comp->tls_lookup_func;
continue;
Expand Down Expand Up @@ -961,6 +960,12 @@ find_lib_dep_sym_in_comp(const char *to_find,
{
for (size_t j = 0; j < comp_to_search->libs[i]->lib_syms_count; ++j)
{
// Ignore non-symbol relocations
if (!comp_to_search->libs[i]->lib_syms[j].sym_name)
{
continue;
}

// TODO eyeball performance of this approach versus using `&&`
// Ignore `LOCAL` bind symbols - they cannot be relocated against
bool cond
Expand Down
1 change: 1 addition & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ set(tests
"simple_libc"
"simple_malloc"
"simple_open_write"
"simple_printf"
"simple_static_var"
"simple_syscall_getpid"
"simple_syscall_write"
Expand Down