Re: git: b165e9e3ea4e - main - Add fchroot(2)

From: Maxim Sobolev <sobomax_at_sippysoft.com>
Date: Sun, 01 Dec 2024 00:25:30 UTC
This is crazy and should be stopped at some point. I usually have a rule of
thumb, is that if I have to duplicate same API third time to accomodate
slightly different but largely the same usage scenario then it's time to
unify and generalize. By that rule stat() and fstat() are ok, but at the
time we felt the need to add statat()/fstatat() we should have stopped and
instead do a single xstat() that would encapsulate all 4 including original
stat() and fstat() and declare those compat_stat() and compat_fstat(). Plus
make internal structure future-proof by giving it a version number. Of
course none of this actually happened, so the same story repeats over and
over for dozen of other syscals. To make things worse each of the time
basic ABI changes (i.e. struct stat in this example, so we just copy all 4,
ending up with 8 syscals to care for where one would do. All this
contributed greatly to the fact that we are now pushing into 600 of syscals.

But why does it matter, I hear you say? Aren't syscals semi-private,
between our kernel and our libc. Well it's actually not so. There are very
popular tools and frameworks out there bypassing libc and calling into
kernel directly (golang for example, rust may be too). I suspect for that
reason we still have large chunk of freebsd11_xxx syscals shipped as first
class citizens in 14.x releases. Golang is particularly funny, since in the
core it would call latest kevent, but if you are using kevent from their os
package, you'd get compat11_kevent.

The chroot() would be particularly easy to make an exemplary in this, by
making xchroot(2), renaming chroot(2) into compat15_chroot(2) and making
both chroot(3) and fchroot(3) wrappers for xchroot(2). I am even willing to
do PoC if someone is willing to consider it.

-Max


On Fri, Nov 29, 2024, 7:25 AM Konstantin Belousov <kostikbel@gmail.com>
wrote:

> On Fri, Nov 29, 2024 at 12:22:16PM +0000, Edward Tomasz Napierala wrote:
> > The branch main has been updated by trasz:
> >
> > URL:
> https://cgit.FreeBSD.org/src/commit/?id=b165e9e3ea4e327fc421d81c2a89242bd8720780
> >
> > commit b165e9e3ea4e327fc421d81c2a89242bd8720780
> > Author:     Edward Tomasz Napierala <trasz@FreeBSD.org>
> > AuthorDate: 2024-11-29 07:46:07 +0000
> > Commit:     Edward Tomasz Napierala <trasz@FreeBSD.org>
> > CommitDate: 2024-11-29 12:10:02 +0000
> >
> >     Add fchroot(2)
> >
> >     This is similar to chroot(2), but takes a file descriptor instead
> >     of path.  Same syscall exists in NetBSD and Solaris.  It is part of
> a larger
> >     patch to make absolute pathnames usable in Capsicum mode, but should
> >     be useful in other contexts too.
>
> I wonder if it should be fchrootat(fd, path, flags) with the support for
> AT_EMPTY_PATH instead.  Then fchroot() becomes the libc wrapper.
>
> I can see arguments both pro and contra.  Main argument against is that
> the immediate semantic is easily emulated by openat() + fchroot().  But
> the freedom of adding the fchroot-specific flags might be worth
> considering.
>
>