From owner-dev-commits-src-all@freebsd.org Fri Jan 15 20:23:42 2021 Return-Path: Delivered-To: dev-commits-src-all@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 754E14F193B; Fri, 15 Jan 2021 20:23:42 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4DHXgy21KGz3ly7; Fri, 15 Jan 2021 20:23:42 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 37E7A22A1A; Fri, 15 Jan 2021 20:23:42 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 10FKNgte080105; Fri, 15 Jan 2021 20:23:42 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 10FKNgbO080104; Fri, 15 Jan 2021 20:23:42 GMT (envelope-from git) Date: Fri, 15 Jan 2021 20:23:42 GMT Message-Id: <202101152023.10FKNgbO080104@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Mariusz Zaborski Subject: git: aefe30c54371 - main - cat: capsicumize it MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: oshogbo X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: aefe30c5437159a5399bdbc1974d6fbf40f2ba0f Auto-Submitted: auto-generated X-BeenThere: dev-commits-src-all@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Commit messages for all branches of the src repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 15 Jan 2021 20:23:42 -0000 The branch main has been updated by oshogbo: URL: https://cgit.FreeBSD.org/src/commit/?id=aefe30c5437159a5399bdbc1974d6fbf40f2ba0f commit aefe30c5437159a5399bdbc1974d6fbf40f2ba0f Author: Mariusz Zaborski AuthorDate: 2021-01-15 20:22:29 +0000 Commit: Mariusz Zaborski CommitDate: 2021-01-15 20:23:42 +0000 cat: capsicumize it Reviewed by: markj, arichardson Differential Revision: https://reviews.freebsd.org/D28083 --- bin/cat/Makefile | 7 +++++ bin/cat/cat.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++++--- tools/build/Makefile | 1 + 3 files changed, 93 insertions(+), 4 deletions(-) diff --git a/bin/cat/Makefile b/bin/cat/Makefile index cba55d2870bb..abfdcbcfbb2e 100644 --- a/bin/cat/Makefile +++ b/bin/cat/Makefile @@ -15,4 +15,11 @@ CFLAGS+=-DBOOTSTRAP_CAT HAS_TESTS= SUBDIR.${MK_TESTS}+= tests +.if ${MK_CASPER} != "no" && !defined(RESCUE) && !defined(BOOTSTRAPPING) +LIBADD+= casper +LIBADD+= cap_fileargs +LIBADD+= cap_net +CFLAGS+=-DWITH_CASPER +.endif + .include diff --git a/bin/cat/cat.c b/bin/cat/cat.c index 40d91b243bd4..58f7c15cc9cb 100644 --- a/bin/cat/cat.c +++ b/bin/cat/cat.c @@ -48,6 +48,7 @@ static char sccsid[] = "@(#)cat.c 8.2 (Berkeley) 4/27/95"; #include __FBSDID("$FreeBSD$"); +#include #include #include #ifndef NO_UDOM_SUPPORT @@ -56,6 +57,7 @@ __FBSDID("$FreeBSD$"); #include #endif +#include #include #include #include @@ -68,9 +70,14 @@ __FBSDID("$FreeBSD$"); #include #include +#include +#include +#include + static int bflag, eflag, lflag, nflag, sflag, tflag, vflag; static int rval; static const char *filename; +static fileargs_t *fa; static void usage(void) __dead2; static void scanfiles(char *argv[], int cooked); @@ -80,6 +87,8 @@ static void cook_cat(FILE *); static void raw_cat(int); #ifndef NO_UDOM_SUPPORT +static cap_channel_t *capnet; + static int udom_open(const char *path, int flags); #endif @@ -112,6 +121,53 @@ static int udom_open(const char *path, int flags); #define SUPPORTED_FLAGS "belnstuv" #endif +#ifndef NO_UDOM_SUPPORT +static void +init_casper_net(cap_channel_t *casper) +{ + cap_net_limit_t *limit; + int familylimit; + + capnet = cap_service_open(casper, "system.net"); + if (capnet == NULL) + err(EXIT_FAILURE, "unable to create network service"); + + limit = cap_net_limit_init(capnet, CAPNET_NAME2ADDR | + CAPNET_CONNECTDNS); + if (limit == NULL) + err(EXIT_FAILURE, "unable to create limits"); + + familylimit = AF_LOCAL; + cap_net_limit_name2addr_family(limit, &familylimit, 1); + + if (cap_net_limit(limit) < 0) + err(EXIT_FAILURE, "unable to apply limits"); +} +#endif + +static void +init_casper(int argc, char *argv[]) +{ + cap_channel_t *casper; + cap_rights_t rights; + + casper = cap_init(); + if (casper == NULL) + err(EXIT_FAILURE, "unable to create Casper"); + + fa = fileargs_cinit(casper, argc, argv, O_RDONLY, 0, + cap_rights_init(&rights, CAP_READ | CAP_FSTAT | CAP_FCNTL), + FA_OPEN | FA_REALPATH); + if (fa == NULL) + err(EXIT_FAILURE, "unable to create fileargs"); + +#ifndef NO_UDOM_SUPPORT + init_casper_net(casper); +#endif + + cap_close(casper); +} + int main(int argc, char *argv[]) { @@ -150,6 +206,7 @@ main(int argc, char *argv[]) usage(); } argv += optind; + argc -= optind; if (lflag) { stdout_lock.l_len = 0; @@ -160,6 +217,13 @@ main(int argc, char *argv[]) err(EXIT_FAILURE, "stdout"); } + init_casper(argc, argv); + + caph_cache_catpages(); + + if (caph_enter_casper() < 0) + err(EXIT_FAILURE, "capsicum"); + if (bflag || eflag || nflag || sflag || tflag || vflag) scanfiles(argv, 1); else @@ -196,7 +260,7 @@ scanfiles(char *argv[], int cooked __unused) fd = STDIN_FILENO; } else { filename = path; - fd = open(path, O_RDONLY); + fd = fileargs_open(fa, path); #ifndef NO_UDOM_SUPPORT if (fd < 0 && errno == EOPNOTSUPP) fd = udom_open(path, O_RDONLY); @@ -366,20 +430,25 @@ udom_open(const char *path, int flags) char rpath[PATH_MAX]; int fd = -1; int error; + cap_rights_t rights; /* * Construct the unix domain socket address and attempt to connect. */ bzero(&hints, sizeof(hints)); hints.ai_family = AF_LOCAL; - if (realpath(path, rpath) == NULL) + + if (fileargs_realpath(fa, path, rpath) == NULL) return (-1); - error = getaddrinfo(rpath, NULL, &hints, &res0); + + error = cap_getaddrinfo(capnet, rpath, NULL, &hints, &res0); if (error) { warn("%s", gai_strerror(error)); errno = EINVAL; return (-1); } + cap_rights_init(&rights, CAP_CONNECT, CAP_READ, CAP_WRITE, + CAP_SHUTDOWN, CAP_FSTAT, CAP_FCNTL); for (res = res0; res != NULL; res = res->ai_next) { fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); @@ -387,7 +456,11 @@ udom_open(const char *path, int flags) freeaddrinfo(res0); return (-1); } - error = connect(fd, res->ai_addr, res->ai_addrlen); + if (caph_rights_limit(fd, &rights) < 0) { + close(fd); + return (-1); + } + error = cap_connect(capnet, fd, res->ai_addr, res->ai_addrlen); if (error == 0) break; else { @@ -403,16 +476,24 @@ udom_open(const char *path, int flags) if (fd >= 0) { switch(flags & O_ACCMODE) { case O_RDONLY: + cap_rights_clear(&rights, CAP_WRITE); if (shutdown(fd, SHUT_WR) == -1) warn(NULL); break; case O_WRONLY: + cap_rights_clear(&rights, CAP_READ); if (shutdown(fd, SHUT_RD) == -1) warn(NULL); break; default: break; } + + cap_rights_clear(&rights, CAP_CONNECT, CAP_SHUTDOWN); + if (caph_rights_limit(fd, &rights) < 0) { + close(fd); + return (-1); + } } return (fd); } diff --git a/tools/build/Makefile b/tools/build/Makefile index 28257a2ea2e5..c0c1786d4bfa 100644 --- a/tools/build/Makefile +++ b/tools/build/Makefile @@ -202,6 +202,7 @@ CLEANFILES+= subr_capability.c .endif CASPERINC+= ${SRCTOP}/lib/libcasper/services/cap_fileargs/cap_fileargs.h +CASPERINC+= ${SRCTOP}/lib/libcasper/services/cap_net/cap_net.h .if empty(SRCS) SRCS= dummy.c