Package: release.debian.org Severity: normal Tags: bullseye User: release.debian....@packages.debian.org Usertags: pu X-Debbugs-CC: pkg-utopia-maintain...@lists.alioth.debian.org j...@inutil.org
Dear release team, In accordance with the Security Team, we want to fix CVE-2022-31213 via a p-u upload rather than a DSA. https://security-tracker.debian.org/tracker/CVE-2022-31213 I have prepared the backports for the CVE fix, a memory leak fix, and an assertion fix that were merged upstream in the latest release. I have tested the new version in a bullseye nspawn container and found no issue. I have already done the upload as dbus-broker was approved for bullseye-p-u already in the past. debdiff attached. -- Kind regards, Luca Boccassi
diff -Nru dbus-broker-26/debian/changelog dbus-broker-26/debian/changelog --- dbus-broker-26/debian/changelog 2022-06-22 22:27:17.000000000 +0100 +++ dbus-broker-26/debian/changelog 2022-08-04 12:55:19.000000000 +0100 @@ -1,3 +1,11 @@ +dbus-broker (26-1+deb11u2) bullseye; urgency=medium + + * Backport patch to fix assertion failure when disconnecting peer groups + * Backport patch to fix memory leak + * Backport patches to fix null pointer dereference (CVE-2022-31213) + + -- Luca Boccassi <bl...@debian.org> Thu, 04 Aug 2022 12:55:19 +0100 + dbus-broker (26-1+deb11u1) bullseye; urgency=medium * Backport strnspn-fix-buffer-overflow.patch to fix CVE-2022-31212 diff -Nru dbus-broker-26/debian/patches/c-stdaux-add-c_memcpy.patch dbus-broker-26/debian/patches/c-stdaux-add-c_memcpy.patch --- dbus-broker-26/debian/patches/c-stdaux-add-c_memcpy.patch 1970-01-01 01:00:00.000000000 +0100 +++ dbus-broker-26/debian/patches/c-stdaux-add-c_memcpy.patch 2022-08-04 12:55:19.000000000 +0100 @@ -0,0 +1,64 @@ +Author: David Rheinsberg <david.rheinsb...@gmail.com> +Origin: backport, https://github.com/c-util/c-stdaux/commit/7a8493bebc595f94ea57fa1cb6a765a66185aa95 +Description: add c_memcpy() + Alongside c_memset(), this adds c_memcpy() with the same trick of + allowing empty copies. +--- a/subprojects/c-stdaux/src/c-stdaux.h ++++ b/subprojects/c-stdaux/src/c-stdaux.h +@@ -488,6 +488,24 @@ + return p; + } + ++/** ++ * c_memcpy() - copy memory area ++ * @dst: pointer to target area ++ * @src: pointer to source area ++ * @n: length of area to copy ++ * ++ * Copy the memory of size @n from @src to @dst, just as `memcpy(3)` does, ++ * except this function allows either to be NULL if @n is zero. In the latter ++ * case, the operation is a no-op. ++ * ++ * Return: @p is returned. ++ */ ++static inline void *c_memcpy(void *dst, const void *src, size_t n) { ++ if (n > 0) ++ memcpy(dst, src, n); ++ return dst; ++} ++ + /* + * Common Destructors + * +--- a/subprojects/c-stdaux/src/test-api.c ++++ b/subprojects/c-stdaux/src/test-api.c +@@ -188,6 +188,7 @@ + void *fns[] = { + (void *)c_errno, + (void *)c_memset, ++ (void *)c_memcpy, + (void *)c_free, + (void *)c_close, + (void *)c_fclose, +--- a/subprojects/c-stdaux/src/test-basic.c ++++ b/subprojects/c-stdaux/src/test-basic.c +@@ -332,6 +332,19 @@ + abort(); + c_assert(p == NULL); + } ++ ++ /* ++ * Test c_memcpy() with a simple 8-byte copy. ++ */ ++ { ++ uint64_t v1 = (uint64_t)-1, v2 = (uint64_t)0; ++ ++ c_assert(v1 == (uint64_t)-1); ++ c_memcpy(&v1, &v2, sizeof(v1)); ++ c_assert(v1 == (uint64_t)0); ++ ++ c_memcpy(NULL, NULL, 0); ++ } + } + + /* diff -Nru dbus-broker-26/debian/patches/c-stdaux-add-c_memset.patch dbus-broker-26/debian/patches/c-stdaux-add-c_memset.patch --- dbus-broker-26/debian/patches/c-stdaux-add-c_memset.patch 1970-01-01 01:00:00.000000000 +0100 +++ dbus-broker-26/debian/patches/c-stdaux-add-c_memset.patch 2022-08-04 12:55:19.000000000 +0100 @@ -0,0 +1,85 @@ +Author: David Rheinsberg <david.rheinsb...@gmail.com> +Origin: backport, https://github.com/c-util/c-stdaux/commit/1257244f886a4799a1ed739aa2c632e9eb033b8d +Description: add c_memset() + The memset(3) function causes UB if its area pointer is NULL, even if + the area is 0-bytes in length. This is very unfortunate and requires + unnecessary guards in most callers. We really want to be able to call + memset(3) with NULL pointers on empty areas to avoid needless branching + and complexity. + . + Provide c_memset() which is exactly like memset(3) for non-NULL areas, + but a no-op for empty areas. +--- a/subprojects/c-stdaux/src/c-stdaux.h ++++ b/subprojects/c-stdaux/src/c-stdaux.h +@@ -470,6 +470,24 @@ + return _c_likely_(errno > 0) ? errno : ENOTRECOVERABLE; + } + ++/** ++ * c_memset() - fill memory region with constant byte ++ * @p: pointer to memory region, if non-empty ++ * @c: value to fill with ++ * @n: size of the memory region in bytes ++ * ++ * This function works like `memset(3)` if @n is non-zero. If @n is zero, this ++ * function is a no-op. Therefore, unlike `memset(3)` it is safe to call this ++ * function with NULL as @p if @n is 0. ++ * ++ * Return: @p is returned. ++ */ ++static inline void *c_memset(void *p, int c, size_t n) { ++ if (n > 0) ++ memset(p, c, n); ++ return p; ++} ++ + /* + * Common Destructors + * +--- a/subprojects/c-stdaux/src/test-api.c ++++ b/subprojects/c-stdaux/src/test-api.c +@@ -187,6 +187,7 @@ + static void test_api_functions(void) { + void *fns[] = { + (void *)c_errno, ++ (void *)c_memset, + (void *)c_free, + (void *)c_close, + (void *)c_fclose, +--- a/subprojects/c-stdaux/src/test-basic.c ++++ b/subprojects/c-stdaux/src/test-basic.c +@@ -304,6 +304,34 @@ + errno = 0; + c_assert(c_errno() != errno); + } ++ ++ /* ++ * Test c_memset(). Simply verify its most basic behavior, as well as ++ * calling it on empty regions. ++ */ ++ { ++ uint64_t v = (uint64_t)-1; ++ size_t n; ++ void *p; ++ ++ /* try filling with 0 and 0xff */ ++ c_assert(v == (uint64_t)-1); ++ c_memset(&v, 0, sizeof(v)); ++ c_assert(v == (uint64_t)0); ++ c_memset(&v, 0xff, sizeof(v)); ++ c_assert(v == (uint64_t)-1); ++ ++ /* ++ * Try tricking the optimizer into thinking @p cannot be NULL, ++ * as normal `memset(3)` would allow. ++ */ ++ p = NULL; ++ n = 0; ++ c_memset(p, 0, n); ++ if (p) ++ abort(); ++ c_assert(p == NULL); ++ } + } + + /* diff -Nru dbus-broker-26/debian/patches/global-use-c_mem-over-mem.patch dbus-broker-26/debian/patches/global-use-c_mem-over-mem.patch --- dbus-broker-26/debian/patches/global-use-c_mem-over-mem.patch 1970-01-01 01:00:00.000000000 +0100 +++ dbus-broker-26/debian/patches/global-use-c_mem-over-mem.patch 2022-08-04 12:55:19.000000000 +0100 @@ -0,0 +1,372 @@ +Author: David Rheinsberg <david.rheinsb...@gmail.com> +Origin: backport, https://github.com/bus1/dbus-broker/commit/701759a08f5982f515308c269a8e224fc433f4af +Description: global: use c_mem*() over mem*() + Use the new c_mem*() functions rather than mem*() so we protect against + NULL pointers in empty areas, which are UB with the classic mem*() + functions. +--- a/src/broker/controller.c ++++ b/src/broker/controller.c +@@ -56,7 +56,7 @@ + name->controller = controller; + name->controller_node = (CRBNode)C_RBNODE_INIT(name->controller_node); + name->activation = (Activation)ACTIVATION_NULL(name->activation); +- memcpy(name->path, path, n_path + 1); ++ c_memcpy(name->path, path, n_path + 1); + + c_rbtree_add(&controller->name_tree, parent, slot, &name->controller_node); + *namep = name; +@@ -192,7 +192,7 @@ + + listener->controller = controller; + listener->controller_node = (CRBNode)C_RBNODE_INIT(listener->controller_node); +- memcpy(listener->path, path, n_path + 1); ++ c_memcpy(listener->path, path, n_path + 1); + + c_rbtree_add(&controller->listener_tree, parent, slot, &listener->controller_node); + *listenerp = listener; +--- a/src/bus/bus.c ++++ b/src/bus/bus.c +@@ -36,11 +36,11 @@ + *bus = (Bus)BUS_NULL(*bus); + bus->log = log; + +- memcpy(bus->machine_id, machine_id, sizeof(bus->machine_id)); ++ c_memcpy(bus->machine_id, machine_id, sizeof(bus->machine_id)); + + random = (void *)getauxval(AT_RANDOM); + c_assert(random); +- memcpy(bus->guid, random, sizeof(bus->guid)); ++ c_memcpy(bus->guid, random, sizeof(bus->guid)); + + r = user_registry_init(&bus->users, log, _USER_SLOT_N, maxima); + if (r) +--- a/src/bus/name.c ++++ b/src/bus/name.c +@@ -214,7 +214,7 @@ + + *name = (Name)NAME_INIT(*name); + name->registry = registry; +- memcpy(name->name, name_str, n_name + 1); ++ c_memcpy(name->name, name_str, n_name + 1); + + *namep = name; + name = NULL; +--- a/src/dbus/message.c ++++ b/src/dbus/message.c +@@ -83,7 +83,7 @@ + message->vecs[3] = (struct iovec){ message->body, n_body }; + + message->n_copied += sizeof(header); +- memcpy(message->data, &header, sizeof(header)); ++ c_memcpy(message->data, &header, sizeof(header)); + + *messagep = message; + message = NULL; +@@ -616,11 +616,11 @@ + message->patch[2] = 's'; + message->patch[3] = 0; + if (message->big_endian) +- memcpy(message->patch + 4, (uint32_t[1]){ htobe32(n_sender) }, sizeof(uint32_t)); ++ c_memcpy(message->patch + 4, (uint32_t[1]){ htobe32(n_sender) }, sizeof(uint32_t)); + else +- memcpy(message->patch + 4, (uint32_t[1]){ htole32(n_sender) }, sizeof(uint32_t)); +- memcpy(message->patch + 8, sender, n_sender + 1); +- memset(message->patch + 8 + n_sender + 1, 0, n_stitch - n_field); ++ c_memcpy(message->patch + 4, (uint32_t[1]){ htole32(n_sender) }, sizeof(uint32_t)); ++ c_memcpy(message->patch + 8, sender, n_sender + 1); ++ c_memset(message->patch + 8 + n_sender + 1, 0, n_stitch - n_field); + + /* + * After we cut the previous sender field and inserted the new, adjust +--- a/src/dbus/queue.c ++++ b/src/dbus/queue.c +@@ -170,14 +170,14 @@ + c_assert(!iq->data_start); + c_assert(iq->data == iq->buffer); + +- memcpy(p, iq->data, iq->data_end); ++ c_memcpy(p, iq->data, iq->data_end); + iq->data = p; + iq->data_size = IQUEUE_LINE_MAX; + } else if (_c_unlikely_(iq->data != iq->buffer && iq->pending.data)) { + c_assert(!iq->data_start); + c_assert(iq->data_end <= sizeof(iq->buffer)); + +- memcpy(iq->buffer, iq->data, iq->data_end); ++ c_memcpy(iq->buffer, iq->data, iq->data_end); + free(iq->data); + user_charge_deinit(&iq->charge_data); + iq->data = iq->buffer; +@@ -314,9 +314,9 @@ + if (n_data > 0) { + n = c_min(n_data, iq->pending.n_data - iq->pending.n_copied); + +- memcpy(iq->pending.data + iq->pending.n_copied, +- iq->data + iq->data_start, +- n); ++ c_memcpy(iq->pending.data + iq->pending.n_copied, ++ iq->data + iq->data_start, ++ n); + + n_data -= n; + iq->data_start += n; +--- a/src/dbus/socket.c ++++ b/src/dbus/socket.c +@@ -115,7 +115,7 @@ + return error_trace(r); + + buffer->message = message_ref(message); +- memcpy(buffer->vecs, message->vecs, sizeof(message->vecs)); ++ c_memcpy(buffer->vecs, message->vecs, sizeof(message->vecs)); + + r = user_charge(socket->user, + &buffer->charges[0], +@@ -472,11 +472,11 @@ + + socket_buffer_get_line_cursor(buffer, &line_out, &pos); + +- memcpy(line_out, line_in, n); ++ c_memcpy(line_out, line_in, n); + line_out += n; + *pos += n; + +- memcpy(line_out, "\r\n", strlen("\r\n")); ++ c_memcpy(line_out, "\r\n", strlen("\r\n")); + *pos += strlen("\r\n"); + + return 0; +--- a/src/dbus/test-queue.c ++++ b/src/dbus/test-queue.c +@@ -59,7 +59,7 @@ + if (!n) + break; + +- memcpy(buffer + *from, blob, n); ++ c_memcpy(buffer + *from, blob, n); + *from += n; + total += n; + +@@ -110,7 +110,7 @@ + c_assert(!r); + c_assert(to - *from >= 128); + +- memcpy(buffer + *from, (char [1]){}, 1); ++ c_memcpy(buffer + *from, (char [1]){}, 1); + *from += 1; + r = fdlist_new_with_fds(fds, (int [1]){}, 1); + c_assert(!r); +@@ -149,7 +149,7 @@ + c_assert(!r); + c_assert(to - *from >= 128); + +- memcpy(buffer + *from, (char [2]){}, 2); ++ c_memcpy(buffer + *from, (char [2]){}, 2); + *from += 2; + r = fdlist_new_with_fds(fds, (int [1]){ 1 }, 1); + c_assert(!r); +@@ -199,7 +199,7 @@ + c_assert(!r); + c_assert(to - *from >= 128); + +- memcpy(buffer + *from, (char [1]){}, 1); ++ c_memcpy(buffer + *from, (char [1]){}, 1); + *from += 1; + r = fdlist_new_with_fds(fds, (int [1]){}, 1); + c_assert(!r); +@@ -307,7 +307,7 @@ + n = rand() % c_min(n, strlen(send) - i_send); + ++n; + +- memcpy(buffer + *from, send + i_send, n); ++ c_memcpy(buffer + *from, send + i_send, n); + i_send += n; + *from += n; + } +--- a/src/dbus/test-stitching.c ++++ b/src/dbus/test-stitching.c +@@ -62,7 +62,7 @@ + if (before) { + p = malloc(before + 1); + c_assert(p); +- memset(p, 'a', before); ++ c_memset(p, 'a', before); + p[before] = 0; + + c_dvar_write(&v, "(y<s>)", +@@ -82,7 +82,7 @@ + if (after) { + p = malloc(after + 1); + c_assert(p); +- memset(p, 'a', after); ++ c_memset(p, 'a', after); + p[0] = '/'; + p[after] = 0; + +@@ -127,7 +127,7 @@ + c_assert(p); + + for (n = 0, i = 0; i < C_ARRAY_SIZE(message->vecs); ++i) { +- memcpy(p + n, message->vecs[i].iov_base, message->vecs[i].iov_len); ++ c_memcpy(p + n, message->vecs[i].iov_base, message->vecs[i].iov_len); + n += message->vecs[i].iov_len; + } + +@@ -155,7 +155,7 @@ + n = 8 + i % 8; + from = malloc(n + 1); + c_assert(from); +- memset(from, '1', n); ++ c_memset(from, '1', n); + from[0] = ':'; + from[1] = '1'; + from[2] = '.'; +@@ -164,7 +164,7 @@ + n = 8 + i % 11; + to = malloc(n + 1); + c_assert(to); +- memset(to, '2', n); ++ c_memset(to, '2', n); + to[0] = ':'; + to[1] = '1'; + to[2] = '.'; +--- a/src/launch/config.c ++++ b/src/launch/config.c +@@ -64,11 +64,11 @@ + file->parent = config_path_ref(parent); + + if (n_prefix) { +- memcpy(file->path, prefix, n_prefix); ++ c_memcpy(file->path, prefix, n_prefix); + file->path[n_prefix] = '/'; +- memcpy(file->path + n_prefix + 1, path, n_path + 1); ++ c_memcpy(file->path + n_prefix + 1, path, n_path + 1); + } else { +- memcpy(file->path, path, n_path + 1); ++ c_memcpy(file->path, path, n_path + 1); + } + + *filep = file; +@@ -1195,8 +1195,8 @@ + return; + } + +- memcpy(t, state->current->cdata, state->current->n_cdata); +- memcpy(t + state->current->n_cdata, data, n_data); ++ c_memcpy(t, state->current->cdata, state->current->n_cdata); ++ c_memcpy(t + state->current->n_cdata, data, n_data); + t[state->current->n_cdata + n_data] = 0; + free(state->current->cdata); + state->current->cdata = t; +@@ -1232,7 +1232,7 @@ + c_assert(node->type == CONFIG_NODE_INCLUDE); + c_assert(node->include.file); + +- memset(&parser->state, 0, sizeof(parser->state)); ++ c_memset(&parser->state, 0, sizeof(parser->state)); + parser->state.nss = nss_cache; + parser->state.dirwatch = dirwatch; + parser->state.file = node->include.file; +--- a/src/launch/nss-cache.c ++++ b/src/launch/nss-cache.c +@@ -210,7 +210,7 @@ + return error_trace(r); + + if (node) { +- memset(&node->pw, 0, sizeof(node->pw)); ++ c_memset(&node->pw, 0, sizeof(node->pw)); + node->pw.pw_name = node->name; + node->pw.pw_uid = pw->pw_uid; + node->pw.pw_gid = pw->pw_gid; +@@ -232,7 +232,7 @@ + return error_trace(r); + + if (node) { +- memset(&node->gr, 0, sizeof(node->gr)); ++ c_memset(&node->gr, 0, sizeof(node->gr)); + node->gr.gr_name = node->name; + node->gr.gr_gid = gr->gr_gid; + } +--- a/src/util/fdlist.c ++++ b/src/util/fdlist.c +@@ -37,7 +37,7 @@ + list->cmsg->cmsg_len = CMSG_LEN(n_fds * sizeof(int)); + list->cmsg->cmsg_level = SOL_SOCKET; + list->cmsg->cmsg_type = SCM_RIGHTS; +- memcpy(fdlist_data(list), fds, n_fds * sizeof(int)); ++ c_memcpy(fdlist_data(list), fds, n_fds * sizeof(int)); + + *listp = list; + return 0; +--- a/src/util/log.c ++++ b/src/util/log.c +@@ -278,7 +278,7 @@ + control.cmsg.cmsg_len = CMSG_LEN(sizeof(int)); + control.cmsg.cmsg_level = SOL_SOCKET; + control.cmsg.cmsg_type = SCM_RIGHTS; +- memcpy(CMSG_DATA(&control.cmsg), &payload_fd, sizeof(int)); ++ c_memcpy(CMSG_DATA(&control.cmsg), &payload_fd, sizeof(int)); + + msg = (struct msghdr){ + .msg_control = &control.cmsg, +@@ -590,7 +590,7 @@ + return; + } + +- memcpy(log->map + log->offset, data, n_data); ++ c_memcpy(log->map + log->offset, data, n_data); + log->offset += n_data; + } + +--- a/src/util/selinux.c ++++ b/src/util/selinux.c +@@ -71,7 +71,7 @@ + return error_origin(-ENOMEM); + selinux_name->rb = (CRBNode)C_RBNODE_INIT(selinux_name->rb); + selinux_name->context = NULL; +- memcpy(selinux_name->name, name, n_name); ++ c_memcpy(selinux_name->name, name, n_name); + + selinux_name->context = strdup(context); + if (!selinux_name->context) +@@ -105,7 +105,7 @@ + registry->n_refs = REF_INIT; + registry->fallback_context = (const char *)(registry + 1); + registry->names = (CRBTree)C_RBTREE_INIT; +- memcpy((char *)registry->fallback_context, fallback_context, n_fallback_context); ++ c_memcpy((char *)registry->fallback_context, fallback_context, n_fallback_context); + + *registryp = registry; + registry = NULL; +--- a/src/util/user.c ++++ b/src/util/user.c +@@ -389,7 +389,7 @@ + + registry->log = log; + registry->n_slots = n_slots; +- memcpy(registry->maxima, maxima, n_slots * sizeof(*registry->maxima)); ++ c_memcpy(registry->maxima, maxima, n_slots * sizeof(*registry->maxima)); + + return 0; + } +--- a/test/dbus/test-fdstream.c ++++ b/test/dbus/test-fdstream.c +@@ -74,7 +74,7 @@ + if (n_fds > 0) { + int fds[n_fds]; + +- memset(fds, 0, sizeof(fds)); ++ c_memset(fds, 0, sizeof(fds)); + r = fdlist_new_with_fds(&m->fds, fds, n_fds); + c_assert(!r); + } +--- a/test/dbus/util-message.c ++++ b/test/dbus/util-message.c +@@ -43,7 +43,7 @@ + p = realloc(*buf, *n_buf + n_data); + c_assert(p); + +- memcpy(p + *n_buf, data, n_data); ++ c_memcpy(p + *n_buf, data, n_data); + + *buf = p; + *n_buf += n_data; diff -Nru dbus-broker-26/debian/patches/launch-service-fix-release-of-argv-array.patch dbus-broker-26/debian/patches/launch-service-fix-release-of-argv-array.patch --- dbus-broker-26/debian/patches/launch-service-fix-release-of-argv-array.patch 1970-01-01 01:00:00.000000000 +0100 +++ dbus-broker-26/debian/patches/launch-service-fix-release-of-argv-array.patch 2022-08-04 12:55:19.000000000 +0100 @@ -0,0 +1,30 @@ +Author: David Rheinsberg <david.rheinsb...@gmail.com> +Origin: backport, https://github.com/bus1/dbus-broker/commit/6d9b817b7c165be9addbc28b9e84d7ed1697d11a +Description: launch/service: fix release of argv array + While service_free() correctly releases the strv in `argv`, the + service_update() path does not. It frees `argv`, but not the individual + entries. Fix this and properly release all entries. +--- a/src/launch/service.c ++++ b/src/launch/service.c +@@ -96,8 +96,12 @@ + } + + int service_update(Service *service, const char *path, const char *unit, size_t argc, char **argv, const char *user, uid_t uid) { ++ size_t i; ++ + service->path = c_free(service->path); + service->unit = c_free(service->unit); ++ for (i = 0; i < service->argc; ++i) ++ free(service->argv[i]); + service->argc = 0; + service->argv = c_free(service->argv); + service->user = c_free(service->user); +@@ -122,7 +126,7 @@ + + service->argc = argc; + +- for (size_t i = 0; i < argc; ++i) { ++ for (i = 0; i < argc; ++i) { + service->argv[i] = strdup(argv[i]); + if (!service->argv[i]) + return error_origin(-ENOMEM); diff -Nru dbus-broker-26/debian/patches/series dbus-broker-26/debian/patches/series --- dbus-broker-26/debian/patches/series 2022-06-22 22:23:12.000000000 +0100 +++ dbus-broker-26/debian/patches/series 2022-08-04 12:55:19.000000000 +0100 @@ -1 +1,6 @@ strnspn-fix-buffer-overflow.patch +util-user-keep-reference-to-user-in-each-usage-table.patch +launch-service-fix-release-of-argv-array.patch +c-stdaux-add-c_memset.patch +c-stdaux-add-c_memcpy.patch +global-use-c_mem-over-mem.patch diff -Nru dbus-broker-26/debian/patches/util-user-keep-reference-to-user-in-each-usage-table.patch dbus-broker-26/debian/patches/util-user-keep-reference-to-user-in-each-usage-table.patch --- dbus-broker-26/debian/patches/util-user-keep-reference-to-user-in-each-usage-table.patch 1970-01-01 01:00:00.000000000 +0100 +++ dbus-broker-26/debian/patches/util-user-keep-reference-to-user-in-each-usage-table.patch 2022-08-04 12:55:19.000000000 +0100 @@ -0,0 +1,49 @@ +Author: David Rheinsberg <david.rheinsb...@gmail.com> +Origin: backport, https://github.com/bus1/dbus-broker/commit/608b259e25ef1348b9e4a8e022c35b5c68d3df98 +Description: util/user: keep reference to user in each usage table + Keep a reference to an owning user in each usage table. We want to allow + callers to hold charges without holding on to any user references. + . + Also fix the peer-deinitialization to be ordered correctly and free the + user references last (in particular, after the charges). This is not + strictly necessary, but now follows our coding style and would have + avoided possible failures. + . + This fixes an assertion failure when disconnecting entire groups of + peers of the same user, due to the recent fix that actually made + peer-accounting do something. +--- a/src/bus/peer.c ++++ b/src/bus/peer.c +@@ -358,12 +358,12 @@ + name_owner_deinit(&peer->owned_names); + policy_snapshot_free(peer->policy); + connection_deinit(&peer->connection); +- user_unref(peer->user); + user_charge_deinit(&peer->charges[2]); + user_charge_deinit(&peer->charges[1]); + user_charge_deinit(&peer->charges[0]); + free(peer->seclabel); + free(peer->gids); ++ user_unref(peer->user); + free(peer); + + close(fd); +--- a/src/util/user.c ++++ b/src/util/user.c +@@ -48,7 +48,7 @@ + return error_origin(-ENOMEM); + + usage->n_refs = REF_INIT; +- usage->user = user; ++ usage->user = user_ref(user); + usage->uid = uid; + usage->user_node = (CRBNode)C_RBNODE_INIT(usage->user_node); + +@@ -64,6 +64,7 @@ + c_assert(!usage->slots[i]); + + user_usage_unlink(usage); ++ user_unref(usage->user); + free(usage); + } +
signature.asc
Description: This is a digitally signed message part