Friday, December 23, 2011

D-Bus Loadable security module support

While I was thinking about LSM mediations of the D-Bus messages, I found out a nice work that is being developed by the Ubuntu sec team in order to support the AppArmor mediation on D-Bus message exchange and service acquisition.

Having a chat with John Johansen (from Unbuntu sec team), he said that he was missing a loadable module support on the D-Bus. Allowing the support of different Linux Security Modules mediation without messing up the D-Bus daemon code, which does make sense.

I started to implement a little PoC about this loadable support, which consists in the following: the LSM modules can be dynamically loadable at the d-bus daemon startup. By copying a D-Bus LMS module to a given directory (which can be specified at the d-bus configuration) it will be loaded and registered.

The idea is to have independent modules, if possible use only the D-Bus functions provided by libdbus, however, of course, if needed symbols can be copied from libdbus-internal.a.

Despite the fact that the modules can be independent of the D-Bus internals, they must have at least one known function, this function should be named as “pre_init“, and receives the pointer to the D-Bus internal function “register_security“. The “register_security” function should be called by the module if it is loaded successfully. The “pre_init” function must return a “dbus_bool_t“: true if everything goes right or false if not. Note that audit can be also initialized by this function.

The function “register_security” receives as parameter a pointer to the structure “security_validations” that is part of dbus-security.h. The structure is illustrated bellow:
struct security_validations
{
 char *name;
 dbus_bool_t (*bus_security_allows_send) (DBusConnection *,
                                         DBusConnection*,
                                         const char *,
                                         const char *,
                                         const char *,
                                         const char *,
                                         const char *,
                                         const char *,
                                         const char *,
                                         DBusError *);
 dbus_bool_t (*bus_security_allows_acquire_service) (DBusConnection *,
                                                    const char *,
                                                    const char *,
                                                    DBusError *);
 dbus_bool_t (*shutdown) (void);
};

The structure “security_validations” defines the hooks and the name of the security module and also the function to shutdown the mediation. Two main hooks were needed, the first is the one responsible to mediate the message exchanges and the second is the responsible to avoid unauthorized process to acquire some service. The shutdown hook is not less important, but less used. Shutdown is only called when the D-Bus daemon is hanging out.

The current implementation of SELinux mediation needs more hooks to work than what I am offering in this PoC. Since the SELinux implementation has some performance improvements by doing caching, it will be necessary to create new hooks to gather some information before deciding whether some message is ok to go or not, but this may be a later discussion.

The patched D-Bus code is available at:

http://cgit.collabora.com/git/user/zimmerle/dbus-lsm.git/

And there is a dummy module at:

http://cgit.collabora.com/git/user/zimmerle/dbus-dummy-lsm.git/