[PATCH v2 0/7] Extensive bandaging for SELinux policy issues, old and new
The most important fix here is actually the one that allows pasta and passt to create user namespaces (and hence, to start -- we need that for sandboxing) with recent kernels on e.g. Fedora Rawhide -- that's patch 3/7. But there are a number of other issues, some old, some new, that would currently prevent pasta from e.g. starting a shell, or simply run 'ip address show', again at least on Fedora Rawhide. Fix them. v2: Actually override pasta symlinks with hard links in 1/7 Stefano Brivio (7): fedora: Install pasta as hard link to ensure SELinux file context match selinux: Use explicit paths for binaries in file context selinux: Fix user namespace creation after breaking kernel change selinux: Update policy to fix user/group settings selinux: Add rules for sysctl and /proc/net accesses selinux: Allow pasta_t to read nsfs entries selinux: Fix domain transitions for typical commands pasta might run contrib/fedora/passt.spec | 7 +++++++ contrib/selinux/passt.fc | 3 ++- contrib/selinux/passt.te | 10 ++++++++-- contrib/selinux/pasta.fc | 3 ++- contrib/selinux/pasta.te | 33 ++++++++++++++++++++++++++++++--- 5 files changed, 49 insertions(+), 7 deletions(-) -- 2.39.2
The Makefile installs symbolic links by default, which actually
worked at some point (not by design) with SELinux, but at least on
recent kernel versions it doesn't anymore: override pasta (and
pasta.avx2) with hard links.
Otherwise, even if the links are labeled as pasta_exec_t, SELinux
will "resolve" them to passt_exec_t, and we'll have pasta running as
passt_t instead of pasta_t.
Signed-off-by: Stefano Brivio
On Wed, Aug 16, 2023 at 08:17:24PM +0200, Stefano Brivio wrote:
The Makefile installs symbolic links by default, which actually worked at some point (not by design) with SELinux, but at least on recent kernel versions it doesn't anymore: override pasta (and pasta.avx2) with hard links.
Otherwise, even if the links are labeled as pasta_exec_t, SELinux will "resolve" them to passt_exec_t, and we'll have pasta running as passt_t instead of pasta_t.
Signed-off-by: Stefano Brivio
--- contrib/fedora/passt.spec | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/contrib/fedora/passt.spec b/contrib/fedora/passt.spec index 8d28ef6..d0c6895 100644 --- a/contrib/fedora/passt.spec +++ b/contrib/fedora/passt.spec @@ -54,10 +54,17 @@ This package adds SELinux enforcement to passt(1) and pasta(1). %make_build VERSION="%{version}-%{release}.%{_arch}"
%install + %make_install DESTDIR=%{buildroot} prefix=%{_prefix} bindir=%{_bindir} mandir=%{_mandir} docdir=%{_docdir}/%{name} +# The Makefile creates symbolic links for pasta, but we need hard links for +# SELinux file contexts to work as intended. Same with pasta.avx2 if present. +ln -f %{buildroot}%{_bindir}/passt %{buildroot}%{_bindir}/pasta %ifarch x86_64 +ln -f %{buildroot}%{_bindir}/passt.avx2 %{buildroot}%{_bindir}/pasta.avx2 + ln -sr %{buildroot}%{_mandir}/man1/passt.1 %{buildroot}%{_mandir}/man1/passt.avx2.1 ln -sr %{buildroot}%{_mandir}/man1/pasta.1 %{buildroot}%{_mandir}/man1/pasta.avx2.1 +install -p -m 755 %{buildroot}%{_bindir}/passt.avx2 %{buildroot}%{_bindir}/pasta.avx2 %endif
Acked-by: Richard W.M. Jones
On Thu, 17 Aug 2023 08:53:55 +0100
"Richard W.M. Jones"
On Wed, Aug 16, 2023 at 08:17:24PM +0200, Stefano Brivio wrote:
The Makefile installs symbolic links by default, which actually worked at some point (not by design) with SELinux, but at least on recent kernel versions it doesn't anymore: override pasta (and pasta.avx2) with hard links.
Otherwise, even if the links are labeled as pasta_exec_t, SELinux will "resolve" them to passt_exec_t, and we'll have pasta running as passt_t instead of pasta_t.
Signed-off-by: Stefano Brivio
--- contrib/fedora/passt.spec | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/contrib/fedora/passt.spec b/contrib/fedora/passt.spec index 8d28ef6..d0c6895 100644 --- a/contrib/fedora/passt.spec +++ b/contrib/fedora/passt.spec @@ -54,10 +54,17 @@ This package adds SELinux enforcement to passt(1) and pasta(1). %make_build VERSION="%{version}-%{release}.%{_arch}"
%install + %make_install DESTDIR=%{buildroot} prefix=%{_prefix} bindir=%{_bindir} mandir=%{_mandir} docdir=%{_docdir}/%{name} +# The Makefile creates symbolic links for pasta, but we need hard links for +# SELinux file contexts to work as intended. Same with pasta.avx2 if present. +ln -f %{buildroot}%{_bindir}/passt %{buildroot}%{_bindir}/pasta %ifarch x86_64 +ln -f %{buildroot}%{_bindir}/passt.avx2 %{buildroot}%{_bindir}/pasta.avx2 + ln -sr %{buildroot}%{_mandir}/man1/passt.1 %{buildroot}%{_mandir}/man1/passt.avx2.1 ln -sr %{buildroot}%{_mandir}/man1/pasta.1 %{buildroot}%{_mandir}/man1/pasta.avx2.1 +install -p -m 755 %{buildroot}%{_bindir}/passt.avx2 %{buildroot}%{_bindir}/pasta.avx2 %endif
Acked-by: Richard W.M. Jones
... although why not change the Makefile install rule instead so everyone gets this change?
Because that's only needed for SELinux "based" distributions. I have the feeling that symlinks are in general more desirable -- at least personally I find them less confusing. Also, David pointed out that hard links are not supported by a number of filesystems, and we probably don't want to mess this up for embedded environments. On the other hand, I didn't check yet if AppArmor would also benefit from this -- there we have at the moment a single profile for passt and pasta (the symlink behaviour is documented)... if it does, I guess it might make sense to switch to hard links in the Makefile (assuming there are no issues with other distributions), and perhaps export a Makefile variable to have symlinks instead. -- Stefano
There's no reason to use wildcards, and we don't want any
similarly-named binary (not that I'm aware of any) to risk being
associated to passt_exec_t and pasta_exec_t by accident.
Signed-off-by: Stefano Brivio
Kernel commit ed5d44d42c95 ("selinux: Implement userns_create hook")
seems to just introduce a new functionality, but given that SELinux
implements a form of mandatory access control, introducing the new
permission breaks any application (shipping with SELinux policies)
that needs to create user namespaces, such as passt and pasta for
sandboxing purposes.
Add the new 'allow' rules. They appear to be backward compatible,
kernel-wise, and the policy now requires the new 'user_namespace'
class to build, but that's something distributions already ship.
Reported-by: Richard W.M. Jones
Somehow most of this used to work on older kernels, but now we need
to explicitly permit setuid, setgid, and setcap capabilities, as well
as read-only access to passwd (as we support running under a given
login name) and sssd library facilities.
Signed-off-by: Stefano Brivio
That's what we actually need to check networking-related sysctls,
to scan for bound ports, and to manipulate bits of network
configuration inside pasta's target namespaces.
Signed-off-by: Stefano Brivio
This is needed to monitor filesystem-bound namespaces and quit when
they're gone -- this feature never really worked with SELinux.
Fixes: 745a9ba4284c ("pasta: By default, quit if filesystem-bound net namespace goes away")
Signed-off-by: Stefano Brivio
...now it gets ugly. If we use pasta without an existing target
namespace, and run commands directly or spawn a shell, and keep
the pasta_t domain when we do, they won't be able to do much: a
shell might even start, but it's not going to be usable, or to
even display a prompt.
Ideally, pasta should behave like a shell when it spawns a command:
start as unconfined_t and automatically transition to whatever
domain is associated in the specific policy for that command. But
we can't run as unconfined_t, of course.
It would seem natural to switch to unconfined_t "just before", so
that the default transitions happen. But transitions can only happen
when we execvp(), and that's one single transition -- not two.
That is, this approach would work for:
pasta -- sh -c 'ip address show'
but not for:
pasta -- ip address show
If we configure a transition to unconfined_t when we run ip(8), we'll
really try to start that as unconfined_t -- but unconfined_t isn't
allowed as entrypoint for ip(8) itself, and execvp() will fail.
However, there aren't many different types of binaries pasta might
commonly run -- for example, we're unlikely to see pasta used to run
a mount(8) command.
Explicitly set up domain transition for common stuff -- switching to
unconfined_t for bin_t and shells works just fine, ip(8), ping(8),
arping(8) and similar need a different treatment.
While at it, allow commands we spawn to inherit resource limits and
signal masks, because that's what happens by default, and don't
require AT_SECURE sanitisation of the environment (because that
won't happen by default). Slightly unrelated: we also need to
explicitly allow pasta_t to use TTYs, not just PTYs, otherwise
we can't keep stdin and stdout open for shells.
Signed-off-by: Stefano Brivio
participants (2)
-
Richard W.M. Jones
-
Stefano Brivio