From: Radoslaw Pajak Date: Mon, 4 Nov 2013 07:39:36 +0000 (+0100) Subject: [doc][daemon-fix][daemon-opt] Known limitations updated, code fixes, clean-ups, optim... X-Git-Url: http://review.tizen.org/git/?p=platform%2Fupstream%2Fdbus.git;a=commitdiff_plain;h=a0be921da79a78e2c0484d99aac9002a1de1d0cf [doc][daemon-fix][daemon-opt] Known limitations updated, code fixes, clean-ups, optimizations, formatting - org.freedesktop.DBus.GetNameOwner fixed - added policy checking when acquiring well-known name - dbus_connection_get_unix_user rewritten for kdbus - dbus_connection_get_unix_process_id rewritten for kdbus - bus_service_get_primary_owners_connection extended with kdbus support - (kdbus_get_connection_unix_) user and process_id refactored for more universal usage - kdbus_list_services optimized Change-Id: I90896df7bebafe05869778da1aef2a22a24722fe Signed-off-by: Radoslaw Pajak --- diff --git a/bus/driver.c b/bus/driver.c index af85eb0..3d8ede6 100644 --- a/bus/driver.c +++ b/bus/driver.c @@ -1231,6 +1231,9 @@ bus_driver_handle_get_service_owner (DBusConnection *connection, BusRegistry *registry; BusService *service; DBusMessage *reply; +#ifdef ENABLE_KDBUS_TRANSPORT + char unique_name[(unsigned int)(snprintf((char*)base_name, 0, "%llu", ULLONG_MAX) + sizeof(":1."))]; +#endif _DBUS_ASSERT_ERROR_IS_CLEAR (error); @@ -1249,7 +1252,6 @@ bus_driver_handle_get_service_owner (DBusConnection *connection, { int ret; struct nameInfo info; - char unique_name[(unsigned int)(snprintf((char*)base_name, 0, "%llu", ULLONG_MAX) + sizeof(":1."))]; ret = kdbus_NameQuery(text, dbus_connection_get_transport(connection), &info); if(ret == 0) //unique id of the name @@ -1460,7 +1462,11 @@ bus_driver_handle_get_connection_unix_user (DBusConnection *connection, #ifdef ENABLE_KDBUS_TRANSPORT if(bus_context_is_kdbus(bus_transaction_get_context (transaction))) { - if(!kdbus_get_connection_unix_user(connection, message, &uid, error)) + const char* name; + + if(!dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID)) + goto failed; + if(!kdbus_get_connection_unix_user(connection, name, &uid, error)) goto failed; } else @@ -1521,31 +1527,31 @@ bus_driver_handle_get_connection_unix_process_id (DBusConnection *connection, reply = dbus_message_new_method_return (message); if (reply == NULL) goto oom; - #ifdef ENABLE_KDBUS_TRANSPORT if(bus_context_is_kdbus(bus_transaction_get_context (transaction))) - { - if(!kdbus_get_connection_unix_process_id(connection, message, &pid, error)) - goto failed; - } - else + { + const char* name; + + if(!dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID)) + goto failed; + if(!kdbus_get_connection_unix_process_id(connection, name, &pid, error)) + goto failed; + } + else #endif { - conn = bus_driver_get_conn_helper (connection, message, "PID", &service, - error); - - if (conn == NULL) - goto failed; - - + conn = bus_driver_get_conn_helper (connection, message, "PID", &service, + error); + if (conn == NULL) + goto failed; - if (!dbus_connection_get_unix_process_id (conn, &pid)) - { - dbus_set_error (error, - DBUS_ERROR_UNIX_PROCESS_ID_UNKNOWN, - "Could not determine PID for '%s'", service); - goto failed; - } + if (!dbus_connection_get_unix_process_id (conn, &pid)) + { + dbus_set_error (error, + DBUS_ERROR_UNIX_PROCESS_ID_UNKNOWN, + "Could not determine PID for '%s'", service); + goto failed; + } } pid32 = pid; @@ -1739,7 +1745,11 @@ bus_driver_handle_get_connection_credentials (DBusConnection *connection, } else { - if(kdbus_get_connection_unix_process_id(connection, message, &ulong_val, error)) + const char* name; + + if(!dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID)) + goto failed; + if(kdbus_get_connection_unix_process_id(connection, name, &ulong_val, error)) { if (!_dbus_asv_add_uint32 (&array_iter, "ProcessID", ulong_val)) goto oom; @@ -1747,7 +1757,7 @@ bus_driver_handle_get_connection_credentials (DBusConnection *connection, else goto failed; - if(kdbus_get_connection_unix_user(connection, message, &ulong_val, error)) + if(kdbus_get_connection_unix_user(connection, name, &ulong_val, error)) { if (!_dbus_asv_add_uint32 (&array_iter, "UnixUserID", ulong_val)) goto oom; diff --git a/bus/kdbus-d.c b/bus/kdbus-d.c index 00439c5..6b83d4b 100644 --- a/bus/kdbus-d.c +++ b/bus/kdbus-d.c @@ -236,13 +236,84 @@ dbus_uint32_t kdbus_release_name(DBusConnection* connection, const DBusString *s return release_kdbus_name(fd, _dbus_string_get_const_data(service_name), sender_id); } +/* + * Asks kdbus for well-known names registered on the bus + */ dbus_bool_t kdbus_list_services (DBusConnection* connection, char ***listp, int *array_len) { int fd; + struct kdbus_cmd_names* pCmd; + __u64 cmd_size; + dbus_bool_t ret_val = FALSE; + char** list; + int list_len = 0; + int i = 0; + int j; + + cmd_size = sizeof(struct kdbus_cmd_names) + KDBUS_ITEM_SIZE(1); + pCmd = malloc(cmd_size); + if(pCmd == NULL) + goto out; + pCmd->size = cmd_size; _dbus_transport_get_socket_fd(dbus_connection_get_transport(connection), &fd); - return list_kdbus_names(fd, listp, array_len); +again: + cmd_size = 0; + if(ioctl(fd, KDBUS_CMD_NAME_LIST, pCmd)) + { + if(errno == EINTR) + goto again; + if(errno == ENOBUFS) //buffer to small to put all names into it + cmd_size = pCmd->size; //here kernel tells how much memory it needs + else + { + _dbus_verbose("kdbus error asking for name list: err %d (%m)\n",errno); + goto out; + } + } + if(cmd_size) //kernel needs more memory + { + pCmd = realloc(pCmd, cmd_size); //prepare memory + if(pCmd == NULL) + return FALSE; + goto again; //and try again + } + else + { + struct kdbus_cmd_name* pCmd_name; + + for (pCmd_name = pCmd->names; (uint8_t *)(pCmd_name) < (uint8_t *)(pCmd) + pCmd->size; pCmd_name = KDBUS_PART_NEXT(pCmd_name)) + list_len++; + + list = malloc(sizeof(char*) * (list_len + 1)); + if(list == NULL) + goto out; + + for (pCmd_name = pCmd->names; (uint8_t *)(pCmd_name) < (uint8_t *)(pCmd) + pCmd->size; pCmd_name = KDBUS_PART_NEXT(pCmd_name)) + { + list[i] = strdup(pCmd_name->name); + if(list[i] == NULL) + { + for(j=0; j #include #include -#ifdef ENABLE_KDBUS_TRANSPORT -#include -#include -#include -#endif - #include "driver.h" #include "services.h" #include "connection.h" @@ -42,7 +36,14 @@ #include "policy.h" #include "bus.h" #include "selinux.h" + #ifdef ENABLE_KDBUS_TRANSPORT +#include +#include +#include +#include +#include + #include "kdbus-d.h" #include "dbus/kdbus.h" #endif @@ -656,6 +657,7 @@ bus_registry_acquire_kdbus_service (BusRegistry *registry, dbus_uint32_t flags; __u64 sender_id; dbus_bool_t rm_owner_daemon = FALSE; + const char* conn_unique_name; if (!dbus_message_get_args (message, error, DBUS_TYPE_STRING, &name, @@ -692,18 +694,26 @@ bus_registry_acquire_kdbus_service (BusRegistry *registry, goto out; } + conn_unique_name = dbus_message_get_sender(message); + if (_dbus_string_equal_c_str (service_name, DBUS_SERVICE_DBUS)) { dbus_set_error (error, DBUS_ERROR_INVALID_ARGS, "Connection \"%s\" is not allowed to own the service \"%s\"because " "it is reserved for D-Bus' use only", - bus_connection_is_active (connection) ? - bus_connection_get_name (connection) : - "(inactive)", - DBUS_SERVICE_DBUS); + conn_unique_name, DBUS_SERVICE_DBUS); goto out; } + if (!bus_client_policy_check_can_own (bus_connection_get_policy (connection), service_name)) + { + dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED, + "Connection \"%s\" is not allowed to own the service \"%s\" due " + "to security policies in the configuration file", + conn_unique_name, _dbus_string_get_const_data (service_name)); + goto out; + } + service = bus_registry_lookup (registry, service_name); if (service == NULL) { @@ -716,13 +726,13 @@ bus_registry_acquire_kdbus_service (BusRegistry *registry, if(!kdbus_register_policy(service_name, connection)) { dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED, - "Connection is not allowed to own the service \"%s\" due to security policies in the configuration file", - _dbus_string_get_const_data (service_name)); + "Kdbus error when setting policy for connection \"%s\" and service name \"%s\"", + conn_unique_name, _dbus_string_get_const_data (service_name)); goto failed; } } - sender_id = sender_name_to_id(dbus_message_get_sender(message), error); + sender_id = sender_name_to_id(conn_unique_name, error); if(dbus_error_is_set(error)) goto failed; @@ -730,7 +740,7 @@ bus_registry_acquire_kdbus_service (BusRegistry *registry, if(*result == -EPERM) { dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED, - "Connection is not allowed to own the service \"%s\" due to security policies in the configuration file", + "Kdbus not allowed to own the service \"%s\"", _dbus_string_get_const_data (service_name)); goto failed; } @@ -1509,13 +1519,22 @@ DBusConnection * bus_service_get_primary_owners_connection (BusService *service) { BusOwner *owner; +#ifdef ENABLE_KDBUS_TRANSPORT + char unique_name[(unsigned int)(snprintf((char*)NULL, 0, "%llu", ULLONG_MAX) + sizeof(":1."))]; +#endif owner = bus_service_get_primary_owner (service); +#ifdef ENABLE_KDBUS_TRANSPORT + if(kdbus_get_name_owner(owner->conn, bus_service_get_name(service), unique_name) < 0) + return NULL; + return _bus_service_find_owner_connection(service, unique_name); //bus_connections_find_conn_by_name would be safer? but slower +#else if (owner != NULL) return owner->conn; else return NULL; +#endif } BusOwner* diff --git a/dbus/dbus-connection.c b/dbus/dbus-connection.c index 9167619..34eddb5 100644 --- a/dbus/dbus-connection.c +++ b/dbus/dbus-connection.c @@ -5232,7 +5232,7 @@ dbus_connection_get_socket(DBusConnection *connection, return retval; } - +#ifndef ENABLE_KDBUS_TRANSPORT /** * Gets the UNIX user ID of the connection if known. Returns #TRUE if * the uid is filled in. Always returns #FALSE on non-UNIX platforms @@ -5312,6 +5312,7 @@ dbus_connection_get_unix_process_id (DBusConnection *connection, return result; } +#endif /** * Gets the ADT audit data of the connection if any. diff --git a/dbus/dbus-transport-kdbus.c b/dbus/dbus-transport-kdbus.c index 0e77f15..cc226a3 100644 --- a/dbus/dbus-transport-kdbus.c +++ b/dbus/dbus-transport-kdbus.c @@ -475,9 +475,9 @@ int kdbus_NameQuery(const char* name, DBusTransport* transport, struct nameInfo* pInfo->sec_label_len = 0; pInfo->sec_label = NULL; - item_size = KDBUS_PART_HEADER_SIZE + strlen(name) + 1; + item_size = KDBUS_PART_HEADER_SIZE + strlen(name) + 1; item_size = (item_size < 56) ? 56 : item_size; //at least 56 bytes are needed by kernel to place info about name, otherwise error - size = sizeof(struct kdbus_cmd_name_info) + item_size; + size = sizeof(struct kdbus_cmd_name_info) + item_size; msg = malloc(size); if (!msg) diff --git a/dbus/kdbus-common.c b/dbus/kdbus-common.c index 90eb2c2..4a5d7f2 100644 --- a/dbus/kdbus-common.c +++ b/dbus/kdbus-common.c @@ -25,6 +25,7 @@ */ #include "kdbus.h" #include "kdbus-common.h" +#include "dbus-transport-kdbus.h" #include #include #include @@ -130,83 +131,6 @@ dbus_bool_t register_kdbus_policy(const char* name, int fd) return TRUE; } -/* - * Asks kdbus for well-known names registered on the bus - */ -dbus_bool_t list_kdbus_names(int fd, char ***listp, int *array_len) -{ - struct kdbus_cmd_names* pCmd; - __u64 cmd_size; - dbus_bool_t ret_val = FALSE; - char** list; - int list_len = 0; - int i = 0; - int j; - - cmd_size = sizeof(struct kdbus_cmd_names) + KDBUS_ITEM_SIZE(1); - pCmd = malloc(cmd_size); - if(pCmd == NULL) - goto out; - pCmd->size = cmd_size; - -again: - cmd_size = 0; - if(ioctl(fd, KDBUS_CMD_NAME_LIST, pCmd)) - { - if(errno == EINTR) - goto again; - if(errno == ENOBUFS) //buffer to small to put all names into it - cmd_size = pCmd->size; //here kernel tells how much memory it needs - else - { - _dbus_verbose("kdbus error asking for name list: err %d (%m)\n",errno); - goto out; - } - } - if(cmd_size) //kernel needs more memory - { - pCmd = realloc(pCmd, cmd_size); //prepare memory - if(pCmd == NULL) - return FALSE; - goto again; //and try again - } - else - { - struct kdbus_cmd_name* pCmd_name; - - for (pCmd_name = pCmd->names; (uint8_t *)(pCmd_name) < (uint8_t *)(pCmd) + pCmd->size; pCmd_name = KDBUS_PART_NEXT(pCmd_name)) - list_len++; - - list = malloc(sizeof(char*) * (list_len + 1)); - if(list == NULL) - goto out; - - for (pCmd_name = pCmd->names; (uint8_t *)(pCmd_name) < (uint8_t *)(pCmd) + pCmd->size; pCmd_name = KDBUS_PART_NEXT(pCmd_name)) - { - list[i] = strdup(pCmd_name->name); - if(list[i] == NULL) - { - for(j=0; jsize)) #define KDBUS_ITEM_SIZE(s) KDBUS_ALIGN8((s) + KDBUS_PART_HEADER_SIZE) -/*struct kdbus_policy *make_policy_name(const char *name); -struct kdbus_policy *make_policy_access(__u64 type, __u64 bits, __u64 id); -void append_policy(struct kdbus_cmd_policy *cmd_policy, struct kdbus_policy *policy, __u64 max_size);*/ dbus_bool_t register_kdbus_policy(const char* name, int fd); -dbus_bool_t list_kdbus_names(int fd, char ***listp, int *array_len); int request_kdbus_name(int fd, const char *name, const __u64 flags, __u64 id); int release_kdbus_name(int fd, const char *name, __u64 id); diff --git a/doc-kdbus/kdbus_transport_for_dbus.pdf b/doc-kdbus/kdbus_transport_for_dbus.pdf index 4d95e1b..f4fe9b3 100644 Binary files a/doc-kdbus/kdbus_transport_for_dbus.pdf and b/doc-kdbus/kdbus_transport_for_dbus.pdf differ