Skip to content

Commit

Permalink
Add clang-format
Browse files Browse the repository at this point in the history
Added a `WebKit`-derived `clang-format` file. Re-formatted existing
source and header files using the new formatting, and added a
`clang-format` validation step to CI, in `.buildbot.sh`.
  • Loading branch information
0152la committed Feb 7, 2024
1 parent 6a863fe commit 4066e64
Show file tree
Hide file tree
Showing 24 changed files with 736 additions and 601 deletions.
5 changes: 5 additions & 0 deletions .buildbot.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ src_dir="$(pwd)"
cheri_dir="$HOME/cheri/output"
venv_dir="./buildbot-venv"

# Check `clang-format` has been applied
CLANG_FORMAT_BIN="$cheri_dir/morello-sdk/bin/clang-format"
CLANG_FORMAT_SOURCES=("$src_dir/src/*.c" "$src_dir/include/*.h" "$src_dir/tests/*.c")
${CLANG_FORMAT_BIN} --dry-run -Werror ${CLANG_FORMAT_SOURCES[*]}

# Update submodules
git submodule update --init

Expand Down
9 changes: 9 additions & 0 deletions .clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
BasedOnStyle: WebKit
AlwaysBreakAfterReturnType: All
BreakBeforeBraces: Allman
ColumnLimit: 80
IndentCaseLabels: true
PointerAlignment: Right
SeparateDefinitionBlocks: Always
SpaceAfterCStyleCast: true
129 changes: 74 additions & 55 deletions include/compartment.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,21 +26,25 @@
#include <stddef.h>
#endif

#define align_down(x, align) __builtin_align_down(x, align)
#define align_up(x, align) __builtin_align_up(x, align)
#define align_down(x, align) __builtin_align_down(x, align)
#define align_up(x, align) __builtin_align_up(x, align)

// TODO once things stabilize, recheck if all struct members are required
// currently there's quite a bit of redundancy to make things easier to think
// about

void compartment_transition_out();
int64_t comp_exec_in(void*, void* __capability, void*, void*, size_t,
void* __capability);
void comp_exec_out();
void
compartment_transition_out();
int64_t
comp_exec_in(
void *, void *__capability, void *, void *, size_t, void *__capability);
void
comp_exec_out();

// Declare built-in function for cache synchronization:
// https://community.arm.com/arm-community-blogs/b/architectures-and-processors-blog/posts/caches-and-self-modifying-code
extern void __clear_cache(void*, void*);
extern void
__clear_cache(void *, void *);

// Number of instructions to inject at intercepted function call point
// TODO ensure there is sufficient space for these, so we don't spill over
Expand All @@ -49,8 +53,8 @@ extern void __clear_cache(void*, void*);
// Number of instructions required by the transition function
#define COMP_TRANS_FN_INSTR_CNT 4

extern void* __capability sealed_redirect_cap;
extern void* __capability comp_return_caps[2];
extern void *__capability sealed_redirect_cap;
extern void *__capability comp_return_caps[2];

/* For a function to be intercepted, information required to insert the
* redirect code and perform redirection
Expand All @@ -60,10 +64,10 @@ extern void* __capability comp_return_caps[2];
*/
struct intercept_patch
{
int* patch_addr;
int *patch_addr;
int32_t instr[INTERCEPT_INSTR_COUNT];
uintptr_t comp_manager_cap_addr;
void* __capability manager_cap;
void *__capability manager_cap;
};

// Maximum size of an argument, in bytes
Expand All @@ -81,17 +85,17 @@ struct intercept_patch
*/
struct entry_point
{
const char* fn_name;
void* fn_addr;
const char *fn_name;
void *fn_addr;
};

/* Struct representing one segment of an ELF binary.
*
* TODO expand */
struct SegmentMap
{
void* mem_bot;
void* mem_top;
void *mem_bot;
void *mem_top;
size_t offset;
ptrdiff_t correction;
size_t mem_sz;
Expand All @@ -106,31 +110,31 @@ struct SegmentMap
*/
struct CompRelaMapping
{
char* rela_name;
void* rela_address; // address of relocation in compartment
void* target_func_address; // address of actual function
char *rela_name;
void *rela_address; // address of relocation in compartment
void *target_func_address; // address of actual function
};

/* Struct representing a symbol entry of a dependency library
*/
struct LibDependencySymbol
{
char* sym_name;
char *sym_name;
intptr_t sym_offset;
};

/* Struct representing a library dependency for one of our given compartments
*/
struct LibDependency
{
char* lib_name;
char* lib_path;
char *lib_name;
char *lib_path;
size_t lib_segs_count;
size_t lib_segs_size;
void* lib_mem_base;
struct SegmentMap** lib_segs;
void *lib_mem_base;
struct SegmentMap **lib_segs;
size_t lib_syms_count;
struct LibDependencySymbol* lib_syms;
struct LibDependencySymbol *lib_syms;
};

/* Struct representing ELF data necessary to load and eventually execute a
Expand All @@ -144,67 +148,82 @@ struct Compartment
Elf64_Half elf_type;
// Execution info
Elf64_Half phdr;
void* __capability ddc;
void *__capability ddc;
// ELF data
size_t size; // size of compartment in memory
void* base; // address where to load compartment
void *base; // address where to load compartment
size_t entry_point_count;
struct entry_point** comp_fns;
void* mem_top;
struct entry_point **comp_fns;
void *mem_top;
bool mapped;
bool mapped_full;
// Segments data
struct SegmentMap** segs;
struct SegmentMap **segs;
size_t seg_count;
size_t segs_size;
// Scratch memory
void* scratch_mem_base;
void *scratch_mem_base;
size_t scratch_mem_size;
size_t scratch_mem_alloc;

size_t scratch_mem_heap_size;
void* scratch_mem_stack_top;
void *scratch_mem_stack_top;
size_t scratch_mem_stack_size;
void* stack_pointer;
struct mem_alloc* alloc_head;
void *stack_pointer;
struct mem_alloc *alloc_head;

void* manager_caps;
void *manager_caps;
size_t max_manager_caps_count;
size_t active_manager_caps_count;

void* mng_trans_fn;
void *mng_trans_fn;
size_t mng_trans_fn_sz;

// Only for shared object compartments
size_t rela_maps_count;
struct CompRelaMapping* rela_maps;
struct CompRelaMapping *rela_maps;
size_t lib_deps_count;
struct LibDependency** lib_deps;
struct LibDependency **lib_deps;

// Hardware info - maybe move
size_t page_size;

// Misc
short curr_intercept_count;
struct intercept_patch* intercept_patches;
struct intercept_patch *intercept_patches;
};

int entry_point_cmp(const void*, const void*);
struct Compartment* comp_init();
struct Compartment* comp_from_elf(char*, char**, size_t, char**, void**, size_t, void*);
void comp_add_intercept(struct Compartment*, uintptr_t, uintptr_t);
void comp_stack_push(struct Compartment*, const void*, size_t);
void comp_map(struct Compartment*);
void comp_map_full(struct Compartment*);
int64_t comp_exec(struct Compartment*, char*, void*, size_t);
void comp_clean(struct Compartment*);

struct Compartment* find_comp(struct Compartment*);

static ssize_t do_pread(int, void*, size_t, off_t);
static Elf64_Sym* find_symbols(const char**, size_t, bool, Elf64_Sym*, char*, size_t);
static char* find_in_dir(const char*, char*);
static void init_comp_scratch_mem(struct Compartment*);
static void init_lib_dep_info(struct LibDependency*, struct Compartment*);
int
entry_point_cmp(const void *, const void *);
struct Compartment *
comp_init();
struct Compartment *
comp_from_elf(char *, char **, size_t, char **, void **, size_t, void *);
void
comp_add_intercept(struct Compartment *, uintptr_t, uintptr_t);
void
comp_stack_push(struct Compartment *, const void *, size_t);
void
comp_map(struct Compartment *);
void
comp_map_full(struct Compartment *);
int64_t
comp_exec(struct Compartment *, char *, void *, size_t);
void
comp_clean(struct Compartment *);

struct Compartment *
find_comp(struct Compartment *);

static ssize_t
do_pread(int, void *, size_t, off_t);
static Elf64_Sym *
find_symbols(const char **, size_t, bool, Elf64_Sym *, char *, size_t);
static char *
find_in_dir(const char *, char *);
static void
init_comp_scratch_mem(struct Compartment *);
static void
init_lib_dep_info(struct LibDependency *, struct Compartment *);

#endif // _COMPARTMENT_H
87 changes: 52 additions & 35 deletions include/intercept.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
#define _INTERCEPT_H

#include <assert.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <stdarg.h>

// vDSO wrapper needed includes
#include <time.h>
Expand All @@ -15,29 +15,31 @@

// Forward declarations
struct Compartment;
extern struct Compartment* loaded_comp;
int64_t exec_comp(struct Compartment*, char*, char**);
struct Compartment* manager_get_compartment_by_id(size_t);
extern struct Compartment *loaded_comp;
int64_t
exec_comp(struct Compartment *, char *, char **);
struct Compartment *manager_get_compartment_by_id(size_t);

extern void* __capability manager_ddc;
extern void *__capability manager_ddc;

// Number of capabilities required to perform a transition
#define COMP_RETURN_CAPS_COUNT 2

// Capabilities required to transition back into the manager once compartment
// execution has finished
extern void* __capability comp_return_caps[COMP_RETURN_CAPS_COUNT];
extern void *__capability comp_return_caps[COMP_RETURN_CAPS_COUNT];

// Capability used to point to pair of capabilities when transitioning out of a
// compartment via an intercept
extern void* __capability sealed_redirect_cap;
extern void *__capability sealed_redirect_cap;

/* Data required to perform the transition for an intercepted function
*/
struct func_intercept {
char* func_name;
void* redirect_func;
void* __capability intercept_pcc;
struct func_intercept
{
char *func_name;
void *redirect_func;
void *__capability intercept_pcc;
};

/* This function expects the argument be passed in `x10`, rather than `x0`, as
Expand All @@ -47,36 +49,51 @@ struct func_intercept {
* functional. As such, it shouldn't be called from a C context, as that will
* most likely break things.
*/
void intercept_wrapper();

void setup_intercepts();

time_t intercepted_time(time_t*);
FILE* intercepted_fopen(const char*, const char*);
size_t intercepted_fread(void* __restrict, size_t, size_t, FILE* __restrict);
size_t intercepted_fwrite(void* __restrict, size_t, size_t, FILE* __restrict);
int intercepted_fclose(FILE*);
int intercepted_getc(FILE*);
int intercepted_fputc(int, FILE*);
int intercepted___srget(FILE*);

void* my_realloc(void*, size_t);
void* my_malloc(size_t);
void my_free(void*);
int my_fprintf(FILE*, const char*, ...);

size_t my_call_comp(size_t, char*, void*, size_t);
void
intercept_wrapper();

void
setup_intercepts();

time_t
intercepted_time(time_t *);
FILE *
intercepted_fopen(const char *, const char *);
size_t
intercepted_fread(void *__restrict, size_t, size_t, FILE *__restrict);
size_t
intercepted_fwrite(void *__restrict, size_t, size_t, FILE *__restrict);
int
intercepted_fclose(FILE *);
int
intercepted_getc(FILE *);
int
intercepted_fputc(int, FILE *);
int
intercepted___srget(FILE *);

void *
my_realloc(void *, size_t);
void *my_malloc(size_t);
void
my_free(void *);
int
my_fprintf(FILE *, const char *, ...);

size_t
my_call_comp(size_t, char *, void *, size_t);
static const struct func_intercept to_intercept_funcs[] = {
/* vDSO funcs */
{ "time" , (void*) intercepted_time },
{ "time", (void *) intercepted_time },
/* Mem funcs */
{ "malloc" , (void*) my_malloc },
{ "realloc" , (void*) my_realloc },
{ "free" , (void*) my_free },
{ "malloc", (void *) my_malloc },
{ "realloc", (void *) my_realloc },
{ "free", (void *) my_free },
};
//
// Functions to be intercepted and associated data
#define INTERCEPT_FUNC_COUNT sizeof(to_intercept_funcs) / sizeof(to_intercept_funcs[0])
#define INTERCEPT_FUNC_COUNT \
sizeof(to_intercept_funcs) / sizeof(to_intercept_funcs[0])
extern struct func_intercept comp_intercept_funcs[INTERCEPT_FUNC_COUNT];

#endif // _INTERCEPT_H
Loading

0 comments on commit 4066e64

Please sign in to comment.