PERFORCE change 219781 for review
Brooks Davis
brooks at FreeBSD.org
Wed Nov 14 17:28:17 UTC 2012
http://p4web.freebsd.org/@@219781?ac=10
Change 219781 by brooks at 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;
More information about the p4-projects
mailing list