PERFORCE change 219791 for review
Brooks Davis
brooks at FreeBSD.org
Thu Nov 15 02:05:12 UTC 2012
http://p4web.freebsd.org/@@219791?ac=10
Change 219791 by brooks at 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)
More information about the p4-projects
mailing list