Date: Thu, 15 Nov 2012 02:05:11 GMT From: Brooks Davis <brooks@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 219791 for review Message-ID: <201211150205.qAF25Boc030996@skunkworks.freebsd.org>
next in thread | raw e-mail | index | archive | help
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 <sys/cdefs.h> #include <sys/types.h> #include <sys/sysctl.h> +#include <sys/wait.h> #include <de4tc.h> #include <dirent.h> #include <err.h> +#include <errno.h> #include <fcntl.h> #include <fnmatch.h> #include <imagebox.h> +#include <libutil.h> +#include <poll.h> +#include <signal.h> +#include <stdarg.h> #include <stdlib.h> #include <stdio.h> #include <string.h> +#include <syslog.h> +#include <unistd.h> + #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 <slidedir>\n"); + fprintf(stderr, "cheripoint [-f] <slidedir>\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)
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201211150205.qAF25Boc030996>