From b8e0002a6198cb97543a07359d2ad2f04352008c Mon Sep 17 00:00:00 2001 From: Nick Price Date: Sun, 29 Mar 2026 16:51:39 -0700 Subject: [PATCH] cut(1), rev(1): add Capsicum sandboxing Open file arguments through Casper's cap_fileargs service and enter capability mode after limiting stdio rights, so cut(1) and rev(1) run sandboxed. cut(1) is a bootstrap tool, so the Makefile drops the Casper libraries and -DWITH_CASPER while BOOTSTRAPPING; then resolves fileargs_*() to plain fopen(3), matching wc(1)/head(1). Signed-off-by: Nick Price --- usr.bin/cut/Makefile | 6 ++++++ usr.bin/cut/cut.c | 22 +++++++++++++++++++++- usr.bin/rev/Makefile | 8 ++++++++ usr.bin/rev/rev.c | 21 ++++++++++++++++++++- 4 files changed, 55 insertions(+), 2 deletions(-) diff --git a/usr.bin/cut/Makefile b/usr.bin/cut/Makefile index bdb5040c21d83a..e51d8701b7b5f7 100644 --- a/usr.bin/cut/Makefile +++ b/usr.bin/cut/Makefile @@ -2,6 +2,12 @@ PROG= cut +.if ${MK_CASPER} != "no" && !defined(BOOTSTRAPPING) +LIBADD+= casper +LIBADD+= cap_fileargs +CFLAGS+= -DWITH_CASPER +.endif + HAS_TESTS= SUBDIR.${MK_TESTS}+= tests diff --git a/usr.bin/cut/cut.c b/usr.bin/cut/cut.c index e4e322b4e5c99e..ab9a7068cb23a8 100644 --- a/usr.bin/cut/cut.c +++ b/usr.bin/cut/cut.c @@ -32,9 +32,13 @@ * SUCH DAMAGE. */ +#include + +#include #include #include #include +#include #include #include #include @@ -43,6 +47,9 @@ #include #include +#include +#include + static int bflag; static int cflag; static wchar_t dchar; @@ -69,9 +76,11 @@ int main(int argc, char *argv[]) { FILE *fp; + fileargs_t *fa; int (*fcn)(FILE *, const char *); int ch, rval; size_t n; + cap_rights_t rights; setlocale(LC_ALL, ""); @@ -131,13 +140,23 @@ main(int argc, char *argv[]) else if (bflag) fcn = nflag && MB_CUR_MAX > 1 ? b_n_cut : b_cut; + fa = fileargs_init(argc, argv, O_RDONLY, 0, + cap_rights_init(&rights, CAP_FSTAT, CAP_FCNTL, CAP_READ), FA_OPEN); + if (fa == NULL) + err(1, "unable to init casper"); + caph_cache_catpages(); + if (caph_limit_stdio() < 0) + err(1, "unable to limit stdio"); + if (caph_enter_casper() < 0) + err(1, "unable to enter capability mode"); + rval = 0; if (*argv) for (; *argv; ++argv) { if (strcmp(*argv, "-") == 0) rval |= fcn(stdin, "stdin"); else { - if (!(fp = fopen(*argv, "r"))) { + if (!(fp = fileargs_fopen(fa, *argv, "r"))) { warn("%s", *argv); rval = 1; continue; @@ -148,6 +167,7 @@ main(int argc, char *argv[]) } else rval = fcn(stdin, "stdin"); + fileargs_free(fa); exit(rval); } diff --git a/usr.bin/rev/Makefile b/usr.bin/rev/Makefile index 92540c1109387c..02642deb9c3dd7 100644 --- a/usr.bin/rev/Makefile +++ b/usr.bin/rev/Makefile @@ -1,3 +1,11 @@ +.include + PROG= rev +.if ${MK_CASPER} != "no" +LIBADD+= casper +LIBADD+= cap_fileargs +CFLAGS+= -DWITH_CASPER +.endif + .include diff --git a/usr.bin/rev/rev.c b/usr.bin/rev/rev.c index 4bb113d4b53236..4f221cc79009d6 100644 --- a/usr.bin/rev/rev.c +++ b/usr.bin/rev/rev.c @@ -30,9 +30,12 @@ */ #include +#include +#include #include #include +#include #include #include #include @@ -40,6 +43,9 @@ #include #include +#include +#include + static void usage(void) __dead2; int @@ -48,8 +54,10 @@ main(int argc, char *argv[]) const char *filename; wchar_t *p, *t; FILE *fp; + fileargs_t *fa; size_t len; int ch, rval; + cap_rights_t rights; setlocale(LC_ALL, ""); @@ -63,12 +71,22 @@ main(int argc, char *argv[]) argc -= optind; argv += optind; + fa = fileargs_init(argc, argv, O_RDONLY, 0, + cap_rights_init(&rights, CAP_FSTAT, CAP_FCNTL, CAP_READ), FA_OPEN); + if (fa == NULL) + err(1, "unable to init casper"); + caph_cache_catpages(); + if (caph_limit_stdio() < 0) + err(1, "unable to limit stdio"); + if (caph_enter_casper() < 0) + err(1, "unable to enter capability mode"); + fp = stdin; filename = "stdin"; rval = 0; do { if (*argv) { - if ((fp = fopen(*argv, "r")) == NULL) { + if ((fp = fileargs_fopen(fa, *argv, "r")) == NULL) { warn("%s", *argv); rval = 1; ++argv; @@ -90,6 +108,7 @@ main(int argc, char *argv[]) } (void)fclose(fp); } while(*argv); + fileargs_free(fa); exit(rval); }