[PATCH] dbus: Fix compile error for 32-bit platforms
by Mat Martineau
Error encountered with 32-bit gcc 5.3.1:
ell/dbus-kernel.c:412:20: error: cast from pointer to integer of
different size [-Werror=pointer-to-int-cast]
Casting the pointer to uintptr_t instead of uint64_t works on both
32-bit and 64-bit platforms.
---
ell/dbus-kernel.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ell/dbus-kernel.c b/ell/dbus-kernel.c
index 7124c33..863e8e7 100644
--- a/ell/dbus-kernel.c
+++ b/ell/dbus-kernel.c
@@ -409,7 +409,7 @@ int _dbus_kernel_send(int fd, size_t bloom_size, uint8_t bloom_n_hash,
memset(&cmd, 0, sizeof(cmd));
cmd.size = sizeof(cmd);
- cmd.msg_address = (uint64_t) kmsg;
+ cmd.msg_address = (uintptr_t) kmsg;
ret = ioctl(fd, KDBUS_CMD_SEND, &cmd);
if (ret < 0)
--
2.8.0
6 years, 3 months
[PATCH 1/5] dbus: l_dbus_name_acquire public API and driver declarations
by Andrew Zaborowski
---
ell/dbus.c | 34 ++++++++++++++++++++++++++++++++++
ell/dbus.h | 8 ++++++++
2 files changed, 42 insertions(+)
diff --git a/ell/dbus.c b/ell/dbus.c
index b9864bd..7d873ff 100644
--- a/ell/dbus.c
+++ b/ell/dbus.c
@@ -64,6 +64,10 @@ struct l_dbus_ops {
struct l_dbus_message *(*recv_message)(struct l_dbus *bus);
void (*free)(struct l_dbus *bus);
struct _dbus_filter_ops filter_ops;
+ uint32_t (*name_acquire)(struct l_dbus *dbus, const char *name,
+ bool allow_replacement, bool replace_existing,
+ bool queue, l_dbus_name_acquire_func_t callback,
+ void *user_data);
};
struct l_dbus {
@@ -2011,3 +2015,33 @@ LIB_EXPORT bool l_dbus_remove_signal_watch(struct l_dbus *dbus, unsigned int id)
{
return _dbus_filter_remove_rule(dbus->filter, id);
}
+
+/**
+ * l_dbus_name_acquire:
+ * @dbus: D-Bus connection
+ * @name: Well-known bus name to be acquired
+ * @allow_replacement: Whether to allow another peer's name request to
+ * take the name ownership away from this connection
+ * @replace_existing: Whether to allow D-Bus to take the name's ownership
+ * away from another peer in case the name is already
+ * owned and allows replacement. Ignored if name is
+ * currently free.
+ * @queue: Whether to allow the name request to be queued by D-Bus in
+ * case it cannot be acquired now, rather than to return a failure.
+ * @callback: Callback to receive the request result when done.
+ *
+ * Acquire a well-known bus name (service name) on the bus.
+ *
+ * Returns: a non-zero request serial that can be passed to l_dbus_cancel
+ * while waiting for the callback or zero if the callback has
+ * has happened while l_dbus_name_acquire was running.
+ **/
+LIB_EXPORT uint32_t l_dbus_name_acquire(struct l_dbus *dbus, const char *name,
+ bool allow_replacement, bool replace_existing,
+ bool queue, l_dbus_name_acquire_func_t callback,
+ void *user_data)
+{
+ return dbus->driver->name_acquire(dbus, name, allow_replacement,
+ replace_existing, queue,
+ callback, user_data);
+}
diff --git a/ell/dbus.h b/ell/dbus.h
index 0f20499..b096ed3 100644
--- a/ell/dbus.h
+++ b/ell/dbus.h
@@ -67,6 +67,9 @@ typedef void (*l_dbus_interface_setup_func_t) (struct l_dbus_interface *);
typedef void (*l_dbus_watch_func_t) (struct l_dbus *dbus, void *user_data);
+typedef void (*l_dbus_name_acquire_func_t) (struct l_dbus *dbus, bool success,
+ bool queued, void *user_data);
+
struct l_dbus *l_dbus_new(const char *address);
struct l_dbus *l_dbus_new_default(enum l_dbus_bus bus);
void l_dbus_destroy(struct l_dbus *dbus);
@@ -252,6 +255,11 @@ unsigned int l_dbus_add_signal_watch(struct l_dbus *dbus,
const char *member, ...);
bool l_dbus_remove_signal_watch(struct l_dbus *dbus, unsigned int id);
+uint32_t l_dbus_name_acquire(struct l_dbus *dbus, const char *name,
+ bool allow_replacement, bool replace_existing,
+ bool queue, l_dbus_name_acquire_func_t callback,
+ void *user_data);
+
#ifdef __cplusplus
}
#endif
--
2.5.0
6 years, 3 months
[PATCH 1/8] dbus: Rewrite service/disconnect watch APIs on top of filter API
by Andrew Zaborowski
The two advantages are that this should now work on top of kdbus and
that the full list of watches is not traversed on every notification.
---
ell/dbus.c | 220 ++++++++++++++++++++++++++++++++++++++++++-------------------
1 file changed, 153 insertions(+), 67 deletions(-)
diff --git a/ell/dbus.c b/ell/dbus.c
index d976496..6bf5734 100644
--- a/ell/dbus.c
+++ b/ell/dbus.c
@@ -89,6 +89,10 @@ struct l_dbus {
void *debug_data;
struct _dbus_object_tree *tree;
struct _dbus_filter *filter;
+ struct l_hashmap *services_watched;
+ struct service_watch_data *service_watch_head;
+ unsigned int last_service_watch_id;
+ struct l_idle *service_watch_remove_work;
const struct l_dbus_ops *driver;
};
@@ -123,6 +127,18 @@ struct signal_callback {
void *user_data;
};
+struct service_watch_data {
+ char *bus_name;
+ l_dbus_destroy_func_t destroy_func;
+ l_dbus_watch_func_t connect_func;
+ l_dbus_watch_func_t disconnect_func;
+ void *user_data;
+ unsigned int id;
+ bool pending_get_name_owner;
+ struct service_watch_data *next;
+ bool removed;
+};
+
struct dbus1_filter_data {
struct l_dbus *dbus;
char *sender;
@@ -363,6 +379,35 @@ static void bus_ready(struct l_dbus *dbus)
l_io_set_write_handler(dbus->io, message_write_handler, dbus, NULL);
}
+static void name_owner_notify(struct l_dbus *dbus, const char *name,
+ const char *old, const char *new)
+{
+ struct service_watch_data *watch;
+ bool connect = old && new && !*old && *new;
+ bool disconnect = old && new && *old && !*new;
+
+ _dbus_filter_name_owner_notify(dbus->filter, name, new);
+
+ watch = l_hashmap_lookup(dbus->services_watched, name);
+
+ while (watch && !strcmp(watch->bus_name, name)) {
+ if (watch->removed)
+ goto next;
+
+ if (watch->pending_get_name_owner) {
+ watch->pending_get_name_owner = false;
+ if (new && *new)
+ watch->connect_func(dbus, watch->user_data);
+ } else if (connect && watch->connect_func)
+ watch->connect_func(dbus, watch->user_data);
+ else if (disconnect && watch->disconnect_func)
+ watch->disconnect_func(dbus, watch->user_data);
+
+next:
+ watch = watch->next;
+ }
+}
+
static void hello_callback(struct l_dbus_message *message, void *user_data)
{
struct l_dbus *dbus = user_data;
@@ -752,7 +797,7 @@ static void get_name_owner_reply_cb(struct l_dbus_message *reply,
if (!l_dbus_message_get_arguments(req->message, "s", &name))
return;
- _dbus_filter_name_owner_notify(req->dbus->filter, name, owner);
+ name_owner_notify(req->dbus, name, NULL, owner);
}
static bool classic_get_name_owner(struct l_dbus *bus, const char *name)
@@ -800,7 +845,7 @@ static void name_owner_changed_cb(struct l_dbus_message *message,
if (!l_dbus_message_get_arguments(message, "sss", &name, &old, &new))
return;
- _dbus_filter_name_owner_notify(dbus->filter, name, new);
+ name_owner_notify(dbus, name, old, new);
}
static struct l_dbus *setup_dbus1(int fd, const char *guid)
@@ -1000,15 +1045,22 @@ static void kdbus_name_owner_change_func(const char *name, uint64_t old_owner,
void *user_data)
{
struct kdbus_message_recv_data *recv_data = user_data;
- char owner[32];
+ char old[32], new[32];
l_util_debug(recv_data->dbus->debug_handler,
recv_data->dbus->debug_data,
"Read KDBUS Name Owner Change notification");
- snprintf(owner, sizeof(owner), ":1.%" PRIu64, new_owner);
+ if (old_owner)
+ snprintf(old, sizeof(old), ":1.%" PRIu64, new_owner);
+ else
+ *old = '\0';
+ if (new_owner)
+ snprintf(new, sizeof(new), ":1.%" PRIu64, new_owner);
+ else
+ *new = '\0';
- _dbus_filter_name_owner_notify(recv_data->dbus->filter, name, owner);
+ name_owner_notify(recv_data->dbus, name, old, new);
}
static struct l_dbus_message *kdbus_recv_message(struct l_dbus *dbus)
@@ -1070,15 +1122,13 @@ static bool kdbus_get_name_owner(struct l_dbus *dbus, const char *name)
char owner[32];
owner_id = _dbus_kernel_get_name_owner(fd, kdbus->kdbus_pool, name);
- if (!owner_id) {
- l_util_debug(dbus->debug_handler,
- dbus->debug_data, "Error getting name owner");
- return false;
- }
- snprintf(owner, sizeof(owner), ":1.%" PRIu64, owner_id);
+ if (owner_id)
+ snprintf(owner, sizeof(owner), ":1.%" PRIu64, owner_id);
+ else
+ *owner = '\0';
- _dbus_filter_name_owner_notify(dbus->filter, name, owner);
+ name_owner_notify(dbus, name, NULL, owner);
return true;
}
@@ -1222,6 +1272,17 @@ LIB_EXPORT struct l_dbus *l_dbus_new_default(enum l_dbus_bus bus)
return setup_address(address);
}
+static void service_watch_data_free(void *data)
+{
+ struct service_watch_data *watch = data;
+
+ if (watch->destroy_func)
+ watch->destroy_func(watch->user_data);
+
+ l_free(watch->bus_name);
+ l_free(watch);
+}
+
LIB_EXPORT void l_dbus_destroy(struct l_dbus *dbus)
{
if (unlikely(!dbus))
@@ -1236,6 +1297,11 @@ LIB_EXPORT void l_dbus_destroy(struct l_dbus *dbus)
l_hashmap_destroy(dbus->message_list, message_list_destroy);
l_queue_destroy(dbus->message_queue, message_queue_destroy);
+ l_hashmap_destroy(dbus->services_watched, service_watch_data_free);
+
+ if (dbus->service_watch_remove_work)
+ l_idle_remove(dbus->service_watch_remove_work);
+
l_io_destroy(dbus->io);
if (dbus->disconnect_destroy)
@@ -1809,33 +1875,6 @@ void _dbus1_name_owner_changed_filter(struct l_dbus_message *message,
}
}
-static void _dbus1_get_name_owner_reply(struct l_dbus_message *message,
- void *user_data)
-{
- struct dbus1_filter_data *data = user_data;
- const char *name;
-
- data->get_name_owner_id = 0;
-
- /* No name owner yet */
- if (l_dbus_message_is_error(message))
- return;
-
- /* Shouldn't happen */
- if (!l_dbus_message_get_arguments(message, "s", &name))
- return;
-
- /* If the signal arrived before the reply, don't do anything */
- if (data->owner && !strcmp(data->owner, name))
- return;
-
- l_free(data->owner);
- data->owner = l_strdup(name);
-
- if (data->connect_func)
- data->connect_func(data->dbus, data->user_data);
-}
-
LIB_EXPORT unsigned int l_dbus_add_disconnect_watch(struct l_dbus *dbus,
const char *name,
l_dbus_watch_func_t disconnect_func,
@@ -1846,56 +1885,103 @@ LIB_EXPORT unsigned int l_dbus_add_disconnect_watch(struct l_dbus *dbus,
user_data, destroy);
}
-unsigned int l_dbus_add_service_watch(struct l_dbus *dbus,
+LIB_EXPORT unsigned int l_dbus_add_service_watch(struct l_dbus *dbus,
const char *name,
l_dbus_watch_func_t connect_func,
l_dbus_watch_func_t disconnect_func,
void *user_data,
l_dbus_destroy_func_t destroy)
{
- struct dbus1_filter_data *data;
+ struct service_watch_data *watch, *first;
if (!name)
return 0;
- data = _dbus1_filter_data_get(dbus, _dbus1_name_owner_changed_filter,
- DBUS_SERVICE_DBUS, DBUS_PATH_DBUS,
- L_DBUS_INTERFACE_DBUS, "NameOwnerChanged",
- name,
- disconnect_func,
- user_data,
- destroy);
- if (!data)
- return 0;
+ if (!dbus->services_watched)
+ dbus->services_watched = l_hashmap_string_new();
+
+ watch = l_new(struct service_watch_data, 1);
+ watch->bus_name = l_strdup(name);
+ watch->id = ++dbus->last_service_watch_id;
+ watch->connect_func = connect_func;
+ watch->disconnect_func = disconnect_func;
+ watch->destroy_func = destroy;
+
+ /*
+ * Make sure that all the entries for the same bus name are
+ * grouped together on the list and that the first entry for the
+ * name is in the hashmap for easy lookups.
+ */
+ first = l_hashmap_lookup(dbus->services_watched, name);
+ if (first) {
+ watch->next = first->next;
+ first->next = watch;
+ } else {
+ l_hashmap_insert(dbus->services_watched, name, watch);
- add_match(data);
+ watch->next = dbus->service_watch_head;
+ dbus->service_watch_head = watch;
+ }
if (connect_func) {
- struct l_dbus_message *message;
+ watch->pending_get_name_owner = true;
- data->connect_func = connect_func;
+ dbus->driver->filter_ops.get_name_owner(dbus, name);
+ }
- message = l_dbus_message_new_method_call(dbus,
- DBUS_SERVICE_DBUS,
- DBUS_PATH_DBUS,
- L_DBUS_INTERFACE_DBUS,
- "GetNameOwner");
+ return watch->id;
+}
- l_dbus_message_set_arguments(message, "s", name);
+static void service_watch_remove(struct l_idle *idle, void *user_data)
+{
+ struct l_dbus *dbus = user_data;
+ struct service_watch_data **watch, *tmp;
- data->get_name_owner_id =
- l_dbus_send_with_reply(dbus, message,
- _dbus1_get_name_owner_reply,
- data, NULL);
- }
+ l_idle_remove(dbus->service_watch_remove_work);
+ dbus->service_watch_remove_work = NULL;
+
+ for (watch = &dbus->service_watch_head; *watch;
+ watch = &(*watch)->next) {
+ if (!(*watch)->removed)
+ continue;
+
+ tmp = *watch;
+ *watch = tmp->next;
+
+ /* Check if this was the first entry for the bus name */
+ if (l_hashmap_lookup(dbus->services_watched, tmp->bus_name) ==
+ tmp) {
+ l_hashmap_remove(dbus->services_watched, tmp->bus_name);
+
+ if (tmp->next && !strcmp(tmp->bus_name,
+ tmp->next->bus_name))
+ l_hashmap_insert(dbus->services_watched,
+ tmp->bus_name, tmp->next);
+ }
- return l_dbus_register(dbus, _dbus1_signal_dispatcher, data,
- filter_data_destroy);
+ service_watch_data_free(tmp);
+ }
}
LIB_EXPORT bool l_dbus_remove_watch(struct l_dbus *dbus, unsigned int id)
{
- return l_dbus_unregister(dbus, id);
+ struct service_watch_data *watch;
+
+ for (watch = dbus->service_watch_head; watch; watch = watch->next)
+ if (watch->id == id && !watch->removed)
+ break;
+
+ if (!watch)
+ return false;
+
+ watch->removed = true;
+
+ if (!dbus->service_watch_remove_work)
+ dbus->service_watch_remove_work = l_idle_create(
+ service_watch_remove,
+ dbus, NULL);
+
+ return true;
}
/**
--
2.5.0
6 years, 3 months
[PATCH 01/15] dbus: Add _dbus1_message_iter_skip_entry.
by Andrew Zaborowski
This will be used for the get_nth_string_argument function in
dbus-message.c. There seems to be no other way to skip over an iterator
entry without knowing the data type.
---
ell/dbus-private.h | 1 +
ell/dbus-util.c | 16 ++++++++++++++++
2 files changed, 17 insertions(+)
diff --git a/ell/dbus-private.h b/ell/dbus-private.h
index 8322475..cfed4f7 100644
--- a/ell/dbus-private.h
+++ b/ell/dbus-private.h
@@ -77,6 +77,7 @@ bool _dbus1_iter_enter_variant(struct l_dbus_message_iter *iter,
struct l_dbus_message_iter *variant);
bool _dbus1_iter_enter_array(struct l_dbus_message_iter *iter,
struct l_dbus_message_iter *array);
+bool _dbus1_iter_skip_entry(struct l_dbus_message_iter *iter);
struct dbus_builder *_dbus1_builder_new(void *body, size_t body_size);
void _dbus1_builder_free(struct dbus_builder *builder);
diff --git a/ell/dbus-util.c b/ell/dbus-util.c
index 5ab4298..9d5b5af 100644
--- a/ell/dbus-util.c
+++ b/ell/dbus-util.c
@@ -805,6 +805,22 @@ bool _dbus1_iter_enter_array(struct l_dbus_message_iter *iter,
return true;
}
+bool _dbus1_iter_skip_entry(struct l_dbus_message_iter *iter)
+{
+ size_t len;
+ const char *sig_end;
+
+ sig_end = calc_len_next_item(iter->sig_start + iter->sig_pos,
+ iter->data, iter->pos, iter->len, &len);
+ if (!sig_end)
+ return false;
+
+ iter->pos += len;
+ iter->sig_pos = sig_end - iter->sig_start;
+
+ return true;
+}
+
struct dbus_builder {
struct l_string *signature;
void *body;
--
2.5.0
6 years, 3 months
[PATCH v3 1/5] build: Add sanitizer options
by Mat Martineau
Build using Address Sanitizer (asan), Leak Sanitizer (lsan), or
Undefined Behavior Sanitizer (ubsan) by using one of these options for
the configure script:
--enable-asan
--enable-lsan
--enable-ubsan
For each of these to work, the compiler must support the requested
sanitizer and the requisite libraries must be installed (libasan,
liblsan, libubsan).
---
acinclude.m4 | 36 ++++++++++++++++++++++++++++++++++++
configure.ac | 45 +++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 81 insertions(+)
diff --git a/acinclude.m4 b/acinclude.m4
index 0ba4287..8aab4ee 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -10,6 +10,42 @@ AC_DEFUN([AC_PROG_CC_PIE], [
])
])
+AC_DEFUN([AC_PROG_CC_ASAN], [
+ AC_CACHE_CHECK([whether ${CC-cc} accepts -fsanitize=address], ac_cv_prog_cc_asan, [
+ echo 'void f(){}' > conftest.c
+ if test -z "`${CC-cc} -fsanitize=address -c conftest.c 2>&1`"; then
+ ac_cv_prog_cc_asan=yes
+ else
+ ac_cv_prog_cc_asan=no
+ fi
+ rm -rf conftest*
+ ])
+])
+
+AC_DEFUN([AC_PROG_CC_LSAN], [
+ AC_CACHE_CHECK([whether ${CC-cc} accepts -fsanitize=leak], ac_cv_prog_cc_lsan, [
+ echo 'void f(){}' > conftest.c
+ if test -z "`${CC-cc} -fsanitize=leak -c conftest.c 2>&1`"; then
+ ac_cv_prog_cc_lsan=yes
+ else
+ ac_cv_prog_cc_lsan=no
+ fi
+ rm -rf conftest*
+ ])
+])
+
+AC_DEFUN([AC_PROG_CC_UBSAN], [
+ AC_CACHE_CHECK([whether ${CC-cc} accepts -fsanitize=undefined], ac_cv_prog_cc_ubsan, [
+ echo 'void f(){}' > conftest.c
+ if test -z "`${CC-cc} -fsanitize=undefined -c conftest.c 2>&1`"; then
+ ac_cv_prog_cc_ubsan=yes
+ else
+ ac_cv_prog_cc_ubsan=no
+ fi
+ rm -rf conftest*
+ ])
+])
+
AC_DEFUN([COMPILER_FLAGS], [
if (test "${CFLAGS}" = ""); then
CFLAGS="-Wall -O2 -fsigned-char"
diff --git a/configure.ac b/configure.ac
index 39755fe..e4ca5b2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -20,6 +20,9 @@ AC_LANG_C
AC_PROG_CC
AC_PROG_CC_PIE
+AC_PROG_CC_ASAN
+AC_PROG_CC_LSAN
+AC_PROG_CC_UBSAN
AC_PROG_INSTALL
AC_C_CHAR_UNSIGNED
@@ -54,6 +57,48 @@ AC_ARG_ENABLE(pie, AC_HELP_STRING([--enable-pie],
fi
])
+save_LIBS=$LIBS
+AC_CHECK_LIB(asan, __sanitizer_cov_init)
+LIBS=$save_LIBS
+
+AC_ARG_ENABLE(asan, AC_HELP_STRING([--enable-asan],
+ [enable linking with address sanitizer]), [
+ if (test "${enableval}" = "yes" &&
+ test "${ac_cv_lib_asan___sanitizer_cov_init}" = "yes" &&
+ test "${ac_cv_prog_cc_asan}" = "yes"); then
+ CFLAGS="$CFLAGS -fsanitize=address";
+ LDFLAGS="$LDFLAGS -fsanitize=address"
+ fi
+])
+
+save_LIBS=$LIBS
+AC_CHECK_LIB(lsan, __sanitizer_cov_init)
+LIBS=$save_LIBS
+
+AC_ARG_ENABLE(lsan, AC_HELP_STRING([--enable-lsan],
+ [enable linking with leak sanitizer]), [
+ if (test "${enableval}" = "yes" &&
+ test "${ac_cv_lib_lsan___sanitizer_cov_init}" = "yes" &&
+ test "${ac_cv_prog_cc_lsan}" = "yes"); then
+ CFLAGS="$CFLAGS -fsanitize=leak";
+ LDFLAGS="$LDFLAGS -fsanitize=leak"
+ fi
+])
+
+save_LIBS=$LIBS
+AC_CHECK_LIB(ubsan, __sanitizer_cov_init)
+LIBS=$save_LIBS
+
+AC_ARG_ENABLE(ubsan, AC_HELP_STRING([--enable-ubsan],
+ [enable linking with undefined behavior sanitizer]), [
+ if (test "${enableval}" = "yes" &&
+ test "${ac_cv_lib_ubsan___sanitizer_cov_init}" = "yes" &&
+ test "${ac_cv_prog_cc_ubsan}" = "yes"); then
+ CFLAGS="$CFLAGS -fsanitize=undefined";
+ LDFLAGS="$LDFLAGS -fsanitize=undefined"
+ fi
+])
+
AC_CHECK_FUNC(signalfd, dummy=yes,
AC_MSG_ERROR(signalfd support is required))
--
2.7.3
6 years, 3 months
[PATCH] gvariant: Exclude container's offsets from child iterator len
by Andrew Zaborowski
---
ell/gvariant-util.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/ell/gvariant-util.c b/ell/gvariant-util.c
index 79ebf32..38efc0d 100644
--- a/ell/gvariant-util.c
+++ b/ell/gvariant-util.c
@@ -529,7 +529,15 @@ static const void *next_item(struct l_dbus_message_iter *iter,
}
if (iter->container_type != DBUS_CONTAINER_TYPE_ARRAY && last_member) {
- *out_item_size = iter->len - iter->pos;
+ unsigned int len = iter->len;
+
+ offset_len = offset_length(iter->len, 0);
+
+ if (iter->offsets && iter->offsets + offset_len <
+ iter->data + len)
+ len = iter->offsets + offset_len - iter->data;
+
+ *out_item_size = len - iter->pos;
goto done;
}
--
2.5.0
6 years, 3 months
[PATCH] dbus: More complete buffer size check in dbus_message_from_blob
by Andrew Zaborowski
---
ell/dbus-message.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/ell/dbus-message.c b/ell/dbus-message.c
index 84d42d4..f9e13e2 100644
--- a/ell/dbus-message.c
+++ b/ell/dbus-message.c
@@ -643,9 +643,14 @@ struct l_dbus_message *dbus_message_from_blob(const void *data, size_t size)
message->header_size = align_len(DBUS_HEADER_SIZE +
hdr->field_length, 8);
- message->header = l_malloc(message->header_size);
-
message->body_size = hdr->body_length;
+
+ if (message->header_size + message->body_size < size) {
+ l_free(message);
+ return NULL;
+ }
+
+ message->header = l_malloc(message->header_size);
message->body = l_malloc(message->body_size);
memcpy(message->header, data, message->header_size);
--
2.5.0
6 years, 3 months
[PATCH v2 1/3] build: Add sanitizer options
by Mat Martineau
Build using Address Sanitizer (asan), Leak Sanitizer (lsan), or
Undefined Behavior Sanitizer (ubsan) by using one of these options for
the configure script:
--enable-asan
--enable-lsan
--enable-ubsan
For each of these to work, the compiler must support the requested
sanitizer and the requisite libraries must be installed (libasan,
liblsan, libubsan).
---
acinclude.m4 | 36 ++++++++++++++++++++++++++++++++++++
configure.ac | 45 +++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 81 insertions(+)
diff --git a/acinclude.m4 b/acinclude.m4
index 0ba4287..8aab4ee 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -10,6 +10,42 @@ AC_DEFUN([AC_PROG_CC_PIE], [
])
])
+AC_DEFUN([AC_PROG_CC_ASAN], [
+ AC_CACHE_CHECK([whether ${CC-cc} accepts -fsanitize=address], ac_cv_prog_cc_asan, [
+ echo 'void f(){}' > conftest.c
+ if test -z "`${CC-cc} -fsanitize=address -c conftest.c 2>&1`"; then
+ ac_cv_prog_cc_asan=yes
+ else
+ ac_cv_prog_cc_asan=no
+ fi
+ rm -rf conftest*
+ ])
+])
+
+AC_DEFUN([AC_PROG_CC_LSAN], [
+ AC_CACHE_CHECK([whether ${CC-cc} accepts -fsanitize=leak], ac_cv_prog_cc_lsan, [
+ echo 'void f(){}' > conftest.c
+ if test -z "`${CC-cc} -fsanitize=leak -c conftest.c 2>&1`"; then
+ ac_cv_prog_cc_lsan=yes
+ else
+ ac_cv_prog_cc_lsan=no
+ fi
+ rm -rf conftest*
+ ])
+])
+
+AC_DEFUN([AC_PROG_CC_UBSAN], [
+ AC_CACHE_CHECK([whether ${CC-cc} accepts -fsanitize=undefined], ac_cv_prog_cc_ubsan, [
+ echo 'void f(){}' > conftest.c
+ if test -z "`${CC-cc} -fsanitize=undefined -c conftest.c 2>&1`"; then
+ ac_cv_prog_cc_ubsan=yes
+ else
+ ac_cv_prog_cc_ubsan=no
+ fi
+ rm -rf conftest*
+ ])
+])
+
AC_DEFUN([COMPILER_FLAGS], [
if (test "${CFLAGS}" = ""); then
CFLAGS="-Wall -O2 -fsigned-char"
diff --git a/configure.ac b/configure.ac
index 39755fe..e4ca5b2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -20,6 +20,9 @@ AC_LANG_C
AC_PROG_CC
AC_PROG_CC_PIE
+AC_PROG_CC_ASAN
+AC_PROG_CC_LSAN
+AC_PROG_CC_UBSAN
AC_PROG_INSTALL
AC_C_CHAR_UNSIGNED
@@ -54,6 +57,48 @@ AC_ARG_ENABLE(pie, AC_HELP_STRING([--enable-pie],
fi
])
+save_LIBS=$LIBS
+AC_CHECK_LIB(asan, __sanitizer_cov_init)
+LIBS=$save_LIBS
+
+AC_ARG_ENABLE(asan, AC_HELP_STRING([--enable-asan],
+ [enable linking with address sanitizer]), [
+ if (test "${enableval}" = "yes" &&
+ test "${ac_cv_lib_asan___sanitizer_cov_init}" = "yes" &&
+ test "${ac_cv_prog_cc_asan}" = "yes"); then
+ CFLAGS="$CFLAGS -fsanitize=address";
+ LDFLAGS="$LDFLAGS -fsanitize=address"
+ fi
+])
+
+save_LIBS=$LIBS
+AC_CHECK_LIB(lsan, __sanitizer_cov_init)
+LIBS=$save_LIBS
+
+AC_ARG_ENABLE(lsan, AC_HELP_STRING([--enable-lsan],
+ [enable linking with leak sanitizer]), [
+ if (test "${enableval}" = "yes" &&
+ test "${ac_cv_lib_lsan___sanitizer_cov_init}" = "yes" &&
+ test "${ac_cv_prog_cc_lsan}" = "yes"); then
+ CFLAGS="$CFLAGS -fsanitize=leak";
+ LDFLAGS="$LDFLAGS -fsanitize=leak"
+ fi
+])
+
+save_LIBS=$LIBS
+AC_CHECK_LIB(ubsan, __sanitizer_cov_init)
+LIBS=$save_LIBS
+
+AC_ARG_ENABLE(ubsan, AC_HELP_STRING([--enable-ubsan],
+ [enable linking with undefined behavior sanitizer]), [
+ if (test "${enableval}" = "yes" &&
+ test "${ac_cv_lib_ubsan___sanitizer_cov_init}" = "yes" &&
+ test "${ac_cv_prog_cc_ubsan}" = "yes"); then
+ CFLAGS="$CFLAGS -fsanitize=undefined";
+ LDFLAGS="$LDFLAGS -fsanitize=undefined"
+ fi
+])
+
AC_CHECK_FUNC(signalfd, dummy=yes,
AC_MSG_ERROR(signalfd support is required))
--
2.7.3
6 years, 3 months
[PATCH v2 0/3] Sanitizers and race test/fix
by Mat Martineau
v2: Fix whitespace in patch 2/3.
Mat Martineau (3):
build: Add sanitizer options
unit: Add race condition test to test-main
main: Safely free watch_data structures
acinclude.m4 | 36 ++++++++++++++++++++++++++++++++++++
configure.ac | 45 +++++++++++++++++++++++++++++++++++++++++++++
ell/main.c | 28 +++++++++++++++++++++++++++-
unit/test-main.c | 35 +++++++++++++++++++++++++++++++----
4 files changed, 139 insertions(+), 5 deletions(-)
--
2.7.3
6 years, 3 months
[PATCH 1/3] build: Add sanitizer options
by Mat Martineau
Build using Address Sanitizer (asan), Leak Sanitizer (lsan), or
Undefined Behavior Sanitizer (ubsan) by using one of these options for
the configure script:
--enable-asan
--enable-lsan
--enable-ubsan
For each of these to work, the compiler must support the requested
sanitizer and the requisite libraries must be installed (libasan,
liblsan, libubsan).
---
acinclude.m4 | 36 ++++++++++++++++++++++++++++++++++++
configure.ac | 45 +++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 81 insertions(+)
diff --git a/acinclude.m4 b/acinclude.m4
index 0ba4287..8aab4ee 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -10,6 +10,42 @@ AC_DEFUN([AC_PROG_CC_PIE], [
])
])
+AC_DEFUN([AC_PROG_CC_ASAN], [
+ AC_CACHE_CHECK([whether ${CC-cc} accepts -fsanitize=address], ac_cv_prog_cc_asan, [
+ echo 'void f(){}' > conftest.c
+ if test -z "`${CC-cc} -fsanitize=address -c conftest.c 2>&1`"; then
+ ac_cv_prog_cc_asan=yes
+ else
+ ac_cv_prog_cc_asan=no
+ fi
+ rm -rf conftest*
+ ])
+])
+
+AC_DEFUN([AC_PROG_CC_LSAN], [
+ AC_CACHE_CHECK([whether ${CC-cc} accepts -fsanitize=leak], ac_cv_prog_cc_lsan, [
+ echo 'void f(){}' > conftest.c
+ if test -z "`${CC-cc} -fsanitize=leak -c conftest.c 2>&1`"; then
+ ac_cv_prog_cc_lsan=yes
+ else
+ ac_cv_prog_cc_lsan=no
+ fi
+ rm -rf conftest*
+ ])
+])
+
+AC_DEFUN([AC_PROG_CC_UBSAN], [
+ AC_CACHE_CHECK([whether ${CC-cc} accepts -fsanitize=undefined], ac_cv_prog_cc_ubsan, [
+ echo 'void f(){}' > conftest.c
+ if test -z "`${CC-cc} -fsanitize=undefined -c conftest.c 2>&1`"; then
+ ac_cv_prog_cc_ubsan=yes
+ else
+ ac_cv_prog_cc_ubsan=no
+ fi
+ rm -rf conftest*
+ ])
+])
+
AC_DEFUN([COMPILER_FLAGS], [
if (test "${CFLAGS}" = ""); then
CFLAGS="-Wall -O2 -fsigned-char"
diff --git a/configure.ac b/configure.ac
index 39755fe..e4ca5b2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -20,6 +20,9 @@ AC_LANG_C
AC_PROG_CC
AC_PROG_CC_PIE
+AC_PROG_CC_ASAN
+AC_PROG_CC_LSAN
+AC_PROG_CC_UBSAN
AC_PROG_INSTALL
AC_C_CHAR_UNSIGNED
@@ -54,6 +57,48 @@ AC_ARG_ENABLE(pie, AC_HELP_STRING([--enable-pie],
fi
])
+save_LIBS=$LIBS
+AC_CHECK_LIB(asan, __sanitizer_cov_init)
+LIBS=$save_LIBS
+
+AC_ARG_ENABLE(asan, AC_HELP_STRING([--enable-asan],
+ [enable linking with address sanitizer]), [
+ if (test "${enableval}" = "yes" &&
+ test "${ac_cv_lib_asan___sanitizer_cov_init}" = "yes" &&
+ test "${ac_cv_prog_cc_asan}" = "yes"); then
+ CFLAGS="$CFLAGS -fsanitize=address";
+ LDFLAGS="$LDFLAGS -fsanitize=address"
+ fi
+])
+
+save_LIBS=$LIBS
+AC_CHECK_LIB(lsan, __sanitizer_cov_init)
+LIBS=$save_LIBS
+
+AC_ARG_ENABLE(lsan, AC_HELP_STRING([--enable-lsan],
+ [enable linking with leak sanitizer]), [
+ if (test "${enableval}" = "yes" &&
+ test "${ac_cv_lib_lsan___sanitizer_cov_init}" = "yes" &&
+ test "${ac_cv_prog_cc_lsan}" = "yes"); then
+ CFLAGS="$CFLAGS -fsanitize=leak";
+ LDFLAGS="$LDFLAGS -fsanitize=leak"
+ fi
+])
+
+save_LIBS=$LIBS
+AC_CHECK_LIB(ubsan, __sanitizer_cov_init)
+LIBS=$save_LIBS
+
+AC_ARG_ENABLE(ubsan, AC_HELP_STRING([--enable-ubsan],
+ [enable linking with undefined behavior sanitizer]), [
+ if (test "${enableval}" = "yes" &&
+ test "${ac_cv_lib_ubsan___sanitizer_cov_init}" = "yes" &&
+ test "${ac_cv_prog_cc_ubsan}" = "yes"); then
+ CFLAGS="$CFLAGS -fsanitize=undefined";
+ LDFLAGS="$LDFLAGS -fsanitize=undefined"
+ fi
+])
+
AC_CHECK_FUNC(signalfd, dummy=yes,
AC_MSG_ERROR(signalfd support is required))
--
2.7.3
6 years, 3 months