From owner-p4-projects@FreeBSD.ORG Thu Nov 15 02:05:12 2012 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 59AB1D1B; Thu, 15 Nov 2012 02:05:12 +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 171CDD19 for ; Thu, 15 Nov 2012 02:05:12 +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 F14718FC12 for ; Thu, 15 Nov 2012 02:05:11 +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 qAF25BOt030999 for ; Thu, 15 Nov 2012 02:05:11 GMT (envelope-from brooks@freebsd.org) Received: (from perforce@localhost) by skunkworks.freebsd.org (8.14.5/8.14.5/Submit) id qAF25Boc030996 for perforce@freebsd.org; Thu, 15 Nov 2012 02:05:11 GMT (envelope-from brooks@freebsd.org) Date: Thu, 15 Nov 2012 02:05:11 GMT Message-Id: <201211150205.qAF25Boc030996@skunkworks.freebsd.org> X-Authentication-Warning: skunkworks.freebsd.org: perforce set sender to brooks@freebsd.org using -f From: Brooks Davis Subject: PERFORCE change 219791 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: Thu, 15 Nov 2012 02:05:12 -0000 http://p4web.freebsd.org/@@219791?ac=10 Change 219791 by brooks@brooks_zenith on 2012/11/15 02:05:02 Add a -f flag to fork and monitor a child process that runs the main cheripoint process. This will help us manage the exploited application case. Affected files ... .. //depot/projects/ctsrd/cheribsd/src/ctsrd/cheripoint/cheripoint.c#6 edit Differences ... ==== //depot/projects/ctsrd/cheribsd/src/ctsrd/cheripoint/cheripoint.c#6 (text+ko) ==== @@ -31,17 +31,26 @@ #include #include #include +#include #include #include #include +#include #include #include #include +#include +#include +#include +#include #include #include #include +#include +#include + #define vwhite(v) fb_colour((v), (v), (v)) #define black vwhite(0) #define white vwhite(0xFF) @@ -58,6 +67,7 @@ int sb_vis = 0; enum sbtype sb = SB_CHERI; enum mtl_display_mode res = MTL_DM_720x480; +static int zombies_waiting = 0; static uint32_t slide_fcol; static uint32_t slide_width; @@ -67,7 +77,7 @@ usage(void) { - fprintf(stderr, "cheripoint \n"); + fprintf(stderr, "cheripoint [-f] \n"); exit(1); } @@ -537,6 +547,121 @@ (*np)++; } +static void +handle_sigchld(int sig __unused) +{ + + zombies_waiting = 1; +} + +static void +writeall(int fd, const char *buf, ssize_t len) +{ + ssize_t wlen = 0, n; + + while (wlen != len) { + n = write(fd, buf + wlen, len - wlen); + if (n < 0) { + syslog(LOG_ALERT, "write failed: %s", strerror(errno)); + err(1, "write"); + } + wlen += n; + } +} + +static void +fork_child(void) +{ + int pmaster, pslave, status; + ssize_t rlen; + pid_t pid; + struct sigaction act; + struct pollfd pfd[1]; + char buf[1024]; + u_int32_t *image; + +restart: + if (openpty(&pmaster, &pslave, NULL, NULL, NULL) == -1) + err(1, "openpty"); + pid = fork(); + if (pid < 0) + err(1, "fork()"); + else if (pid == 0) { + close(pmaster); + if (login_tty(pslave) < 0) { + syslog(LOG_ALERT, "login_tty failed in child: %s", + strerror(errno)); + err(1, "tty_login"); + } + /* return to begin normal processing */ + return; + } + + memset (&act, 0, sizeof(act)); + act.sa_handler = handle_sigchld; + + if (sigaction(SIGCHLD, &act, 0)) + err(1, "sigacation"); + + close(pslave); + /* + * We poll for data from the child's pty. Don't bother looking for + * tty input since the child couldn't do anything with it. + */ + pfd[0].fd = pmaster; + pfd[0].events = POLLIN; + for (;;) { + if (poll(pfd, 2, INFTIM) < 0) { + if (errno == EINTR) + continue; + syslog(LOG_ALERT, "poll failed with %s", + strerror(errno)); + err(1, "poll"); + } + if (zombies_waiting) { + wait4(pid, &status, 0, NULL); + if (WIFEXITED(status) && WEXITSTATUS(status) != 0) { + warnx("child exited with %d", + WEXITSTATUS(status)); + if (WEXITSTATUS(status) == 99) { + warnx("child was exploited"); + image = malloc(sizeof(u_int32_t) * + fb_width * fb_height); + if (image == NULL) + err(1, "malloc"); + fb_save(image); + fb_dialog(FBDT_PINCH2CLOSE, black, + white, black, + "CheriPoint Exited", +"CheriPoint vulnerability exploited\n" +"\n" +"Pinch to close dialog and restart" + ); + fb_post(image); + free(image); + } + } else if(WIFSIGNALED(status)) { + warn("child killed by signal %d", + WTERMSIG(status)); + } else { + exit(0); + } + zombies_waiting = 0; + close(pmaster); /* XXX: should we drain it first? */ + fb_fill_region(vwhite(128), 0, 0, fb_width, fb_height); + goto restart; + } + + if (pfd[0].revents & POLLIN) { + rlen = read(pmaster, buf, sizeof(buf)); + if (rlen < 0) { + err(1, "read"); + } else if (rlen > 0) + writeall(1, buf, rlen); + } + } +} + int main(int argc, char **argv) { @@ -545,11 +670,24 @@ char *coverpat; char **covers, **slides; int error; + int ch, forkflag = 0; int cover, ncovers, maxcovers; int slide, nslides, maxslides; struct tsstate *ts; - if (argc != 2) + while ((ch = getopt(argc, argv, "f")) != -1) { + switch (ch) { + case 'f': + forkflag = 1; + break; + default: + usage(); + } + } + argc -= optind; + argv += optind; + + if (argc != 1) usage(); fb_init(); @@ -558,6 +696,9 @@ fb_fill_region(white, 0, 0, fb_width, fb_height); fb_fade2on(); fb_load_syscons_font(NULL, "/usr/share/syscons/fonts/iso-8x16.fnt"); + + if (forkflag) + fork_child(); busy_indicator(); set_display_mode(res); @@ -566,8 +707,8 @@ maxcovers = ncovers = 0; maxslides = nslides = 0; - if ((dirp = opendir(argv[1])) == NULL) - err(1, "opendir(%s)", argv[1]); + if ((dirp = opendir(argv[0])) == NULL) + err(1, "opendir(%s)", argv[0]); while ((entry = readdir(dirp)) != NULL) { /* XXX: doesn't support symlinks */ if (entry->d_type != DT_REG)