[lib-fix] Fixed return value of kdbus_write_msg
[platform/upstream/dbus.git] / dbus / dbus-transport-kdbus.c
index 72e3d56..67c85f3 100644 (file)
@@ -337,7 +337,7 @@ static struct kdbus_msg* kdbus_init_msg(const char* name, __u64 dst_id, uint64_t
  */
 static int kdbus_write_msg(DBusTransportKdbus *transport, DBusMessage *message, const char* destination)
 {
-  struct kdbus_msg *msg;
+  struct kdbus_msg *msg = NULL;
   struct kdbus_item *item;
   uint64_t dst_id = KDBUS_DST_ID_BROADCAST;
   const DBusString *header;
@@ -356,7 +356,14 @@ static int kdbus_write_msg(DBusTransportKdbus *transport, DBusMessage *message,
       dst_id = KDBUS_DST_ID_NAME;
       if((destination[0] == ':') && (destination[1] == '1') && (destination[2] == '.'))  /* if name starts with ":1." it is a unique name and should be send as number */
         {
+          errno = 0;
           dst_id = strtoull(&destination[3], NULL, 10);
+          if(errno)
+          {
+            _dbus_verbose("error: unique name is not a number: %s (%m)\n", destination);
+            ret_size = -1;
+            goto out;
+          }
           destination = NULL;
         }
     }
@@ -369,14 +376,22 @@ static int kdbus_write_msg(DBusTransportKdbus *transport, DBusMessage *message,
   // check whether we can and should use memfd
   if((dst_id != KDBUS_DST_ID_BROADCAST) && (ret_size > MEMFD_SIZE_THRESHOLD))
     {
-      use_memfd = TRUE;
-      kdbus_init_memfd(transport);
+      if(kdbus_init_memfd(transport) == 0)
+        {
+          use_memfd = TRUE;
+        }
     }
 
   _dbus_message_get_unix_fds(message, &unix_fds, &fds_count);
 
   // init basic message fields
   msg = kdbus_init_msg(destination, dst_id, body_size, use_memfd, fds_count, transport);
+  if(msg == NULL)
+    {
+      _dbus_verbose("Can't alloc memory for new message\n");
+      ret_size = -1;
+      goto out;
+    }
   msg->cookie = dbus_message_get_serial(message);
   autostart = dbus_message_get_auto_start (message);
   if(!autostart)
@@ -385,13 +400,14 @@ static int kdbus_write_msg(DBusTransportKdbus *transport, DBusMessage *message,
   // build message contents
   item = msg->items;
 
-  if(use_memfd)
+  if(use_memfd == TRUE)
     {
       char *buf;
 
       if(ioctl(transport->memfd, KDBUS_CMD_MEMFD_SEAL_SET, 0) < 0)
         {
           _dbus_verbose("memfd sealing failed: \n");
+          ret_size = -1;
           goto out;
         }
 
@@ -399,6 +415,7 @@ static int kdbus_write_msg(DBusTransportKdbus *transport, DBusMessage *message,
       if (buf == MAP_FAILED)
         {
           _dbus_verbose("mmap() fd=%i failed:%m", transport->memfd);
+          ret_size = -1;
           goto out;
         }
 
@@ -480,25 +497,30 @@ static int kdbus_write_msg(DBusTransportKdbus *transport, DBusMessage *message,
         goto again;
       else if(errno == ENXIO) //no such id on the bus
         {
+          ret_size = 0;
           if(!reply_with_error(DBUS_ERROR_NAME_HAS_NO_OWNER, "Name \"%s\" does not exist", dbus_message_get_destination(message), message, transport->base.connection))
-            goto out;
+              goto out;
+
         }
       else if((errno == ESRCH) || (errno = EADDRNOTAVAIL))  //when well known name is not available on the bus
         {
+          ret_size = 0;
           if(autostart)
             {
               if(!reply_with_error(DBUS_ERROR_SERVICE_UNKNOWN, "The name %s was not provided by any .service files", dbus_message_get_destination(message), message, transport->base.connection))
-                goto out;
+                  goto out;
             }
           else
             if(!reply_with_error(DBUS_ERROR_NAME_HAS_NO_OWNER, "Name \"%s\" does not exist", dbus_message_get_destination(message), message, transport->base.connection))
-              goto out;
+                goto out;
         }
+      else
+        ret_size = -1;
       _dbus_verbose("kdbus error sending message: err %d (%m)\n", errno);
-      ret_size = -1;
     }
   out:
-  free(msg);
+  if(msg)
+    free(msg);
   if(use_memfd)
     close(transport->memfd);
 
@@ -744,7 +766,7 @@ static int kdbus_decode_msg(const struct kdbus_msg* msg, char *data, DBusTranspo
        DBusMessageIter args;
        const char* emptyString = "";
        const char* pString = NULL;
-       char dbus_name[(unsigned int)(snprintf((char*)pString, 0, ":1.%llu0", ULLONG_MAX))];
+       char dbus_name[128];
        const char* pDBusName = dbus_name;
 #if KDBUS_MSG_DECODE_DEBUG == 1
        char buf[32];
@@ -765,7 +787,8 @@ static int kdbus_decode_msg(const struct kdbus_msg* msg, char *data, DBusTranspo
                if (item->size < KDBUS_ITEM_HEADER_SIZE)
                {
                        _dbus_verbose("  +%s (%llu bytes) invalid data record\n", enum_MSG(item->type), item->size);
-                       break;  //??? continue (because dbus will find error) or break
+                       ret_size = -1;
+                       break;
                }
 
                switch (item->type)
@@ -1371,6 +1394,12 @@ do_writing (DBusTransport *transport)
               goto out;
             }
         }
+      else if (bytes_written == 0)
+        {
+           _dbus_verbose ("Destination is not available\n");
+           _dbus_connection_message_sent_unlocked (transport->connection,
+                   message);
+        }
       else
         {
           _dbus_verbose (" wrote %d bytes of %d\n", bytes_written,