From: Radoslaw Pajak Date: Fri, 27 Sep 2013 09:16:33 +0000 (+0200) Subject: [daemon-dev][lib-fix][lib-dev] ListQueuedOwners method in daemon, fixed strcpy issue... X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=492a317ae9fb1e1bc5ff500fd14536bf11f1d6bd;p=platform%2Fupstream%2Fdbus.git [daemon-dev][lib-fix][lib-dev] ListQueuedOwners method in daemon, fixed strcpy issue, added kdbus priority on opening transpot - ListQueuedOwners method handling added to daemon - GetAdtAuditSessionData method now passed to daemon, but still can not return anything interesting for kdbus transport (neither it does for std socket and std authentication method) - fixed issue with strcpy causing buffer overflow on foxp - strcpy replaced with memcpy - set kdbus precendence when opening transport, thus with kdbus and unix transport both present in DBUS_SESSION_BUS_ADDRESS, modified library will try to use kdbus first Change-Id: If481bbd446bf64bc40b767ccdec177cce5f1e719 --- diff --git a/autogen.sh b/autogen.sh index e5d8342..a1e97f4 100755 --- a/autogen.sh +++ b/autogen.sh @@ -100,9 +100,9 @@ else run_configure=false fi -#--enable-developer +#--enable-developer --enable-verbose-mode if $run_configure; then - $srcdir/configure --enable-developer --config-cache "$@" || exit $? + $srcdir/configure --enable-verbose-mode --config-cache "$@" || exit $? echo echo "Now type 'make' to compile $PROJECT." else diff --git a/bus/kdbus-d.c b/bus/kdbus-d.c index 385d32f..b0466ee 100644 --- a/bus/kdbus-d.c +++ b/bus/kdbus-d.c @@ -8,14 +8,15 @@ * */ +#include #include "kdbus-d.h" #include -#include #include #include "dispatch.h" #include #include #include +#include "connection.h" #include #include @@ -284,3 +285,33 @@ dbus_bool_t kdbus_get_connection_unix_selinux_security_context(DBusConnection* c return ret; } + +DBusConnection* create_phantom_connection(DBusConnection* connection, const char* unique_name) +{ + DBusConnection *phantom_connection; + DBusString name; + DBusError error; + + _dbus_string_init_const(&name, unique_name); + + phantom_connection = _dbus_connection_new_for_used_transport (dbus_connection_get_transport(connection)); + if(phantom_connection == NULL) + return FALSE; + if(!bus_connections_setup_connection(bus_connection_get_connections(connection), phantom_connection)) + { + /*todo FIXME something should be done to clean up the phantom connection + * but we can't use standard disconnect, unref or last_unref because the transport is taken from connection + * so we probably should write own function on the basis of _dbus_connection_last_unref + */ + phantom_connection = NULL; + } + if(!bus_connection_complete(phantom_connection, &name, &error)) + { + /* todo FIXME exactly the same issue as above */ + phantom_connection = NULL; + } + + _dbus_verbose ("Created phantom connection for %s\n", bus_connection_get_name(phantom_connection)); + + return phantom_connection; +} diff --git a/bus/kdbus-d.h b/bus/kdbus-d.h index 57acfe0..bd69167 100644 --- a/bus/kdbus-d.h +++ b/bus/kdbus-d.h @@ -32,4 +32,5 @@ dbus_bool_t kdbus_get_connection_unix_user(DBusConnection* connection, DBusMessa dbus_bool_t kdbus_get_connection_unix_process_id(DBusConnection* connection, DBusMessage* message, unsigned long* pid, DBusError* error); dbus_bool_t kdbus_get_connection_unix_selinux_security_context(DBusConnection* connection, DBusMessage* message, DBusMessage* reply, DBusError* error); +DBusConnection* create_phantom_connection(DBusConnection* connection, const char* unique_name); #endif /* KDBUS_H_ */ diff --git a/bus/services.c b/bus/services.c index 322ffcf..e88ca10 100644 --- a/bus/services.c +++ b/bus/services.c @@ -315,7 +315,7 @@ bus_registry_ensure (BusRegistry *registry, BUS_SET_OOM (error); return NULL; } - + return service; } @@ -669,7 +669,7 @@ bus_registry_acquire_kdbus_service (BusRegistry *registry, if (service == NULL) { service = bus_registry_ensure (registry, service_name, connection, flags, - transaction, error); //todo need correction because it will send NameOwnerChangedSignal + transaction, error); //adds daemon to service owners list - must be removed after right owner is set if (service == NULL) goto out; @@ -700,6 +700,20 @@ bus_registry_acquire_kdbus_service (BusRegistry *registry, goto out; } + if((*result == DBUS_REQUEST_NAME_REPLY_IN_QUEUE) || (*result == DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)) + { + DBusConnection* phantom; + + phantom = create_phantom_connection(connection, dbus_message_get_sender(message)); + if(phantom == NULL) + goto out; + if (!bus_service_add_owner (service, phantom, flags, transaction, error)) + goto out; /* todo FIXME what to do with phantom connection? look into create_phantom_connection for a clue*/ + if(*result == DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) + if (!bus_service_remove_owner (service, connection, transaction, error)) + goto out; /* todo FIXME what to do with phantom connection? look into create_phantom_connection for a clue*/ + } + activation = bus_context_get_activation (registry->context); retval = bus_activation_send_pending_auto_activation_messages (activation, service, @@ -928,7 +942,7 @@ add_cancel_ownership_to_transaction (BusTransaction *transaction, bus_service_ref (d->service); bus_owner_ref (owner); dbus_connection_ref (d->owner->conn); - + return TRUE; } diff --git a/dbus/dbus-connection-internal.h b/dbus/dbus-connection-internal.h index 2842f2f..56ce771 100644 --- a/dbus/dbus-connection-internal.h +++ b/dbus/dbus-connection-internal.h @@ -72,6 +72,7 @@ void _dbus_connection_toggle_timeout_unlocked (DBusConnection DBusTimeout *timeout, dbus_bool_t enabled); DBusConnection* _dbus_connection_new_for_transport (DBusTransport *transport); +DBusConnection* _dbus_connection_new_for_used_transport (DBusTransport *transport); void _dbus_connection_do_iteration_unlocked (DBusConnection *connection, DBusPendingCall *pending, unsigned int flags, diff --git a/dbus/dbus-connection.c b/dbus/dbus-connection.c index 77b0a36..21d0db9 100644 --- a/dbus/dbus-connection.c +++ b/dbus/dbus-connection.c @@ -1246,9 +1246,9 @@ _dbus_connection_do_iteration_unlocked (DBusConnection *connection, * * @param transport the transport. * @returns the new connection, or #NULL on failure. - */ -DBusConnection* -_dbus_connection_new_for_transport (DBusTransport *transport) +*/ +static DBusConnection* +_dbus_connection_new_for_transport_internal (DBusTransport *transport, dbus_bool_t exists) { DBusConnection *connection; DBusWatchList *watch_list; @@ -1278,7 +1278,7 @@ _dbus_connection_new_for_transport (DBusTransport *transport) pending_replies = _dbus_hash_table_new (DBUS_HASH_INT, - NULL, + NULL, (DBusFreeFunction)free_pending_call_on_hash_removal); if (pending_replies == NULL) goto error; @@ -1359,18 +1359,21 @@ _dbus_connection_new_for_transport (DBusTransport *transport) connection->disconnect_message_link = disconnect_link; - CONNECTION_LOCK (connection); - - if (!_dbus_transport_set_connection (transport, connection)) - { - CONNECTION_UNLOCK (connection); + if(!exists) + { + CONNECTION_LOCK (connection); - goto error; - } + if (!_dbus_transport_set_connection (transport, connection)) + { + CONNECTION_UNLOCK (connection); - _dbus_transport_ref (transport); + goto error; + } - CONNECTION_UNLOCK (connection); + _dbus_transport_ref (transport); + + CONNECTION_UNLOCK (connection); + } _dbus_connection_trace_ref (connection, 0, 1, "new_for_transport"); return connection; @@ -1411,6 +1414,27 @@ _dbus_connection_new_for_transport (DBusTransport *transport) } /** + * Creates a new connection for the given transport. A transport + * represents a message stream that uses some concrete mechanism, such + * as UNIX domain sockets. May return #NULL if insufficient + * memory exists to create the connection. + * + * @param transport the transport. + * @returns the new connection, or #NULL on failure. + */ +DBusConnection* +_dbus_connection_new_for_transport (DBusTransport *transport) +{ + return _dbus_connection_new_for_transport_internal(transport, FALSE); +} + +DBusConnection* +_dbus_connection_new_for_used_transport (DBusTransport *transport) +{ + return _dbus_connection_new_for_transport_internal(transport, TRUE); +} + +/** * Increments the reference count of a DBusConnection. * Requires that the caller already holds the connection lock. * diff --git a/dbus/dbus-transport-kdbus.c b/dbus/dbus-transport-kdbus.c index cf19608..a7b4477 100644 --- a/dbus/dbus-transport-kdbus.c +++ b/dbus/dbus-transport-kdbus.c @@ -43,6 +43,7 @@ #define MEMFD_SIZE_THRESHOLD (2 * 1024 * 1024LU) // over this memfd is used #define KDBUS_MSG_DECODE_DEBUG 0 +//#define DBUS_AUTHENTICATION #define ITER_APPEND_STR(string) \ if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &string)) \ @@ -394,7 +395,7 @@ static int kdbus_write_msg(DBusTransportSocket *transport, DBusMessage *message, item = KDBUS_PART_NEXT(item); item->type = KDBUS_MSG_DST_NAME; item->size = KDBUS_PART_HEADER_SIZE + strlen(name) + 1; - strcpy(item->str, name); + memcpy(item->str, name, item->size - KDBUS_PART_HEADER_SIZE); } else if (dst_id == KDBUS_DST_ID_BROADCAST) { @@ -472,7 +473,7 @@ int kdbus_NameQuery(const char* name, DBusTransport* transport, struct nameInfo* item = msg->items; item->type = KDBUS_NAME_INFO_ITEM_NAME; item->size = item_size; - strcpy(item->str, name); + memcpy(item->str, name, strlen(name) + 1); again: ret = ioctl(((DBusTransportSocket*)transport)->fd, KDBUS_CMD_NAME_QUERY, msg); @@ -496,13 +497,12 @@ int kdbus_NameQuery(const char* name, DBusTransport* transport, struct nameInfo* pInfo->uniqueId = msg->id; pInfo->userId = msg->creds.uid; pInfo->processId = msg->creds.pid; - item = msg->items; while((uint8_t *)(item) < (uint8_t *)(msg) + msg->size) { if(item->type == KDBUS_NAME_INFO_ITEM_SECLABEL) { - pInfo->sec_label_len = item->size - KDBUS_PART_HEADER_SIZE - 1; + pInfo->sec_label_len = item->size - KDBUS_PART_HEADER_SIZE - 1; if(pInfo->sec_label_len != 0) { pInfo->sec_label = malloc(pInfo->sec_label_len); @@ -511,7 +511,6 @@ int kdbus_NameQuery(const char* name, DBusTransport* transport, struct nameInfo* else memcpy(pInfo->sec_label, item->data, pInfo->sec_label_len); } - break; } item = KDBUS_PART_NEXT(item); @@ -730,7 +729,7 @@ dbus_bool_t add_match_kdbus (DBusTransport* transport, __u64 id, const char *rul { pItem->type = KDBUS_MATCH_SRC_NAME; pItem->size = KDBUS_PART_HEADER_SIZE + name_size + 1; - strcpy(pItem->str, pName); + memcpy(pItem->str, pName, strlen(pName) + 1); pItem = KDBUS_PART_NEXT(pItem); } @@ -1067,13 +1066,13 @@ out: return ret_value; } #endif - else if(!strcmp(dbus_message_get_member(message), "GetAdtAuditSessionData")) //todo to be implemented - now can not be simply passed to daemon +/* else if(!strcmp(dbus_message_get_member(message), "GetAdtAuditSessionData")) //todo to be implemented { char* name = NULL; dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID); return reply_with_error(DBUS_ERROR_ADT_AUDIT_DATA_UNKNOWN, "Could not determine audit session data for '%s'", name, message, transport->connection); - } + }*/ #ifdef DBUS_SERVICES_IN_LIB else if(!strcmp(dbus_message_get_member(message), "GetConnectionSELinuxSecurityContext")) { @@ -1681,7 +1680,7 @@ check_write_watch (DBusTransport *transport) _dbus_transport_ref (transport); #ifdef DBUS_AUTHENTICATION - if (_dbus_transport_get_is_authenticated (transport)) + if (_dbus_transport_try_to_authenticate (transport)) #endif needed = _dbus_connection_has_messages_to_send_unlocked (transport->connection); #ifdef DBUS_AUTHENTICATION @@ -1739,7 +1738,7 @@ check_read_watch (DBusTransport *transport) _dbus_transport_ref (transport); #ifdef DBUS_AUTHENTICATION - if (_dbus_transport_get_is_authenticated (transport)) + if (_dbus_transport_try_to_authenticate (transport)) #endif need_read_watch = (_dbus_counter_get_size_value (transport->live_messages) < transport->max_live_messages_size) && @@ -1800,12 +1799,13 @@ read_data_into_auth (DBusTransport *transport, DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport; DBusString *buffer; int bytes_read; + int *fds, n_fds; *oom = FALSE; _dbus_auth_get_buffer (transport->auth, &buffer); - bytes_read = kdbus_read_message(socket_transport, buffer); + bytes_read = kdbus_read_message(socket_transport, buffer, fds, &n_fds); _dbus_auth_return_buffer (transport->auth, buffer, bytes_read > 0 ? bytes_read : 0); @@ -1845,11 +1845,38 @@ read_data_into_auth (DBusTransport *transport, } } +static int kdbus_send_auth (DBusTransport *transport, const DBusString *buffer) +{ + int len; + int bytes_written = -1; + struct kdbus_msg *msg; + struct kdbus_item *item; + + len = _dbus_string_get_length (buffer); +// data = _dbus_string_get_const_data_len (buffer, 0, len); + + msg = kdbus_init_msg(NULL, 1, 0, FALSE, 0, (DBusTransportSocket*)transport); + item = msg->items; + MSG_ITEM_BUILD_VEC(_dbus_string_get_const_data_len (buffer, 0, len), len); + + again: + if(ioctl(((DBusTransportSocket*)transport)->fd, KDBUS_CMD_MSG_SEND, msg)) + { + if(errno == EINTR) + goto again; + _dbus_verbose ("Error writing auth: %d, %m\n", errno); + } + else + bytes_written = len; + + return bytes_written; +} + /* Return value is whether we successfully wrote any bytes */ static dbus_bool_t write_data_from_auth (DBusTransport *transport) { - DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport; +// DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport; int bytes_written; const DBusString *buffer; @@ -1857,9 +1884,7 @@ write_data_from_auth (DBusTransport *transport) &buffer)) return FALSE; - bytes_written = _dbus_write_socket (socket_transport->fd, - buffer, - 0, _dbus_string_get_length (buffer)); + bytes_written = kdbus_send_auth (transport, buffer); if (bytes_written > 0) { @@ -1955,7 +1980,7 @@ do_authentication (DBusTransport *transport, oom = FALSE; - orig_auth_state = _dbus_transport_get_is_authenticated (transport); + orig_auth_state = _dbus_transport_try_to_authenticate (transport); /* This is essential to avoid the check_write_watch() at the end, * we don't want to add a write watch in do_iteration before @@ -1970,7 +1995,7 @@ do_authentication (DBusTransport *transport, _dbus_transport_ref (transport); - while (!_dbus_transport_get_is_authenticated (transport) && + while (!_dbus_transport_try_to_authenticate (transport) && _dbus_transport_get_is_connected (transport)) { if (!exchange_credentials (transport, do_reading, do_writing)) @@ -2027,7 +2052,7 @@ do_authentication (DBusTransport *transport, out: if (auth_completed) - *auth_completed = (orig_auth_state != _dbus_transport_get_is_authenticated (transport)); + *auth_completed = (orig_auth_state != _dbus_transport_try_to_authenticate (transport)); check_read_watch (transport); check_write_watch (transport); @@ -2049,7 +2074,7 @@ do_writing (DBusTransport *transport) #ifdef DBUS_AUTHENTICATION /* No messages without authentication! */ - if (!_dbus_transport_get_is_authenticated (transport)) + if (!_dbus_transport_try_to_authenticate (transport)) { _dbus_verbose ("Not authenticated, not writing anything\n"); return TRUE; @@ -2205,7 +2230,7 @@ do_reading (DBusTransport *transport) #ifdef DBUS_AUTHENTICATION /* No messages without authentication! */ - if (!_dbus_transport_get_is_authenticated (transport)) + if (!_dbus_transport_try_to_authenticate (transport)) return TRUE; #endif @@ -2510,7 +2535,7 @@ kdbus_do_iteration (DBusTransport *transport, poll_fd.fd = socket_transport->fd; poll_fd.events = 0; - if (_dbus_transport_peek_is_authenticated (transport)) + if (_dbus_transport_try_to_authenticate (transport)) { /* This is kind of a hack; if we have stuff to write, then try * to avoid the poll. This is probably about a 5% speedup on an diff --git a/dbus/dbus-transport.c b/dbus/dbus-transport.c index 5191e75..8957962 100644 --- a/dbus/dbus-transport.c +++ b/dbus/dbus-transport.c @@ -347,9 +347,9 @@ static const struct { DBusTransport **transport_p, DBusError *error); } open_funcs[] = { + { _dbus_transport_open_kdbus }, { _dbus_transport_open_socket }, { _dbus_transport_open_platform_specific }, - { _dbus_transport_open_kdbus }, { _dbus_transport_open_autolaunch } #ifdef DBUS_ENABLE_EMBEDDED_TESTS , { _dbus_transport_open_debug_pipe } diff --git a/packaging/com.samsung.dbus.spec b/packaging/com.samsung.dbus.spec index 273ca86..2c49403 100644 --- a/packaging/com.samsung.dbus.spec +++ b/packaging/com.samsung.dbus.spec @@ -32,7 +32,8 @@ else sed -i 's/\/\* #undef HAVE_ABSTRACT_SOCKETS \*\//#define HAVE_ABSTRACT_SOCKETS 1/' config.h fi -make %{?jobs:-j%jobs} +#make %{?jobs:-j%jobs} +make -j8 %install