From owner-p4-projects@FreeBSD.ORG Wed Nov 14 17:28:17 2012 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id E166115B; Wed, 14 Nov 2012 17:28:16 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 9DEA8159 for ; Wed, 14 Nov 2012 17:28:16 +0000 (UTC) (envelope-from brooks@freebsd.org) Received: from skunkworks.freebsd.org (skunkworks.freebsd.org [IPv6:2001:4f8:fff6::2d]) by mx1.freebsd.org (Postfix) with ESMTP id 830078FC13 for ; Wed, 14 Nov 2012 17:28:16 +0000 (UTC) Received: from skunkworks.freebsd.org (localhost [127.0.0.1]) by skunkworks.freebsd.org (8.14.5/8.14.5) with ESMTP id qAEHSG01010495 for ; Wed, 14 Nov 2012 17:28:16 GMT (envelope-from brooks@freebsd.org) Received: (from perforce@localhost) by skunkworks.freebsd.org (8.14.5/8.14.5/Submit) id qAEHSGFb010492 for perforce@freebsd.org; Wed, 14 Nov 2012 17:28:16 GMT (envelope-from brooks@freebsd.org) Date: Wed, 14 Nov 2012 17:28:16 GMT Message-Id: <201211141728.qAEHSGFb010492@skunkworks.freebsd.org> X-Authentication-Warning: skunkworks.freebsd.org: perforce set sender to brooks@freebsd.org using -f From: Brooks Davis Subject: PERFORCE change 219781 for review To: Perforce Change Reviews Precedence: bulk X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.14 List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 14 Nov 2012 17:28:17 -0000 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 #include +#include +#include + #include #include #include @@ -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 ==== //depot/projects/ctsrd/cheribsd/src/ctsrd/cheripoint/cheripoint.c#4 (text+ko) ==== @@ -30,6 +30,7 @@ #include #include +#include #include #include @@ -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 SUBDIR= readpng +SUBDIR+= readpng-cheri .include ==== //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;