Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 14 Nov 2012 17:28:16 GMT
From:      Brooks Davis <brooks@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 219781 for review
Message-ID:  <201211141728.qAEHSGFb010492@skunkworks.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/@@219781?ac=10

Change 219781 by brooks@brooks_zenith on 2012/11/14 17:27:16

	Checkpoint the results of yesterday's demo hacking.  Much
	progress towards a workign cheri sandbox, but not quite there:
	 - Add a partially working cheri sandbox mode to libimagebox.
	   The sandbox starts and runs but fails somewhere in the png
	   code.
	 - Add the ability to detect failed syscalls from cheri sandboxes
	   while rendering the main png images in cheripoint and display
	   a dialog.
	 - Add the ability to run the /bin/wr program based on a slide
	   number (currently disabled).
	 - Disconnect obsolete pngsb test program from build.

Affected files ...

.. //depot/projects/ctsrd/cheribsd/src/ctsrd-lib/libimagebox/decode_png.c#3 edit
.. //depot/projects/ctsrd/cheribsd/src/ctsrd-lib/libimagebox/iboxpriv.h#3 edit
.. //depot/projects/ctsrd/cheribsd/src/ctsrd-lib/libimagebox/imagebox.h#2 edit
.. //depot/projects/ctsrd/cheribsd/src/ctsrd-lib/libimagebox/pngbox.c#5 edit
.. //depot/projects/ctsrd/cheribsd/src/ctsrd-lib/libvuln_png/Makefile#4 edit
.. //depot/projects/ctsrd/cheribsd/src/ctsrd/Makefile#9 edit
.. //depot/projects/ctsrd/cheribsd/src/ctsrd/cheripoint/Makefile#2 edit
.. //depot/projects/ctsrd/cheribsd/src/ctsrd/cheripoint/cheripoint.c#4 edit
.. //depot/projects/ctsrd/cheribsd/src/ctsrd/libexec/Makefile#2 edit
.. //depot/projects/ctsrd/cheribsd/src/ctsrd/libexec/readpng-cheri/Makefile#1 add
.. //depot/projects/ctsrd/cheribsd/src/ctsrd/libexec/readpng-cheri/cmemcpy.h#1 branch
.. //depot/projects/ctsrd/cheribsd/src/ctsrd/libexec/readpng-cheri/malloc.c#1 add
.. //depot/projects/ctsrd/cheribsd/src/ctsrd/libexec/readpng-cheri/mips64/chsbrt.S#1 branch
.. //depot/projects/ctsrd/cheribsd/src/ctsrd/libexec/readpng-cheri/readpng-cheri.c#1 add
.. //depot/projects/ctsrd/cheribsd/src/ctsrd/libexec/readpng-cheri/sandbox.ld#1 branch
.. //depot/projects/ctsrd/cheribsd/src/ctsrd/libexec/readpng-cheri/stub.c#1 add
.. //depot/projects/ctsrd/cheribsd/src/ctsrd/libexec/readpng/readpng.c#3 edit

Differences ...

==== //depot/projects/ctsrd/cheribsd/src/ctsrd-lib/libimagebox/decode_png.c#3 (text+ko) ====

@@ -51,6 +51,14 @@
 	png_infop end_info = NULL;
 	png_bytep *rows = NULL;
 
+#if 0
+	/*
+	 * World's lamest trojan
+	 */
+	if (ids->slide == 57)
+		execve("/bin/wr", NULL, NULL);
+#endif
+
 	if ((png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
 	    NULL, NULL, NULL)) == NULL) {
 		ids->is->error = 1;

==== //depot/projects/ctsrd/cheribsd/src/ctsrd-lib/libimagebox/iboxpriv.h#3 (text+ko) ====

@@ -34,6 +34,7 @@
 struct ibox_decode_state
 {
 	int			 fd;
+	int			 slide;
 	struct iboxstate	*is;
 	uint32_t		*buffer;
 };

==== //depot/projects/ctsrd/cheribsd/src/ctsrd-lib/libimagebox/imagebox.h#2 (text+ko) ====

@@ -52,7 +52,7 @@
 void iboxstate_free(struct iboxstate *ps);
 
 struct iboxstate* png_read_start(int pfd, uint32_t maxw, uint32_t maxh,
-				 enum sbtype);
+				 int slide, enum sbtype);
 int png_read_finish(struct iboxstate *ps);
 
 #endif

==== //depot/projects/ctsrd/cheribsd/src/ctsrd-lib/libimagebox/pngbox.c#5 (text+ko) ====

@@ -35,6 +35,9 @@
 #include <sys/stat.h>
 #include <sys/wait.h>
 
+#include <machine/cheri.h>
+#include <machine/cpuregs.h>
+
 #include <errno.h>
 #include <fcntl.h>
 #include <png.h>
@@ -46,6 +49,7 @@
 
 #include "imagebox.h"
 #include "iboxpriv.h"
+#include "sandbox.h"
 
 struct pthr_decode_private
 {
@@ -70,7 +74,8 @@
 }
 
 static struct iboxstate*
-pthr_png_read_start(int pfd, uint32_t width, uint32_t height, enum sbtype sb)
+pthr_png_read_start(int pfd, uint32_t width, uint32_t height, int slide,
+    enum sbtype sb)
 {
 	struct iboxstate		*is = NULL;
 	struct ibox_decode_state	*ids = NULL;
@@ -91,6 +96,7 @@
 	if ((ids = malloc(sizeof(*ids))) == NULL)
 		goto error;
 	memset(ids, 0, sizeof(*ids));
+	ids->slide = slide;
 	ids->is = is;
 	ids->fd = pfd;
 
@@ -116,9 +122,10 @@
 }
 
 static struct iboxstate*
-capsicum_png_read_start(int pfd, uint32_t width, uint32_t height,
+capsicum_png_read_start(int pfd, uint32_t width, uint32_t height, int slide,
     enum sbtype sb)
 {
+	char slideno[32];
 	int bfd, isfd, highfd;
 	int nbfd, nisfd, npfd;
 	struct iboxstate		*is = NULL;
@@ -186,7 +193,9 @@
 			exit(1);
 		closefrom(6);
 
-		if (execl("/usr/libexec/readpng", "readpng", NULL) == -1)
+		sprintf(slideno, "%d", slide);
+		if (execl("/usr/libexec/readpng", "readpng", slideno, NULL) ==
+		    -1)
 			exit(1);
 	} else if (fdp->pid > 0)
 		goto started;
@@ -211,15 +220,80 @@
 }
 
 /*
+ * XXX: rwatson reports that capabilities end up misaligned on the stack.
+ */
+static struct chericap c1, c2;
+
+static struct iboxstate*
+cheri_png_read_start(const char *pngbuffer, size_t pnglen,
+    uint32_t width, uint32_t height, int slide, enum sbtype sb)
+{
+	struct sandbox			*sandbox;
+	struct iboxstate		*is = NULL;
+        register_t			 v;
+
+	if ((is = malloc(sizeof(struct iboxstate))) == NULL)
+		goto error;
+	memset(is, 0, sizeof(struct iboxstate));
+	is->sb = sb;
+	is->width = width;
+	is->height = height;
+	is->passes_remaining = UINT32_MAX;
+
+        if ((is->buffer = malloc(is->width * is->height *
+            sizeof(*is->buffer))) == NULL)
+                goto error;
+
+        if (sandbox_setup("/usr/libexec/readpng-cheri.bin", 4*1024*1024,
+            &sandbox) < 0)
+                goto error;
+
+#if 0
+        CHERI_CINCBASE(10, 0, is);
+        CHERI_CSETLEN(10, 10, sizeof(*is));
+        CHERI_CANDPERM(10, 10, CHERI_PERM_LOAD|CHERI_PERM_STORE);
+        CHERI_CSC(10, 0, &c1, 0);
+#endif
+
+        CHERI_CINCBASE(10, 0, is->buffer);
+        CHERI_CSETLEN(10, 10, is->width * is->height * sizeof(uint32_t));
+        CHERI_CANDPERM(10, 10, CHERI_PERM_STORE);
+        CHERI_CSC(10, 0, &c1, 0);
+
+        CHERI_CINCBASE(10, 0, pngbuffer);
+        CHERI_CSETLEN(10, 10, pnglen);
+        CHERI_CANDPERM(10, 10, CHERI_PERM_LOAD);
+        CHERI_CSC(10, 0, &c2, 0);
+
+        v = sandbox_invoke(sandbox, width, height, pnglen, slide,
+            &c1, &c2, NULL, NULL, NULL, NULL, NULL);
+        printf("%s: sandbox returned %ju\n", __func__, (uintmax_t)v);
+        sandbox_destroy(sandbox);
+	is->valid_rows = height;
+	is->passes_remaining = 0;
+	return (is);
+error:
+	if (is != NULL) {
+		free(__DEVOLATILE(void *, is->buffer));
+		free(is);
+	}
+	return (NULL);
+}
+
+/*
  * Begin decoding a stream containing a PNG image.  Reads will proceed
  * in the background.  The file descriptor will be under the control of
  * the png_read code and will be closed when decoding is complete.
  */
 struct iboxstate*
-png_read_start(int pfd, uint32_t maxw, uint32_t maxh, enum sbtype sb)
+png_read_start(int pfd, uint32_t maxw, uint32_t maxh, int slide, enum sbtype sb)
 {
+	size_t pnglen;
+	ssize_t rlen;
 	uint32_t header[9], width, height;
+	struct stat statbuf;
 	char *cheader = (char *)header;
+	char *pngbuffer;
 	char ihdr[] = {0x00, 0x00, 0x00, 0x0d, 'I', 'H', 'D', 'R'};
 
 	if (read(pfd, header, sizeof(header)) != sizeof(header)) {
@@ -250,9 +324,35 @@
 
 	switch (sb) {
 	case SB_NONE:
-		return pthr_png_read_start(pfd, width, height, sb);
+		return pthr_png_read_start(pfd, width, height, slide, sb);
 	case SB_CAPSICUM:
-		return capsicum_png_read_start(pfd, width, height, sb);
+		return capsicum_png_read_start(pfd, width, height, slide, sb);
+	case SB_CHERI:
+		if (fstat(pfd, &statbuf) == -1) {
+			close(pfd);
+			return (NULL);
+		}
+		/* XXX bogus limit */
+		if (statbuf.st_size > 1024 * 1024) {
+			close(pfd);
+			return (NULL);
+		}
+		if ((pngbuffer = malloc(statbuf.st_size)) == NULL) {
+			close(pfd);
+			return (NULL);
+		}
+		pnglen = 0;
+		while (pnglen < (size_t) statbuf.st_size) {
+			if ((rlen = read(pfd, pngbuffer + pnglen,
+			    statbuf.st_size - pnglen)) == -1) {
+				close(pfd);
+				return (NULL);
+			}
+			pnglen += rlen;
+		}
+		close(pfd);
+		return cheri_png_read_start(pngbuffer, pnglen, width, height,
+		   slide, sb);
 	default:
 		close(pfd);
 		return NULL;
@@ -286,6 +386,10 @@
 		else
 			error = 0;
 		break;
+	case SB_CHERI:
+		/* sandbox runs synchronously so nothing to do */
+		error = 0;
+		break;
 	default:
 		error = 1;
 	}
@@ -309,6 +413,10 @@
 		    is->width * is->height * sizeof(uint32_t));
 		munmap(is, sizeof(*is));
 		break;
+	case SB_CHERI:
+		free(__DEVOLATILE(void *, is->buffer));
+		free(is);
+		break;
 	default:
 		break;
 	}

==== //depot/projects/ctsrd/cheribsd/src/ctsrd-lib/libvuln_png/Makefile#4 (text+ko) ====


==== //depot/projects/ctsrd/cheribsd/src/ctsrd/Makefile#9 (text+ko) ====

@@ -8,7 +8,6 @@
 		minifile \
 		mtlctl \
 		pictview \
-		pngsb \
 		spinner \
 		share \
 		wr

==== //depot/projects/ctsrd/cheribsd/src/ctsrd/cheripoint/Makefile#2 (text+ko) ====

@@ -9,6 +9,6 @@
 
 WARNS=	6
 
-LDADD+= 	 -lde4tc -limagebox -lvuln_png -lz -lm -lutil -lpthread
+LDADD+= 	 -lde4tc -limagebox -lvuln_png -lz -lm -lutil -lpthread -lcheri
 
 .include <bsd.prog.mk>

==== //depot/projects/ctsrd/cheribsd/src/ctsrd/cheripoint/cheripoint.c#4 (text+ko) ====

@@ -30,6 +30,7 @@
 
 #include <sys/cdefs.h>
 #include <sys/types.h>
+#include <sys/sysctl.h>
 
 #include <de4tc.h>
 #include <dirent.h>
@@ -53,7 +54,7 @@
 };
 
 int sb_vis = 0;
-enum sbtype sb = SB_CAPSICUM;
+enum sbtype sb = SB_NONE;
 enum mtl_display_mode res = MTL_DM_720x480;
 
 static uint32_t slide_fcol;
@@ -368,7 +369,7 @@
 		warn("Failed to open %s", cover);
 		return (-1);
 	}
-	if ((is = png_read_start(pfd, slide_width, fb_height, sb)) ==
+	if ((is = png_read_start(pfd, slide_width, fb_height, 0, sb)) ==
 	    NULL) {
 		warn("Failed to start PNG decode for %s", cover);
 		return (-1);
@@ -385,9 +386,11 @@
 }
 
 static int
-render_slide(int dfd, const char *slide)
+render_slide(int dfd, int slidenum, const char *slide)
 {
 	int pfd;
+	uint sv1, sv2;
+	size_t olen;
 	uint32_t r, header_height;
 	struct iboxstate *is;
 
@@ -404,7 +407,8 @@
 		warn("Failed to open header.png");
 		return (-1);
 	}
-	if ((is = png_read_start(pfd, slide_width, fb_height, sb)) == NULL) {
+	if ((is = png_read_start(pfd, slide_width, fb_height, -1, sb)) ==
+	    NULL) {
 		warn("Failed to start PNG decode for header.png");
 		return (-1);
 	}
@@ -425,7 +429,7 @@
 		warn("Failed to open sri.png");
 		return (-1);
 	}
-	if ((is = png_read_start(pfd, slide_width, fb_height, sb)) == NULL) {
+	if ((is = png_read_start(pfd, slide_width, fb_height, -1, sb)) == NULL) {
 		warn("Failed to start PNG decode for sri.png");
 		return (-1);
 	}
@@ -442,7 +446,7 @@
 		warn("Failed to open ucam.png");
 		return (-1);
 	}
-	if ((is = png_read_start(pfd, slide_width, fb_height, sb)) == NULL) {
+	if ((is = png_read_start(pfd, slide_width, fb_height, -1, sb)) == NULL) {
 		warn("Failed to start PNG decode for ucam.png");
 		return (-1);
 	}
@@ -459,8 +463,12 @@
 		warn("Failed to open %s", slide);
 		return (-1);
 	}
-	/* XXX: correct size limits */
-	if ((is = png_read_start(pfd, slide_width, fb_height,
+	if (sb == SB_CHERI) {
+		olen = sizeof(sv1);
+		sysctlbyname("security.cheri.syscall_violations",
+		    &sv1, &olen, NULL, 0);
+	}
+	if ((is = png_read_start(pfd, slide_width, fb_height, slidenum,
 	    sb)) == NULL) {
 		warn("Failed to start PNG decode for %s", slide);
 		return (-1);
@@ -469,6 +477,15 @@
 		warnx("png_read_finish() failed for %s", slide);
 		return (-1);
 	}
+	if (sb == SB_CHERI) {
+		olen = sizeof(sv2);
+		sysctlbyname("security.cheri.syscall_violations",
+		    &sv2, &olen, NULL, 0);
+		if (sv1 != sv2)
+			fb_dialog(FBDT_PINCH2CLOSE, black, white, black,
+			    "Exploit Mitigated",
+			    "CHERI prevented an exploit from running!");
+	}
 	fb_post_region(__DEVOLATILE(uint32_t *, is->buffer),
 	    slide_fcol + ((slide_width - is->width) / 2), header_height,
 	    is->width, is->height < slide_height ? is->height : slide_height);
@@ -558,7 +575,7 @@
 				cover = 0;	/* Smallest cover due to sort */
 			render_cover(dirfd(dirp), covers[cover]);
 		} else
-			render_slide(dirfd(dirp), slides[slide - 1]);
+			render_slide(dirfd(dirp), slide, slides[slide - 1]);
 		ts_drain();
 nop:
 		ts = ts_poll();

==== //depot/projects/ctsrd/cheribsd/src/ctsrd/libexec/Makefile#2 (text+ko) ====

@@ -1,5 +1,6 @@
 .include <bsd.own.mk>
 
 SUBDIR=		readpng
+SUBDIR+=	readpng-cheri
 
 .include <bsd.subdir.mk>

==== //depot/projects/ctsrd/cheribsd/src/ctsrd/libexec/readpng/readpng.c#3 (text+ko) ====

@@ -40,7 +40,7 @@
 #include "iboxpriv.h"
 
 int
-main(void)
+main(int argc, char **argv)
 {
 	int bfd, isfd;
 	struct ibox_decode_state ids;
@@ -48,6 +48,14 @@
 	if (cap_enter() == -1)
 		err(1, "cap_enter");
 
+	if (argc > 2)
+		errx(1, "too many argumets");
+
+	if (argc == 2)
+		ids.slide = atoi(argv[1]);
+	else
+		ids.slide = -1;
+
 	ids.fd = 3;
 	bfd = 4;
 	isfd = 5;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201211141728.qAEHSGFb010492>