GetConnectionCredentials - add smack support
authorPatrick Ohly <patrick.ohly@intel.com>
Fri, 20 Jun 2014 14:55:00 +0000 (16:55 +0200)
committerŁukasz Stelmach <l.stelmach@samsung.com>
Tue, 27 Oct 2015 14:30:58 +0000 (15:30 +0100)
A process should never change its Smack label while connected to
D-Bus. If it did, we would end up with race conditions around
permission checking. Therefore we can retrieve the Smack label once,
when the process connects, and use that label whenever it is needed.

A new public libdbus API also gets added: dbus_connection_get_smack_label()
This is primarily for dbus-daemon, but may also be useful for other applications
creating direct connections.

Change-Id: I16ec50a031809aab879a543ec2d7effd56768bf1

bus/Makefile.am
bus/driver.c
bus/smack.c
dbus/Makefile.am
dbus/dbus-connection.c
dbus/dbus-connection.h
doc/dbus-specification.xml

index 26ec6d4..a5c39d0 100644 (file)
@@ -86,8 +86,8 @@ BUS_SOURCES=                                  \
        services.h                              \
        signals.c                               \
        signals.h                               \
-       smack.c                                 \
-       smack.h                                 \
+       smack.c                                 \
+       smack.h                                 \
        stats.c                                 \
        stats.h                                 \
        test.c                                  \
index 1337148..cf69b4d 100644 (file)
@@ -1602,6 +1602,16 @@ bus_driver_handle_get_connection_credentials (DBusConnection *connection,
         goto oom;
     }
 
+#ifdef DBUS_ENABLE_SMACK
+  {
+    const char *smack_label;
+    if (dbus_connection_get_smack_label (conn, &smack_label)) {
+      if (!_dbus_asv_add_string (&array_iter, "SmackLabel", smack_label))
+        goto oom;
+    }
+  }
+#endif
+
   if (!_dbus_asv_close (&reply_iter, &array_iter))
     goto oom;
 
index d4546a3..300d9da 100644 (file)
 #define SMACK_READ_WRITE "RW"
 
 
-#ifdef DBUS_ENABLE_SMACK
-static char *
-bus_smack_get_label (DBusConnection *connection)
-{
-  char *label;
-  int sock_fd;
-
-  if (!dbus_connection_get_socket(connection, &sock_fd))
-    return NULL;
-
-  if (smack_new_label_from_socket(sock_fd, &label) < 0)
-    return NULL;
-  return label;
-}
-#endif
-
 dbus_bool_t
 bus_smack_handle_get_connection_context (DBusConnection *connection,
                                          BusTransaction *transaction,
@@ -69,7 +53,7 @@ bus_smack_handle_get_connection_context (DBusConnection *connection,
   BusService *service;
   DBusConnection *remote_connection;
   DBusMessage *reply = NULL;
-  char *label;
+  const char *label;
 
   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
 
@@ -99,8 +83,7 @@ bus_smack_handle_get_connection_context (DBusConnection *connection,
   if (reply == NULL)
     goto oom;
 
-  label = bus_smack_get_label (remote_connection);
-  if (label == NULL)
+  if (!dbus_connection_get_smack_label(remote_connection, &label))
     {
       dbus_set_error (error, DBUS_ERROR_FAILED,
                       "Failed to get the socket fd of the connection",
@@ -116,7 +99,6 @@ bus_smack_handle_get_connection_context (DBusConnection *connection,
     goto oom;
 
   dbus_message_unref (reply);
-  dbus_free(label);
 
   return TRUE;
 
@@ -127,8 +109,6 @@ err:
   if (reply != NULL)
     dbus_message_unref (reply);
 
-  dbus_free(label);
-
   return FALSE;
 #else
   dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
@@ -161,15 +141,15 @@ bus_smack_generate_allowed_list (DBusConnection *connection,
                                  dbus_bool_t *nomem_err)
 {
 #ifdef DBUS_ENABLE_SMACK
-  char *subject_label;
+  const char *subject_label;
   DBusHashIter iter;
   dbus_bool_t is_allowed;
   DBusList **allowed_list;
 
   /* the label of the subject, is the label on the new connection,
      either the service itself or one of its clients */
-  subject_label = bus_smack_get_label (connection);
-  if (subject_label == NULL)
+
+  if (!dbus_connection_get_smack_label(connection, &subject_label))
     return NULL;
 
   allowed_list = dbus_new0 (DBusList*, 1);
@@ -226,14 +206,12 @@ bus_smack_generate_allowed_list (DBusConnection *connection,
         }
     }
 
-  dbus_free(subject_label);
   return allowed_list;
 
 nomem:
   if (allowed_list != NULL)
     _dbus_list_clear (allowed_list);
 
-  dbus_free(subject_label);
   *nomem_err = TRUE;
   return NULL;
 
index b248107..86d5d46 100644 (file)
@@ -5,6 +5,7 @@ AM_CPPFLAGS = \
        -I$(top_builddir) \
        -I$(top_srcdir) \
        $(SYSTEMD_CFLAGS) \
+       $(LIBSMACK_CFLAGS) \
        $(VALGRIND_CFLAGS) \
        -DDBUS_COMPILATION \
        -DDBUS_MACHINE_UUID_FILE=\""$(localstatedir)/lib/dbus/machine-id"\" \
@@ -283,7 +284,7 @@ libdbus_1_la_CPPFLAGS = \
        $(AM_CPPFLAGS) \
        -Ddbus_1_EXPORTS \
        $(NULL)
-libdbus_1_la_LIBADD= $(LIBDBUS_LIBS)
+libdbus_1_la_LIBADD= $(LIBDBUS_LIBS) $(LIBSMACK_LIBS)
 libdbus_1_la_LDFLAGS = \
        $(AM_LDFLAGS) \
        $(export_symbols) \
@@ -295,7 +296,7 @@ libdbus_internal_la_CPPFLAGS = \
        $(AM_CPPFLAGS) \
        -DDBUS_STATIC_BUILD \
        $(NULL)
-libdbus_internal_la_LIBADD=$(LIBDBUS_LIBS) $(SYSTEMD_LIBS)
+libdbus_internal_la_LIBADD=$(LIBDBUS_LIBS) $(SYSTEMD_LIBS) $(LIBSMACK_LIBS)
 
 if DBUS_WIN
 # This must be a separate convenience library, otherwise libtool notices
index b574207..2b2b853 100644 (file)
 #include "dbus-bus.h"
 #include "dbus-marshal-basic.h"
 
+#ifdef DBUS_ENABLE_SMACK
+#include <sys/smack.h>
+#include <stdlib.h>
+#endif
+
 #ifdef DBUS_DISABLE_CHECKS
 #define TOOK_LOCK_CHECK(connection)
 #define RELEASING_LOCK_CHECK(connection)
@@ -304,6 +309,9 @@ struct DBusConnection
   DBusObjectTree *objects; /**< Object path handlers registered with this connection */
 
   char *server_guid; /**< GUID of server if we are in shared_connections, #NULL if server GUID is unknown or connection is private */
+#ifdef DBUS_ENABLE_SMACK
+  char *peer_smack_label; /** Smack label of the peer at the time when the connection was established. Allocated with malloc(), NULL if unknown. */
+#endif
 
   /* These two MUST be bools and not bitfields, because they are protected by a separate lock
    * from connection->mutex and all bitfields in a word have to be read/written together.
@@ -1285,6 +1293,19 @@ _dbus_connection_new_for_transport (DBusTransport *transport)
   if (connection == NULL)
     goto error;
 
+#ifdef DBUS_ENABLE_SMACK
+  /* If we cannot get the Smack label, proceed without. */
+  {
+    int sock_fd;
+    if (_dbus_transport_get_socket_fd(transport, &sock_fd)) {
+      char *label;
+      if (smack_new_label_from_socket(sock_fd, &label) >= 0) {
+        connection->peer_smack_label = label;
+      }
+    }
+  }
+#endif
+
   _dbus_rmutex_new_at_location (&connection->mutex);
   if (connection->mutex == NULL)
     goto error;
@@ -2790,7 +2811,12 @@ _dbus_connection_last_unref (DBusConnection *connection)
   _dbus_rmutex_free_at_location (&connection->slot_mutex);
 
   _dbus_rmutex_free_at_location (&connection->mutex);
-  
+
+#ifdef DBUS_ENABLE_SMACK
+  if (connection->peer_smack_label)
+    free (connection->peer_smack_label);
+#endif
+
   dbus_free (connection);
 }
 
@@ -5244,6 +5270,27 @@ dbus_connection_get_unix_process_id (DBusConnection *connection,
   return result;
 }
 
+#ifdef DBUS_ENABLE_SMACK
+/**
+ * Gets the Smack label of the peer at the time when the connection
+ * was established. Returns #TRUE if the label is filled in.
+ *
+ * @param connection the connection
+ * @param label return location for the Smack label; returned value is valid as long as the connection exists
+ * @returns #TRUE if uid is filled in with a valid process ID
+ */
+dbus_bool_t
+dbus_connection_get_smack_label (DBusConnection *connection,
+                                const char **label)
+{
+  _dbus_return_val_if_fail (connection != NULL, FALSE);
+  _dbus_return_val_if_fail (label != NULL, FALSE);
+
+  *label = connection->peer_smack_label;
+  return *label != NULL;
+}
+#endif
+
 /**
  * Gets the ADT audit data of the connection if any.
  * Returns #TRUE if the structure pointer is returned.
index fe4d04e..aac5704 100644 (file)
@@ -264,6 +264,11 @@ dbus_bool_t        dbus_connection_get_unix_user                (DBusConnection
 DBUS_EXPORT
 dbus_bool_t        dbus_connection_get_unix_process_id          (DBusConnection             *connection,
                                                                  unsigned long              *pid);
+#ifdef DBUS_ENABLE_SMACK
+DBUS_EXPORT
+dbus_bool_t        dbus_connection_get_smack_label              (DBusConnection             *connection,
+                                                                 const char                **label);
+#endif
 DBUS_EXPORT
 dbus_bool_t        dbus_connection_get_adt_audit_session_data   (DBusConnection             *connection,
                                                                  void                      **data,
index f6b0215..9f4a843 100644 (file)
                   this concept. On Unix, this is the process ID defined by
                   POSIX.</entry>
               </row>
+              <row>
+                <entry>SmackLabel</entry>
+                <entry>STRING</entry>
+                <entry>The Smack label of the process at the time when it connected
+                  to D-Bus, on platforms that have this concept.</entry>
+              </row>
             </tbody>
           </tgroup>
         </informaltable>