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