Dear Security Team, I'm ready to upload libqb-1.0.1-1+deb9u1 with the following debdiff:
diff -Nru libqb-1.0.1/debian/changelog libqb-1.0.1/debian/changelog --- libqb-1.0.1/debian/changelog 2016-12-07 14:55:45.000000000 +0100 +++ libqb-1.0.1/debian/changelog 2019-06-16 23:41:50.000000000 +0200 @@ -1,3 +1,21 @@ +libqb (1.0.1-1+deb9u1) stretch-security; urgency=high + + * [38e0e13] Backport upstream security fixes for CVE-2019-12779. + Libqb creates files in world-writable directories (/dev/shm, /tmp) with + rather predictable file names (for example in case of USBGuard with names + like /dev/shm/qb-usbguard-request-7096-835-12-data). Also O_EXCL flag is + not used when opening the files. This could be exploited by a local + attacker to overwrite privileged system files (if not restricted by + sandboxing, MAC or symlinking policies). + Original report: https://github.com/ClusterLabs/libqb/issues/338 + Add O_EXCL: https://github.com/ClusterLabs/libqb/pull/339 + Use mkdtemp(): https://github.com/ClusterLabs/libqb/pull/345 + Regression fixes: https://github.com/ClusterLabs/libqb/pull/349 + (Closes: #927159) + * [79734d7] Acknowledge new internal symbol + + -- Ferenc Wágner <wf...@debian.org> Sun, 16 Jun 2019 23:41:50 +0200 + libqb (1.0.1-1) unstable; urgency=medium [ Christoph Berg ] diff -Nru libqb-1.0.1/debian/gbp.conf libqb-1.0.1/debian/gbp.conf --- libqb-1.0.1/debian/gbp.conf 2016-12-07 14:47:16.000000000 +0100 +++ libqb-1.0.1/debian/gbp.conf 2019-06-16 22:48:22.000000000 +0200 @@ -1,14 +1,12 @@ [DEFAULT] -debian-branch = debian/master +debian-branch = debian/stretch upstream-branch = upstream/latest -debian-tag-msg = Debian release %(version)s - -[import-orig] pristine-tar = True -[gbp-pq] -patch-numbers = False - -[gbp-dch] +[dch] +full = True multimaint-merge = True id-length = 7 + +[pq] +patch-numbers = False diff -Nru libqb-1.0.1/debian/libqb0.symbols libqb-1.0.1/debian/libqb0.symbols --- libqb-1.0.1/debian/libqb0.symbols 2016-12-07 14:47:16.000000000 +0100 +++ libqb-1.0.1/debian/libqb0.symbols 2019-06-16 23:41:22.000000000 +0200 @@ -236,5 +236,6 @@ qb_util_timespec_from_epoch_get@Base 0.11.1 qb_vsnprintf_deserialize@Base 0.11.1 qb_vsnprintf_serialize@Base 0.14.2 + remove_tempdir@Base 1.0.1-1+deb9u1~ strlcat@Base 0.11.1 strlcpy@Base 0.11.1 diff -Nru libqb-1.0.1/debian/patches/CVE-2019-12779/Allow-group-access-to-the-IPC-directory.patch libqb-1.0.1/debian/patches/CVE-2019-12779/Allow-group-access-to-the-IPC-directory.patch --- libqb-1.0.1/debian/patches/CVE-2019-12779/Allow-group-access-to-the-IPC-directory.patch 1970-01-01 01:00:00.000000000 +0100 +++ libqb-1.0.1/debian/patches/CVE-2019-12779/Allow-group-access-to-the-IPC-directory.patch 2019-06-16 23:10:03.000000000 +0200 @@ -0,0 +1,29 @@ +From: =?utf-8?q?Ferenc_W=C3=A1gner?= <wf...@debian.org> +Date: Thu, 18 Apr 2019 13:20:38 +0200 +Subject: Allow group access to the IPC directory + +And don't abort if we aren't permitted to chown() it. The client might +still have the privileges to enter it. +--- + lib/ipc_setup.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/lib/ipc_setup.c b/lib/ipc_setup.c +index f6f1d7d..6183001 100644 +--- a/lib/ipc_setup.c ++++ b/lib/ipc_setup.c +@@ -640,11 +640,12 @@ handle_new_connection(struct qb_ipcs_service *s, + res = -errno; + goto send_response; + } +- res = chown(c->description, c->auth.uid, c->auth.gid); +- if (res != 0) { ++ if (chmod(c->description, 0770)) { + res = -errno; + goto send_response; + } ++ /* chown can fail because we might not be root */ ++ (void)chown(c->description, c->auth.uid, c->auth.gid); + + /* We can't pass just a directory spec to the clients */ + strncat(c->description,"/qb", CONNECTION_DESCRIPTION); diff -Nru libqb-1.0.1/debian/patches/CVE-2019-12779/Errors-are-represented-as-negative-values.patch libqb-1.0.1/debian/patches/CVE-2019-12779/Errors-are-represented-as-negative-values.patch --- libqb-1.0.1/debian/patches/CVE-2019-12779/Errors-are-represented-as-negative-values.patch 1970-01-01 01:00:00.000000000 +0100 +++ libqb-1.0.1/debian/patches/CVE-2019-12779/Errors-are-represented-as-negative-values.patch 2019-06-16 23:10:03.000000000 +0200 @@ -0,0 +1,27 @@ +From: =?utf-8?q?Ferenc_W=C3=A1gner?= <wf...@debian.org> +Date: Wed, 17 Apr 2019 15:09:42 +0200 +Subject: Errors are represented as negative values + +--- + lib/ipc_setup.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/lib/ipc_setup.c b/lib/ipc_setup.c +index a66004d..f6f1d7d 100644 +--- a/lib/ipc_setup.c ++++ b/lib/ipc_setup.c +@@ -637,12 +637,12 @@ handle_new_connection(struct qb_ipcs_service *s, + snprintf(c->description, CONNECTION_DESCRIPTION, + "/dev/shm/qb-%d-%d-%d-XXXXXX", s->pid, ugp->pid, c->setup.u.us.sock); + if (mkdtemp(c->description) == NULL) { +- res = errno; ++ res = -errno; + goto send_response; + } + res = chown(c->description, c->auth.uid, c->auth.gid); + if (res != 0) { +- res = errno; ++ res = -errno; + goto send_response; + } + diff -Nru libqb-1.0.1/debian/patches/CVE-2019-12779/ipc-Use-mkdtemp-for-more-secure-IPC-files.patch libqb-1.0.1/debian/patches/CVE-2019-12779/ipc-Use-mkdtemp-for-more-secure-IPC-files.patch --- libqb-1.0.1/debian/patches/CVE-2019-12779/ipc-Use-mkdtemp-for-more-secure-IPC-files.patch 1970-01-01 01:00:00.000000000 +0100 +++ libqb-1.0.1/debian/patches/CVE-2019-12779/ipc-Use-mkdtemp-for-more-secure-IPC-files.patch 2019-06-16 23:10:03.000000000 +0200 @@ -0,0 +1,226 @@ +From: Christine Caulfield <ccaul...@redhat.com> +Date: Mon, 8 Apr 2019 16:24:19 +0100 +Subject: ipc: Use mkdtemp for more secure IPC files + +Use mkdtemp makes sure that IPC files are only visible to the +owning (client) process and do not use predictable names outside +of that. + +This is not meant to be the last word on the subject, it's mainly a +simple way of making the current libqb more secure. Importantly, it's +backwards compatible with an old server. + +It calls rmdir on the directory created by mkdtemp way too often, but +it seems to be the only way to be sure that things get cleaned up on +the various types of server/client exit. I'm sure we can come up with +something tidier for master but I hope this, or something similar, will +be OK for 1.0.x. +--- + lib/ipc_int.h | 4 +++- + lib/ipc_setup.c | 39 +++++++++++++++++++++++++++++++++++++++ + lib/ipc_shm.c | 8 +++++--- + lib/ipc_socket.c | 13 ++++++++++--- + lib/ipcs.c | 3 ++- + lib/ringbuffer.c | 4 ++-- + lib/unix.c | 4 +++- + 7 files changed, 64 insertions(+), 11 deletions(-) + +diff --git a/lib/ipc_int.h b/lib/ipc_int.h +index f63e053..a5c3e56 100644 +--- a/lib/ipc_int.h ++++ b/lib/ipc_int.h +@@ -160,7 +160,7 @@ enum qb_ipcs_connection_state { + QB_IPCS_CONNECTION_SHUTTING_DOWN, + }; + +-#define CONNECTION_DESCRIPTION (34) /* INT_MAX length + 3 */ ++#define CONNECTION_DESCRIPTION NAME_MAX + + struct qb_ipcs_connection_auth { + uid_t uid; +@@ -205,4 +205,6 @@ int32_t qb_ipcs_process_request(struct qb_ipcs_service *s, + + int32_t qb_ipc_us_sock_error_is_disconnected(int err); + ++void remove_tempdir(const char *name, size_t namelen); ++ + #endif /* QB_IPC_INT_H_DEFINED */ +diff --git a/lib/ipc_setup.c b/lib/ipc_setup.c +index 1724fb2..a66004d 100644 +--- a/lib/ipc_setup.c ++++ b/lib/ipc_setup.c +@@ -632,8 +632,28 @@ handle_new_connection(struct qb_ipcs_service *s, + c->auth.gid = c->egid = ugp->gid; + c->auth.mode = 0600; + c->stats.client_pid = ugp->pid; ++ ++#if defined(QB_LINUX) || defined(QB_CYGWIN) ++ snprintf(c->description, CONNECTION_DESCRIPTION, ++ "/dev/shm/qb-%d-%d-%d-XXXXXX", s->pid, ugp->pid, c->setup.u.us.sock); ++ if (mkdtemp(c->description) == NULL) { ++ res = errno; ++ goto send_response; ++ } ++ res = chown(c->description, c->auth.uid, c->auth.gid); ++ if (res != 0) { ++ res = errno; ++ goto send_response; ++ } ++ ++ /* We can't pass just a directory spec to the clients */ ++ strncat(c->description,"/qb", CONNECTION_DESCRIPTION); ++#else + snprintf(c->description, CONNECTION_DESCRIPTION, + "%d-%d-%d", s->pid, ugp->pid, c->setup.u.us.sock); ++#endif ++ ++ + + if (auth_result == 0 && c->service->serv_fns.connection_accept) { + res = c->service->serv_fns.connection_accept(c, +@@ -854,3 +874,22 @@ retry_accept: + qb_ipcs_uc_recv_and_auth(new_fd, s); + return 0; + } ++ ++void remove_tempdir(const char *name, size_t namelen) ++{ ++#if defined(QB_LINUX) || defined(QB_CYGWIN) ++ char dirname[PATH_MAX]; ++ char *slash; ++ memcpy(dirname, name, namelen); ++ ++ slash = strrchr(dirname, '/'); ++ if (slash) { ++ *slash = '\0'; ++ /* This gets called more than it needs to be really, so we don't check ++ * the return code. It's more of a desperate attempt to clean up after ourself ++ * in either the server or client. ++ */ ++ (void)rmdir(dirname); ++ } ++#endif ++} +diff --git a/lib/ipc_shm.c b/lib/ipc_shm.c +index 699f4e4..bdd0a0d 100644 +--- a/lib/ipc_shm.c ++++ b/lib/ipc_shm.c +@@ -239,6 +239,8 @@ qb_ipcs_shm_disconnect(struct qb_ipcs_connection *c) + qb_rb_close(qb_rb_lastref_and_ret(&c->request.u.shm.rb)); + } + } ++ ++ remove_tempdir(c->description, CONNECTION_DESCRIPTION); + } + + static int32_t +@@ -285,11 +287,11 @@ qb_ipcs_shm_connect(struct qb_ipcs_service *s, + qb_util_log(LOG_DEBUG, "connecting to client [%d]", c->pid); + + snprintf(r->request, NAME_MAX, "%s-request-%s", +- s->name, c->description); ++ c->description, s->name); + snprintf(r->response, NAME_MAX, "%s-response-%s", +- s->name, c->description); ++ c->description, s->name); + snprintf(r->event, NAME_MAX, "%s-event-%s", +- s->name, c->description); ++ c->description, s->name); + + res = qb_ipcs_shm_rb_open(c, &c->request, + r->request); +diff --git a/lib/ipc_socket.c b/lib/ipc_socket.c +index 8aaa420..22fbb95 100644 +--- a/lib/ipc_socket.c ++++ b/lib/ipc_socket.c +@@ -346,6 +346,10 @@ qb_ipcc_us_disconnect(struct qb_ipcc_connection *c) + unlink(sock_name); + } + #endif ++ ++ /* Last-ditch attempt to tidy up after ourself */ ++ remove_tempdir(c->request.u.us.shared_file_name, PATH_MAX); ++ + qb_ipcc_us_sock_close(c->event.u.us.sock); + qb_ipcc_us_sock_close(c->request.u.us.sock); + qb_ipcc_us_sock_close(c->setup.u.us.sock); +@@ -726,7 +730,10 @@ qb_ipcs_us_disconnect(struct qb_ipcs_connection *c) + c->state == QB_IPCS_CONNECTION_ACTIVE) { + munmap(c->request.u.us.shared_data, SHM_CONTROL_SIZE); + unlink(c->request.u.us.shared_file_name); ++ ++ + } ++ remove_tempdir(c->description, CONNECTION_DESCRIPTION); + } + + static int32_t +@@ -745,9 +752,9 @@ qb_ipcs_us_connect(struct qb_ipcs_service *s, + c->request.u.us.sock = c->setup.u.us.sock; + c->response.u.us.sock = c->setup.u.us.sock; + +- snprintf(r->request, NAME_MAX, "qb-%s-control-%s", +- s->name, c->description); +- snprintf(r->response, NAME_MAX, "qb-%s-%s", s->name, c->description); ++ snprintf(r->request, NAME_MAX, "%s-control-%s", ++ c->description, s->name); ++ snprintf(r->response, NAME_MAX, "%s-%s", c->description, s->name); + + fd_hdr = qb_sys_mmap_file_open(path, r->request, + SHM_CONTROL_SIZE, +diff --git a/lib/ipcs.c b/lib/ipcs.c +index 4a375fc..29f3431 100644 +--- a/lib/ipcs.c ++++ b/lib/ipcs.c +@@ -642,12 +642,13 @@ qb_ipcs_disconnect(struct qb_ipcs_connection *c) + scheduled_retry = 1; + } + } +- ++ remove_tempdir(c->description, CONNECTION_DESCRIPTION); + if (scheduled_retry == 0) { + /* This removes the initial alloc ref */ + qb_ipcs_connection_unref(c); + } + } ++ + } + + static void +diff --git a/lib/ringbuffer.c b/lib/ringbuffer.c +index dde95dd..81a3cba 100644 +--- a/lib/ringbuffer.c ++++ b/lib/ringbuffer.c +@@ -166,7 +166,7 @@ qb_rb_open_2(const char *name, size_t size, uint32_t flags, + /* + * Create a shared_hdr memory segment for the header. + */ +- snprintf(filename, PATH_MAX, "qb-%s-header", name); ++ snprintf(filename, PATH_MAX, "%s-header", name); + fd_hdr = qb_sys_mmap_file_open(path, filename, + shared_size, file_flags); + if (fd_hdr < 0) { +@@ -217,7 +217,7 @@ qb_rb_open_2(const char *name, size_t size, uint32_t flags, + * They have to be separate. + */ + if (flags & QB_RB_FLAG_CREATE) { +- snprintf(filename, PATH_MAX, "qb-%s-data", name); ++ snprintf(filename, PATH_MAX, "%s-data", name); + fd_data = qb_sys_mmap_file_open(path, + filename, + real_size, file_flags); +diff --git a/lib/unix.c b/lib/unix.c +index c31145e..643f361 100644 +--- a/lib/unix.c ++++ b/lib/unix.c +@@ -81,7 +81,9 @@ qb_sys_mmap_file_open(char *path, const char *file, size_t bytes, + (void)strlcpy(path, file, PATH_MAX); + } else { + #if defined(QB_LINUX) || defined(QB_CYGWIN) || defined(QB_GNU) +- snprintf(path, PATH_MAX, "/dev/shm/%s", file); ++ /* This is only now called when talking to an old libqb ++ where we need to add qb- to the name */ ++ snprintf(path, PATH_MAX, "/dev/shm/qb-%s", file); + #else + snprintf(path, PATH_MAX, "%s/%s", SOCKETDIR, file); + is_absolute = path; diff -Nru libqb-1.0.1/debian/patches/CVE-2019-12779/ipc-use-O_EXCL-when-opening-IPC-files.patch libqb-1.0.1/debian/patches/CVE-2019-12779/ipc-use-O_EXCL-when-opening-IPC-files.patch --- libqb-1.0.1/debian/patches/CVE-2019-12779/ipc-use-O_EXCL-when-opening-IPC-files.patch 1970-01-01 01:00:00.000000000 +0100 +++ libqb-1.0.1/debian/patches/CVE-2019-12779/ipc-use-O_EXCL-when-opening-IPC-files.patch 2019-06-16 23:10:03.000000000 +0200 @@ -0,0 +1,35 @@ +From: Christine Caulfield <ccaul...@redhat.com> +Date: Mon, 8 Apr 2019 13:31:38 +0100 +Subject: ipc: use O_EXCL when opening IPC files + +--- + lib/ipc_socket.c | 2 +- + lib/ringbuffer.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/lib/ipc_socket.c b/lib/ipc_socket.c +index 09981b4..8aaa420 100644 +--- a/lib/ipc_socket.c ++++ b/lib/ipc_socket.c +@@ -751,7 +751,7 @@ qb_ipcs_us_connect(struct qb_ipcs_service *s, + + fd_hdr = qb_sys_mmap_file_open(path, r->request, + SHM_CONTROL_SIZE, +- O_CREAT | O_TRUNC | O_RDWR); ++ O_CREAT | O_TRUNC | O_RDWR | O_EXCL); + if (fd_hdr < 0) { + res = fd_hdr; + errno = -fd_hdr; +diff --git a/lib/ringbuffer.c b/lib/ringbuffer.c +index 60b0ea1..dde95dd 100644 +--- a/lib/ringbuffer.c ++++ b/lib/ringbuffer.c +@@ -155,7 +155,7 @@ qb_rb_open_2(const char *name, size_t size, uint32_t flags, + sizeof(struct qb_ringbuffer_shared_s) + shared_user_data_size; + + if (flags & QB_RB_FLAG_CREATE) { +- file_flags |= O_CREAT | O_TRUNC; ++ file_flags |= O_CREAT | O_TRUNC | O_EXCL; + } + + rb = calloc(1, sizeof(struct qb_ringbuffer_s)); diff -Nru libqb-1.0.1/debian/patches/CVE-2019-12779/Let-remote_tempdir-assume-a-NUL-terminated-name.patch libqb-1.0.1/debian/patches/CVE-2019-12779/Let-remote_tempdir-assume-a-NUL-terminated-name.patch --- libqb-1.0.1/debian/patches/CVE-2019-12779/Let-remote_tempdir-assume-a-NUL-terminated-name.patch 1970-01-01 01:00:00.000000000 +0100 +++ libqb-1.0.1/debian/patches/CVE-2019-12779/Let-remote_tempdir-assume-a-NUL-terminated-name.patch 2019-06-16 23:10:03.000000000 +0200 @@ -0,0 +1,100 @@ +From: =?utf-8?q?Ferenc_W=C3=A1gner?= <wf...@debian.org> +Date: Thu, 18 Apr 2019 16:06:04 +0200 +Subject: Let remote_tempdir() assume a NUL-terminated name + +This is the case already. We also fix a buffer overflow opportunity in +the memcpy() call by this change. +--- + lib/ipc_int.h | 2 +- + lib/ipc_setup.c | 11 +++++------ + lib/ipc_shm.c | 2 +- + lib/ipc_socket.c | 4 ++-- + lib/ipcs.c | 2 +- + 5 files changed, 10 insertions(+), 11 deletions(-) + +diff --git a/lib/ipc_int.h b/lib/ipc_int.h +index a5c3e56..d3dde49 100644 +--- a/lib/ipc_int.h ++++ b/lib/ipc_int.h +@@ -205,6 +205,6 @@ int32_t qb_ipcs_process_request(struct qb_ipcs_service *s, + + int32_t qb_ipc_us_sock_error_is_disconnected(int err); + +-void remove_tempdir(const char *name, size_t namelen); ++void remove_tempdir(const char *name); + + #endif /* QB_IPC_INT_H_DEFINED */ +diff --git a/lib/ipc_setup.c b/lib/ipc_setup.c +index 070f9d3..b660db4 100644 +--- a/lib/ipc_setup.c ++++ b/lib/ipc_setup.c +@@ -894,16 +894,15 @@ retry_accept: + return 0; + } + +-void remove_tempdir(const char *name, size_t namelen) ++void remove_tempdir(const char *name) + { + #if defined(QB_LINUX) || defined(QB_CYGWIN) + char dirname[PATH_MAX]; +- char *slash; +- memcpy(dirname, name, namelen); ++ char *slash = strrchr(name, '/'); + +- slash = strrchr(dirname, '/'); +- if (slash) { +- *slash = '\0'; ++ if (slash && slash - name < sizeof dirname) { ++ memcpy(dirname, name, slash - name); ++ dirname[slash - name] = '\0'; + /* This gets called more than it needs to be really, so we don't check + * the return code. It's more of a desperate attempt to clean up after ourself + * in either the server or client. +diff --git a/lib/ipc_shm.c b/lib/ipc_shm.c +index bdd0a0d..41906cb 100644 +--- a/lib/ipc_shm.c ++++ b/lib/ipc_shm.c +@@ -240,7 +240,7 @@ qb_ipcs_shm_disconnect(struct qb_ipcs_connection *c) + } + } + +- remove_tempdir(c->description, CONNECTION_DESCRIPTION); ++ remove_tempdir(c->description); + } + + static int32_t +diff --git a/lib/ipc_socket.c b/lib/ipc_socket.c +index 22fbb95..81bb53d 100644 +--- a/lib/ipc_socket.c ++++ b/lib/ipc_socket.c +@@ -348,7 +348,7 @@ qb_ipcc_us_disconnect(struct qb_ipcc_connection *c) + #endif + + /* Last-ditch attempt to tidy up after ourself */ +- remove_tempdir(c->request.u.us.shared_file_name, PATH_MAX); ++ remove_tempdir(c->request.u.us.shared_file_name); + + qb_ipcc_us_sock_close(c->event.u.us.sock); + qb_ipcc_us_sock_close(c->request.u.us.sock); +@@ -733,7 +733,7 @@ qb_ipcs_us_disconnect(struct qb_ipcs_connection *c) + + + } +- remove_tempdir(c->description, CONNECTION_DESCRIPTION); ++ remove_tempdir(c->description); + } + + static int32_t +diff --git a/lib/ipcs.c b/lib/ipcs.c +index 29f3431..0609e46 100644 +--- a/lib/ipcs.c ++++ b/lib/ipcs.c +@@ -642,7 +642,7 @@ qb_ipcs_disconnect(struct qb_ipcs_connection *c) + scheduled_retry = 1; + } + } +- remove_tempdir(c->description, CONNECTION_DESCRIPTION); ++ remove_tempdir(c->description); + if (scheduled_retry == 0) { + /* This removes the initial alloc ref */ + qb_ipcs_connection_unref(c); diff -Nru libqb-1.0.1/debian/patches/CVE-2019-12779/Make-it-impossible-to-truncate-or-overflow-the-connection.patch libqb-1.0.1/debian/patches/CVE-2019-12779/Make-it-impossible-to-truncate-or-overflow-the-connection.patch --- libqb-1.0.1/debian/patches/CVE-2019-12779/Make-it-impossible-to-truncate-or-overflow-the-connection.patch 1970-01-01 01:00:00.000000000 +0100 +++ libqb-1.0.1/debian/patches/CVE-2019-12779/Make-it-impossible-to-truncate-or-overflow-the-connection.patch 2019-06-16 23:10:03.000000000 +0200 @@ -0,0 +1,72 @@ +From: =?utf-8?q?Ferenc_W=C3=A1gner?= <wf...@debian.org> +Date: Thu, 18 Apr 2019 14:32:46 +0200 +Subject: Make it impossible to truncate or overflow the connection description + +It's hard to predict the length of formatted output, so we'd better +notice (and abort) if the description is truncated. Incidentally, +mkdtemp() does this for us in the shared memory branch, but do an +explicit check there as well for consistency, and get rid of the wrongly +parametrized strncat() risking a buffer overflow (CONNECTION_DESCRIPTION +is not the length of the source "/qb"). + +Similar truncation checks should be added to qb_ipcs_{shm,us}_connect() +where they build the request/response names, and possibly to other +places using snprintf(). +--- + lib/ipc_setup.c | 28 +++++++++++++++++++++++----- + 1 file changed, 23 insertions(+), 5 deletions(-) + +diff --git a/lib/ipc_setup.c b/lib/ipc_setup.c +index 6183001..070f9d3 100644 +--- a/lib/ipc_setup.c ++++ b/lib/ipc_setup.c +@@ -610,6 +610,8 @@ handle_new_connection(struct qb_ipcs_service *s, + int32_t res2 = 0; + uint32_t max_buffer_size = QB_MAX(req->max_msg_size, s->max_buffer_size); + struct qb_ipc_connection_response response; ++ const char suffix[] = "/qb"; ++ int desc_len; + + c = qb_ipcs_connection_alloc(s); + if (c == NULL) { +@@ -634,8 +636,16 @@ handle_new_connection(struct qb_ipcs_service *s, + c->stats.client_pid = ugp->pid; + + #if defined(QB_LINUX) || defined(QB_CYGWIN) +- snprintf(c->description, CONNECTION_DESCRIPTION, +- "/dev/shm/qb-%d-%d-%d-XXXXXX", s->pid, ugp->pid, c->setup.u.us.sock); ++ desc_len = snprintf(c->description, CONNECTION_DESCRIPTION - sizeof suffix, ++ "/dev/shm/qb-%d-%d-%d-XXXXXX", s->pid, ugp->pid, c->setup.u.us.sock); ++ if (desc_len < 0) { ++ res = -errno; ++ goto send_response; ++ } ++ if (desc_len >= CONNECTION_DESCRIPTION - sizeof suffix) { ++ res = -ENAMETOOLONG; ++ goto send_response; ++ } + if (mkdtemp(c->description) == NULL) { + res = -errno; + goto send_response; +@@ -648,10 +658,18 @@ handle_new_connection(struct qb_ipcs_service *s, + (void)chown(c->description, c->auth.uid, c->auth.gid); + + /* We can't pass just a directory spec to the clients */ +- strncat(c->description,"/qb", CONNECTION_DESCRIPTION); ++ memcpy(c->description + desc_len, suffix, sizeof suffix); + #else +- snprintf(c->description, CONNECTION_DESCRIPTION, +- "%d-%d-%d", s->pid, ugp->pid, c->setup.u.us.sock); ++ desc_len = snprintf(c->description, CONNECTION_DESCRIPTION, ++ "%d-%d-%d", s->pid, ugp->pid, c->setup.u.us.sock); ++ if (desc_len < 0) { ++ res = -errno; ++ goto send_response; ++ } ++ if (desc_len >= CONNECTION_DESCRIPTION) { ++ res = -ENAMETOOLONG; ++ goto send_response; ++ } + #endif + + diff -Nru libqb-1.0.1/debian/patches/series libqb-1.0.1/debian/patches/series --- libqb-1.0.1/debian/patches/series 2016-12-07 14:54:25.000000000 +0100 +++ libqb-1.0.1/debian/patches/series 2019-06-16 23:10:03.000000000 +0200 @@ -9,3 +9,9 @@ Restrict-pthreads-to-where-it-s-actually-needed.patch Restrict-socket-lib-to-where-it-s-actually-needed.patch Restrict-nsl-lib-to-where-it-s-actually-needed.patch +CVE-2019-12779/ipc-use-O_EXCL-when-opening-IPC-files.patch +CVE-2019-12779/ipc-Use-mkdtemp-for-more-secure-IPC-files.patch +CVE-2019-12779/Errors-are-represented-as-negative-values.patch +CVE-2019-12779/Allow-group-access-to-the-IPC-directory.patch +CVE-2019-12779/Make-it-impossible-to-truncate-or-overflow-the-connection.patch +CVE-2019-12779/Let-remote_tempdir-assume-a-NUL-terminated-name.patch It would be best released together with pacemaker_1.1.16-1+deb9u1 (already in your review queue), because this libqb security upgrade requires a restart of the full cluster stack (corosync and pacemaker) anyway to replace all the vulnerable library code. Such restarts may mean temporary service degradation, so the fewer the better. -- Regards, Feri