1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2 /* kdbus-common.c kdbus related utils for daemon and libdbus
4 * Copyright (C) 2013 Samsung Electronics
6 * Licensed under the Academic Free License version 2.1
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version and under the terms of the GNU
12 * Lesser General Public License as published by the
13 * Free Software Foundation; either version 2.1 of the License, or (at
14 * your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
27 #include <linux/kdbus.h>
28 #include "kdbus-common.h"
29 #include "dbus-transport-kdbus.h"
30 #include "dbus-valgrind-internal.h"
36 #include <dbus/dbus-internals.h>
37 #include <dbus/dbus-shared.h>
38 #include "dbus-signals.h"
40 #include <sys/ioctl.h>
41 #include <sys/types.h>
48 int fd; /**< File descriptor */
49 void *mmap_ptr; /**< Mapped memory where kdbus (kernel) writes
50 * messages incoming to us.
52 size_t pool_size; /**< Size of mapped memory */
53 __u64 id; /**< unique id of the connection */
54 char bus_id[sizeof (((struct kdbus_cmd_hello *)(0))->id128)]; /**< id of the bus */
55 struct kdbus_bloom_parameter bloom; /**< bloom parameters*/
58 /* ALIGN8 and KDBUS_FOREACH taken from systemd */
59 #define ALIGN8(l) (((l) + 7) & ~7)
60 #define KDBUS_FOREACH(iter, first, _size) \
61 for (iter = (first); \
62 ((uint8_t *)(iter) < (uint8_t *)(first) + (_size)) && \
63 ((uint8_t *)(iter) >= (uint8_t *)(first)); \
64 iter = (void*)(((uint8_t *)iter) + ALIGN8((iter)->size)))
68 unsigned long request,
74 ret = ioctl (fd, request, data);
76 while (-1 == ret && EINTR == errno);
82 free_by_offset (kdbus_t *kdbus,
85 struct kdbus_cmd_free cmd;
88 * Kdbus requires to initialize ioctl params partially. Some parts
89 * are for data passed from user to kernel, and other parts
90 * for data passed from kernel to user.
92 * Valgrind detects when uninitialized data is passed to kernel
93 * and has no way to know that it is meant to be filled by kernel.
94 * Thus, we initialize params for Valgrind to stop complaining.
96 VALGRIND_MAKE_MEM_DEFINED (&cmd, sizeof (cmd));
98 cmd.size = sizeof (cmd);
102 if (safe_ioctl (kdbus->fd, KDBUS_CMD_FREE, &cmd )!= 0)
108 static void make_item_name (const char *name, struct kdbus_item *item)
110 size_t len = strlen (name) + 1;
111 item->size = KDBUS_ITEM_HEADER_SIZE + len;
112 item->type = KDBUS_ITEM_NAME;
114 memcpy (item->str, name, len);
118 * Adds an item in the current position of items array.
120 * @param item item to fill
121 * @param item_type type of the item
122 * @param string value of the item
123 * @param string_size size of the value
124 * @returns pointer to the next item
127 _kdbus_item_add_string (struct kdbus_item *item,
129 const char *item_string,
130 __u64 item_string_size)
132 item->size = KDBUS_ITEM_HEADER_SIZE + item_string_size;
133 item->type = item_type;
134 memcpy (item->str, item_string, item_string_size);
135 return KDBUS_ITEM_NEXT (item);
139 _kdbus_item_add_payload_memfd (struct kdbus_item *item,
144 item->type = KDBUS_ITEM_PAYLOAD_MEMFD;
145 item->size = KDBUS_ITEM_HEADER_SIZE + sizeof (struct kdbus_memfd);
146 item->memfd.start = start;
147 item->memfd.size = size;
149 return KDBUS_ITEM_NEXT (item);
153 _kdbus_item_add_payload_vec (struct kdbus_item *item,
155 __u64 address_or_offset)
157 item->type = KDBUS_ITEM_PAYLOAD_VEC;
158 item->size = KDBUS_ITEM_HEADER_SIZE + sizeof (struct kdbus_vec);
159 item->vec.size = size;
160 item->vec.address = address_or_offset;
161 return KDBUS_ITEM_NEXT (item);
165 _kdbus_item_add_fds (struct kdbus_item *item,
169 item->type = KDBUS_ITEM_FDS;
170 item->size = KDBUS_ITEM_HEADER_SIZE + (__u64)fds_count * sizeof (int);
171 memcpy (item->fds, fds, fds_count * sizeof (int));
172 return KDBUS_ITEM_NEXT (item);
176 _kdbus_item_add_bloom_filter (struct kdbus_item *item,
178 struct kdbus_bloom_filter **out_ptr)
180 item->type = KDBUS_ITEM_BLOOM_FILTER;
181 item->size = KDBUS_ITEM_HEADER_SIZE
182 + sizeof (struct kdbus_bloom_filter)
184 memset (item->bloom_filter.data, 0, kdbus->bloom.size);
185 item->bloom_filter.generation = 0;
186 *out_ptr = &item->bloom_filter;
187 return KDBUS_ITEM_NEXT (item);
191 _kdbus_bloom_filter_get_data (struct kdbus_bloom_filter *bloom_filter)
193 return bloom_filter->data;
197 _kdbus_item_add_name_change (struct kdbus_item *item,
203 item->size = KDBUS_ITEM_HEADER_SIZE + sizeof (struct kdbus_notify_name_change);
204 item->type = KDBUS_ITEM_NAME_CHANGE;
205 item->name_change.old_id.id = old_id;
206 item->name_change.old_id.flags = old_id_flags;
207 item->name_change.new_id.id = new_id;
208 item->name_change.new_id.flags = new_id_flags;
209 return KDBUS_ITEM_NEXT (item);
213 _kdbus_item_add_id_add (struct kdbus_item *item,
217 item->size = KDBUS_ITEM_HEADER_SIZE + sizeof (struct kdbus_notify_id_change);
218 item->type = KDBUS_ITEM_ID_ADD;
219 item->id_change.id = id;
220 item->id_change.flags = id_flags;
221 return KDBUS_ITEM_NEXT (item);
225 _kdbus_item_add_id (struct kdbus_item *item,
228 item->size = KDBUS_ITEM_HEADER_SIZE + sizeof (id);
229 item->type = KDBUS_ITEM_ID;
231 return KDBUS_ITEM_NEXT (item);
235 _kdbus_item_add_bloom_mask (struct kdbus_item *item,
237 kdbus_bloom_data_t **bloom)
239 item->size = KDBUS_ITEM_HEADER_SIZE + kdbus->bloom.size;
240 item->type = KDBUS_ITEM_BLOOM_MASK;
241 memset (item->data64, 0, kdbus->bloom.size);
243 *bloom = item->data64;
244 return KDBUS_ITEM_NEXT (item);
248 get_from_offset (kdbus_t *kdbus,
251 return ((char *)kdbus->mmap_ptr) + offset;
257 return dbus_new (kdbus_t, 1);
261 _kdbus_free (kdbus_t *kdbus)
267 * Opens a connection to the kdbus bus
269 * @param kdbus kdbus object
270 * @param path the path to kdbus bus
271 * @returns 0 on success, -errno on failure
274 _kdbus_open (kdbus_t *kdbus, const char *path)
276 int fd = open (path, O_RDWR|O_CLOEXEC|O_NONBLOCK);
285 _kdbus_close (kdbus_t *kdbus)
293 ret = close (kdbus->fd);
294 } while (-1 == ret && EINTR == errno);
298 ret = munmap (kdbus->mmap_ptr, kdbus->pool_size);
310 _kdbus_get_fd (kdbus_t *kdbus)
316 _kdbus_get_id (kdbus_t *kdbus)
322 _kdbus_get_bus_id (kdbus_t *kdbus)
324 return kdbus->bus_id;
328 _kdbus_get_bus_id_size (void)
330 return sizeof (((struct kdbus_t *)(0))->bus_id);
334 _kdbus_hello (kdbus_t *kdbus,
336 __u64 attach_flags_send,
337 __u64 attach_flags_recv,
339 const char *activator_name,
340 const char *connection_name)
342 struct kdbus_cmd_hello *hello;
343 struct kdbus_item *item, *items;
345 size_t activator_name_size = 0;
346 size_t connection_name_size = 0;
350 hello_size = sizeof (struct kdbus_cmd_hello);
352 if (NULL != activator_name)
354 activator_name_size = strlen (activator_name) + 1;
355 hello_size += KDBUS_ITEM_SIZE (activator_name_size);
358 if (NULL != connection_name)
360 connection_name_size = strlen (connection_name) + 1;
361 hello_size += KDBUS_ITEM_SIZE (connection_name_size);
364 hello = dbus_malloc (hello_size);
368 VALGRIND_MAKE_MEM_DEFINED (hello, hello_size);
370 hello->flags = flags;
371 hello->attach_flags_send = attach_flags_send;
372 hello->attach_flags_recv = attach_flags_recv;
373 hello->pool_size = pool_size;
376 if (connection_name_size > 0)
377 item = _kdbus_item_add_string (item,
378 KDBUS_ITEM_CONN_DESCRIPTION,
380 connection_name_size);
381 if (activator_name_size > 0)
383 _kdbus_item_add_string (item,
386 activator_name_size);
387 hello->flags |= KDBUS_HELLO_ACTIVATOR;
390 hello->size = hello_size;
392 if (safe_ioctl (kdbus->fd, KDBUS_CMD_HELLO, hello) != 0)
398 kdbus->id = hello->id;
399 memcpy (kdbus->bus_id, hello->id128, sizeof (kdbus->bus_id));
401 offset = hello->offset;
402 items_size = hello->items_size;
405 kdbus->mmap_ptr = mmap (NULL, pool_size, PROT_READ, MAP_SHARED, kdbus->fd, 0);
406 if (MAP_FAILED == kdbus->mmap_ptr)
409 kdbus->pool_size = pool_size;
411 items = get_from_offset (kdbus, offset);
412 KDBUS_FOREACH (item, items, items_size)
414 if (KDBUS_ITEM_BLOOM_PARAMETER == item->type)
415 kdbus->bloom = item->bloom_parameter;
418 free_by_offset (kdbus, offset);
424 _kdbus_send (kdbus_t *kdbus,
426 struct kdbus_msg *msg,
427 struct kdbus_msg **msg_reply)
429 struct kdbus_cmd_send cmd;
431 VALGRIND_MAKE_MEM_DEFINED (&cmd, sizeof (cmd));
433 cmd.size = sizeof (cmd);
434 cmd.msg_address = (uintptr_t)msg;
437 if (-1 == safe_ioctl (kdbus->fd, KDBUS_CMD_SEND, &cmd))
440 if (flags & KDBUS_SEND_SYNC_REPLY)
442 if (NULL != msg_reply)
443 *msg_reply = get_from_offset (kdbus, cmd.reply.offset);
445 free_by_offset (kdbus, cmd.reply.offset);
452 _kdbus_recv (kdbus_t *kdbus,
455 struct kdbus_msg **msg)
457 struct kdbus_cmd_recv cmd;
459 VALGRIND_MAKE_MEM_DEFINED (&cmd, sizeof (cmd));
461 cmd.size = sizeof (cmd);
463 cmd.priority = priority;
465 if (-1 == safe_ioctl (kdbus->fd, KDBUS_CMD_RECV, &cmd))
468 *msg = get_from_offset (kdbus, cmd.msg.offset);
474 * Provides list of names on the bus.
476 * @param kdbus kdbus object
477 * @param flags specification of required names. See enum kdbus_list_flags in kdbus.h.
478 * @param name_list data from kdbus response - the list
479 * @param list_size size of name_list in bytes
480 * @return 0 on success, errno on failure
482 * Note that name_list is allocated in kdbus pool and must be freed by _kdbus_free_mem.
485 _kdbus_list (kdbus_t *kdbus,
487 struct kdbus_info **name_list,
490 struct kdbus_cmd_list cmd;
492 VALGRIND_MAKE_MEM_DEFINED (&cmd, sizeof (cmd));
494 cmd.size = sizeof (cmd);
497 if (-1 == safe_ioctl (kdbus->fd, KDBUS_CMD_LIST, &cmd))
500 *name_list = get_from_offset (kdbus, cmd.offset);
501 *list_size = cmd.list_size;
507 _kdbus_compute_match_items_size (kdbus_t *kdbus,
508 dbus_bool_t with_bloom_mask,
510 const char *sender_name)
515 size += KDBUS_ITEM_SIZE (kdbus->bloom.size);
517 if (KDBUS_MATCH_ID_ANY != sender_id) /* unique name present */
518 size += KDBUS_ITEM_SIZE (sizeof (sender_id));
519 else if (NULL != sender_name)
520 size += KDBUS_ITEM_SIZE (strlen (sender_name) + 1);
525 struct kdbus_cmd_match *
526 _kdbus_new_cmd_match (kdbus_t *kdbus,
531 struct kdbus_cmd_match *cmd;
532 __u64 cmd_size = sizeof (*cmd) + items_size;
533 cmd = dbus_malloc (cmd_size);
537 VALGRIND_MAKE_MEM_DEFINED (cmd, cmd_size);
539 cmd->size = cmd_size;
541 cmd->cookie = cookie;
547 _kdbus_free_cmd_match (struct kdbus_cmd_match *cmd)
553 _kdbus_add_match_name_acquired (kdbus_t *kdbus,
562 struct kdbus_cmd_match *cmd;
563 struct kdbus_item *item;
565 unsigned int len = 0;
568 len = strlen(name) + 1;
569 cmd = _kdbus_new_cmd_match (kdbus,
570 KDBUS_ITEM_SIZE (sizeof (struct kdbus_notify_name_change) + len),
577 _kdbus_item_add_name_change (item,
578 old_id, old_id_flags,
579 new_id, new_id_flags);
582 memcpy(item->name_change.name, name, len);
584 ret = safe_ioctl (kdbus->fd, KDBUS_CMD_MATCH_ADD, cmd);
586 goto err_name_acquired;
588 item->type = KDBUS_ITEM_NAME_ADD;
589 ret = safe_ioctl (kdbus->fd, KDBUS_CMD_MATCH_ADD, cmd);
591 goto err_name_acquired;
596 _kdbus_free_cmd_match (cmd);
601 _kdbus_add_match_name_lost (kdbus_t *kdbus,
610 struct kdbus_cmd_match *cmd;
611 struct kdbus_item *item;
613 unsigned int len = 0;
616 len = strlen(name) + 1;
618 cmd = _kdbus_new_cmd_match (kdbus,
619 KDBUS_ITEM_SIZE (sizeof (struct kdbus_notify_name_change) + len),
626 _kdbus_item_add_name_change (item,
627 old_id, old_id_flags,
628 new_id, new_id_flags);
632 memcpy(item->name_change.name, name, len);
634 ret = safe_ioctl (kdbus->fd, KDBUS_CMD_MATCH_ADD, cmd);
636 goto err_name_remove;
638 item->type = KDBUS_ITEM_NAME_REMOVE;
639 ret = safe_ioctl (kdbus->fd, KDBUS_CMD_MATCH_ADD, cmd);
641 goto err_name_remove;
646 _kdbus_free_cmd_match (cmd);
651 _kdbus_add_match_name_change (kdbus_t *kdbus,
660 struct kdbus_cmd_match *cmd;
661 struct kdbus_item *item;
663 unsigned int len = 0;
666 len = strlen(name) + 1;
668 /* name = NULL or Well-known Name */
669 if (name == NULL || (name[0] != ':')) {
670 cmd = _kdbus_new_cmd_match (kdbus,
671 KDBUS_ITEM_SIZE (sizeof (struct kdbus_notify_name_change) + len),
678 _kdbus_item_add_name_change (item,
679 old_id, old_id_flags,
680 new_id, new_id_flags);
684 memcpy(item->name_change.name, name, len);
686 ret = safe_ioctl (kdbus->fd, KDBUS_CMD_MATCH_ADD, cmd);
689 item->type = KDBUS_ITEM_NAME_ADD;
690 ret = safe_ioctl (kdbus->fd, KDBUS_CMD_MATCH_ADD, cmd);
693 item->type = KDBUS_ITEM_NAME_REMOVE;
694 ret = safe_ioctl (kdbus->fd, KDBUS_CMD_MATCH_ADD, cmd);
701 _kdbus_free_cmd_match (cmd);
709 _kdbus_add_match_id_change (kdbus_t *kdbus,
716 struct kdbus_cmd_match *cmd;
717 struct kdbus_item *item;
720 /* name = NULL or Unique Name */
721 if (name == NULL || name[0] == ':')
723 cmd = _kdbus_new_cmd_match (kdbus,
724 KDBUS_ITEM_SIZE (sizeof (struct kdbus_notify_id_change)),
731 _kdbus_item_add_id_add (item, id, id_flags);
734 item->id_change.id = strtoull (name + 3, NULL, 10);
736 ret = safe_ioctl (kdbus->fd, KDBUS_CMD_MATCH_ADD, cmd);
739 item->type = KDBUS_ITEM_ID_REMOVE;
740 ret = safe_ioctl (kdbus->fd, KDBUS_CMD_MATCH_ADD, cmd);
746 _kdbus_free_cmd_match (cmd);
752 int _kdbus_add_match (kdbus_t *kdbus,
753 struct kdbus_cmd_match *cmd)
755 int ret = safe_ioctl (kdbus->fd, KDBUS_CMD_MATCH_ADD, cmd);
763 * Allocates and initializes kdbus message structure.
764 * @param kdbus kdbus object
765 * @param size_for_items size of items that will be attached to this message
766 * @param flags flags for message
767 * @returns initialized kdbus message or NULL if malloc failed
770 _kdbus_new_msg (kdbus_t *kdbus,
771 __u64 size_for_items,
776 enum kdbus_payload_type payload_type,
778 __u64 timeout_ns_or_cookie_reply)
780 struct kdbus_msg *msg;
781 __u64 msg_size = sizeof (struct kdbus_msg) + size_for_items;
783 msg = dbus_malloc (msg_size);
787 msg->size = msg_size;
789 msg->priority = priority;
790 msg->dst_id = dst_id;
791 msg->src_id = src_id;
792 msg->payload_type = payload_type;
793 msg->cookie = cookie;
794 msg->timeout_ns = timeout_ns_or_cookie_reply;
800 _kdbus_free_msg (struct kdbus_msg *msg)
806 _kdbus_free_mem (kdbus_t *kdbus, void *mem)
808 char *base_ptr = kdbus->mmap_ptr;
809 char *mem_ptr = (char *)mem;
811 return free_by_offset (kdbus, mem_ptr - base_ptr);
815 * Computes size of items that will be attached to a message.
817 * @param kdbus kdbus object
818 * @param destination Well-known name or NULL. If NULL, dst_id must be supplied.
819 * @param dst_id Numeric id of recipient. Ignored if name is not NULL.
820 * @param body_size Size of message body (may be 0).
821 * @param use_memfd Flag to build memfd message.
822 * @param fds_count Number of file descriptors sent in the message.
823 * @returns size in bytes needed for the message object
826 _kdbus_compute_msg_items_size (kdbus_t *kdbus,
827 const char *destination,
830 dbus_bool_t use_memfd,
833 __u64 items_size = 0;
836 items_size += KDBUS_ITEM_SIZE (sizeof (struct kdbus_vec));
841 items_size += KDBUS_ITEM_SIZE (sizeof (struct kdbus_memfd));
844 items_size += KDBUS_ITEM_SIZE (sizeof (struct kdbus_vec));
848 __u64 vectors = (body_size + KDBUS_MSG_MAX_PAYLOAD_VEC_SIZE - 1)
849 / KDBUS_MSG_MAX_PAYLOAD_VEC_SIZE;
850 /* subsequent vectors -> parts of body */
851 items_size += vectors * KDBUS_ITEM_SIZE (sizeof (struct kdbus_vec));
855 items_size += KDBUS_ITEM_SIZE (sizeof (int) * fds_count);
858 items_size += KDBUS_ITEM_SIZE (strlen (destination) + 1);
859 else if (KDBUS_DST_ID_BROADCAST == dst_id)
860 items_size += KDBUS_ITEM_SIZE (sizeof (struct kdbus_bloom_filter))
867 * Asks the bus to assign the given name to the connection.
869 * Use same flags as original dbus version with one exception below.
870 * Result flag #DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER is currently
871 * never returned by kdbus, instead DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER
872 * is returned by kdbus.
874 * @param transport transport of the connection
875 * @param name the name to request
877 * @returns a DBus result code on success, -errno on error
880 _kdbus_request_name (kdbus_t *kdbus,
884 struct kdbus_cmd *cmd_name;
885 size_t len = strlen (name) + 1;
886 __u64 size = sizeof (*cmd_name) + KDBUS_ITEM_SIZE (len);
887 __u64 flags_kdbus = 0;
889 cmd_name = alloca (size);
890 cmd_name->size = size;
892 if (flags & DBUS_NAME_FLAG_ALLOW_REPLACEMENT)
893 flags_kdbus |= KDBUS_NAME_ALLOW_REPLACEMENT;
894 if (!(flags & DBUS_NAME_FLAG_DO_NOT_QUEUE))
895 flags_kdbus |= KDBUS_NAME_QUEUE;
896 if (flags & DBUS_NAME_FLAG_REPLACE_EXISTING)
897 flags_kdbus |= KDBUS_NAME_REPLACE_EXISTING;
899 cmd_name->flags = flags_kdbus;
900 make_item_name (name, &(cmd_name->items[0]));
902 _dbus_verbose ("Request name - flags sent: 0x%llx !!!!!!!!!\n", cmd_name->flags);
904 if (ioctl (kdbus->fd, KDBUS_CMD_NAME_ACQUIRE, cmd_name) < 0)
906 _dbus_verbose ("error acquiring name '%s': %m, %d\n", name, errno);
908 return DBUS_REQUEST_NAME_REPLY_EXISTS;
909 if (errno == EALREADY)
910 return DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER;
913 else if ((cmd_name->return_flags & KDBUS_NAME_PRIMARY)
914 && !(cmd_name->return_flags & KDBUS_NAME_ACQUIRED))
915 return DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER;
917 _dbus_verbose ("Request name - received flag: 0x%llx !!!!!!!!!\n", cmd_name->flags);
919 if (cmd_name->return_flags & KDBUS_NAME_IN_QUEUE)
920 return DBUS_REQUEST_NAME_REPLY_IN_QUEUE;
922 return DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER;
927 * Releases well-known name - the connections resign from the name
928 * which can be then assigned to another connection or the connection
929 * is being removed from the queue for that name
931 * @param name the name to request
932 * @param id unique id of the connection for which the name is being released
933 * @returns a DBus result code on success, -errno on error
936 _kdbus_release_name (kdbus_t *kdbus,
939 struct kdbus_cmd *cmd_name;
940 size_t len = strlen (name)+1;
941 __u64 size = sizeof (*cmd_name) + KDBUS_ITEM_SIZE (len);
943 cmd_name = alloca (size);
944 cmd_name->size = size;
946 make_item_name (name, &(cmd_name->items[0]));
948 if (ioctl (kdbus->fd, KDBUS_CMD_NAME_RELEASE, cmd_name))
950 if ((errno == ESRCH))
951 return DBUS_RELEASE_NAME_REPLY_NON_EXISTENT;
952 else if (errno == EADDRINUSE)
953 return DBUS_RELEASE_NAME_REPLY_NOT_OWNER;
954 _dbus_verbose ("error releasing name '%s'. Error: %m, %d\n", name, errno);
958 _dbus_verbose ("Name '%s' released\n", name);
960 return DBUS_RELEASE_NAME_REPLY_RELEASED;
964 decode_connection_info (struct kdbus_info *connection_info,
965 struct nameInfo *pInfo,
966 dbus_bool_t get_sec_label)
968 struct kdbus_item *item;
970 memset (pInfo, 0, sizeof (*pInfo));
972 pInfo->uniqueId = connection_info->id;
973 pInfo->flags = connection_info->flags;
975 item = connection_info->items;
977 while ((uint8_t *)item < ((uint8_t *)connection_info) + connection_info->size)
981 case KDBUS_ITEM_PIDS:
982 pInfo->processId = item->pids.pid;
984 case KDBUS_ITEM_CREDS:
985 pInfo->userId = item->creds.uid;
987 case KDBUS_ITEM_SECLABEL:
990 pInfo->sec_label_len = item->size - KDBUS_ITEM_HEADER_SIZE;
991 if (0 != pInfo->sec_label_len)
993 pInfo->sec_label = dbus_malloc (pInfo->sec_label_len);
994 if (NULL == pInfo->sec_label)
997 memcpy (pInfo->sec_label, item->data, pInfo->sec_label_len);
1003 item = KDBUS_ITEM_NEXT (item);
1009 process_connection_info_cmd (kdbus_t *kdbus,
1010 struct kdbus_cmd_info *cmd,
1011 struct nameInfo *pInfo,
1012 dbus_bool_t get_sec_label)
1015 struct kdbus_info *kdbus_info;
1020 ret = safe_ioctl (kdbus->fd, KDBUS_CMD_CONN_INFO, cmd);
1024 pInfo->uniqueId = 0;
1029 kdbus_info = get_from_offset (kdbus, cmd->offset);
1030 ret = decode_connection_info (kdbus_info,
1038 ret = free_by_offset (kdbus, cmd->offset);
1041 _dbus_verbose ("kdbus error freeing pool: %d (%m)\n", errno);
1044 free (pInfo->sec_label);
1045 pInfo->sec_label = NULL;
1055 * In this function either id is equal to 0 AND name is not NULL,
1056 * or id is greater than 0 AND name is NULL.
1057 * Thus, condition NULL != name is equivalent to 0 == id.
1059 static struct kdbus_cmd_info *
1060 prepare_connection_info_cmd (__u64 id,
1062 dbus_bool_t get_sec_label)
1064 struct kdbus_cmd_info *cmd;
1065 __u64 size = sizeof (*cmd);
1068 size += KDBUS_ITEM_SIZE (strlen (name) + 1);
1070 cmd = dbus_malloc (size);
1077 make_item_name (name, &(cmd->items[0]));
1079 cmd->attach_flags = KDBUS_ATTACH_CREDS | KDBUS_ATTACH_PIDS;
1081 cmd->attach_flags |= KDBUS_ATTACH_SECLABEL;
1089 * Gets connection info for the given unique id.
1091 * @param kdbus kdbus object
1092 * @param id unique id to query for
1093 * @param get_sec_label #TRUE if sec_label field in pInfo should be filled
1094 * @param pInfo nameInfo structure address to store info about the name
1095 * @return 0 on success, errno if failed
1097 * @note If you specify #TRUE in get_sec_label param, you must free
1098 * pInfo.sec_label with dbus_free() after use.
1101 _kdbus_connection_info_by_id (kdbus_t *kdbus,
1103 dbus_bool_t get_sec_label,
1104 struct nameInfo *pInfo)
1106 struct kdbus_cmd_info *cmd = prepare_connection_info_cmd (id, NULL, get_sec_label);
1108 return process_connection_info_cmd (kdbus, cmd, pInfo, get_sec_label);
1112 * Gets connection info for the given name
1114 * @param kdbus kdbus object
1115 * @param name name to query for
1116 * @param get_sec_label #TRUE if sec_label field in pInfo should be filled
1117 * @param pInfo nameInfo structure address to store info about the name
1118 * @return 0 on success, errno if failed
1120 * @note If you specify #TRUE in get_sec_label param, you must free
1121 * pInfo.sec_label with dbus_free() after use.
1124 _kdbus_connection_info_by_name (kdbus_t *kdbus,
1126 dbus_bool_t get_sec_label,
1127 struct nameInfo *pInfo)
1129 struct kdbus_cmd_info *cmd;
1131 /* if name starts with ":1." it is a unique name and should be send as number */
1132 if ((name[0] == ':') && (name[1] == '1') && (name[2] == '.'))
1134 return _kdbus_connection_info_by_id (kdbus,
1135 strtoull (&name[3], NULL, 10),
1140 cmd = prepare_connection_info_cmd (0, name, get_sec_label);
1142 return process_connection_info_cmd (kdbus, cmd, pInfo, get_sec_label);
1146 * Removes match rule in kdbus on behalf of sender of the message
1147 * @param kdbus kdbus object
1148 * @param cookie cookie of the rules to be removed
1151 _kdbus_remove_match (kdbus_t *kdbus,
1154 struct kdbus_cmd_match cmd;
1156 VALGRIND_MAKE_MEM_DEFINED (&cmd, sizeof (cmd));
1158 cmd.cookie = cookie;
1159 cmd.size = sizeof (struct kdbus_cmd_match);
1162 if (safe_ioctl (kdbus->fd, KDBUS_CMD_MATCH_REMOVE, &cmd) != 0)
1168 /************************* BLOOM FILTERS ***********************/
1171 * Macros for SipHash algorithm
1173 #define ROTL(x,b) (uint64_t)( ((x) << (b)) | ( (x) >> (64 - (b))) )
1175 #define U32TO8_LE(p, v) \
1176 (p)[0] = (unsigned char)((v) ); (p)[1] = (unsigned char)((v) >> 8); \
1177 (p)[2] = (unsigned char)((v) >> 16); (p)[3] = (unsigned char)((v) >> 24);
1179 #define U64TO8_LE(p, v) \
1180 U32TO8_LE((p), (uint32_t)((v) )); \
1181 U32TO8_LE((p) + 4, (uint32_t)((v) >> 32));
1183 #define U8TO64_LE(p) \
1184 (((uint64_t)((p)[0]) ) | \
1185 ((uint64_t)((p)[1]) << 8) | \
1186 ((uint64_t)((p)[2]) << 16) | \
1187 ((uint64_t)((p)[3]) << 24) | \
1188 ((uint64_t)((p)[4]) << 32) | \
1189 ((uint64_t)((p)[5]) << 40) | \
1190 ((uint64_t)((p)[6]) << 48) | \
1191 ((uint64_t)((p)[7]) << 56))
1195 v0 += v1; v1=ROTL(v1,13); v1 ^= v0; v0=ROTL(v0,32); \
1196 v2 += v3; v3=ROTL(v3,16); v3 ^= v2; \
1197 v0 += v3; v3=ROTL(v3,21); v3 ^= v0; \
1198 v2 += v1; v1=ROTL(v1,17); v1 ^= v2; v2=ROTL(v2,32); \
1203 * Hash keys for bloom filters
1205 static const unsigned char hash_keys[8][16] =
1207 {0xb9,0x66,0x0b,0xf0,0x46,0x70,0x47,0xc1,0x88,0x75,0xc4,0x9c,0x54,0xb9,0xbd,0x15},
1208 {0xaa,0xa1,0x54,0xa2,0xe0,0x71,0x4b,0x39,0xbf,0xe1,0xdd,0x2e,0x9f,0xc5,0x4a,0x3b},
1209 {0x63,0xfd,0xae,0xbe,0xcd,0x82,0x48,0x12,0xa1,0x6e,0x41,0x26,0xcb,0xfa,0xa0,0xc8},
1210 {0x23,0xbe,0x45,0x29,0x32,0xd2,0x46,0x2d,0x82,0x03,0x52,0x28,0xfe,0x37,0x17,0xf5},
1211 {0x56,0x3b,0xbf,0xee,0x5a,0x4f,0x43,0x39,0xaf,0xaa,0x94,0x08,0xdf,0xf0,0xfc,0x10},
1212 {0x31,0x80,0xc8,0x73,0xc7,0xea,0x46,0xd3,0xaa,0x25,0x75,0x0f,0x9e,0x4c,0x09,0x29},
1213 {0x7d,0xf7,0x18,0x4b,0x7b,0xa4,0x44,0xd5,0x85,0x3c,0x06,0xe0,0x65,0x53,0x96,0x6d},
1214 {0xf2,0x77,0xe9,0x6f,0x93,0xb5,0x4e,0x71,0x9a,0x0c,0x34,0x88,0x39,0x25,0xbf,0x35}
1221 _g_siphash24 (unsigned char out[8],
1224 const unsigned char k[16])
1226 uint64_t v0 = 0x736f6d6570736575ULL;
1227 uint64_t v1 = 0x646f72616e646f6dULL;
1228 uint64_t v2 = 0x6c7967656e657261ULL;
1229 uint64_t v3 = 0x7465646279746573ULL;
1231 uint64_t k0 = U8TO64_LE (k);
1232 uint64_t k1 = U8TO64_LE (k + 8);
1234 const unsigned char *in = _in;
1235 const unsigned char *end = in + inlen - (inlen % sizeof (uint64_t));
1236 const int left = inlen & 7;
1237 b = ((uint64_t) inlen) << 56;
1243 for (; in != end; in += 8)
1254 case 7: b |= ((uint64_t) in[6]) << 48;
1255 case 6: b |= ((uint64_t) in[5]) << 40;
1256 case 5: b |= ((uint64_t) in[4]) << 32;
1257 case 4: b |= ((uint64_t) in[3]) << 24;
1258 case 3: b |= ((uint64_t) in[2]) << 16;
1259 case 2: b |= ((uint64_t) in[1]) << 8;
1260 case 1: b |= ((uint64_t) in[0]); break;
1274 b = v0 ^ v1 ^ v2 ^ v3;
1279 _kdbus_bloom_add_data (kdbus_t *kdbus,
1280 kdbus_bloom_data_t *bloom_data,
1284 unsigned char hash[8];
1286 unsigned int bytes_num = 0;
1287 unsigned int cnt_1, cnt_2;
1288 unsigned int hash_index = 0;
1293 bit_num = kdbus->bloom.size * 8;
1296 bytes_num = ((__builtin_clzll (bit_num) ^ 63U) + 7) / 8;
1298 for (cnt_1 = 0; cnt_1 < kdbus->bloom.n_hash; cnt_1++)
1300 for (cnt_2 = 0, hash_index = 0; cnt_2 < bytes_num; cnt_2++)
1304 _g_siphash24 (hash, data, data_size, hash_keys[hash_index++]);
1308 p = (p << 8ULL) | (uint64_t) hash[8 - c];
1313 bloom_data[p >> 6] |= 1ULL << (p & 63);