From 82526d2fe9137e8b604f1bbae6d6e39ba41377f9 Mon Sep 17 00:00:00 2001
From: Christine Caulfield <ccaulfie@redhat.com>
Date: Mon, 16 Mar 2015 11:37:52 +0000
Subject: [PATCH] quorum: don't allow quorum_trackstart to be called twice
If quorum_trackstart() or votequorum_trackstart() are called twice with
CS_TRACK_CHANGES then the client gets added twice to the notifications
list effectively corrupting it. Users have reported segfaults in
corosync when they did this (by mistake!).
As there's already a tracking_enabled flag in the private-data, we check
that before adding to the list again and return an error if
the process is already registered.
Signed-off-by: Christine Caulfield <ccaulfie@redhat.com>
Reviewed-by: Jan Friesse <jfriesse@redhat.com>
---
exec/votequorum.c | 12 ++++++++++--
exec/vsf_quorum.c | 11 +++++++++--
2 files changed, 19 insertions(+), 4 deletions(-)
diff --git a/exec/votequorum.c b/exec/votequorum.c
index 2ff0b43..f6faa25 100644
--- a/exec/votequorum.c
+++ b/exec/votequorum.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009-2014 Red Hat, Inc.
+ * Copyright (c) 2009-2015 Red Hat, Inc.
*
* All rights reserved.
*
@@ -2615,8 +2615,10 @@ static void message_handler_req_lib_votequorum_trackstart (void *conn,
const struct req_lib_votequorum_trackstart *req_lib_votequorum_trackstart = message;
struct res_lib_votequorum_status res_lib_votequorum_status;
struct quorum_pd *quorum_pd = (struct quorum_pd *)corosync_api->ipc_private_data_get (conn);
+ cs_error_t error = CS_OK;
ENTER();
+
/*
* If an immediate listing of the current cluster membership
* is requested, generate membership list
@@ -2627,6 +2629,11 @@ static void message_handler_req_lib_votequorum_trackstart (void *conn,
votequorum_exec_send_quorum_notification(conn, req_lib_votequorum_trackstart->context);
}
+ if (quorum_pd->tracking_enabled) {
+ error = CS_ERR_EXIST;
+ goto response_send;
+ }
+
/*
* Record requests for tracking
*/
@@ -2640,9 +2647,10 @@ static void message_handler_req_lib_votequorum_trackstart (void *conn,
list_add (&quorum_pd->list, &trackers_list);
}
+response_send:
res_lib_votequorum_status.header.size = sizeof(res_lib_votequorum_status);
res_lib_votequorum_status.header.id = MESSAGE_RES_VOTEQUORUM_STATUS;
- res_lib_votequorum_status.header.error = CS_OK;
+ res_lib_votequorum_status.header.error = error;
corosync_api->ipc_response_send(conn, &res_lib_votequorum_status, sizeof(res_lib_votequorum_status));
LEAVE();
diff --git a/exec/vsf_quorum.c b/exec/vsf_quorum.c
index 2a3a263..a6c739d 100644
--- a/exec/vsf_quorum.c
+++ b/exec/vsf_quorum.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008-2012 Red Hat, Inc.
+ * Copyright (c) 2008-2015 Red Hat, Inc.
*
* All rights reserved.
*
@@ -409,6 +409,7 @@ static void message_handler_req_lib_quorum_trackstart (void *conn,
const struct req_lib_quorum_trackstart *req_lib_quorum_trackstart = msg;
struct qb_ipc_response_header res;
struct quorum_pd *quorum_pd = (struct quorum_pd *)corosync_api->ipc_private_data_get (conn);
+ cs_error_t error = CS_OK;
log_printf(LOGSYS_LEVEL_DEBUG, "got trackstart request on %p", conn);
@@ -422,6 +423,11 @@ static void message_handler_req_lib_quorum_trackstart (void *conn,
send_library_notification(conn);
}
+ if (quorum_pd->tracking_enabled) {
+ error = CS_ERR_EXIST;
+ goto response_send;
+ }
+
/*
* Record requests for tracking
*/
@@ -434,10 +440,11 @@ static void message_handler_req_lib_quorum_trackstart (void *conn,
list_add (&quorum_pd->list, &lib_trackers_list);
}
+response_send:
/* send status */
res.size = sizeof(res);
res.id = MESSAGE_RES_QUORUM_TRACKSTART;
- res.error = CS_OK;
+ res.error = error;
corosync_api->ipc_response_send(conn, &res, sizeof(struct qb_ipc_response_header));
}
--
1.7.1