File bsc#1137835-0001-ipc-use-O_EXCL-on-SHM-files-and-randomize-the-names.patch of Package libqb.30654
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 1/2] 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 0e16964..36ae2cf 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 fe2040e..1f7cde3 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 4a375fc..573b427 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 1cba422..2947162 100644
--- a/lib/log_blackbox.c
+++ b/lib/log_blackbox.c
@@ -188,7 +188,7 @@ qb_log_blackbox_write_to_file(const char *filename)
ssize_t written_size = 0;
struct qb_log_target *t;
struct _blackbox_file_header header;
- 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 81411cb..8852ff5 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));
--
2.16.4