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

Parameterised compartments #37

Merged
merged 1 commit into from
Aug 30, 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
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