Skip to content

Commit

Permalink
Re-enable Lua tests
Browse files Browse the repository at this point in the history
* Add `environ` support to pass Lua tests
* Add `simple_environ` test to check `environ` support implementation
* Re-enable `lua_simple` and `lua_script`, which now pass
  • Loading branch information
0152la committed Jul 2, 2024
1 parent 03283a9 commit 78c6733
Show file tree
Hide file tree
Showing 8 changed files with 161 additions and 22 deletions.
4 changes: 4 additions & 0 deletions include/compartment.h
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,10 @@ struct Compartment
void *mem_top;
bool mapped;

// Environ
char **environ_ptr;
size_t environ_sz;

// Scratch memory
void *scratch_mem_base;
size_t scratch_mem_size;
Expand Down
6 changes: 6 additions & 0 deletions src/comp_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,12 @@ realloc(void *to_realloc, size_t new_size)
return new_alloc;
}

void *
reallocarray(void *to_realloc, size_t elem_count, size_t elem_size)
{
return realloc(to_realloc, elem_count * elem_size);
}

void
tls_lookup_stub()
{
Expand Down
71 changes: 57 additions & 14 deletions src/compartment.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ const char *libs_path_env_var = "COMP_LIBRARY_PATH";
const char *tls_rtld_dropin = "tls_lookup_stub";
const char *comp_utils_soname = "libcomputils.so";

extern char **proc_env_ptr;
extern const size_t max_env_sz;
extern const unsigned short max_env_count;

/*******************************************************************************
* Forward declarations
******************************************************************************/
Expand Down Expand Up @@ -34,6 +38,10 @@ find_in_dir(const char *, char *);
static void
init_comp_scratch_mem(struct Compartment *);
static void
adjust_comp_scratch_mem(struct Compartment *, size_t);
static void
setup_environ(struct Compartment *);
static void
resolve_comp_tls_regions(struct Compartment *);

static void
Expand Down Expand Up @@ -157,6 +165,7 @@ comp_from_elf(char *filename, char **entry_points, size_t entry_point_count,
assert(entry_point_count > 0);

init_comp_scratch_mem(new_comp);
setup_environ(new_comp);
find_comp_entry_points(entry_points, entry_point_count, new_comp);
resolve_rela_syms(new_comp);
resolve_comp_tls_regions(new_comp);
Expand Down Expand Up @@ -223,6 +232,27 @@ comp_map(struct Compartment *to_map)
err(1, "Error mapping compartment %zu scratch memory", to_map->id);
}

/* Copy over environ variables
//
// We need a pointer to an array of string pointers, so we synthetically
// create one. We don't expect this pointer to move, as the maximum allowed
// size for the `environ` array is already allocated
*/
*to_map->environ_ptr = (char *) (to_map->environ_ptr + 1);
to_map->environ_ptr += 1;

// Copy over prepared `environ` data from manager
memcpy(to_map->environ_ptr, proc_env_ptr, max_env_sz);
for (unsigned short i = 0; i < max_env_count; ++i)
{
if (*(to_map->environ_ptr + i) == 0x0)
{
break;
}
// Update entry offsets relative to compartment address
*(to_map->environ_ptr + i) += (uintptr_t) to_map->environ_ptr;
}

size_t tls_allocd = 0x0;
for (size_t i = 0; i < to_map->libs_count; ++i)
{
Expand Down Expand Up @@ -758,17 +788,7 @@ parse_lib_rela(Elf64_Shdr *rela_shdr, Elf64_Ehdr *lib_ehdr, int lib_fd,

// Filter out some `libc` symbols we don't want to handle
// TODO at least right now
if (!strcmp(&dyn_str_tbl[curr_rela_sym.st_name], "environ"))
{
warnx("Currently not relocating symbol `environ` from "
"library "
"%s - "
"using within a container might cause a crash.",
lib_dep->lib_name);
continue;
}
else if (!strcmp(
&dyn_str_tbl[curr_rela_sym.st_name], "__progname"))
if (!strcmp(&dyn_str_tbl[curr_rela_sym.st_name], "__progname"))
{
warnx("Currently not relocating symbol `__progname` from "
"library %s "
Expand Down Expand Up @@ -900,6 +920,13 @@ resolve_rela_syms(struct Compartment *new_comp)
continue;
}

if (curr_rela_map->rela_name
&& !strcmp(curr_rela_map->rela_name, "environ"))
{
curr_rela_map->target_func_address = new_comp->environ_ptr;
continue;
}

struct LibSymSearchResult found_sym
= find_lib_dep_sym_in_comp(curr_rela_map->rela_name, new_comp,
curr_rela_map->rela_sym_type);
Expand Down Expand Up @@ -1061,6 +1088,23 @@ init_comp_scratch_mem(struct Compartment *new_comp)
assert(new_comp->scratch_mem_size % 16 == 0);
}

static void
adjust_comp_scratch_mem(struct Compartment *new_comp, size_t to_adjust)
{
new_comp->scratch_mem_size += to_adjust;
new_comp->mem_top = (char *) new_comp->mem_top + to_adjust;
}

static void
setup_environ(struct Compartment *new_comp)
{
assert(proc_env_ptr != NULL); // TODO consider optional check
new_comp->environ_sz
= align_up(max_env_sz, new_comp->page_size) + new_comp->page_size;
new_comp->environ_ptr = new_comp->mem_top;
adjust_comp_scratch_mem(new_comp, new_comp->environ_sz);
}

static void
resolve_comp_tls_regions(struct Compartment *new_comp)
{
Expand All @@ -1072,7 +1116,7 @@ resolve_comp_tls_regions(struct Compartment *new_comp)

// TODO currently we only support one thread
new_comp->libs_tls_sects->region_count = 1;
new_comp->libs_tls_sects->region_start = new_comp->scratch_mem_stack_top;
new_comp->libs_tls_sects->region_start = new_comp->mem_top;
new_comp->libs_tls_sects->libs_count = 0;

unsigned short *lib_idxs
Expand All @@ -1098,8 +1142,7 @@ resolve_comp_tls_regions(struct Compartment *new_comp)

intptr_t total_tls_size
= comp_tls_size * new_comp->libs_tls_sects->region_count;
new_comp->scratch_mem_size += total_tls_size;
new_comp->mem_top = (char *) new_comp->mem_top + total_tls_size;
adjust_comp_scratch_mem(new_comp, total_tls_size);
new_comp->libs_tls_sects->region_size = comp_tls_size;

assert((uintptr_t) new_comp->libs_tls_sects->region_start % 16 == 0);
Expand Down
39 changes: 39 additions & 0 deletions src/manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,21 @@ void *__capability manager_ddc = 0;

const char *comp_config_suffix = ".comp";

char **proc_env_ptr = NULL;
const unsigned short avg_sz_per_env_entry = 128; // TODO
const unsigned short max_env_count = 128; // TODO
const size_t max_env_sz
= max_env_count * sizeof(char *) + avg_sz_per_env_entry * max_env_count;
extern char **environ;

static struct CompEntryPointDef *
parse_compartment_config(char *, size_t *, bool);
static struct CompEntryPointDef *
make_default_entry_point();
static struct CompEntryPointDef
get_entry_point(char *, struct CompEntryPointDef *, size_t);
static void
prepare_compartment_environ();
static void *
prepare_compartment_args(char **args, struct CompEntryPointDef);

Expand Down Expand Up @@ -78,6 +87,11 @@ get_next_comp_addr(void)
struct Compartment *
register_new_comp(char *filename, bool allow_default_entry)
{
if (!proc_env_ptr)
{
prepare_compartment_environ();
}

size_t new_comp_ep_count;
struct CompEntryPointDef *new_cep = parse_compartment_config(
filename, &new_comp_ep_count, allow_default_entry);
Expand Down Expand Up @@ -145,6 +159,9 @@ clean_all_comps()
clean_comp(comps[i]->comp);
}
free(comps);

free(proc_env_ptr);
proc_env_ptr = NULL;
}

void
Expand Down Expand Up @@ -324,6 +341,28 @@ get_entry_point(
errx(1, "Did not find entry point for function %s!\n", entry_point_fn);
}

static void
prepare_compartment_environ()
{
proc_env_ptr = malloc(max_env_sz);
memset(proc_env_ptr, 0, max_env_sz);
char **prov_env_vals = proc_env_ptr + max_env_count * sizeof(char *);

size_t envs_parsed = 0;
size_t envs_parsed_sz = 0;
const uintptr_t vals_offset = max_env_count * sizeof(char *);
for (char **curr_env = environ; *curr_env; curr_env++)
{
// We only save offsets for the pointers, since they'll be relocated
// relative to the compartment base address
proc_env_ptr[envs_parsed] = (char *) (vals_offset + envs_parsed_sz);
strcpy((char *) proc_env_ptr + vals_offset + envs_parsed_sz, *curr_env);

envs_parsed += 1;
envs_parsed_sz += strlen(*curr_env) + 1;
}
}

static void *
prepare_compartment_args(char **args, struct CompEntryPointDef cep)
{
Expand Down
14 changes: 8 additions & 6 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ set(comp_binaries
"simple_call_internal"
"simple_call_internal_static"
"simple_call_internal_weak"
"simple_environ"
"simple_external"
"simple_fopen"
"simple_fputs"
Expand All @@ -142,8 +143,8 @@ set(comp_binaries
"simple_time"
"simple_va_args"

#"lua_simple"
#"lua_script"
"lua_simple"
"lua_script"

"args_simple"
#"test_two_comps-comp1"
Expand All @@ -156,6 +157,7 @@ set(tests
"simple_call_internal"
"simple_call_internal_static"
"simple_call_internal_weak"
"simple_environ"
"simple_fopen"
"simple_fputs"
"simple_global_var"
Expand All @@ -170,8 +172,8 @@ set(tests
"simple_time"
"simple_va_args"

#"lua_simple"
#"lua_script"
"lua_simple"
"lua_script"

"test_map"
#"test_args_near_unmapped"
Expand Down Expand Up @@ -217,9 +219,9 @@ new_dependency(simple_global_var $<TARGET_FILE:simple_global_var-external>)
target_link_libraries(simple_thrloc_var PRIVATE simple_thrloc_var-external)
new_dependency(simple_thrloc_var $<TARGET_FILE:simple_thrloc_var-external>)

#new_dependency(test_map $<TARGET_FILE:simple>)
new_dependency(test_map $<TARGET_FILE:simple>)

#new_dependency(lua_script ${CMAKE_CURRENT_SOURCE_DIR}/hello_world.lua)
new_dependency(lua_script ${CMAKE_CURRENT_SOURCE_DIR}/hello_world.lua)
#new_dependency(test_args_near_unmapped $<TARGET_FILE:args_simple>)
#new_dependency(test_args_near_unmapped ${CMAKE_CURRENT_SOURCE_DIR}/args_simple.comp)

Expand Down
2 changes: 1 addition & 1 deletion tests/lua_script.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ do_script()
}

int
main(int argc, char **argv)
main()
{
do_script_arg("./hello_world.lua");
return 0;
Expand Down
2 changes: 1 addition & 1 deletion tests/lua_simple.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,5 @@ main(void)
lua_Integer len = luaL_len(L, 1);

lua_close(L);
return (len == strlen(test_string) ? 0 : 1);
return ((unsigned long) len == strlen(test_string) ? 0 : 1);
}
45 changes: 45 additions & 0 deletions tests/simple_environ.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

extern char **environ;

int
main()
{
size_t i = 0;
for (char **curr_env = environ; *curr_env; ++curr_env)
{
printf("ENV -- %s\n", *curr_env);
++i;
}
printf("---- COUNT - %zu\n", i);

char *lang = getenv("LANG");
assert(lang);
printf("getenv -- environ['LANG'] == %s\n", lang);

char *term = getenv("TERM");
assert(term);
printf("getenv -- environ['TERM'] == %s\n", term);

char *no = getenv("DOESNTEXIST");
assert(no == NULL);

const char *set_name = "TRYENV";
const char *set_val = "Hello Env";
int set_check = setenv(set_name, set_val, 1);
assert(set_check == 0);
char *set_get = getenv(set_name);
printf("setenv -- environ['%s'] == %s\n", set_name, set_get);
assert(!strcmp(set_get, set_val));

set_check = putenv("TRYENV=Goodbye Env");
assert(set_check == 0);
set_get = getenv(set_name);
printf("putenv -- environ['%s'] == %s\n", set_name, set_get);
assert(!strcmp(set_get, "Goodbye Env"));

return 0;
}

0 comments on commit 78c6733

Please sign in to comment.