[daemon-dev][lib-fix][lib-dev] ListQueuedOwners method in daemon, fixed strcpy issue...
authorRadoslaw Pajak <r.pajak@samsung.com>
Fri, 27 Sep 2013 09:16:33 +0000 (11:16 +0200)
committerRadoslaw Pajak <r.pajak@samsung.com>
Fri, 27 Sep 2013 09:16:33 +0000 (11:16 +0200)
- 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

autogen.sh
bus/kdbus-d.c
bus/kdbus-d.h
bus/services.c
dbus/dbus-connection-internal.h
dbus/dbus-connection.c
dbus/dbus-transport-kdbus.c
dbus/dbus-transport.c
packaging/com.samsung.dbus.spec

index e5d8342..a1e97f4 100755 (executable)
@@ -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
index 385d32f..b0466ee 100644 (file)
@@ -8,14 +8,15 @@
  *
  */
 
+#include <dbus/dbus-connection-internal.h>
 #include "kdbus-d.h"
 #include <dbus/kdbus.h>
-#include <dbus/dbus-connection-internal.h>
 #include <dbus/dbus-bus.h>
 #include "dispatch.h"
 #include <dbus/kdbus-common.h>
 #include <dbus/dbus-transport.h>
 #include <dbus/dbus-transport-kdbus.h>
+#include "connection.h"
 
 #include <utils.h>
 #include <stdlib.h>
@@ -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;
+}
index 57acfe0..bd69167 100644 (file)
@@ -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_ */
index 322ffcf..e88ca10 100644 (file)
@@ -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;
 }
 
index 2842f2f..56ce771 100644 (file)
@@ -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,
index 77b0a36..21d0db9 100644 (file)
@@ -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.
  *
index cf19608..a7b4477 100644 (file)
@@ -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
index 5191e75..8957962 100644 (file)
@@ -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 }
index 273ca86..2c49403 100644 (file)
@@ -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