Skip to content
Open
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
2 changes: 1 addition & 1 deletion runtime/libia2/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 4.0)
project(libia2)

add_library(libia2 ia2.c init.c threads.c main.c exit.c memory_maps.c thread_name.c)
add_library(libia2 ia2.c init.c threads.c main.c memory_maps.c thread_name.c)
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: Do we want to keep the option of exiting the process in the untrusted compartment?

target_compile_options(libia2 PRIVATE "-fPIC")

if (LIBIA2_AARCH64)
Expand Down
14 changes: 13 additions & 1 deletion runtime/libia2/ia2.c
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,16 @@ int protect_tls_pages(struct dl_phdr_info *info, size_t size, void *data) {
return 0;
}

static bool is_syslib(struct dl_phdr_info *info, int32_t pkey) {
const char *libname = basename(info->dlpi_name);
//bool is_libc = !strcmp(libname, "libc.so.6");
bool is_ldso = !strcmp(libname, "ld-linux-x86-64.so.2");
// TODO: Check for C++ standard library
// Always put C standard library and dynamic linker in compartment 1. This is an arbitrary choice.
const int32_t syslib_pkey = 1;
return (is_ldso) && (pkey == syslib_pkey);
}

int protect_pages(struct dl_phdr_info *info, size_t size, void *data) {
if (!data || !info) {
printf("Passed invalid args to dl_iterate_phdr callback\n");
Expand All @@ -433,7 +443,9 @@ int protect_pages(struct dl_phdr_info *info, size_t size, void *data) {

Elf64_Addr address = (Elf64_Addr)search_args->address;
bool extra = in_extra_libraries(info, search_args->extra_libraries);
if (!in_loaded_segment(info, address) && !extra) {
const int32_t syslib_pkey = 1;
bool syslib = is_syslib(info, search_args->pkey);
if (!in_loaded_segment(info, address) && !extra && !syslib) {
// Continue iterating to check the next object
return 0;
}
Expand Down
12 changes: 8 additions & 4 deletions runtime/libia2/main.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
#include "ia2.h"

void ia2_compartment_destructor_1(void);
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: Move this somewhere else/generate it from the rewriter.

void __wrap_ia2_compartment_destructor_1(void) {
ia2_compartment_destructor_1();
}
int __real_main(int argc, char **argv);

/* Stores the stack pointer to return to after main() is called. */
Expand Down Expand Up @@ -46,10 +50,10 @@ __asm__(
// Save return value
"mov %rax,%r10\n"
// Switch pkey to untrusted compartment
"xor %ecx,%ecx\n"
"xor %edx,%edx\n"
"mov_pkru_eax 0\n"
"wrpkru\n"
//"xor %ecx,%ecx\n"
//"xor %edx,%edx\n"
//"mov_pkru_eax 0\n"
//"wrpkru\n"
// Restore return value
"mov %r10,%rax\n"
"popq %rbp\n"
Expand Down
7 changes: 7 additions & 0 deletions tests/tls_protected/library.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@ void lib_print_main_secret() {
cr_assert(false); // should not reach here
}

#if IA2_REWRITING
void * __tls_get_addr(size_t m, size_t offset);
#endif

void lib_print_lib_secret() {
#if IA2_REWRITING
__tls_get_addr(0, 0);
#endif
cr_log_info("library: lib secret is %x\n", lib_secret);
}
6 changes: 6 additions & 0 deletions tests/tls_protected/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,9 @@ Test(tls_protected, no_access_lib_secret) {
Test(tls_protected, access_lib_secret) {
run_test(true);
}

#if IA2_REWRITING
void *__tls_get_addr(size_t m, size_t offset) {
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be autogenerated by the rewriter w/o requiring that it appears in user-code, but this was the easiest way to test this. This function is defined in ld.so which is in the same compartment as main.c and the call to __tls_get_addr in library.c is required for the rewriter to realize it needs to generate callgates to call it from that compartment. It then adds the -Wl,--wrap flag for this function and uses that when linking library.o.

return NULL;
}
#endif
5 changes: 3 additions & 2 deletions tools/rewriter/SourceRewriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1291,6 +1291,7 @@ int main(int argc, const char **argv) {
}
// Insert extra args from command line
new_args.insert(double_hyphen_pos, ExtraArgs.begin(), ExtraArgs.end());
new_args.push_back("-DIA2_REWRITING=1"s);
return new_args;
});

Expand Down Expand Up @@ -1587,7 +1588,7 @@ int main(int argc, const char **argv) {
}

// Create wrapper for compartment destructor
for (int compartment_pkey = 1; compartment_pkey < num_pkeys; compartment_pkey++) {
for (int compartment_pkey = 2; compartment_pkey < num_pkeys; compartment_pkey++) {
std::string fn_name = "ia2_compartment_destructor_" + std::to_string(compartment_pkey);
FnSignature fn_sig;
try {
Expand All @@ -1600,7 +1601,7 @@ int main(int argc, const char **argv) {
std::string wrapper_name = "__wrap_"s + fn_name;
std::string asm_wrapper =
emit_asm_wrapper(ctx, fn_sig, std::nullopt, wrapper_name, fn_name, WrapperKind::Direct,
0, compartment_pkey, Target);
1, compartment_pkey, Target);
wrapper_out << asm_wrapper;

write_to_file(ld_args_out, compartment_pkey,
Expand Down
Loading