Re: https://reviews.freebsd.org/D57255 - migrating cut and rev

Mark Johnston <[email protected]> Mon, 15 Jun 2026 11:48:52 -0400
Newsgroups gmane.os.freebsd.architechture
Message-ID <ajAe5E2fipMBuULh@nuc>
On Thu, Jun 11, 2026 at 03:29:34PM -0400, Mark Johnston wrote:
> On Thu, Jun 11, 2026 at 02:04:17PM -0400, Ed Maste wrote:
> > On Fri, 5 Jun 2026 at 10:46, Adrian Chadd <[email protected]> wrote:
> > >
> > > I'd rather not add command line options / environment settings that can disable
> > > sandboxing. These should be cheap operations.
> > 
> > Yeah, we don't really want to have this be a command-line option.
> > 
> > The performance issue is really just a consequence of process-based
> > privilege separation. We could enter capability mode when processing
> > the last (or only) file specified on the command line (or stdio),
> > giving us the benefit of sandboxing for a large fraction of uses of
> > these tools without incurring much overhead.
> 
> For these simple "filter" programs which read some set of user-specified
> input files, an alternative is to do something like the following:
> 
> 1. Pre-open the root directory and cwd, and limit rights on the
>    directory fds.  CAP_READ+CAP_SEEK+CAP_FSTAT is probably enough for
>    most applications.
> 2. Enter capability mode.
> 3. When opening files, open relative paths relative to the cwd
>    descriptor, and absolute paths relative to the root dfd.
> 
> This gives the application limited access to the filesystem, but it can
> only write data to the output stream, can't make network connections,
> etc..  This is not as constrained as a proper Capsicum sandbox of
> course, but it's simpler and cheaper to integrate.  It is morally
> similar to calling pledge("rpath"), I believe.  
> 
> We could go further and modify fchroot() and fchdir() to save the rights
> associated with the user-specified fd in the process' pwd structure, and
> then require that all lookups relative to the root or cwd be limited by
> those saved rights.  That is, if I do something like
> 
> 	rfd = open("/", O_DIRECTORY);
> 	cap_rights_limit(rfd, cap_rights_init(&rights, CAP_READ, CAP_LOOKUP, CAP_PREAD));
> 	fchroot(rfd);
> 	fd = open("/foo/bar/baz", O_RDWR);
> 
> then rights on "fd" would automatically be limited by those on "rfd",
> just as if I had instead done
> 
> 	fd = openat(rfd, "foo/bar/baz", O_RDWR);
> 
> To make this more useful, we would have to allow openat(AT_FDCWD, ...)
> in capability mode, provided that the process called fchroot()/fchdir()
> first.  That would save the pain of converting all open("/foo/bar/baz")
> calls to openat(rfd, "foo/bar/baz") etc..
> 
> Is this a terrible idea for some reason?

https://reviews.freebsd.org/D57599 demonstrates what I meant.  It allows
cat to run in a relatively tight sandbox without forking.

If the rest of my proposal is implemented, it would be able to use
getaddrinfo() again too; currently this fails because /etc/nsswitch.conf
can't be opened in capability mode.