Skip to content

Commit

Permalink
Parameterised compartments
Browse files Browse the repository at this point in the history
Add a `CompConfig` struct, which contains parameterisable values for
compartment properties. Currently this includes only the heap and stack
sizes, as well as entry points. The parameters are taken from the
`.comp` TOML config file, similar to how entry points are determined.

Enable `lua_suite_some` test, which runs a few hand-picked tests from
the Lua test suite, just to see if we can find any other parts of Lua
that need further handling in the manager.

NOTE `gc.lua` *should* work, but it seems to take 10 hours on a
virtualised CHERI instance. I think it might be due to the unoptimised
memory allocator implementation, but that would need further
benchmarking.

Additionally refactor some old code, including getting rid of
`CompEntryPoint` in favour of the singular `CompEntryPointDef` struct.
  • Loading branch information
0152la committed Aug 30, 2024
1 parent db6e231 commit 604293c
Show file tree
Hide file tree
Showing 8 changed files with 210 additions and 177 deletions.
40 changes: 29 additions & 11 deletions include/compartment.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,9 @@ extern void *__capability comp_return_caps[2];
#error Expecting 64-bit Arm Morello platform
#endif

/* Struct representing a valid entry point to a compartment
*/
struct CompEntryPoint
{
const char *fn_name;
void *fn_addr;
};
// Default sizes for compartment heap and stack, if not explicitly given
#define DEFAULT_COMP_HEAP_SZ 0x800000UL // 800kB
#define DEFAULT_COMP_STACK_SZ 0x80000UL // 80kB

/* Struct representing one segment of an ELF binary.
*
Expand Down Expand Up @@ -169,14 +165,38 @@ struct TLSDesc
unsigned short libs_count;
};

/* Struct representing configuration data for one entry point; this is just
* information that we expect to appear in the compartment, as given by its
* compartment configuration file
*/
struct CompEntryPointDef
{
char *name;
size_t arg_count;
char **args_type;
void *comp_addr;
};

/* Struct representing a compartment configuration.
*/
struct CompConfig
{
size_t heap_size;
size_t stack_size;
struct CompEntryPointDef *entry_points;
size_t entry_point_count;
void *base_address;
};

/**
* Struct representing ELF data necessary to load and eventually execute a
* compartment
*/
struct Compartment
{
// Identifiers
// Identifiers, manager by `manager.c`
size_t id;
struct CompConfig *cc;
// Execution info
void *__capability ddc;
// ELF data
Expand All @@ -201,8 +221,6 @@ struct Compartment
// Internal libraries and relocations
size_t libs_count;
struct LibDependency **libs;
size_t entry_point_count;
struct CompEntryPoint *entry_points;
void *tls_lookup_func;
size_t total_tls_size;
struct TLSDesc *libs_tls_sects;
Expand All @@ -216,7 +234,7 @@ entry_point_cmp(const void *, const void *);
struct Compartment *
comp_init();
struct Compartment *
comp_from_elf(char *, char **, size_t, void *);
comp_from_elf(char *, struct CompConfig *); // char **, size_t, void *);
void
comp_map(struct Compartment *);
void
Expand Down
19 changes: 1 addition & 18 deletions include/manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
#define align_up(x, align) __builtin_align_up(x, align)

extern void *__capability manager_ddc;
extern struct CompWithEntries **comps;
extern struct Compartment **comps;
extern struct Compartment *loaded_comp;

/*******************************************************************************
Expand All @@ -31,23 +31,6 @@ extern struct Compartment *loaded_comp;
// Compartment configuration file suffix
extern const char *comp_config_suffix;

/* Struct representing configuration data for one entry point; this is just
* information that we expect to appear in the compartment, as given by its
* compartment configuration file
*/
struct CompEntryPointDef
{
const char *name;
size_t arg_count;
char **args_type;
};

struct CompWithEntries
{
struct Compartment *comp;
struct CompEntryPointDef *cep;
};

void *
get_next_comp_addr(void);
struct Compartment *
Expand Down
82 changes: 39 additions & 43 deletions src/compartment.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ parse_lib_rela(Elf64_Shdr *, Elf64_Ehdr *, int, struct LibDependency *);
static void
parse_lib_dynamic_deps(Elf64_Shdr *, Elf64_Ehdr *, int, struct LibDependency *);
static void
find_comp_entry_points(char **, size_t, struct Compartment *);
map_comp_entry_points(struct Compartment *);
static void
resolve_rela_syms(struct Compartment *);
static struct LibSymSearchResult
Expand Down Expand Up @@ -86,35 +86,23 @@ comp_init()

new_comp->libs_count = 0;
new_comp->libs = NULL;
new_comp->entry_point_count = 0;
new_comp->entry_points = NULL;
new_comp->libs_tls_sects = NULL;

new_comp->page_size = sysconf(_SC_PAGESIZE);

return new_comp;
}

/* Comparison function for `struct CompEntryPoint`
*/
int
entry_point_cmp(const void *val1, const void *val2)
{
struct CompEntryPoint *ep1 = *(struct CompEntryPoint **) val1;
struct CompEntryPoint *ep2 = *(struct CompEntryPoint **) val2;
return strcmp(ep1->fn_name, ep2->fn_name);
}

/* Give a binary ELF file in `filename`, read the ELF data and store it within
* a `struct Compartment`. At this point, we only read data.
*/
struct Compartment *
comp_from_elf(char *filename, char **entry_points, size_t entry_point_count,
void *new_comp_base)
comp_from_elf(char *filename, struct CompConfig *cc)
{
struct Compartment *new_comp = comp_init();
new_comp->base = new_comp_base;
new_comp->mem_top = new_comp_base;
new_comp->cc = cc;
new_comp->base = cc->base_address; // TODO reuse `cc` base
new_comp->mem_top = cc->base_address;

unsigned short libs_to_parse_count = 1;
unsigned short libs_parsed_count = 0;
Expand Down Expand Up @@ -166,12 +154,12 @@ comp_from_elf(char *filename, char **entry_points, size_t entry_point_count,
}
free(libs_to_parse);

assert(entry_points);
assert(entry_point_count > 0);
assert(cc->entry_points);
assert(cc->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);
map_comp_entry_points(new_comp);
resolve_comp_tls_regions(new_comp);
resolve_rela_syms(new_comp);

Expand Down Expand Up @@ -253,11 +241,11 @@ comp_map(struct Compartment *to_map)
}

/* 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
*/
*
* 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;

Expand Down Expand Up @@ -328,11 +316,11 @@ comp_exec(
to_exec->mapped && "Attempting to execute an unmapped compartment.\n");

void *fn = NULL;
for (size_t i = 0; i < to_exec->entry_point_count; ++i)
for (size_t i = 0; i < to_exec->cc->entry_point_count; ++i)
{
if (!strcmp(fn_name, to_exec->entry_points[i].fn_name))
if (!strcmp(fn_name, to_exec->cc->entry_points[i].name))
{
fn = (void *) to_exec->entry_points[i].fn_addr;
fn = (void *) to_exec->cc->entry_points[i].comp_addr;
break;
}
}
Expand Down Expand Up @@ -414,8 +402,20 @@ comp_clean(struct Compartment *to_clean)
free(curr_lib_dep->lib_path);
free(curr_lib_dep);
}
struct CompEntryPointDef curr_cep;
for (size_t i = 0; i < to_clean->cc->entry_point_count; ++i)
{
curr_cep = to_clean->cc->entry_points[i];
for (size_t j = 0; j < curr_cep.arg_count; ++j)
{
free(curr_cep.args_type[j]);
}
free(curr_cep.args_type);
free(curr_cep.name);
}
free(to_clean->cc->entry_points);
free(to_clean->cc);
free(to_clean->libs);
free(to_clean->entry_points);
if (to_clean->libs_tls_sects)
{
free(to_clean->libs_tls_sects);
Expand Down Expand Up @@ -896,25 +896,21 @@ parse_lib_dynamic_deps(Elf64_Shdr *dynamic_shdr, Elf64_Ehdr *lib_ehdr,
}

static void
find_comp_entry_points(
char **entry_points, size_t entry_point_count, struct Compartment *new_comp)
map_comp_entry_points(struct Compartment *new_comp)
{
new_comp->entry_points
= malloc(entry_point_count * sizeof(struct CompEntryPoint));
for (size_t i = 0; i < entry_point_count; ++i)
for (size_t i = 0; i < new_comp->cc->entry_point_count; ++i)
{
// TODO are entry points always in the main loaded library?
// TODO is the main loaded library always the 0th indexed one?
struct LibSymSearchResult found_sym = find_lib_dep_sym_in_comp(
entry_points[i], new_comp, 0, STT_FUNC, true);
const char *ep_name = new_comp->cc->entry_points[i].name;
struct LibSymSearchResult found_sym
= find_lib_dep_sym_in_comp(ep_name, new_comp, 0, STT_FUNC, true);
if (!found_sym.found)
{
errx(1, "Did not find entry point %s!\n", entry_points[i]);
errx(1, "Did not find entry point %s!\n", ep_name);
}
struct CompEntryPoint new_entry_point
= { entry_points[i], extract_sym_offset(new_comp, found_sym) };
new_comp->entry_points[new_comp->entry_point_count] = new_entry_point;
new_comp->entry_point_count += 1;
new_comp->cc->entry_points[i].comp_addr
= extract_sym_offset(new_comp, found_sym);
}
}

Expand Down Expand Up @@ -1161,8 +1157,8 @@ init_comp_scratch_mem(struct Compartment *new_comp)
new_comp->scratch_mem_base = align_up(
(char *) new_comp->base + new_comp->size + new_comp->page_size,
new_comp->page_size);
new_comp->scratch_mem_heap_size = 0x800000UL; // TODO
new_comp->scratch_mem_stack_size = 0x80000UL; // TODO
new_comp->scratch_mem_heap_size = new_comp->cc->heap_size;
new_comp->scratch_mem_stack_size = new_comp->cc->stack_size;
new_comp->scratch_mem_stack_top = align_down(
(char *) new_comp->scratch_mem_base + new_comp->scratch_mem_stack_size,
16);
Expand Down
Loading

0 comments on commit 604293c

Please sign in to comment.