!17 Upgrade to 1.0.5
From: @si-gui Reviewed-by: @liqingqing_1229 Signed-off-by: @liqingqing_1229
This commit is contained in:
commit
39989275b4
1770
IPC-avoid-temporary-channel-priority-loss.patch
Normal file
1770
IPC-avoid-temporary-channel-priority-loss.patch
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,134 +0,0 @@
|
|||||||
From e322e98dc264bc5911d6fe1d371e55ac9f95a71e Mon Sep 17 00:00:00 2001
|
|
||||||
From: Christine Caulfield <ccaulfie@redhat.com>
|
|
||||||
Date: Tue, 12 Mar 2019 10:15:41 +0000
|
|
||||||
Subject: [PATCH] ipc: use O_EXCL on SHM files, and randomize the names
|
|
||||||
|
|
||||||
Signed-off-by: Christine Caulfield <ccaulfie@redhat.com>
|
|
||||||
---
|
|
||||||
lib/ipc_setup.c | 14 ++++++++++++--
|
|
||||||
lib/ipc_socket.c | 2 +-
|
|
||||||
lib/ipcs.c | 14 ++++++++++++++
|
|
||||||
lib/log_blackbox.c | 2 +-
|
|
||||||
lib/ringbuffer.c | 2 +-
|
|
||||||
5 files changed, 29 insertions(+), 5 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/lib/ipc_setup.c b/lib/ipc_setup.c
|
|
||||||
index 0e169643..36ae2cfb 100644
|
|
||||||
--- a/lib/ipc_setup.c
|
|
||||||
+++ b/lib/ipc_setup.c
|
|
||||||
@@ -43,6 +43,9 @@
|
|
||||||
#include "util_int.h"
|
|
||||||
#include "ipc_int.h"
|
|
||||||
|
|
||||||
+/* Maximum number of times we generate a random socket name before giving up */
|
|
||||||
+#define MAX_NAME_RETRY_COUNT 20
|
|
||||||
+
|
|
||||||
struct ipc_auth_ugp {
|
|
||||||
uid_t uid;
|
|
||||||
gid_t gid;
|
|
||||||
@@ -619,6 +622,7 @@ handle_new_connection(struct qb_ipcs_service *s,
|
|
||||||
struct qb_ipc_connection_request *req = msg;
|
|
||||||
int32_t res = auth_result;
|
|
||||||
int32_t res2 = 0;
|
|
||||||
+ uint32_t retry_count = 0;
|
|
||||||
uint32_t max_buffer_size = QB_MAX(req->max_msg_size, s->max_buffer_size);
|
|
||||||
struct qb_ipc_connection_response response;
|
|
||||||
|
|
||||||
@@ -643,8 +647,6 @@ 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;
|
|
||||||
- snprintf(c->description, CONNECTION_DESCRIPTION,
|
|
||||||
- "%d-%d-%d", s->pid, ugp->pid, c->setup.u.us.sock);
|
|
||||||
|
|
||||||
if (auth_result == 0 && c->service->serv_fns.connection_accept) {
|
|
||||||
res = c->service->serv_fns.connection_accept(c,
|
|
||||||
@@ -657,9 +659,17 @@ handle_new_connection(struct qb_ipcs_service *s,
|
|
||||||
qb_util_log(LOG_DEBUG, "IPC credentials authenticated (%s)",
|
|
||||||
c->description);
|
|
||||||
|
|
||||||
+retry_description:
|
|
||||||
+ snprintf(c->description, CONNECTION_DESCRIPTION,
|
|
||||||
+ "%d-%d-%lu", s->pid, ugp->pid, (unsigned long)(random()%65536));
|
|
||||||
+
|
|
||||||
memset(&response, 0, sizeof(response));
|
|
||||||
if (s->funcs.connect) {
|
|
||||||
res = s->funcs.connect(s, c, &response);
|
|
||||||
+ if (res == -EEXIST && ++retry_count < MAX_NAME_RETRY_COUNT) {
|
|
||||||
+ qb_util_log(LOG_DEBUG, "Retrying socket name %s (count=%ld)\n", c->description, retry_count);
|
|
||||||
+ goto retry_description;
|
|
||||||
+ }
|
|
||||||
if (res != 0) {
|
|
||||||
goto send_response;
|
|
||||||
}
|
|
||||||
diff --git a/lib/ipc_socket.c b/lib/ipc_socket.c
|
|
||||||
index fe2040e2..1f7cde38 100644
|
|
||||||
--- a/lib/ipc_socket.c
|
|
||||||
+++ b/lib/ipc_socket.c
|
|
||||||
@@ -790,7 +790,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/ipcs.c b/lib/ipcs.c
|
|
||||||
index 4a375fca..573b4276 100644
|
|
||||||
--- a/lib/ipcs.c
|
|
||||||
+++ b/lib/ipcs.c
|
|
||||||
@@ -40,6 +40,8 @@ qb_ipcs_create(const char *name,
|
|
||||||
enum qb_ipc_type type, struct qb_ipcs_service_handlers *handlers)
|
|
||||||
{
|
|
||||||
struct qb_ipcs_service *s;
|
|
||||||
+ int fd;
|
|
||||||
+ unsigned int seed;
|
|
||||||
|
|
||||||
s = calloc(1, sizeof(struct qb_ipcs_service));
|
|
||||||
if (s == NULL) {
|
|
||||||
@@ -75,6 +77,18 @@ qb_ipcs_create(const char *name,
|
|
||||||
qb_list_init(&s->list);
|
|
||||||
qb_list_add(&s->list, &qb_ipc_services);
|
|
||||||
|
|
||||||
+ /* Randomise socket names */
|
|
||||||
+ fd = open("/dev/urandom", O_RDONLY);
|
|
||||||
+ if (fd == -1) {
|
|
||||||
+ seed = (time_t)time(NULL);
|
|
||||||
+ } else {
|
|
||||||
+ if (read(fd, &seed, sizeof(seed)) != 4) {
|
|
||||||
+ seed = (time_t)time(NULL);
|
|
||||||
+ }
|
|
||||||
+ close(fd);
|
|
||||||
+ }
|
|
||||||
+ srand(seed);
|
|
||||||
+
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
diff --git a/lib/log_blackbox.c b/lib/log_blackbox.c
|
|
||||||
index 64c30fe..a451742 100644
|
|
||||||
--- a/lib/log_blackbox.c
|
|
||||||
+++ b/lib/log_blackbox.c
|
|
||||||
@@ -165,7 +165,7 @@ qb_log_blackbox_write_to_file(const char *filename)
|
|
||||||
{
|
|
||||||
ssize_t written_size = 0;
|
|
||||||
struct qb_log_target *t;
|
|
||||||
- int fd = open(filename, O_CREAT | O_RDWR, 0700);
|
|
||||||
+ int fd = open(filename, O_CREAT | O_RDWR | O_EXCL, 0700);
|
|
||||||
|
|
||||||
if (fd < 0) {
|
|
||||||
return -errno;
|
|
||||||
diff --git a/lib/ringbuffer.c b/lib/ringbuffer.c
|
|
||||||
index 81411cb1..8852ff5b 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));
|
|
||||||
@ -1,106 +0,0 @@
|
|||||||
From 7cd7b06d52ac80c343f362c7e39ef75495439dfc Mon Sep 17 00:00:00 2001
|
|
||||||
From: Christine Caulfield <ccaulfie@redhat.com>
|
|
||||||
Date: Tue, 12 Mar 2019 14:08:47 +0000
|
|
||||||
Subject: [PATCH] ipc: fixes
|
|
||||||
|
|
||||||
Use O_EXCL on IPC files
|
|
||||||
---
|
|
||||||
lib/ipc_setup.c | 14 ++------------
|
|
||||||
lib/ipcs.c | 14 --------------
|
|
||||||
lib/log_blackbox.c | 2 +-
|
|
||||||
3 files changed, 3 insertions(+), 27 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/lib/ipc_setup.c b/lib/ipc_setup.c
|
|
||||||
index 36ae2cfb..0e169643 100644
|
|
||||||
--- a/lib/ipc_setup.c
|
|
||||||
+++ b/lib/ipc_setup.c
|
|
||||||
@@ -43,9 +43,6 @@
|
|
||||||
#include "util_int.h"
|
|
||||||
#include "ipc_int.h"
|
|
||||||
|
|
||||||
-/* Maximum number of times we generate a random socket name before giving up */
|
|
||||||
-#define MAX_NAME_RETRY_COUNT 20
|
|
||||||
-
|
|
||||||
struct ipc_auth_ugp {
|
|
||||||
uid_t uid;
|
|
||||||
gid_t gid;
|
|
||||||
@@ -622,7 +619,6 @@ handle_new_connection(struct qb_ipcs_service *s,
|
|
||||||
struct qb_ipc_connection_request *req = msg;
|
|
||||||
int32_t res = auth_result;
|
|
||||||
int32_t res2 = 0;
|
|
||||||
- uint32_t retry_count = 0;
|
|
||||||
uint32_t max_buffer_size = QB_MAX(req->max_msg_size, s->max_buffer_size);
|
|
||||||
struct qb_ipc_connection_response response;
|
|
||||||
|
|
||||||
@@ -647,6 +643,8 @@ 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;
|
|
||||||
+ snprintf(c->description, CONNECTION_DESCRIPTION,
|
|
||||||
+ "%d-%d-%d", s->pid, ugp->pid, c->setup.u.us.sock);
|
|
||||||
|
|
||||||
if (auth_result == 0 && c->service->serv_fns.connection_accept) {
|
|
||||||
res = c->service->serv_fns.connection_accept(c,
|
|
||||||
@@ -659,17 +657,9 @@ handle_new_connection(struct qb_ipcs_service *s,
|
|
||||||
qb_util_log(LOG_DEBUG, "IPC credentials authenticated (%s)",
|
|
||||||
c->description);
|
|
||||||
|
|
||||||
-retry_description:
|
|
||||||
- snprintf(c->description, CONNECTION_DESCRIPTION,
|
|
||||||
- "%d-%d-%lu", s->pid, ugp->pid, (unsigned long)(random()%65536));
|
|
||||||
-
|
|
||||||
memset(&response, 0, sizeof(response));
|
|
||||||
if (s->funcs.connect) {
|
|
||||||
res = s->funcs.connect(s, c, &response);
|
|
||||||
- if (res == -EEXIST && ++retry_count < MAX_NAME_RETRY_COUNT) {
|
|
||||||
- qb_util_log(LOG_DEBUG, "Retrying socket name %s (count=%ld)\n", c->description, retry_count);
|
|
||||||
- goto retry_description;
|
|
||||||
- }
|
|
||||||
if (res != 0) {
|
|
||||||
goto send_response;
|
|
||||||
}
|
|
||||||
diff --git a/lib/ipcs.c b/lib/ipcs.c
|
|
||||||
index 573b4276..4a375fca 100644
|
|
||||||
--- a/lib/ipcs.c
|
|
||||||
+++ b/lib/ipcs.c
|
|
||||||
@@ -40,8 +40,6 @@ qb_ipcs_create(const char *name,
|
|
||||||
enum qb_ipc_type type, struct qb_ipcs_service_handlers *handlers)
|
|
||||||
{
|
|
||||||
struct qb_ipcs_service *s;
|
|
||||||
- int fd;
|
|
||||||
- unsigned int seed;
|
|
||||||
|
|
||||||
s = calloc(1, sizeof(struct qb_ipcs_service));
|
|
||||||
if (s == NULL) {
|
|
||||||
@@ -77,18 +75,6 @@ qb_ipcs_create(const char *name,
|
|
||||||
qb_list_init(&s->list);
|
|
||||||
qb_list_add(&s->list, &qb_ipc_services);
|
|
||||||
|
|
||||||
- /* Randomise socket names */
|
|
||||||
- fd = open("/dev/urandom", O_RDONLY);
|
|
||||||
- if (fd == -1) {
|
|
||||||
- seed = (time_t)time(NULL);
|
|
||||||
- } else {
|
|
||||||
- if (read(fd, &seed, sizeof(seed)) != 4) {
|
|
||||||
- seed = (time_t)time(NULL);
|
|
||||||
- }
|
|
||||||
- close(fd);
|
|
||||||
- }
|
|
||||||
- srand(seed);
|
|
||||||
-
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
diff --git a/lib/log_blackbox.c b/lib/log_blackbox.c
|
|
||||||
index a451742..9727b4c 100644
|
|
||||||
--- a/lib/log_blackbox.c
|
|
||||||
+++ b/lib/log_blackbox.c
|
|
||||||
@@ -165,7 +165,7 @@ qb_log_blackbox_write_to_file(const char *filename)
|
|
||||||
{
|
|
||||||
ssize_t written_size = 0;
|
|
||||||
struct qb_log_target *t;
|
|
||||||
- int fd = open(filename, O_CREAT | O_RDWR | O_EXCL, 0700);
|
|
||||||
+ int fd = open(filename, O_CREAT | O_RDWR, 0700);
|
|
||||||
|
|
||||||
if (fd < 0) {
|
|
||||||
return -errno;
|
|
||||||
@ -1,228 +0,0 @@
|
|||||||
From 6a4067c1d1764d93d255eccecfd8bf9f43cb0b4d Mon Sep 17 00:00:00 2001
|
|
||||||
From: Christine Caulfield <ccaulfie@redhat.com>
|
|
||||||
Date: Mon, 8 Apr 2019 16:24:19 +0100
|
|
||||||
Subject: [PATCH] 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 | 9 ++++++---
|
|
||||||
lib/ipc_socket.c | 13 ++++++++++---
|
|
||||||
lib/ipcs.c | 3 ++-
|
|
||||||
lib/ringbuffer.c | 4 ++--
|
|
||||||
lib/unix.c | 4 +++-
|
|
||||||
7 files changed, 65 insertions(+), 11 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/lib/ipc_int.h b/lib/ipc_int.h
|
|
||||||
index 9cd06cfe..c8904487 100644
|
|
||||||
--- a/lib/ipc_int.h
|
|
||||||
+++ b/lib/ipc_int.h
|
|
||||||
@@ -161,7 +161,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;
|
|
||||||
@@ -208,4 +208,6 @@ int32_t qb_ipc_us_sock_error_is_disconnected(int err);
|
|
||||||
|
|
||||||
int use_filesystem_sockets(void);
|
|
||||||
|
|
||||||
+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 0e169643..43dc3e78 100644
|
|
||||||
--- a/lib/ipc_setup.c
|
|
||||||
+++ b/lib/ipc_setup.c
|
|
||||||
@@ -643,8 +643,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,
|
|
||||||
@@ -865,3 +885,22 @@ qb_ipcs_us_connection_acceptor(int fd, int revent, void *data)
|
|
||||||
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 9f237b6e..758a2b51 100644
|
|
||||||
--- a/lib/ipc_shm.c
|
|
||||||
+++ b/lib/ipc_shm.c
|
|
||||||
@@ -265,6 +265,9 @@ qb_ipcs_shm_disconnect(struct qb_ipcs_connection *c)
|
|
||||||
c->setup.u.us.sock = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+
|
|
||||||
+ remove_tempdir(c->description, CONNECTION_DESCRIPTION);
|
|
||||||
+
|
|
||||||
end_disconnect:
|
|
||||||
sigaction(SIGBUS, &old_sa, NULL);
|
|
||||||
}
|
|
||||||
@@ -313,11 +316,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 1f7cde38..59492323 100644
|
|
||||||
--- a/lib/ipc_socket.c
|
|
||||||
+++ b/lib/ipc_socket.c
|
|
||||||
@@ -374,6 +374,10 @@ qb_ipcc_us_disconnect(struct qb_ipcc_connection *c)
|
|
||||||
free(base_name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+
|
|
||||||
+ /* 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);
|
|
||||||
@@ -765,7 +769,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
|
|
||||||
@@ -784,9 +791,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 4a375fca..29f3431b 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 8852ff5b..f85ad979 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 3c8f327c..49701a33 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)
|
|
||||||
- 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;
|
|
||||||
@ -1,189 +0,0 @@
|
|||||||
From 75ab31bdd05a15947dc56edf4d6b7f377355435e Mon Sep 17 00:00:00 2001
|
|
||||||
From: Chrissie Caulfield <ccaulfie@redhat.com>
|
|
||||||
Date: Fri, 20 Apr 2018 09:48:04 +0100
|
|
||||||
Subject: [PATCH] ipc_shm: Don't truncate SHM files of an active server (#307)
|
|
||||||
|
|
||||||
* ipc_shm: Don't truncate SHM files of an active server
|
|
||||||
|
|
||||||
I've put in an extra check so that clients don't truncate the
|
|
||||||
SHM file if the server still exists. Sadly on FreeBSD we can't
|
|
||||||
get the server PID for the client (unless someone has a patch handy!)
|
|
||||||
so we still do the truncate when disconnected. As a backstop (and also
|
|
||||||
to cover the BSD issue) I've added a SIGBUS trap to the server shutdown
|
|
||||||
so that it doesn't cause a server crash.
|
|
||||||
|
|
||||||
Signed-off-by: Christine Caulfield <ccaulfie@redhat.com>
|
|
||||||
Reviewed by: Jan Friesse <jfriesse@redhat.com>
|
|
||||||
---
|
|
||||||
include/qb/qbipcs.h | 4 ++++
|
|
||||||
lib/ipc_int.h | 1 +
|
|
||||||
lib/ipc_setup.c | 1 +
|
|
||||||
lib/ipc_shm.c | 48 +++++++++++++++++++++++++++++++++++----------
|
|
||||||
tests/check_ipc.c | 24 +++++++++++++++++------
|
|
||||||
5 files changed, 62 insertions(+), 16 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/include/qb/qbipcs.h b/include/qb/qbipcs.h
|
|
||||||
index 55c0f815..7b4daa7d 100644
|
|
||||||
--- a/include/qb/qbipcs.h
|
|
||||||
+++ b/include/qb/qbipcs.h
|
|
||||||
@@ -142,6 +142,10 @@ typedef void (*qb_ipcs_connection_created_fn) (qb_ipcs_connection_t *c);
|
|
||||||
* successfully created.
|
|
||||||
* @note if you return anything but 0 this function will be
|
|
||||||
* repeatedly called (until 0 is returned).
|
|
||||||
+ *
|
|
||||||
+ * With SHM connections libqb will briefly trap SIGBUS during the
|
|
||||||
+ * disconnect process to guard against server crashes if the mapped
|
|
||||||
+ * file is truncated. The signal will be restored afterwards.
|
|
||||||
*/
|
|
||||||
typedef int32_t (*qb_ipcs_connection_closed_fn) (qb_ipcs_connection_t *c);
|
|
||||||
|
|
||||||
diff --git a/lib/ipc_int.h b/lib/ipc_int.h
|
|
||||||
index 67fc444c..9cd06cfe 100644
|
|
||||||
--- a/lib/ipc_int.h
|
|
||||||
+++ b/lib/ipc_int.h
|
|
||||||
@@ -92,6 +92,7 @@ struct qb_ipcc_connection {
|
|
||||||
char name[NAME_MAX];
|
|
||||||
int32_t needs_sock_for_poll;
|
|
||||||
gid_t egid;
|
|
||||||
+ pid_t server_pid;
|
|
||||||
struct qb_ipc_one_way setup;
|
|
||||||
struct qb_ipc_one_way request;
|
|
||||||
struct qb_ipc_one_way response;
|
|
||||||
diff --git a/lib/ipc_setup.c b/lib/ipc_setup.c
|
|
||||||
index 57d755b4..0e169643 100644
|
|
||||||
--- a/lib/ipc_setup.c
|
|
||||||
+++ b/lib/ipc_setup.c
|
|
||||||
@@ -494,6 +494,7 @@ qb_ipcc_us_setup_connect(struct qb_ipcc_connection *c,
|
|
||||||
|
|
||||||
qb_ipc_auth_creds(data);
|
|
||||||
c->egid = data->ugp.gid;
|
|
||||||
+ c->server_pid = data->ugp.pid;
|
|
||||||
|
|
||||||
destroy_ipc_auth_data(data);
|
|
||||||
return r->hdr.error;
|
|
||||||
diff --git a/lib/ipc_shm.c b/lib/ipc_shm.c
|
|
||||||
index 699f4e47..9f237b6e 100644
|
|
||||||
--- a/lib/ipc_shm.c
|
|
||||||
+++ b/lib/ipc_shm.c
|
|
||||||
@@ -20,6 +20,8 @@
|
|
||||||
*/
|
|
||||||
#include "os_base.h"
|
|
||||||
#include <poll.h>
|
|
||||||
+#include <signal.h>
|
|
||||||
+#include <setjmp.h>
|
|
||||||
|
|
||||||
#include "ipc_int.h"
|
|
||||||
#include "util_int.h"
|
|
||||||
@@ -36,9 +38,12 @@
|
|
||||||
static void
|
|
||||||
qb_ipcc_shm_disconnect(struct qb_ipcc_connection *c)
|
|
||||||
{
|
|
||||||
- void (*rb_destructor)(struct qb_ringbuffer_s *) = c->is_connected
|
|
||||||
- ? qb_rb_close
|
|
||||||
- : qb_rb_force_close;
|
|
||||||
+ void (*rb_destructor)(struct qb_ringbuffer_s *);
|
|
||||||
+
|
|
||||||
+ rb_destructor = qb_rb_close;
|
|
||||||
+ if (!c->is_connected && (!c->server_pid || (kill(c->server_pid, 0) == -1 && errno == ESRCH))) {
|
|
||||||
+ rb_destructor = qb_rb_force_close;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
qb_ipcc_us_sock_close(c->setup.u.us.sock);
|
|
||||||
|
|
||||||
@@ -215,18 +220,30 @@ qb_ipcc_shm_connect(struct qb_ipcc_connection * c,
|
|
||||||
* service functions
|
|
||||||
* --------------------------------------------------------
|
|
||||||
*/
|
|
||||||
+static jmp_buf sigbus_jmpbuf;
|
|
||||||
+static void catch_sigbus(int signal)
|
|
||||||
+{
|
|
||||||
+ longjmp(sigbus_jmpbuf, 1);
|
|
||||||
+}
|
|
||||||
|
|
||||||
static void
|
|
||||||
qb_ipcs_shm_disconnect(struct qb_ipcs_connection *c)
|
|
||||||
{
|
|
||||||
- if (c->state == QB_IPCS_CONNECTION_ESTABLISHED ||
|
|
||||||
- c->state == QB_IPCS_CONNECTION_ACTIVE) {
|
|
||||||
- if (c->setup.u.us.sock > 0) {
|
|
||||||
- (void)c->service->poll_fns.dispatch_del(c->setup.u.us.sock);
|
|
||||||
- qb_ipcc_us_sock_close(c->setup.u.us.sock);
|
|
||||||
- c->setup.u.us.sock = -1;
|
|
||||||
- }
|
|
||||||
+ struct sigaction sa;
|
|
||||||
+ struct sigaction old_sa;
|
|
||||||
+
|
|
||||||
+ /* Don't die if the client has truncated the SHM under us */
|
|
||||||
+ memset(&old_sa, 0, sizeof(old_sa));
|
|
||||||
+ memset(&sa, 0, sizeof(sa));
|
|
||||||
+ sa.sa_handler = catch_sigbus;
|
|
||||||
+ sigemptyset(&sa.sa_mask);
|
|
||||||
+ sa.sa_flags = 0;
|
|
||||||
+ sigaction(SIGBUS, &sa, &old_sa);
|
|
||||||
+
|
|
||||||
+ if (setjmp(sigbus_jmpbuf) == 1) {
|
|
||||||
+ goto end_disconnect;
|
|
||||||
}
|
|
||||||
+
|
|
||||||
if (c->state == QB_IPCS_CONNECTION_SHUTTING_DOWN ||
|
|
||||||
c->state == QB_IPCS_CONNECTION_ACTIVE) {
|
|
||||||
if (c->response.u.shm.rb) {
|
|
||||||
@@ -239,6 +256,17 @@ qb_ipcs_shm_disconnect(struct qb_ipcs_connection *c)
|
|
||||||
qb_rb_close(qb_rb_lastref_and_ret(&c->request.u.shm.rb));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+
|
|
||||||
+ if (c->state == QB_IPCS_CONNECTION_ESTABLISHED ||
|
|
||||||
+ c->state == QB_IPCS_CONNECTION_ACTIVE) {
|
|
||||||
+ if (c->setup.u.us.sock > 0) {
|
|
||||||
+ (void)c->service->poll_fns.dispatch_del(c->setup.u.us.sock);
|
|
||||||
+ qb_ipcc_us_sock_close(c->setup.u.us.sock);
|
|
||||||
+ c->setup.u.us.sock = -1;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+end_disconnect:
|
|
||||||
+ sigaction(SIGBUS, &old_sa, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t
|
|
||||||
diff --git a/tests/check_ipc.c b/tests/check_ipc.c
|
|
||||||
index f8af2c5e..46c3b404 100644
|
|
||||||
--- a/tests/check_ipc.c
|
|
||||||
+++ b/tests/check_ipc.c
|
|
||||||
@@ -444,18 +444,30 @@ run_ipc_server(void)
|
|
||||||
static pid_t
|
|
||||||
run_function_in_new_process(void (*run_ipc_server_fn)(void))
|
|
||||||
{
|
|
||||||
- pid_t pid = fork ();
|
|
||||||
+ pid_t pid1 = fork ();
|
|
||||||
+ pid_t pid2;
|
|
||||||
|
|
||||||
- if (pid == -1) {
|
|
||||||
+ if (pid1 == -1) {
|
|
||||||
fprintf (stderr, "Can't fork\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
- if (pid == 0) {
|
|
||||||
- run_ipc_server_fn();
|
|
||||||
- exit(0);
|
|
||||||
+ /* Double-fork so the servers can be reaped in a timely manner */
|
|
||||||
+ if (pid1 == 0) {
|
|
||||||
+ pid2 = fork();
|
|
||||||
+ if (pid2 == -1) {
|
|
||||||
+ fprintf (stderr, "Can't fork twice\n");
|
|
||||||
+ exit(0);
|
|
||||||
+ }
|
|
||||||
+ if (pid2 == 0) {
|
|
||||||
+ run_ipc_server_fn();
|
|
||||||
+ exit(0);
|
|
||||||
+ } else {
|
|
||||||
+ waitpid(pid2, NULL, 0);
|
|
||||||
+ exit(0);
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
- return pid;
|
|
||||||
+ return pid1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
Binary file not shown.
BIN
libqb-1.0.5.tar.xz
Normal file
BIN
libqb-1.0.5.tar.xz
Normal file
Binary file not shown.
37
libqb-fix-list-handling-gcc10.patch
Normal file
37
libqb-fix-list-handling-gcc10.patch
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
From 4f0a30f4e05e140e1325784195e79c5ec62c689c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Christine Caulfield <ccaulfie@redhat.com>
|
||||||
|
Date: Mon, 17 Feb 2020 16:28:57 +0000
|
||||||
|
Subject: [PATCH] list: fix list handling for gcc10
|
||||||
|
|
||||||
|
---
|
||||||
|
configure.ac | 1 -
|
||||||
|
include/qb/qblist.h | 4 ++--
|
||||||
|
2 files changed, 2 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/configure.ac b/configure.ac
|
||||||
|
index ec8736cb..108b2f18 100644
|
||||||
|
--- a/configure.ac
|
||||||
|
+++ b/configure.ac
|
||||||
|
@@ -558,7 +558,6 @@
|
||||||
|
suggest-attribute=noreturn
|
||||||
|
suggest-attribute=format
|
||||||
|
strict-prototypes
|
||||||
|
- pointer-arith
|
||||||
|
write-strings
|
||||||
|
cast-align
|
||||||
|
bad-function-cast
|
||||||
|
diff --git a/include/qb/qblist.h b/include/qb/qblist.h
|
||||||
|
index e3ae3f18..8064c874 100644
|
||||||
|
--- a/include/qb/qblist.h
|
||||||
|
+++ b/include/qb/qblist.h
|
||||||
|
@@ -193,8 +193,8 @@ static inline void qb_list_splice_tail(struct qb_list_head *list,
|
||||||
|
* @param type: the type of the struct this is embedded in.
|
||||||
|
* @param member: the name of the list_struct within the struct.
|
||||||
|
*/
|
||||||
|
-#define qb_list_entry(ptr,type,member)\
|
||||||
|
- ((type *)((char *)(ptr)-(char*)(&((type *)0)->member)))
|
||||||
|
+#define qb_list_entry(ptr,type,member) ({ \
|
||||||
|
+ ((type *)((void*)ptr - offsetof(type, member))); })
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the first element from a list
|
||||||
76
libqb.spec
76
libqb.spec
@ -1,58 +1,45 @@
|
|||||||
Name: libqb
|
Name: libqb
|
||||||
Version: 1.0.3
|
Version: 1.0.5
|
||||||
Release: 7
|
Release: 1
|
||||||
Summary: High performance servers IPC library
|
Summary: Library providing high performance logging, tracing, ipc, and poll
|
||||||
Group: System Environment/Libraries
|
License: LGPLv2+
|
||||||
License: LGPLv2+
|
URL: https://github.com/ClusterLabs/libqb
|
||||||
URL: https://github.com/ClusterLabs/libqb
|
Source0: https://github.com/ClusterLabs/libqb/releases/download/v%{version}/%{name}-%{version}.tar.xz
|
||||||
Source0: https://github.com/ClusterLabs/libqb/releases/download/v%{version}/libqb-%{version}.tar.xz
|
Patch0: IPC-avoid-temporary-channel-priority-loss.patch
|
||||||
|
Patch1: libqb-fix-list-handling-gcc10.patch
|
||||||
Patch1: backport-ipc_shm-Don-t-truncate-SHM-files-of-an-active-server.patch
|
BuildRequires: autoconf automake libtool check-devel doxygen gcc procps pkgconfig(glib-2.0)
|
||||||
Patch2: backport-0001-CVE-2019-12779-ipc-use-O_EXCL-on-SHM-files-and-randomize-the-names.patch
|
BuildRequires: git-core
|
||||||
Patch3: backport-0002-CVE-2019-12779-ipc-fixes.patch
|
|
||||||
Patch4: backport-0003-CVE-2019-12779-ipc-Use-mkdtemp-for-more-secure-IPC-files.patch
|
|
||||||
|
|
||||||
BuildRequires: autoconf automake libtool doxygen procps check-devel gcc
|
|
||||||
|
|
||||||
%description
|
%description
|
||||||
The high-performance, reusable features of libqb are provided for client-server
|
libqb provides high-performance, reusable features for client-server
|
||||||
architecture, such as logging, tracing, inter-process communication (IPC),
|
architecture, such as logging, tracing, inter-process communication (IPC),
|
||||||
and polling.
|
and polling.
|
||||||
|
|
||||||
%prep
|
%prep
|
||||||
%autosetup -n libqb-%{version} -p1
|
%autosetup -p1 -S git_am
|
||||||
|
|
||||||
%build
|
%build
|
||||||
./autogen.sh
|
./autogen.sh
|
||||||
%configure --disable-static
|
%configure --disable-static
|
||||||
%make_build V=1
|
%{make_build}
|
||||||
|
|
||||||
%if 0%{?with_check}
|
%if 0%{?with_check}
|
||||||
|
|
||||||
%check
|
%check
|
||||||
make VERBOSE=1 check \
|
make check V=1 \
|
||||||
&& make -C tests/functional/log_internal VERBOSE=1 check
|
&& make -C tests/functional/log_internal check V=1
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
%install
|
%install
|
||||||
%make_install
|
%{make_install}
|
||||||
%delete_la
|
find $RPM_BUILD_ROOT -name '*.la' -delete
|
||||||
rm -rf $RPM_BUILD_ROOT/%{_docdir}/*
|
rm -rf $RPM_BUILD_ROOT/%{_docdir}/*
|
||||||
|
%ldconfig_scriptlets
|
||||||
%post
|
|
||||||
/sbin/ldconfig
|
|
||||||
|
|
||||||
%postun
|
|
||||||
/sbin/ldconfig
|
|
||||||
|
|
||||||
%package devel
|
%package devel
|
||||||
Summary: Development files for libqb
|
Summary: Development files for %{name}
|
||||||
Requires: libqb = %{version}-%{release}
|
Requires: %{name} = %{version}-%{release} pkgconfig
|
||||||
Requires: pkgconfig
|
|
||||||
|
|
||||||
%description devel
|
%description devel
|
||||||
The libqb-devel package contains libraries and header files for
|
The %{name}-devel package contains libraries and header files for
|
||||||
developing applications that use libqb.
|
developing applications that use %{name}.
|
||||||
|
|
||||||
%package help
|
%package help
|
||||||
Summary: help documents for libqb package
|
Summary: help documents for libqb package
|
||||||
@ -61,22 +48,31 @@ Buildarch: noarch
|
|||||||
help documents for libqb package
|
help documents for libqb package
|
||||||
|
|
||||||
%files
|
%files
|
||||||
%doc README.markdown COPYING
|
%license COPYING
|
||||||
%{_sbindir}/qb-blackbox
|
%{_sbindir}/qb-blackbox
|
||||||
%{_libdir}/libqb.so.*
|
%{_libdir}/libqb.so.*
|
||||||
|
|
||||||
%files devel
|
%files devel
|
||||||
|
%doc README.markdown
|
||||||
%{_includedir}/qb/
|
%{_includedir}/qb/
|
||||||
%{_libdir}/libqb.so
|
%{_libdir}/libqb.so
|
||||||
%{_libdir}/pkgconfig/libqb.pc
|
%{_libdir}/pkgconfig/libqb.pc
|
||||||
|
|
||||||
%files help
|
%files help
|
||||||
%{_mandir}/man8/qb-blackbox.8*
|
%{_mandir}/man8/qb-blackbox.8*
|
||||||
%{_mandir}/man3/qb*3*
|
%{_mandir}/man3/qb*3*
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
* Fri Feb 5 2021 yangzhuangzhuang <yangzhuangzhuang1@huawei.com> - 1.0.3-7
|
* Thu Feb 25 2021 sunguoshuai <sunguoshuai@huawei.com> - 1.0.5-1
|
||||||
- Fix CVE-2019-12779
|
- upgrade to 1.0.5
|
||||||
|
|
||||||
|
* Tue Feb 8 2021 yangzhuangzhuang <yangzhuangzhuang1@huawei.com> - 1.0.3-7
|
||||||
|
- Fix CVE-2019-12779 libqb before 1.0.5 allows local users to overwrite arbitrary files via a symlink attack.
|
||||||
|
CVE Link: https://nvd.nist.gov/vuln/detail/CVE-2019-12779
|
||||||
|
Community Patch Link:
|
||||||
|
https://github.com/ClusterLabs/libqb/commit/e322e98dc264bc5911d6fe1d371e55ac9f95a71e
|
||||||
|
https://github.com/ClusterLabs/libqb/commit/7cd7b06d52ac80c343f362c7e39ef75495439dfc
|
||||||
|
https://github.com/ClusterLabs/libqb/commit/6a4067c1d1764d93d255eccecfd8bf9f43cb0b4d
|
||||||
|
|
||||||
* Tue Apr 27 2020 wangerfeng <wangerfeng5@huawei.com> - 1.0.3-6
|
* Tue Apr 27 2020 wangerfeng <wangerfeng5@huawei.com> - 1.0.3-6
|
||||||
- Package init
|
- Package init
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user