Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 30 Nov 2024 16:25:30 -0800
From:      Maxim Sobolev <sobomax@sippysoft.com>
To:        Konstantin Belousov <kostikbel@gmail.com>
Cc:        Edward Tomasz Napierala <trasz@freebsd.org>, src-committers <src-committers@freebsd.org>,  dev-commits-src-all@freebsd.org, dev-commits-src-main@freebsd.org
Subject:   Re: git: b165e9e3ea4e - main - Add fchroot(2)
Message-ID:  <CAH7qZfuFYHp0%2By0dfu3DvykgzZrYWP01ktuY%2B7wMYXOr%2BF06gw@mail.gmail.com>
In-Reply-To: <Z0ncu8p149bHqCC_@kib.kiev.ua>
References:  <202411291222.4ATCMG8Y068265@gitrepo.freebsd.org> <Z0ncu8p149bHqCC_@kib.kiev.ua>

next in thread | previous in thread | raw e-mail | index | archive | help
--000000000000dba1f606282a7800
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

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=E2=80=AFAM 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=3Db165e9e3ea4e327fc421d81c2a89242=
bd8720780
> >
> > 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 shoul=
d
> >     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.
>
>

--000000000000dba1f606282a7800
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"auto">This is crazy and should be stopped at some point. I usua=
lly have a rule of thumb, is that if I have to duplicate same API third tim=
e to accomodate slightly different but largely the same usage scenario then=
 it&#39;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 h=
ave stopped and instead do a single xstat() that would encapsulate all 4 in=
cluding original stat() and fstat() and declare those compat_stat() and com=
pat_fstat(). Plus make internal structure future-proof by giving it a versi=
on number. Of course none of this actually happened, so the same story repe=
ats 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 co=
py 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 syscal=
s.<div dir=3D"auto"><br></div><div dir=3D"auto">But why does it matter, I h=
ear you say? Aren&#39;t syscals semi-private, between our kernel and our li=
bc. Well it&#39;s actually not so. There are very popular tools and framewo=
rks out there bypassing libc and calling into kernel directly (golang for e=
xample, rust may be too). I suspect for that reason we still have large chu=
nk of freebsd11_xxx syscals shipped as first class citizens in 14.x release=
s. Golang is particularly funny, since in the core it would call latest kev=
ent, but if you are using kevent from their os package, you&#39;d get compa=
t11_kevent.</div><div dir=3D"auto"><br></div><div dir=3D"auto">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) a=
nd fchroot(3) wrappers for xchroot(2). I am even willing to do PoC if someo=
ne is willing to consider it.</div><div dir=3D"auto"><br></div><div dir=3D"=
auto">-Max</div><br><br><div class=3D"gmail_quote" dir=3D"auto"><div dir=3D=
"ltr" class=3D"gmail_attr">On Fri, Nov 29, 2024, 7:25=E2=80=AFAM Konstantin=
 Belousov &lt;<a href=3D"mailto:kostikbel@gmail.com">kostikbel@gmail.com</a=
>&gt; wrote:<br></div><blockquote class=3D"gmail_quote" style=3D"margin:0 0=
 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On Fri, Nov 29, 2024 a=
t 12:22:16PM +0000, Edward Tomasz Napierala wrote:<br>
&gt; The branch main has been updated by trasz:<br>
&gt; <br>
&gt; URL: <a href=3D"https://cgit.FreeBSD.org/src/commit/?id=3Db165e9e3ea4e=
327fc421d81c2a89242bd8720780" rel=3D"noreferrer noreferrer" target=3D"_blan=
k">https://cgit.FreeBSD.org/src/commit/?id=3Db165e9e3ea4e327fc421d81c2a8924=
2bd8720780</a><br>
&gt; <br>
&gt; commit b165e9e3ea4e327fc421d81c2a89242bd8720780<br>
&gt; Author:=C2=A0 =C2=A0 =C2=A0Edward Tomasz Napierala &lt;trasz@FreeBSD.o=
rg&gt;<br>
&gt; AuthorDate: 2024-11-29 07:46:07 +0000<br>
&gt; Commit:=C2=A0 =C2=A0 =C2=A0Edward Tomasz Napierala &lt;trasz@FreeBSD.o=
rg&gt;<br>
&gt; CommitDate: 2024-11-29 12:10:02 +0000<br>
&gt; <br>
&gt;=C2=A0 =C2=A0 =C2=A0Add fchroot(2)<br>
&gt;=C2=A0 =C2=A0 =C2=A0<br>
&gt;=C2=A0 =C2=A0 =C2=A0This is similar to chroot(2), but takes a file desc=
riptor instead<br>
&gt;=C2=A0 =C2=A0 =C2=A0of path.=C2=A0 Same syscall exists in NetBSD and So=
laris.=C2=A0 It is part of a larger<br>
&gt;=C2=A0 =C2=A0 =C2=A0patch to make absolute pathnames usable in Capsicum=
 mode, but should<br>
&gt;=C2=A0 =C2=A0 =C2=A0be useful in other contexts too.<br>
<br>
I wonder if it should be fchrootat(fd, path, flags) with the support for<br=
>
AT_EMPTY_PATH instead.=C2=A0 Then fchroot() becomes the libc wrapper.<br>
<br>
I can see arguments both pro and contra.=C2=A0 Main argument against is tha=
t<br>
the immediate semantic is easily emulated by openat() + fchroot().=C2=A0 Bu=
t<br>
the freedom of adding the fchroot-specific flags might be worth considering=
.<br>
<br>
</blockquote></div></div>

--000000000000dba1f606282a7800--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAH7qZfuFYHp0%2By0dfu3DvykgzZrYWP01ktuY%2B7wMYXOr%2BF06gw>