Re: https://reviews.freebsd.org/D57255 - migrating cut and rev
Mark Johnston <[email protected]> Thu, 11 Jun 2026 15:29:30 -0400
| Newsgroups | gmane.os.freebsd.architechture |
|---|---|
| Message-ID | <aisMmjrfCr9G2cOx@nuc> |
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?