Granting a capability to a service

Florian Weimer fweimer at redhat.com
Sat Jul 18 08:42:43 UTC 2015


Let's assume I want to start a service as an ordinary user, but allow to
bind it to a privileged port.  The program implementing the service does
not manipulate capabilities in any way.

I came up with with this system unit for testing purposes:

[Unit]
Description=Test unit

[Service]
Type=oneshot
ExecStart=/usr/sbin/getpcaps self
Capabilities=cap_net_bind_service+ep
SecureBits=keep-caps
User=fweimer
StandardOutput=journal

However, this does not work, the capability set remains empty.  Is there
a way to achieve what I want?

The algorithm documented in capabilities(7) suggests that retaining
effective capabilities across an execve system call absolutely requires
file capabilities (the inheritable part).  The only way to bypass that
if you perform the execve call with UID 0 (i.e., the literal UID 0, not
a capability).

This design is really odd because setting file capabilities always
increases the attack surface (even if it is just the inheritable bits),
and the only alternative appears to modify the service so that it is
capability-aware and switches away from UID 0, and grant sufficient
capabilities so that it can do so.  At that point, you can just skip the
configuration in the systemd service and do everything capablity-related
within the program.

What am I missing?

-- 
Florian Weimer / Red Hat Product Security


More information about the devel mailing list