AsiaBSDCon 2017 Secure CGI

Asynchronous example with pledge() sandbox

Asynchronous example with pledge() sandbox

    1 /* Title: Asynchronous example with pledge() sandbox */
    2 
    3 #include <err.h>
    4 #include <stdlib.h>
    5 #include <stdio.h>
    6 #include <unistd.h>
    7 
    8 int
    9 main(int argc, char *argv[])
   10 {
   11 	int	 c, async = 0;
   12 	pid_t	 pid;
   13 
   14 	/*
   15 	 * Really, all we want is our response (stdio)
   16 	 * and to start the long-running process.
   17 	 * If we were to also have some sort of
   18 	 * database, we'd use the database things here.
   19 	 */
   20 
   21 	if (-1 == pledge("stdio rpath proc exec", NULL))
   22 		err(EXIT_FAILURE, NULL);
   23 
   24 	while (-1 != (c = getopt(argc, argv, "X"))) 
   25 		switch (c) {
   26 		case 'X':
   27 			async = 1;
   28 			break;
   29 		default:
   30 			return(EXIT_SUCCESS);
   31 		}
   32 
   33 	if (async) {	
   34 		/* Assume we'll want stdio... */
   35 
   36 		if (-1 == pledge("stdio", NULL))
   37 			err(EXIT_FAILURE, NULL);
   38 		sleep(20);
   39 		return(EXIT_SUCCESS);
   40 	}
   41 
   42 	puts("Status: 200 OK\r");
   43 	puts("Content-Type: text/html\r");
   44 	puts("\r");
   45 	puts("Hello, world!");
   46 
   47 	if (0 == (pid = fork())) {
   48 		if (-1 == daemon(1, 0))
   49 			err(EXIT_FAILURE, NULL);
   50 		execl(argv[0], argv[0], "-X", (char *)NULL);
   51 		err(EXIT_FAILURE, "%s", argv[0]);
   52 	} else if (-1 == pid)
   53 		err(EXIT_FAILURE, NULL);
   54 
   55 	return(EXIT_SUCCESS);
   56 }
gcc -I/usr/local/include -static -o async-pledge async-pledge.c -L/usr/local/lib -lksql -lsqlite3