Date: Thu, 12 Jul 2012 22:52:50 GMT From: Brooks Davis <brooks@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 214311 for review Message-ID: <201207122252.q6CMqoGT063702@skunkworks.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/@@214311?ac=10 Change 214311 by brooks@brooks_ecr_current on 2012/07/12 22:52:42 Add a -f option to fork and monitor a child. When the child exits with error 99 show a dialog box indicating that the program was exploited. Affected files ... .. //depot/projects/ctsrd/beribsd/src/ctsrd/browser/browser.c#11 edit Differences ... ==== //depot/projects/ctsrd/beribsd/src/ctsrd/browser/browser.c#11 (text+ko) ==== @@ -45,6 +45,8 @@ #include <fnmatch.h> #include <libutil.h> #include <magic.h> +#include <poll.h> +#include <signal.h> #define _WITH_DPRINTF #include <stdio.h> #include <stdlib.h> @@ -179,13 +181,17 @@ static u_int32_t *bgimage; static u_int32_t *icons; static magic_t magic; +static int zombies_waiting = 0; static void usage(void) { - printf("usage: browser <dir> <tty>\n"); - printf(" browser -T <dir>\n"); + printf("usage: browser [-f] <dir> <tty>\n"); + printf(" browser [-f] -T <dir>\n"); + printf("\n"); + printf(" -f Fork and monitor a child instance\n"); + printf(" -T Don't open a tty\n"); exit(1); } @@ -211,6 +217,118 @@ } 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]; + +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) { + printf("zombie!\n"); + 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"); + fb_dialog(FBDT_PINCH2CLOSE, black, + white, black, + "Browser Exited", +"Browser vulnerability exploited\n" +"\n" +"Pinch to close dialog and restart" + ); + } + } else if(WIFSIGNALED(status)) { + warn("child killed by signal %d", + WTERMSIG(status)); + } else { + printf("child exited cleanly, exiting\n"); + exit(0); + } + printf("child exited badly, restarting\n"); + 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); + } + } + + + +} + +static void init_magic(void) { magic = magic_open(MAGIC_MIME_TYPE); if (magic == NULL) @@ -262,8 +380,9 @@ exit(0); } else { close(pfd[1]); - if (wait4(pid, &status, 0, NULL) == -1) - err(1, "wait4()"); + while (wait4(pid, &status, 0, NULL) == -1) + if (errno != EINTR) + err(1, "wait4()"); if (WIFEXITED(status) && WEXITSTATUS(status) != 0) { warnx("child exited with %d", @@ -435,11 +554,11 @@ get_action(void) { struct tsstate *ts; - int action = -1, col, i, row; + int col, i, row; printf("entering get_action\n"); - while(action < 0) { + for (;;) { ts = ts_poll(); printf("gesture = %x\n", ts->ts_gesture); if (ts->ts_gesture == TSG_CLICK) { @@ -594,10 +713,13 @@ main(int argc, char *argv[]) { int ch, dfd; - int ttyflag = 1; + int ttyflag = 1, forkflag = 0; - while ((ch = getopt(argc, argv, "T")) != -1) { + while ((ch = getopt(argc, argv, "fT")) != -1) { switch (ch) { + case 'f': + forkflag = 1; + break; case 'T': ttyflag = 0; break; @@ -608,14 +730,23 @@ argc -= optind; argv += optind; - if (argc <= 0 && argc > 2) + if (argc <= 0 || argc > 2) usage(); - if (argc == 2) - init_tty(argv[1]); - init_magic(); + if (argc == 2) { + if (ttyflag) + init_tty(argv[1]); + else + usage(); + } + fb_init(); fb_load_syscons_font(NULL, "/usr/share/syscons/fonts/iso-8x16.fnt"); + + if (forkflag) + fork_child(); + + init_magic(); init_bgimage(); icons = malloc(sizeof(u_int32_t) * ICON_WH * 640);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201207122252.q6CMqoGT063702>