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);
+ }
+ 

Attachment: signature.asc
Description: This is a digitally signed message part

Reply via email to