diff options
author | Patrick Ohly <patrick.ohly@intel.com> | 2014-06-20 16:55:00 +0200 |
---|---|---|
committer | Jacek Bukarewicz <j.bukarewicz@samsung.com> | 2014-12-10 17:45:13 +0100 |
commit | 27f7a8fcd8d6d3e1379c5525294ede5ea7574037 (patch) | |
tree | 13fef2cd5a3d77b1bf206907c0d35460505a4e28 | |
parent | 7142988408fd3cc4e844e71c30ec00a49feca0e0 (diff) | |
download | dbus-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.am | 4 | ||||
-rw-r--r-- | bus/driver.c | 10 | ||||
-rw-r--r-- | bus/smack.c | 32 | ||||
-rw-r--r-- | dbus/Makefile.am | 5 | ||||
-rw-r--r-- | dbus/dbus-connection.c | 49 | ||||
-rw-r--r-- | dbus/dbus-connection.h | 5 | ||||
-rw-r--r-- | doc/dbus-specification.xml | 6 |
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> |