PERFORCE change 980156 for review
Robert Watson
rwatson at FreeBSD.org
Sun Oct 6 10:40:28 UTC 2013
http://p4web.freebsd.org/@@980156?ac=10
Change 980156 by rwatson at rwatson_zenith_cl_cam_ac_uk on 2013/10/06 10:40:15
Rework setup of simple CCall/CReturn sandboxes in cheritest a
little:
- Abstract the code very mildly to allow different types of
sandboxes to be created.
- Clear $c3 once a sandbox is set up for calling in $c1 and $c2,
as it is no longer required.
- Save the host environment $c0 in $idc before CCall, and clear
it before entering the sandbox; restore it from $idc after
the sandbox has returned; sandboxes no longer inherit access
to the global address space by default.
- Add a new and highly adventurous ccall_nop_creturn test case,
which not only enters and returns from a sandbox, but runs
three (3) nops inside.
Affected files ...
.. //depot/projects/ctsrd/cheribsd/src/bin/cheritest/cheritest.c#24 edit
.. //depot/projects/ctsrd/cheribsd/src/bin/cheritest/cheritest_sandbox.S#3 edit
.. //depot/projects/ctsrd/cheribsd/src/bin/cheritest/cheritest_sandbox.h#3 edit
Differences ...
==== //depot/projects/ctsrd/cheribsd/src/bin/cheritest/cheritest.c#24 (text+ko) ====
@@ -68,9 +68,9 @@
usage(void)
{
- fprintf(stderr, "cheritest ccall\n");
+ fprintf(stderr, "cheritest ccall_creturn\n");
+ fprintf(stderr, "cheritest ccall_nop_creturn\n");
fprintf(stderr, "cheritest copyregs\n");
- fprintf(stderr, "cheritest creturn\n");
fprintf(stderr, "cheritest listcausereg\n");
fprintf(stderr, "cheritest listprivregs\n");
fprintf(stderr, "cheritest listregs\n");
@@ -99,8 +99,13 @@
CHERI_CSB(0, 0, 0, 1);
}
+/*
+ * Configure $c1 and $c2 to enter a simple sandbox. Not suitable for more
+ * complex tests as it has no notion of configuring heaps/stacks/etc.
+ */
static void
-cheritest_ccall(void)
+cheritest_sandbox_setup(void *sandbox_base, void *sandbox_end,
+ register_t sandbox_pc)
{
/*-
@@ -109,16 +114,10 @@
*
* Derive from $c3 a code capability in $c1, and data capability in
* $c2, suitable for use with CCall.
- *
- * Current limitations:
- * - $c2 doesn't matter as sandbox_creturn doesn't access data.
- * - We don't flush registers before CCall.
- * - We don't restore registers after CCall.
*/
- CHERI_CINCBASE(3, 0, &sandbox_creturn);
- CHERI_CSETTYPE(3, 3, 0);
- CHERI_CSETLEN(3, 3, (uintptr_t)&sandbox_creturn_end -
- (uintptr_t)&sandbox_creturn);
+ CHERI_CINCBASE(3, 0, sandbox_base);
+ CHERI_CSETTYPE(3, 3, sandbox_pc);
+ CHERI_CSETLEN(3, 3, (uintptr_t)sandbox_end - (uintptr_t)sandbox_base);
/*
* Construct a code capability in $c1, derived from $c3, suitable for
@@ -133,16 +132,59 @@
*/
CHERI_CANDPERM(2, 3, CHERI_PERM_LOAD);
CHERI_CSEALDATA(2, 2, 3);
-
- /* Invoke capability. */
- CHERI_CCALL(1, 2);
+
+ /*
+ * Clear $c3 which we no longer require.
+ */
+ CHERI_CCLEARTAG(3);
+}
+
+/*
+ * Wrapper for CHERI_CCALL(). We don't use the normal CHERI_CCALL() macro
+ * because we want to sort out $c0, and can't let compiler-generated code run
+ * between $c0 manipulation and CCall.
+ *
+ * XXXRW: We should probably be flushing much of the general-purpose register
+ * file before CCall, and restore them afterwards, at measurable cost.
+ *
+ * XXXRW: This should probably just be an assembly function rather than inline
+ * assembly, because then the compiler would save caller-save registers for
+ * us, if required, saving some work.
+ */
+static void
+cheritest_ccall(void)
+{
+
+ __asm__ __volatile__ (
+ /* Move $c0 to $idc so that it will be saved by CCall. */
+ "cmove $c26, $c0;"
+
+ /* Clear $c0 so it's not available to sandbox. */
+ "ccleartag $c0;"
+
+ /* Invoke object capability. */
+ "ccall $c1, $c2;"
+
+ /* Set $c0 back to stored $idc. */
+ "cmove $c0, $c26"
+ : : : "memory");
+}
+
+static void
+cheritest_ccall_creturn(void)
+{
+
+ cheritest_sandbox_setup(&sandbox_creturn, &sandbox_creturn_end, 0);
+ cheritest_ccall();
}
static void
-cheritest_creturn(void)
+cheritest_ccall_nop_creturn(void)
{
- CHERI_CRETURN();
+ cheritest_sandbox_setup(&sandbox_nop_creturn,
+ &sandbox_nop_creturn_end, 0);
+ cheritest_ccall();
}
static void
@@ -345,12 +387,12 @@
cheritest_listprivregs();
else if (strcmp(argv[i], "listregs") == 0)
cheritest_listregs();
- else if (strcmp(argv[i], "ccall") == 0)
- cheritest_ccall();
+ else if (strcmp(argv[i], "ccall_creturn") == 0)
+ cheritest_ccall_creturn();
+ else if (strcmp(argv[i], "ccall_nop_creturn") == 0)
+ cheritest_ccall_nop_creturn();
else if (strcmp(argv[i], "copyregs") == 0)
cheritest_copyregs();
- else if (strcmp(argv[i], "creturn") == 0)
- cheritest_creturn();
else if (strcmp(argv[i], "nullderef") == 0)
cheritest_nullderef();
else if (strcmp(argv[i], "overrun") == 0)
==== //depot/projects/ctsrd/cheribsd/src/bin/cheritest/cheritest_sandbox.S#3 (text+ko) ====
@@ -50,3 +50,22 @@
.global sandbox_creturn_end
sandbox_creturn_end:
+
+
+ /*
+ * Sandbox code that performs a series of nops before creturn.
+ * Position-independent, no memory access.
+ */
+ .text
+ .global sandbox_nop_creturn
+ .ent sandbox_nop_creturn
+sandbox_nop_creturn:
+
+ nop
+ nop
+ nop
+ creturn
+ .end sandbox_nop_creturn
+
+ .global sandbox_nop_creturn_end
+sandbox_nop_creturn_end:
==== //depot/projects/ctsrd/cheribsd/src/bin/cheritest/cheritest_sandbox.h#3 (text+ko) ====
@@ -34,4 +34,7 @@
extern void *sandbox_creturn;
extern void *sandbox_creturn_end;
+extern void *sandbox_nop_creturn;
+extern void *sandbox_nop_creturn_end;
+
#endif /* !_CHERITEST_SANDBOX_H_ */
More information about the p4-projects
mailing list