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