While reviewing Bob's presentation[1] on pledge and unveil I came across his idea about pledge utility which will take unveil paths, pledge promises and execute a program with the restrictions (slide 12).
What do you think about the idea and implementation? [1] - https://www.openbsd.org/papers/BeckPledgeUnveilBSDCan2018.pdf #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <string.h> #include <err.h> void usage(void) { fprintf(stderr, "%s: [-p path mode ...] <-P \"promises\"> " "<program> [arguments]\n", getprogname()); exit(1); } int main(int argc, char **argv) { int i, j, k, Pflag = 0, pflag = 0; char promises[1024] = { 0 }; char **paths = NULL; char **modes = NULL; for (i = 1; i < argc; i++) { if (strcmp(argv[i], "-P") == 0) { if (Pflag) usage(); Pflag = 1; strlcpy(promises, argv[++i], sizeof(promises)); break; } if (strcmp(argv[i], "-p") == 0) { if (pflag) usage(); pflag = 1; i++; j = 0; while (argv[i] != NULL && strcmp(argv[i], "-P") != 0) { paths = reallocarray(paths, j+1, sizeof(*paths)); modes = reallocarray(modes, j+1, sizeof(*modes)); paths[j] = strdup(argv[i++]); /* We've advanced 'i', check if it's not EOL */ if (argv[i] == NULL) usage(); modes[j++] = strdup(argv[i++]); } /* If we have no args after -p */ if (j == 0) usage(); /* Last cycle advanced i to -P, shift it back */ i--; continue; } } /* -P is mandatory */ if (Pflag == 0) usage(); if (pledge("stdio exec unveil", promises) == -1) err(1, "pledge"); if (pflag) { for (k = 0; k < j; k++) { if (unveil(paths[k], modes[k]) == -1) err(1, "unveil: %s mode %s", paths[k], modes[k]); } unveil(NULL, NULL); } char *progname = argv[++i]; char **progargs = &argv[i]; if (execvp(progname, progargs) == -1) err(1, "execvp: %s", progname); return (0); }