I did partial work before if was called pledge. Now, with fork and exec, simple pledge is easy.
There might be something down the line to explicitly allow m4 to fork and exec, but unfortunately, the corresponding macros are used by both sendmail and autoconf scripts, so I would say they're rather ubiquitous. Index: main.c =================================================================== RCS file: /cvs/src/usr.bin/m4/main.c,v retrieving revision 1.84 diff -u -p -r1.84 main.c --- main.c 21 Dec 2014 09:33:12 -0000 1.84 +++ main.c 1 Nov 2015 09:12:04 -0000 @@ -174,6 +174,9 @@ main(int argc, char *argv[]) int n; char *p; + if (pledge("stdio proc exec rpath wpath cpath", NULL) == -1) + err(1, "pledge"); + if (signal(SIGINT, SIG_IGN) != SIG_IGN) signal(SIGINT, onintr);