summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Ohly <patrick.ohly@intel.com>2014-06-20 16:55:00 +0200
committerJacek Bukarewicz <j.bukarewicz@samsung.com>2014-12-10 17:45:13 +0100
commit27f7a8fcd8d6d3e1379c5525294ede5ea7574037 (patch)
tree13fef2cd5a3d77b1bf206907c0d35460505a4e28
parent7142988408fd3cc4e844e71c30ec00a49feca0e0 (diff)
downloaddbus-27f7a8fcd8d6d3e1379c5525294ede5ea7574037.tar.gz
dbus-27f7a8fcd8d6d3e1379c5525294ede5ea7574037.tar.bz2
dbus-27f7a8fcd8d6d3e1379c5525294ede5ea7574037.zip
GetConnectionCredentials - add smack support
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
-rw-r--r--bus/Makefile.am4
-rw-r--r--bus/driver.c10
-rw-r--r--bus/smack.c32
-rw-r--r--dbus/Makefile.am5
-rw-r--r--dbus/dbus-connection.c49
-rw-r--r--dbus/dbus-connection.h5
-rw-r--r--doc/dbus-specification.xml6
7 files changed, 79 insertions, 32 deletions
diff --git a/bus/Makefile.am b/bus/Makefile.am
index 26ec6d4b..a5c39d0c 100644
--- a/bus/Makefile.am
+++ b/bus/Makefile.am
@@ -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 \
diff --git a/bus/driver.c b/bus/driver.c
index fac614e7..58f184c5 100644
--- a/bus/driver.c
+++ b/bus/driver.c
@@ -1564,6 +1564,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;
diff --git a/bus/smack.c b/bus/smack.c
index d4546a3a..300d9dac 100644
--- a/bus/smack.c
+++ b/bus/smack.c
@@ -40,22 +40,6 @@
#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;
diff --git a/dbus/Makefile.am b/dbus/Makefile.am
index b2481073..86d5d466 100644
--- a/dbus/Makefile.am
+++ b/dbus/Makefile.am
@@ -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
diff --git a/dbus/dbus-connection.c b/dbus/dbus-connection.c
index f0b6871e..af8be962 100644
--- a/dbus/dbus-connection.c
+++ b/dbus/dbus-connection.c
@@ -45,6 +45,11 @@
#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;
@@ -2763,7 +2784,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);
}
@@ -5217,6 +5243,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.
diff --git a/dbus/dbus-connection.h b/dbus/dbus-connection.h
index fe4d04ef..aac57046 100644
--- a/dbus/dbus-connection.h
+++ b/dbus/dbus-connection.h
@@ -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,
diff --git a/doc/dbus-specification.xml b/doc/dbus-specification.xml
index f6b02152..9f4a843f 100644
--- a/doc/dbus-specification.xml
+++ b/doc/dbus-specification.xml
@@ -5829,6 +5829,12 @@
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>