Re: [PATCH 0/3] Enable namespaced file capabilities

From: Stefan Berger
Date: Thu Jun 22 2017 - 17:03:35 EST


On 06/22/2017 04:33 PM, Casey Schaufler wrote:
On 6/22/2017 1:12 PM, Stefan Berger wrote:
On 06/22/2017 03:59 PM, Casey Schaufler wrote:
On 6/22/2017 11:59 AM, Stefan Berger wrote:
This series of patches primary goal is to enable file capabilities
in user namespaces without affecting the file capabilities that are
effective on the host. This is to prevent that any unprivileged user
on the host maps his own uid to root in a private namespace, writes
the xattr, and executes the file with privilege on the host.

We achieve this goal by writing extended attributes with a different
name when a user namespace is used. If for example the root user
in a user namespace writes the security.capability xattr, the name
of the xattr that is actually written is encoded as
security.capability@uid=1000 for root mapped to uid 1000 on the host.
You need to identify the instance of the user namespace for
this to work right on a system with multiple user namespaces.
If I have a shared filesystem mounted in two different user
namespaces a change by one will affect the other.
Two different user namespaces with different uid mappings will not affect each other.
But two namespaces with the same uid mapping will, and I
don't think this meets the principle of least astonishment.
I also object to associating capabilities with UIDs. The
whole point of capabilities is to disassociate UID 0 from
privilege. What you've done is explicitly associate a UID
with the ability to have privilege. That's an architectural
regression.

It has privilege within the bounding set of the capabilities that it is given. Afaik, a process cannot gain additional capabilities through file capabilities. Allowing to set a process's file capabilities allows one to _restrict_ what it can do, which is useful for shared filesystems where I can now set my ping capabilities to cap_net_raw, overriding the ones one the host which could be cap_net_admin+cap_net_raw. So I don't need to extend my bounding set with cap_net_admin or mess with xattrs on the host.



If root in userns1 mapped to uid 1000 (size 1000) writes security.capability, it will write security.capability@uid=1000 into the fs.
If root in userns2 mapped to uid 2000 (size 1000) writes security.capability, it will write security.capability@uid=2000 into the fs.

Neither of the two will see each other's security.capability, but each will see their own 'security.capability'.

Assume now userns1 has a size of 2000, so overlapping with userns2, it will now see userns2's security.capability@uid=1000 as well as its own 'security.capability'. security.capability@uid=1000 (of userns2) in userns1 will not have an effect on effective file capabilities.

... unless I'm missing something obvious about namespace behavior.

When listing the xattrs on the host, the existing security.capability
as well as the security.capability@uid=1000 will be shown. Inside the
namespace only 'security.capability', with the value of
security.capability@uid=1000, is visible.

To maintain compatibility with existing behavior, the value of
security.capability of the host is shown inside the user namespace
once the security.capability of the user namespace has been removed
(which really removes security.capability@uid=1000). Writing to
an extended attribute inside a user namespace effectively hides the
extended attribute of the host.

The general framework that is established with these patches can
be applied to other extended attributes as well, such as security.ima
or the 'trusted.' prefix . Another extended attribute that needed to
be enabled here is 'security.selinux,' since otherwise this extended
attribute would not be shown anymore inside a user namespace.

Regards,
Stefan & Serge


Stefan Berger (3):
xattr: Enable security.capability in user namespaces
Enable capabilities of files from shared filesystem
Enable security.selinux in user namespaces

fs/xattr.c | 472 ++++++++++++++++++++++++++++++++++++++++++++++-
security/commoncap.c | 36 +++-
security/selinux/hooks.c | 9 +-
3 files changed, 501 insertions(+), 16 deletions(-)