}\
#define MSG_ITEM_BUILD_VEC(data, datasize) \
- item->type = KDBUS_MSG_PAYLOAD_VEC; \
- item->size = KDBUS_PART_HEADER_SIZE + sizeof(struct kdbus_vec); \
+ item->type = KDBUS_ITEM_PAYLOAD_VEC; \
+ item->size = KDBUS_ITEM_HEADER_SIZE + sizeof(struct kdbus_vec); \
item->vec.address = (unsigned long) data; \
item->vec.size = datasize;
}
/**
+ * Gets pointer to the memory pool, wher received messages are
+ * placed and some ioctls return their info
+ * @param transport transport
+ * @returns pointer to the pool
+ */
+void* dbus_transport_get_pool_pointer(DBusTransport* transport)
+{
+ return ((DBusTransportKdbus*)transport)->kdbus_mmap_ptr;
+}
+
+/**
* Puts locally generated message into received messages queue
* @param message message that will be added
* @param connection connection to which message will be added
if (name)
msg_size += KDBUS_ITEM_SIZE(strlen(name) + 1);
else if (dst_id == KDBUS_DST_ID_BROADCAST)
- msg_size += KDBUS_PART_HEADER_SIZE + transport->bloom_size;
+ msg_size += KDBUS_ITEM_HEADER_SIZE + transport->bloom_size;
msg = malloc(msg_size);
if (!msg)
memset(msg, 0, msg_size);
msg->size = msg_size;
- msg->payload_type = KDBUS_PAYLOAD_DBUS1;
+ msg->payload_type = KDBUS_PAYLOAD_DBUS;
msg->dst_id = name ? 0 : dst_id;
msg->src_id = strtoull(dbus_bus_get_unique_name(transport->base.connection), NULL , 10);
*/
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;
// determine destination and destination id
if(destination)
{
- dst_id = KDBUS_DST_ID_WELL_KNOWN_NAME;
+ 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;
}
}
// 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)
// 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;
}
if (buf == MAP_FAILED)
{
_dbus_verbose("mmap() fd=%i failed:%m", transport->memfd);
+ ret_size = -1;
goto out;
}
goto out;
}
- item->type = KDBUS_MSG_PAYLOAD_MEMFD;
- item->size = KDBUS_PART_HEADER_SIZE + sizeof(struct kdbus_memfd);
+ item->type = KDBUS_ITEM_PAYLOAD_MEMFD;
+ item->size = KDBUS_ITEM_HEADER_SIZE + sizeof(struct kdbus_memfd);
item->memfd.size = ret_size;
item->memfd.fd = transport->memfd;
}
if(fds_count)
{
item = KDBUS_PART_NEXT(item);
- item->type = KDBUS_MSG_FDS;
- item->size = KDBUS_PART_HEADER_SIZE + (sizeof(int) * fds_count);
+ item->type = KDBUS_ITEM_FDS;
+ item->size = KDBUS_ITEM_HEADER_SIZE + (sizeof(int) * fds_count);
memcpy(item->fds, unix_fds, sizeof(int) * fds_count);
}
if (destination)
{
item = KDBUS_PART_NEXT(item);
- item->type = KDBUS_MSG_DST_NAME;
- item->size = KDBUS_PART_HEADER_SIZE + strlen(destination) + 1;
- memcpy(item->str, destination, item->size - KDBUS_PART_HEADER_SIZE);
+ item->type = KDBUS_ITEM_DST_NAME;
+ item->size = KDBUS_ITEM_HEADER_SIZE + strlen(destination) + 1;
+ memcpy(item->str, destination, item->size - KDBUS_ITEM_HEADER_SIZE);
}
else if (dst_id == KDBUS_DST_ID_BROADCAST)
{
item = KDBUS_PART_NEXT(item);
- item->type = KDBUS_MSG_BLOOM;
- item->size = KDBUS_PART_HEADER_SIZE + transport->bloom_size;
+ item->type = KDBUS_ITEM_BLOOM;
+ item->size = KDBUS_ITEM_HEADER_SIZE + transport->bloom_size;
strncpy(item->data, dbus_message_get_interface(message), transport->bloom_size);
}
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);
static dbus_bool_t bus_register_kdbus(char* name, DBusTransportKdbus* transportS)
{
struct kdbus_cmd_hello __attribute__ ((__aligned__(8))) hello;
+ memset(&hello, 0, sizeof(hello));
hello.conn_flags = KDBUS_HELLO_ACCEPT_FD/* |
KDBUS_HELLO_ATTACH_COMM |
strcpy(name, ":1.");
if(!bus_register_kdbus(&name[3], (DBusTransportKdbus*)transport))
goto out;
+#ifdef POLICY_TO_KDBUS
if(!register_kdbus_policy(&name[3], transport, geteuid()))
goto out;
-
+#endif
((DBusTransportKdbus*)transport)->sender = name;
if(!reply_1_data(message, DBUS_TYPE_STRING, &name, transport->connection))
}
const char *enum_MSG(long long id);
TABLE(MSG) = {
- ENUM(_KDBUS_MSG_NULL),
- ENUM(KDBUS_MSG_PAYLOAD_VEC),
- ENUM(KDBUS_MSG_PAYLOAD_OFF),
- ENUM(KDBUS_MSG_PAYLOAD_MEMFD),
- ENUM(KDBUS_MSG_FDS),
- ENUM(KDBUS_MSG_BLOOM),
- ENUM(KDBUS_MSG_DST_NAME),
- ENUM(KDBUS_MSG_SRC_CREDS),
- ENUM(KDBUS_MSG_SRC_PID_COMM),
- ENUM(KDBUS_MSG_SRC_TID_COMM),
- ENUM(KDBUS_MSG_SRC_EXE),
- ENUM(KDBUS_MSG_SRC_CMDLINE),
- ENUM(KDBUS_MSG_SRC_CGROUP),
- ENUM(KDBUS_MSG_SRC_CAPS),
- ENUM(KDBUS_MSG_SRC_SECLABEL),
- ENUM(KDBUS_MSG_SRC_AUDIT),
- ENUM(KDBUS_MSG_SRC_NAMES),
- ENUM(KDBUS_MSG_TIMESTAMP),
- ENUM(KDBUS_MSG_NAME_ADD),
- ENUM(KDBUS_MSG_NAME_REMOVE),
- ENUM(KDBUS_MSG_NAME_CHANGE),
- ENUM(KDBUS_MSG_ID_ADD),
- ENUM(KDBUS_MSG_ID_REMOVE),
- ENUM(KDBUS_MSG_REPLY_TIMEOUT),
- ENUM(KDBUS_MSG_REPLY_DEAD),
+ ENUM(_KDBUS_ITEM_NULL),
+ ENUM(KDBUS_ITEM_PAYLOAD_VEC),
+ ENUM(KDBUS_ITEM_PAYLOAD_OFF),
+ ENUM(KDBUS_ITEM_PAYLOAD_MEMFD),
+ ENUM(KDBUS_ITEM_FDS),
+ ENUM(KDBUS_ITEM_BLOOM),
+ ENUM(KDBUS_ITEM_DST_NAME),
+ ENUM(KDBUS_ITEM_CREDS),
+ ENUM(KDBUS_ITEM_PID_COMM),
+ ENUM(KDBUS_ITEM_TID_COMM),
+ ENUM(KDBUS_ITEM_EXE),
+ ENUM(KDBUS_ITEM_CMDLINE),
+ ENUM(KDBUS_ITEM_CGROUP),
+ ENUM(KDBUS_ITEM_CAPS),
+ ENUM(KDBUS_ITEM_SECLABEL),
+ ENUM(KDBUS_ITEM_AUDIT),
+ ENUM(KDBUS_ITEM_NAME),
+ ENUM(KDBUS_ITEM_TIMESTAMP),
+ ENUM(KDBUS_ITEM_NAME_ADD),
+ ENUM(KDBUS_ITEM_NAME_REMOVE),
+ ENUM(KDBUS_ITEM_NAME_CHANGE),
+ ENUM(KDBUS_ITEM_ID_ADD),
+ ENUM(KDBUS_ITEM_ID_REMOVE),
+ ENUM(KDBUS_ITEM_REPLY_TIMEOUT),
+ ENUM(KDBUS_ITEM_REPLY_DEAD),
};
LOOKUP(MSG);
const char *enum_PAYLOAD(long long id);
TABLE(PAYLOAD) = {
ENUM(KDBUS_PAYLOAD_KERNEL),
- ENUM(KDBUS_PAYLOAD_DBUS1),
- ENUM(KDBUS_PAYLOAD_GVARIANT),
+ ENUM(KDBUS_PAYLOAD_DBUS),
};
LOOKUP(PAYLOAD);
KDBUS_PART_FOREACH(item, msg, items)
{
- if (item->size <= KDBUS_PART_HEADER_SIZE)
+ if (item->size < KDBUS_ITEM_HEADER_SIZE)
{
_dbus_verbose(" +%s (%llu bytes) invalid data record\n", enum_MSG(item->type), item->size);
return -1;
}
switch (item->type)
{
- case KDBUS_MSG_PAYLOAD_OFF:
+ case KDBUS_ITEM_PAYLOAD_OFF:
ret_size += item->vec.size;
break;
- case KDBUS_MSG_PAYLOAD_MEMFD:
+ case KDBUS_ITEM_PAYLOAD_MEMFD:
ret_size += item->memfd.size;
break;
default:
DBusMessage *message = NULL;
DBusMessageIter args;
const char* emptyString = "";
- const char* pString = NULL;
- char dbus_name[(unsigned int)(snprintf((char*)pString, 0, ":1.%llu0", ULLONG_MAX))];
+ const char* pString = NULL;
+ char dbus_name[128];
const char* pDBusName = dbus_name;
#if KDBUS_MSG_DECODE_DEBUG == 1
char buf[32];
KDBUS_PART_FOREACH(item, msg, items)
{
- if (item->size <= KDBUS_PART_HEADER_SIZE)
+ 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)
{
- case KDBUS_MSG_PAYLOAD_OFF:
+ case KDBUS_ITEM_PAYLOAD_OFF:
memcpy(data, (char *)kdbus_transport->kdbus_mmap_ptr + item->vec.offset, item->vec.size);
data += item->vec.size;
ret_size += item->vec.size;
(unsigned long long)item->vec.size);
break;
- case KDBUS_MSG_PAYLOAD_MEMFD:
+ case KDBUS_ITEM_PAYLOAD_MEMFD:
{
char *buf;
uint64_t size;
break;
}
- case KDBUS_MSG_FDS:
+ case KDBUS_ITEM_FDS:
{
int i;
- *n_fds = (item->size - KDBUS_PART_HEADER_SIZE) / sizeof(int);
+ *n_fds = (item->size - KDBUS_ITEM_HEADER_SIZE) / sizeof(int);
memcpy(fds, item->fds, *n_fds * sizeof(int));
for (i = 0; i < *n_fds; i++)
_dbus_fd_set_close_on_exec(fds[i]);
}
#if KDBUS_MSG_DECODE_DEBUG == 1
- case KDBUS_MSG_SRC_CREDS:
+ case KDBUS_ITEM_CREDS:
_dbus_verbose(" +%s (%llu bytes) uid=%lld, gid=%lld, pid=%lld, tid=%lld, starttime=%lld\n",
enum_MSG(item->type), item->size,
item->creds.uid, item->creds.gid,
item->creds.starttime);
break;
- case KDBUS_MSG_SRC_PID_COMM:
- case KDBUS_MSG_SRC_TID_COMM:
- case KDBUS_MSG_SRC_EXE:
- case KDBUS_MSG_SRC_CGROUP:
- case KDBUS_MSG_SRC_SECLABEL:
- case KDBUS_MSG_DST_NAME:
+ case KDBUS_ITEM_PID_COMM:
+ case KDBUS_ITEM_TID_COMM:
+ case KDBUS_ITEM_EXE:
+ case KDBUS_ITEM_CGROUP:
+ case KDBUS_ITEM_SECLABEL:
+ case KDBUS_ITEM_DST_NAME:
_dbus_verbose(" +%s (%llu bytes) '%s' (%zu)\n",
enum_MSG(item->type), item->size, item->str, strlen(item->str));
break;
- case KDBUS_MSG_SRC_CMDLINE:
- case KDBUS_MSG_SRC_NAMES: {
- __u64 size = item->size - KDBUS_PART_HEADER_SIZE;
+ case KDBUS_ITEM_CMDLINE:
+ case KDBUS_ITEM_NAME: {
+ __u64 size = item->size - KDBUS_ITEM_HEADER_SIZE;
const char *str = item->str;
int count = 0;
break;
}
- case KDBUS_MSG_SRC_AUDIT:
+ case KDBUS_ITEM_AUDIT:
_dbus_verbose(" +%s (%llu bytes) loginuid=%llu sessionid=%llu\n",
enum_MSG(item->type), item->size,
(unsigned long long)item->data64[0],
(unsigned long long)item->data64[1]);
break;
- case KDBUS_MSG_SRC_CAPS: {
+ case KDBUS_ITEM_CAPS: {
int n;
const uint32_t *cap;
int i;
_dbus_verbose(" +%s (%llu bytes) len=%llu bytes)\n",
enum_MSG(item->type), item->size,
- (unsigned long long)item->size - KDBUS_PART_HEADER_SIZE);
+ (unsigned long long)item->size - KDBUS_ITEM_HEADER_SIZE);
cap = item->data32;
- n = (item->size - KDBUS_PART_HEADER_SIZE) / 4 / sizeof(uint32_t);
+ n = (item->size - KDBUS_ITEM_HEADER_SIZE) / 4 / sizeof(uint32_t);
_dbus_verbose(" CapInh=");
for (i = 0; i < n; i++)
break;
}
- case KDBUS_MSG_TIMESTAMP:
+ case KDBUS_ITEM_TIMESTAMP:
_dbus_verbose(" +%s (%llu bytes) realtime=%lluns monotonic=%lluns\n",
enum_MSG(item->type), item->size,
(unsigned long long)item->timestamp.realtime_ns,
break;
#endif
- case KDBUS_MSG_REPLY_TIMEOUT:
+ case KDBUS_ITEM_REPLY_TIMEOUT:
_dbus_verbose(" +%s (%llu bytes) cookie=%llu\n",
enum_MSG(item->type), item->size, msg->cookie_reply);
ret_size = put_message_into_data(message, data);
break;
- case KDBUS_MSG_REPLY_DEAD:
+ case KDBUS_ITEM_REPLY_DEAD:
_dbus_verbose(" +%s (%llu bytes) cookie=%llu\n",
enum_MSG(item->type), item->size, msg->cookie_reply);
ret_size = put_message_into_data(message, data);
break;
- case KDBUS_MSG_NAME_ADD:
- _dbus_verbose(" +%s (%llu bytes) '%s', old id=%lld, new id=%lld, flags=0x%llx\n",
+ case KDBUS_ITEM_NAME_ADD:
+ _dbus_verbose(" +%s (%llu bytes) '%s', old id=%lld, new id=%lld, old flags=0x%llx, new flags=0x%llx\n",
enum_MSG(item->type), (unsigned long long) item->size,
item->name_change.name, item->name_change.old_id,
- item->name_change.new_id, item->name_change.flags);
+ item->name_change.new_id, item->name_change.old_flags,
+ item->name_change.new_flags);
message = dbus_message_new_signal(DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, "NameOwnerChanged");
if(message == NULL)
ret_size = put_message_into_data(message, data);
break;
- case KDBUS_MSG_NAME_REMOVE:
- _dbus_verbose(" +%s (%llu bytes) '%s', old id=%lld, new id=%lld, flags=0x%llx\n",
+ case KDBUS_ITEM_NAME_REMOVE:
+ _dbus_verbose(" +%s (%llu bytes) '%s', old id=%lld, new id=%lld, old flags=0x%llx, new flags=0x%llx\n",
enum_MSG(item->type), (unsigned long long) item->size,
item->name_change.name, item->name_change.old_id,
- item->name_change.new_id, item->name_change.flags);
+ item->name_change.new_id, item->name_change.old_flags,
+ item->name_change.new_flags);
message = dbus_message_new_signal(DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, "NameOwnerChanged"); // name of the signal
if(message == NULL)
ret_size = put_message_into_data(message, data);
break;
- case KDBUS_MSG_NAME_CHANGE:
- _dbus_verbose(" +%s (%llu bytes) '%s', old id=%lld, new id=%lld, flags=0x%llx\n",
+ case KDBUS_ITEM_NAME_CHANGE:
+ _dbus_verbose(" +%s (%llu bytes) '%s', old id=%lld, new id=%lld, old flags=0x%llx, new flags=0x%llx\n",
enum_MSG(item->type), (unsigned long long) item->size,
item->name_change.name, item->name_change.old_id,
- item->name_change.new_id, item->name_change.flags);
+ item->name_change.new_id, item->name_change.old_flags,
+ item->name_change.new_flags);
message = dbus_message_new_signal(DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, "NameOwnerChanged");
if(message == NULL)
ret_size = put_message_into_data(message, data);
break;
- case KDBUS_MSG_ID_ADD:
+ case KDBUS_ITEM_ID_ADD:
_dbus_verbose(" +%s (%llu bytes) id=%llu flags=%llu\n",
enum_MSG(item->type), (unsigned long long) item->size,
(unsigned long long) item->id_change.id,
ret_size = put_message_into_data(message, data);
break;
- case KDBUS_MSG_ID_REMOVE:
+ case KDBUS_ITEM_ID_REMOVE:
_dbus_verbose(" +%s (%llu bytes) id=%llu flags=%llu\n",
enum_MSG(item->type), (unsigned long long) item->size,
(unsigned long long) item->id_change.id,
}
again2:
- if (ioctl(kdbus_transport->fd, KDBUS_CMD_MSG_RELEASE, &offset) < 0)
+ if (ioctl(kdbus_transport->fd, KDBUS_CMD_FREE, &offset) < 0)
{
if(errno == EINTR)
goto again2;
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,