Skip to content

Commit adf8676

Browse files
author
Andrei Lascu
committed
Compartment reuse
Implement a "pseudo" compartment caching feature to evaluate performance in a more ideal implementation. Rather than fully cleaning a mapping for a compartment, we emulate keeping around the last copy, which precludes a pair of `mmap` / `munmap`, as well as downsizing the amount of cleanup needed to be done (we only need to reset the stack, the allocated parts of the heap, and the writeable segments). Note that this is not a full implementation, and it likely breaks with multiple compartments as it currently is. Major changes * Move `mappings` code in a separate file * Implement mapping reuse (includes caching a mapping, cleaning the stack and heap allocations, and resetting writeable segments) * Add a benchmarking implementation; this is done as it is useful to have, and calls to the benchmarking API are not present in the tree, but can be added by users * Allow only an entry point be specified in `manager_arg_passer`, rather than requiring arguments to be passed to that entry point * Add some additional tests, including more failing ones (comment out `lua_suite_some`, as it crashes on the CI system) * Other fixes
1 parent 6cb2842 commit adf8676

21 files changed

+677
-82
lines changed

include/benchmarking.h

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#ifndef _BENCHMARKING_COMP_H
2+
#define _BENCHMARKING_COMP_H
3+
4+
#include <assert.h>
5+
#include <math.h>
6+
#include <stdint.h>
7+
#include <stdio.h>
8+
#include <stdlib.h>
9+
#include <string.h>
10+
#include <time.h>
11+
12+
#define BENCH(name, func) \
13+
do \
14+
{ \
15+
size_t id = bench_init(name); \
16+
bench_start(id); \
17+
func; \
18+
bench_end(id); \
19+
} while (0)
20+
21+
struct bench_entry
22+
{
23+
const char *fn_name;
24+
struct timespec start;
25+
struct timespec end;
26+
int res_start;
27+
double diff;
28+
};
29+
30+
size_t
31+
bench_init(const char *);
32+
void bench_start(size_t);
33+
void bench_end(size_t);
34+
35+
void bench_report_one_id(size_t);
36+
37+
#endif // _BENCHMARKING_COMP_H

include/comp_utils.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <stdbool.h>
66
#include <stddef.h>
77
#include <stdint.h>
8+
#include <stdlib.h>
89
#include <string.h>
910
#include <sys/mman.h>
1011

include/compartment.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,8 @@ extern void *__capability comp_return_caps[2];
6666
#endif
6767

6868
// Default sizes for compartment heap and stack, if not explicitly given
69-
#define DEFAULT_COMP_HEAP_SZ 0x800000UL // 800kB
70-
#define DEFAULT_COMP_STACK_SZ 0x80000UL // 80kB
69+
#define DEFAULT_COMP_HEAP_SZ 2 * 1024 * 1024 // 2MB
70+
#define DEFAULT_COMP_STACK_SZ 500 * 1024 // 500kB
7171

7272
/* Struct representing one segment of an ELF binary.
7373
*
@@ -207,6 +207,8 @@ struct Compartment
207207
void *scratch_mem_stack_top;
208208
size_t scratch_mem_stack_size;
209209

210+
void *heap_mem_header;
211+
210212
// Internal libraries and relocations
211213
size_t libs_count;
212214
struct LibDependency **libs;
@@ -239,4 +241,7 @@ get_seg_target(void *, struct LibDependency *, size_t);
239241
struct Compartment *
240242
find_comp(struct Compartment *);
241243

244+
void
245+
print_comp_simple(struct Compartment *);
246+
242247
#endif // _COMPARTMENT_H

include/manager.h

Lines changed: 2 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,10 @@
1414
// Third-party libraries
1515
#include "toml.h"
1616

17+
#include "benchmarking.h"
1718
#include "compartment.h"
1819
#include "intercept.h"
20+
#include "mappings.h"
1921

2022
#define align_down(x, align) __builtin_align_down(x, align)
2123
#define align_up(x, align) __builtin_align_up(x, align)
@@ -52,25 +54,4 @@ clean_comp(struct Compartment *);
5254
void
5355
clean_compartment_config(struct CompEntryPointDef *, size_t);
5456

55-
/*******************************************************************************
56-
* Compartment mappings
57-
******************************************************************************/
58-
59-
struct CompMapping *
60-
mapping_new(struct Compartment *);
61-
struct CompMapping *
62-
mapping_new_fixed(struct Compartment *, void *);
63-
void
64-
mapping_free(struct CompMapping *);
65-
int64_t
66-
mapping_exec(struct CompMapping *, char *, char **);
67-
68-
struct CompMapping
69-
{
70-
size_t id;
71-
void *__capability ddc;
72-
void *map_addr;
73-
struct Compartment *comp;
74-
};
75-
7657
#endif // _MANAGER_H

include/mappings.h

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
#ifndef _CHERICOMP_MAPPINGS_H
2+
#define _CHERICOMP_MAPPINGS_H
3+
4+
#include <err.h>
5+
6+
#include "compartment.h"
7+
8+
/*******************************************************************************
9+
* Compartment mappings
10+
******************************************************************************/
11+
12+
struct CompMapping
13+
{
14+
size_t id;
15+
void *__capability ddc;
16+
void *map_addr;
17+
struct Compartment *comp;
18+
bool in_use;
19+
};
20+
21+
struct CompMapping *
22+
mapping_new(struct Compartment *);
23+
struct CompMapping *
24+
mapping_new_fixed(struct Compartment *, void *);
25+
void
26+
mapping_free(struct CompMapping *);
27+
int64_t
28+
mapping_exec(struct CompMapping *, char *, char **);
29+
30+
/*******************************************************************************
31+
* Mappings list
32+
******************************************************************************/
33+
34+
#include "tommy.h"
35+
36+
#define mapping_hash(x) tommy_inthash_u64(x)
37+
#define MAPPINGS_MAX_SZ 1024
38+
39+
struct CompMappingEntry
40+
{
41+
struct CompMapping *map_ref;
42+
tommy_node node;
43+
};
44+
45+
typedef tommy_hashtable mappings_list;
46+
typedef struct CompMappingEntry mapping_entry;
47+
extern mappings_list *mappings;
48+
49+
mappings_list *
50+
mappings_init(void);
51+
void
52+
mappings_clean(mappings_list *);
53+
void
54+
mappings_clean_deep(mappings_list *);
55+
void
56+
mappings_insert(mapping_entry *, mappings_list *);
57+
struct CompMapping *
58+
mappings_search_free(struct Compartment *, mappings_list *);
59+
void
60+
mappings_delete(struct CompMapping *, mappings_list *);
61+
62+
#endif // _CHERICOMP_MAPPINGS_H

src/CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ add_library(chcomp STATIC
33
compartment.c
44
intercept.c
55
manager.c
6+
mappings.c
67
symbols_comp.c
78
symbols_lib.c
89
transition.S
@@ -13,3 +14,8 @@ target_link_libraries(chcomp PRIVATE tomllib tommydslib)
1314
add_library(computils SHARED
1415
comp_utils.c)
1516
target_include_directories(computils PRIVATE ${INCLUDE_DIR})
17+
18+
add_library(compbench SHARED
19+
benchmarking.c)
20+
target_include_directories(compbench PRIVATE ${INCLUDE_DIR})
21+
target_link_libraries(compbench PRIVATE m)

src/benchmarking.c

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
#include <benchmarking.h>
2+
3+
static size_t next_id = 0;
4+
static struct bench_entry **benchs;
5+
6+
/*******************************************************************************
7+
* Diff functions
8+
******************************************************************************/
9+
10+
static double
11+
timespec_diff(struct timespec *end, struct timespec *start)
12+
{
13+
return (end->tv_sec - start->tv_sec)
14+
+ (end->tv_nsec - start->tv_nsec) * pow(10, -9);
15+
}
16+
17+
/*******************************************************************************
18+
* Benchmark one function
19+
******************************************************************************/
20+
21+
size_t
22+
bench_init(const char *fn_name)
23+
{
24+
return 0;
25+
struct bench_entry *new_be = malloc(sizeof(struct bench_entry));
26+
new_be->fn_name = fn_name;
27+
next_id += 1;
28+
benchs = realloc(benchs, next_id * sizeof(struct bench_entry *));
29+
benchs[next_id - 1] = new_be;
30+
return next_id - 1;
31+
}
32+
33+
void
34+
bench_start(size_t id)
35+
{
36+
return;
37+
benchs[id]->res_start = clock_gettime(CLOCK_MONOTONIC, &benchs[id]->start);
38+
}
39+
40+
void
41+
bench_end(size_t id)
42+
{
43+
return;
44+
int res_end = clock_gettime(CLOCK_MONOTONIC, &benchs[id]->end);
45+
assert(benchs[id]->res_start != -1);
46+
assert(res_end != -1);
47+
benchs[id]->diff = timespec_diff(&benchs[id]->end, &benchs[id]->start);
48+
bench_report_one_id(id);
49+
}
50+
51+
/*******************************************************************************
52+
* Printing
53+
******************************************************************************/
54+
55+
static void
56+
print_timespec(char *buf, struct timespec *ts)
57+
{
58+
sprintf(buf, "%lld.%9ld", (long long) ts->tv_sec, ts->tv_nsec);
59+
}
60+
61+
static void
62+
bench_report_one(struct bench_entry *entry)
63+
{
64+
65+
const unsigned short buf_sz = 30;
66+
char *buf_st = alloca(buf_sz);
67+
print_timespec(buf_st, &entry->start);
68+
char *buf_en = alloca(buf_sz);
69+
print_timespec(buf_en, &entry->end);
70+
printf("Func <%s> -- start %s -- end %s -- seconds %f\n", entry->fn_name,
71+
buf_st, buf_en, entry->diff);
72+
}
73+
74+
void
75+
bench_report_one_id(size_t id)
76+
{
77+
printf("ID %zu == ", id);
78+
bench_report_one(benchs[id]);
79+
}

src/comp_utils.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,9 @@ malloc(size_t to_alloc)
7575
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
7676
if (mem_begin == MAP_FAILED)
7777
{
78-
err(1, "comp_utils: Failed `mmap`");
78+
exit(1);
79+
/*err(1, "comp_utils: Failed `mmap`"); // TODO replace with a
80+
* signal*/
7981
}
8082
mem_left = NON_COMP_DEFAULT_SIZE;
8183
}
@@ -175,7 +177,9 @@ free(void *to_free)
175177
void *
176178
calloc(size_t elem_count, size_t elem_size)
177179
{
178-
return malloc(elem_count * elem_size);
180+
void *alloc = malloc(elem_count * elem_size);
181+
explicit_bzero(alloc, elem_count * elem_size);
182+
return alloc;
179183
}
180184

181185
void *

src/compartment.c

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
const char *libs_path_env_var = "COMP_LIBRARY_PATH";
44
const char *tls_rtld_dropin = "tls_lookup_stub";
5+
const char *comp_malloc_header = "heap_header";
56
const char *comp_utils_soname = "libcomputils.so";
67

78
/*******************************************************************************
@@ -66,8 +67,6 @@ static void
6667
print_lib_dep_seg(struct SegmentMap *);
6768
static void
6869
print_lib_dep(struct LibDependency *);
69-
static void
70-
print_comp_simple(struct Compartment *);
7170

7271
/*******************************************************************************
7372
* Main compartment functions
@@ -94,6 +93,8 @@ comp_init(void)
9493
new_comp->scratch_mem_stack_size = 0;
9594
new_comp->scratch_mem_extra = 0;
9695

96+
new_comp->heap_mem_header = NULL;
97+
9798
new_comp->libs_count = 0;
9899
new_comp->libs = NULL;
99100
new_comp->libs_tls_sects = NULL;
@@ -171,6 +172,16 @@ comp_from_elf(char *filename, struct CompConfig *cc)
171172
next_dep:
172173
(void) 0;
173174
}
175+
176+
if (!strcmp(parsed_lib->lib_name, comp_utils_soname))
177+
{
178+
new_comp->heap_mem_header
179+
= (char *) lib_syms_search(
180+
comp_malloc_header, parsed_lib->lib_syms)
181+
->sym_offset
182+
+ (uintptr_t) parsed_lib->lib_mem_base;
183+
}
184+
174185
libs_parsed_count += 1;
175186
}
176187
free(libs_to_parse);
@@ -216,7 +227,6 @@ comp_from_elf(char *filename, struct CompConfig *cc)
216227
assert(new_comp->environ_sz + new_comp->total_tls_size
217228
== new_comp->scratch_mem_extra);
218229

219-
print_comp_simple(new_comp);
220230
return new_comp;
221231
}
222232

@@ -1231,7 +1241,7 @@ print_lib_dep(struct LibDependency *lib_dep)
12311241
printf("== DONE\n");
12321242
}
12331243

1234-
static void
1244+
void
12351245
print_comp_simple(struct Compartment *to_print)
12361246
{
12371247
printf("== COMPARTMENT SIMPLE -- ID %zu\n", to_print->id);

0 commit comments

Comments
 (0)