Nikolas, thanks for the report and the suggestion. Some comments:
On Fri, 13 Mar 2026 11:24:20 +0000
Nikolas Kyx <[email protected]> wrote:
> Running on a kernel with no CONFIG_USER_NS gives:
I'm not sure if this is a coincidence, but I suppose you tried this in
the wake of the CrackArmor disclosure last week.
I guess the wording of some articles covering those issues might be
misleading for some users, in particular:
1. AppArmor profiles being bypassed doesn't automatically make services
run with "full privileges" (which would seem to imply "as root").
They'll just be (dangerously) less confined than expected, but
certainly not with full privileges, as long as they are started as
separate, non-root users (which is a very reasonable expectation in
terms of security posture)
2. unprivileged users could create namespaces regardless of the
'apparmor_restrict_unprivileged_unconfined' procfs entry (0
by default on Debian, that is, not restricted), but that doesn't make
them "fully-capable".
Further, user namespaces aren't something that was "previously
mitigated". They provide a helpful security feature that doesn't need
to be "mitigated", in absence of other vulnerabilities.
And that's the case for the usage passt(1) and pasta(1) make of
them. That is:
> Can't determine if we're in init namespace: No such file or directory
> The file in question is /proc/self/uid_map and being requested from util.c:
>
> bool ns_is_init(void)
> {
> ...
> if ((fd = open("/proc/self/uid_map", O_RDONLY | O_CLOEXEC)) < 0)
> die_perror("Can't determine if we're in init namespace");
>
> Can we somehow avoid that die_perror()? Maybe if there is no uid_map,
> so no user namespaces, so we're automatically in the root one?
...yes, we could assume that, but you wouldn't gain any usable
functionality, if user namespaces are not available. We have four cases:
a. passt(1) running as non-root: the ns_is_init() check is not needed
for the check in conf_ugid(), we already know we're not root. It's
only needed to decide whether to retain some capabilities in
isolate_initial(), and we could simply decide to drop them.
On the other hand, if user namespaces are not available, we can't
enable an important sandboxing feature for passt(1), that is, the
filesystem isolation, which needs mount namespaces to make the
current filesystem inaccessible to the process, by remounting / from
an empty one, see isolate_prefork().
b. passt(1) running as root: the ns_is_init() check is needed for the
check in conf_ugid(). We know that it's the initial namespace, and
consequently switch to 'nobody'. This would be fine, but the problem
listed above for a. remains
c. pasta(1) running as non-root: same problem as a., plus the fact that
we actually need network namespaces to provide any functionality,
and you can detach one only if you detach the user namespace at the
same time
d. pasta(1) running as root: same as b., plus the problem from c.
I understand the impetus of disabling user namespaces that way.
But to avoid a class of vulnerabilities, for which patches are
available and were available before disclosure, you introduce a
weakness (we would need to skip parts of sandboxing in passt), for
which there will never be patches.
All in all, I would suggest that supporting operation without user
namespaces is not a blanket solution to improve security. It can
actually make things worse. This is not just the case for passt by the
way, it also affects sandboxing in Chromium and Firefox, see:
https://github.com/flatpak/flatpak/issues/5921
Do you have any remaining question, or perhaps other proposals?
--
Stefano