# dbus not dropping capabilities thus not starting --system

## vaxbrat

Currently having no joy starting up dbus system daemon from init.  The last dbus ebuild that would start correctly has been dropped from ebuilds.

This is a 2.6.23-hardened-r8 selinux system running unstable amd64 with the 2.6 audit daemon.  Startup of dbus from /etc/init.d will silently fail.

Manually starting as root with the command and not forking shows problems dropping capabilities:

```
dbus-daemon --system --nofork

Failed to start message bus: Failed to drop capabilities: Operation not permitted
```

This comes from the following code in dbus-sysdeps-util-unix.c

```
  if (we_were_root)

    {

      cap_value_t new_cap_list[] = { CAP_AUDIT_WRITE };

      cap_value_t tmp_cap_list[] = { CAP_AUDIT_WRITE, CAP_SETUID, CAP_SETGID };

      cap_t tmp_caps = cap_init();

        

      if (!tmp_caps || !(new_caps = cap_init ()))

        {

          dbus_set_error (error, DBUS_ERROR_FAILED,

                          "Failed to initialize drop of capabilities: %s\n",

                          _dbus_strerror (errno));

          if (tmp_caps)

            cap_free (tmp_caps);

          return FALSE;

        }

      /* assume these work... */

      cap_set_flag (new_caps, CAP_PERMITTED, 1, new_cap_list, CAP_SET);

      cap_set_flag (new_caps, CAP_EFFECTIVE, 1, new_cap_list, CAP_SET);

      cap_set_flag (tmp_caps, CAP_PERMITTED, 3, tmp_cap_list, CAP_SET);

      cap_set_flag (tmp_caps, CAP_EFFECTIVE, 3, tmp_cap_list, CAP_SET);

      

      if (prctl (PR_SET_KEEPCAPS, 1, 0, 0, 0) == -1)

        {

          dbus_set_error (error, _dbus_error_from_errno (errno),

                          "Failed to set keep-capabilities: %s\n",

                          _dbus_strerror (errno));

          cap_free (tmp_caps);

          goto fail;

        }

        

      if (cap_set_proc (tmp_caps) == -1)

        {

          dbus_set_error (error, DBUS_ERROR_FAILED,

                          "Failed to drop capabilities: %s\n",

                          _dbus_strerror (errno));

          cap_free (tmp_caps);

          goto fail;

        }

```

I'm not seeing much googling around about this and those are standard capabilities in <linux/capability.h>.  I'm not sure why SETUID and SETGID are being messed around with here since it is a system daemon and the dbus-daemon binary isn't setuid or setgid anyway.  Is this really a warning that shouldn't be treated like an error?

----------

## DarKRaveR

Well, a setuid executeable can be run 'as root' by 'non-root' users.

The setgid/setguid caps are there for doing exactly that, changing the user/group of the process. Assuming root spawns dbus (or an init script with root priviledges) the executeable will have basicly all caps. Since dbus certainly does not run as root but as whatever user+group, it is probably best to throw away all caps not needed (but keeping those needed to setuid/setgid to this user). That's what it is trying to do, throw away all caps, except those needed to change the user/group and the audit cap.

----------

## depontius

What root capabilities are needed by dbus?

From what I've read, file-based capabilities have gotten into the kernel as of 2.6.25.  That should make it so that root can use extended attributes to grant the necessary capabilities to the dbus executable, and then it won't need to be setuid/setgid.  This presumes that the capabilities it needs are covered by filesystem capabilities in a reasonably fine-grained fashion.

For instance, ping only needs one capability granted at the filesystem level, and then its setuid can be dropped.

----------

## DarKRaveR

Aside from file-based caps, caps have been around for ages.

If you start dbus as root, and it is supposed to run as user dbus (in example) and group daemon, than it needs the setgid+setuid caps to change the user and group.

If a process wants to bind() to ports<1024 it will need the net_bind cap ... etc. etc.

You might want to read man capabilities.

Giving the caps via etended attributes is a completely different story.

Assume you develop a httpd daemon, you will need several priviledged operations, yet you don't want it to have all of them. So, as a developer, you will drop all caps appropriately as soon as they are not needed anymore.

----------

## depontius

Of course good programs will drop capabilities that the don't need, and if possible use those that they do need during initialization and then drop them.  Those same good programs will also switch to a non-privileged ID as soon as possible.

That's well-written code, but how much code is that well-written?  How much code just requires root because they don't have to fuss with all of that capability crap, and stay as root because it's too much trouble to write good install scripts to handle the non-privileged ID stuff.  Finally how many users know the difference and pick the right code?

With file-based capabilities you grant what is needed.  Then the program is never root at all, either run by root or through setuid.  It has the capabilities it needs, and if it's a good program it drops even those when they're no longer needed.

----------

## vaxbrat

I've gotten dbus to run again on this system by commenting out this section as well as another.  Both are wrapped by checks to see if libaudit is present.  That's why I was scratching my head about why setuid and setuid caps are being played with along with CAP_AUDIT_WRITE.  I may try to uncomment the blocks with only the audit cap in the list to see what happens here.

I wasn't familiar enough with caps to decide whether dropping setuid and setgid are appropriate (or permitted) in the first place when the exe isn't marked setuid or setgid.

----------

