Skip to content

Commit def5689

Browse files
committed
c18n: Compartment switch tracing & counting for CHERI-RISC-V
1 parent aecaaba commit def5689

File tree

4 files changed

+113
-13
lines changed

4 files changed

+113
-13
lines changed

libexec/rtld-elf/aarch64/rtld_c18n_asm.S

-1
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,6 @@ ENTRY(tramp_hook)
217217

218218
mov c0, c10
219219
mov c1, c11
220-
mrs c2, TRUSTED_STACK
221220
bl tramp_hook_impl
222221

223222
restore_arguments

libexec/rtld-elf/riscv/rtld_c18n_asm.S

+66-7
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,30 @@ ENTRY(create_untrusted_stk)
166166
cjr cs8
167167
END(create_untrusted_stk)
168168

169+
/*
170+
* The tramp_hook function has non-standard ABI and is only called by
171+
* trampolines to trace compartment transitions.
172+
*/
173+
ENTRY(tramp_hook)
174+
/*
175+
* NON-STANDARD CALLING CONVENTION
176+
*
177+
* ct0-ct1 hold the first two arguments of tramp_hook.
178+
*
179+
* All argument registers and callee-saved registers must be preserved.
180+
*/
181+
182+
save_arguments
183+
184+
cmove ca0, ct0
185+
cmove ca1, ct1
186+
cjal tramp_hook_impl
187+
188+
restore_arguments
189+
190+
cret
191+
END(tramp_hook)
192+
169193
/*
170194
* The trampoline templates are assembly code sequences used to construct
171195
* trampolines by tramp_compile. They are code but reside in rodata. Hence a new
@@ -322,7 +346,25 @@ TRAMP(tramp_push_frame)
322346
* Save the the compartment ID of the caller.
323347
*/
324348
csw t4, (-CLEN_BYTES * TRUSTED_FRAME_SIZE + TRUSTED_FRAME_CALLER)(TRUSTED_STACK_C)
349+
TRAMPEND(tramp_push_frame)
350+
351+
PATCH_POINT(tramp_push_frame, pcc, 1b)
352+
PATCH_POINT(tramp_push_frame, unsealer, 2b)
353+
PATCH_POINT(tramp_push_frame, cid, 3b)
354+
PATCH_POINT(tramp_push_frame, target, 5b)
355+
356+
TRAMP(tramp_count_entry)
357+
.option push
358+
.option norvc
359+
1: clc cs6, 0(ct0) /* To be patched at runtime */
360+
.option pop
361+
li s7, 1
362+
camoadd.d x0, s7, (cs6)
363+
TRAMPEND(tramp_count_entry)
364+
365+
PATCH_POINT(tramp_count_entry, counter, 1b)
325366

367+
TRAMP(tramp_push_frame_2)
326368
/*
327369
* Get the landing address.
328370
*/
@@ -373,14 +415,27 @@ TRAMP(tramp_push_frame)
373415
* trusted frame would be inconsistent with the untrusted stack.
374416
*/
375417
set_untrusted_stk cs5
376-
TRAMPEND(tramp_push_frame)
418+
TRAMPEND(tramp_push_frame_2)
377419

378-
PATCH_POINT(tramp_push_frame, pcc, 1b)
379-
PATCH_POINT(tramp_push_frame, unsealer, 2b)
380-
PATCH_POINT(tramp_push_frame, cid, 3b)
381-
PATCH_POINT(tramp_push_frame, target, 5b)
382-
PATCH_POINT(tramp_push_frame, landing, 7b)
383-
PATCH_POINT(tramp_push_frame, n_rets, 10b)
420+
PATCH_POINT(tramp_push_frame_2, landing, 7b)
421+
PATCH_POINT(tramp_push_frame_2, n_rets, 10b)
422+
423+
TRAMP(tramp_call_hook)
424+
1: auipcc ct1, 0
425+
.option push
426+
.option norvc
427+
2: clc cra, 0(ct1) /* To be patched at runtime */
428+
429+
3: addi t0, x0, 0 /* To be patched at runtime */
430+
4: cincoffsetimm ct1, ct1, 0 /* To be patched at runtime */
431+
.option pop
432+
cjalr cra, cra
433+
TRAMPEND(tramp_call_hook)
434+
435+
PATCH_POINT(tramp_call_hook, pcc, 1b)
436+
PATCH_POINT(tramp_call_hook, function, 2b)
437+
PATCH_POINT(tramp_call_hook, event, 3b)
438+
PATCH_POINT(tramp_call_hook, header, 4b)
384439

385440
/*
386441
* Save the address of the current frame to fp so that unwinders can locate it.
@@ -427,6 +482,10 @@ TRAMP(tramp_invoke)
427482
cjalr cra, cs4
428483
TRAMPEND(tramp_invoke)
429484

485+
TRAMP(tramp_count_return)
486+
camoadd.d x0, s7, (cs6)
487+
TRAMPEND(tramp_count_return)
488+
430489
TRAMP(tramp_pop_frame)
431490
1: auipcc ct4, 0
432491
/*

libexec/rtld-elf/riscv/rtld_c18n_machdep.c

+44-2
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#include "rtld.h"
3939
#include "rtld_c18n.h"
4040
#include "rtld_libc.h"
41+
#include "rtld_utrace.h"
4142

4243
/*
4344
* Trampolines
@@ -50,15 +51,23 @@ tramp_compile(char **entry, const struct tramp_data *data)
5051
extern const size_t size_tramp_##template
5152

5253
IMPORT(push_frame);
54+
IMPORT(count_entry);
55+
IMPORT(push_frame_2);
56+
IMPORT(call_hook);
5357
IMPORT(update_fp);
5458
IMPORT(update_fp_untagged);
5559
IMPORT(clear_args);
5660
IMPORT(invoke);
61+
IMPORT(count_return);
5762
IMPORT(pop_frame);
5863

5964
size_t size = 0;
6065
char *buf = *entry;
66+
size_t count_off, hook_off, hook_pcc_off, header_off;
6167
size_t sealer_off, target_off, pcc_off, landing_off, unused_regs;
68+
bool count = ld_compartment_switch_count != NULL;
69+
bool hook = ld_compartment_utrace != NULL ||
70+
ld_compartment_overhead != NULL;
6271

6372
#define COPY_VALUE(val) ({ \
6473
size_t _old_size = size; \
@@ -103,6 +112,12 @@ tramp_compile(char **entry, const struct tramp_data *data)
103112
*PATCH_INS(PATCH_OFF(tramp, name)) |= _value; \
104113
} while (0)
105114

115+
if (count)
116+
count_off = COPY_VALUE(&c18n_stats->rcs_switch);
117+
118+
if (hook)
119+
hook_off = COPY_VALUE(&tramp_hook);
120+
106121
sealer_off = COPY_VALUE(sealer_tidc);
107122

108123
*(struct tramp_header *)(buf + size) = (struct tramp_header) {
@@ -112,6 +127,7 @@ tramp_compile(char **entry, const struct tramp_data *data)
112127
0 : data->def - data->defobj->symtab,
113128
.sig = data->sig
114129
};
130+
header_off = size;
115131
target_off = size + offsetof(struct tramp_header, target);
116132
*entry = buf + size;
117133
size += offsetof(struct tramp_header, entry);
@@ -122,17 +138,32 @@ tramp_compile(char **entry, const struct tramp_data *data)
122138
PATCH_I_TYPE(push_frame, cid,
123139
cid_to_index(data->defobj->compart_id).val);
124140
PATCH_I_TYPE(push_frame, target, target_off - pcc_off);
125-
landing_off = PATCH_OFF(push_frame, landing);
141+
142+
if (count) {
143+
COPY(count_entry);
144+
PATCH_I_TYPE(count_entry, counter, count_off - pcc_off);
145+
}
146+
147+
COPY(push_frame_2);
148+
landing_off = PATCH_OFF(push_frame_2, landing);
126149
/*
127150
* The number of return value registers is encoded as follows:
128151
* - TWO: 0b00
129152
* - ONE: 0b01
130153
* - NONE: 0b10
131154
* - INDIRECT: 0b11
132155
*/
133-
PATCH_I_TYPE(push_frame, n_rets,
156+
PATCH_I_TYPE(push_frame_2, n_rets,
134157
data->sig.valid ? data->sig.ret_args : 0);
135158

159+
if (hook) {
160+
COPY(call_hook);
161+
hook_pcc_off = PATCH_OFF(call_hook, pcc);
162+
PATCH_I_TYPE(call_hook, function, hook_off - hook_pcc_off);
163+
PATCH_I_TYPE(call_hook, event, UTRACE_COMPARTMENT_ENTER);
164+
PATCH_I_TYPE(call_hook, header, header_off - hook_pcc_off);
165+
}
166+
136167
if (ld_compartment_unwind != NULL)
137168
COPY(update_fp);
138169
else
@@ -148,6 +179,17 @@ tramp_compile(char **entry, const struct tramp_data *data)
148179
COPY(invoke);
149180
PATCH_LANDING(landing_off, size - pcc_off);
150181

182+
if (count)
183+
COPY(count_return);
184+
185+
if (hook) {
186+
COPY(call_hook);
187+
hook_pcc_off = PATCH_OFF(call_hook, pcc);
188+
PATCH_I_TYPE(call_hook, function, hook_off - hook_pcc_off);
189+
PATCH_I_TYPE(call_hook, event, UTRACE_COMPARTMENT_LEAVE);
190+
PATCH_I_TYPE(call_hook, header, header_off - hook_pcc_off);
191+
}
192+
151193
COPY(pop_frame);
152194
pcc_off = PATCH_OFF(pop_frame, pcc);
153195
PATCH_I_TYPE(pop_frame, unsealer, sealer_off - pcc_off);

libexec/rtld-elf/rtld_c18n.c

+3-3
Original file line numberDiff line numberDiff line change
@@ -1348,16 +1348,16 @@ resize_table(int exp)
13481348
}
13491349

13501350
void
1351-
tramp_hook_impl(int, const struct tramp_header *, const struct trusted_frame *);
1351+
tramp_hook_impl(int, const struct tramp_header *);
13521352

13531353
void
1354-
tramp_hook_impl(int event, const struct tramp_header *hdr,
1355-
const struct trusted_frame *tf)
1354+
tramp_hook_impl(int event, const struct tramp_header *hdr)
13561355
{
13571356
const char *sym;
13581357
const char *callee;
13591358
const char *caller;
13601359
struct utrace_c18n ut;
1360+
const struct trusted_frame *tf = get_trusted_stk();
13611361

13621362
if (ld_compartment_utrace != NULL) {
13631363
if (hdr->symnum == 0)

0 commit comments

Comments
 (0)