Login
Log in using an SSO provider:
Fedora Account System
Red Hat Associate
Red Hat Customer
Login using a Red Hat Bugzilla account
Forgot Password
Create an Account
Red Hat Bugzilla – Attachment 1722701 Details for
Bug 1888191
CVE-2020-25654 pacemaker: ACL restrictions bypass
Home
New
Search
Simple Search
Advanced Search
My Links
Browse
Requests
Reports
Current State
Search
Tabular reports
Graphical reports
Duplicates
Other Reports
User Changes
Plotly Reports
Bug Status
Bug Severity
Non-Defaults
Product Dashboard
Help
Page Help!
Bug Writing Guidelines
What's new
Browser Support Policy
5.0.4.rh92 Release notes
FAQ
Guides index
User guide
Web Services
Contact
Legal
[?]
This site requires JavaScript to be enabled to function correctly, please enable it.
[patch]
Fix for pacemaker CVE-2020-25654 (upstream 1.1.23 release)
CVE-2020-25654_1.1.23.patch (text/plain), 24.56 KB, created by
Ken Gaillot
on 2020-10-19 20:22:45 UTC
(
hide
)
Description:
Fix for pacemaker CVE-2020-25654 (upstream 1.1.23 release)
Filename:
MIME Type:
Creator:
Ken Gaillot
Created:
2020-10-19 20:22:45 UTC
Size:
24.56 KB
patch
obsolete
>From 23beea9083e61f7cae48f1b76adcc249ab4dea77 Mon Sep 17 00:00:00 2001 >From: Ken Gaillot <kgaillot@redhat.com> >Date: Tue, 27 Mar 2018 15:05:47 -0500 >Subject: [PATCH 1/8] Refactor: lrmd: functionize creating reply > >reduces duplication, and enforces consistency in reply XML and logging >--- > lrmd/lrmd.c | 94 ++++++++++++++++++++++++++----------------------------------- > 1 file changed, 40 insertions(+), 54 deletions(-) > >diff --git a/lrmd/lrmd.c b/lrmd/lrmd.c >index 2e8ea41..ceeb10b 100644 >--- a/lrmd/lrmd.c >+++ b/lrmd/lrmd.c >@@ -373,23 +373,15 @@ schedule_lrmd_cmd(lrmd_rsc_t * rsc, lrmd_cmd_t * cmd) > } > } > >-static void >-send_reply(crm_client_t * client, int rc, uint32_t id, int call_id) >+static xmlNode * >+create_lrmd_reply(const char *origin, int rc, int call_id) > { >- int send_rc = 0; >- xmlNode *reply = NULL; >+ xmlNode *reply = create_xml_node(NULL, T_LRMD_REPLY); > >- reply = create_xml_node(NULL, T_LRMD_REPLY); >- crm_xml_add(reply, F_LRMD_ORIGIN, __FUNCTION__); >+ crm_xml_add(reply, F_LRMD_ORIGIN, origin); > crm_xml_add_int(reply, F_LRMD_RC, rc); > crm_xml_add_int(reply, F_LRMD_CALLID, call_id); >- >- send_rc = lrmd_server_send_reply(client, id, reply); >- >- free_xml(reply); >- if (send_rc < 0) { >- crm_warn("LRMD reply to %s failed: %d", client->name, send_rc); >- } >+ return reply; > } > > static void >@@ -1396,23 +1388,24 @@ free_rsc(gpointer data) > free(rsc); > } > >-static int >-process_lrmd_signon(crm_client_t * client, uint32_t id, xmlNode * request) >+static xmlNode * >+process_lrmd_signon(crm_client_t *client, xmlNode *request, int call_id) > { >- xmlNode *reply = create_xml_node(NULL, "reply"); >+ xmlNode *reply = NULL; >+ int rc = pcmk_ok; > const char *is_ipc_provider = crm_element_value(request, F_LRMD_IS_IPC_PROVIDER); > const char *protocol_version = crm_element_value(request, F_LRMD_PROTOCOL_VERSION); > > if (compare_version(protocol_version, LRMD_MIN_PROTOCOL_VERSION) < 0) { > crm_err("Cluster API version must be greater than or equal to %s, not %s", > LRMD_MIN_PROTOCOL_VERSION, protocol_version); >- crm_xml_add_int(reply, F_LRMD_RC, -EPROTO); >+ rc = -EPROTO; > } > >+ reply = create_lrmd_reply(__FUNCTION__, rc, call_id); > crm_xml_add(reply, F_LRMD_OPERATION, CRM_OP_REGISTER); > crm_xml_add(reply, F_LRMD_CLIENTID, client->id); > crm_xml_add(reply, F_LRMD_PROTOCOL_VERSION, LRMD_PROTOCOL_VERSION); >- lrmd_server_send_reply(client, id, reply); > > if (crm_is_true(is_ipc_provider)) { > /* this is a remote connection from a cluster nodes crmd */ >@@ -1420,9 +1413,7 @@ process_lrmd_signon(crm_client_t * client, uint32_t id, xmlNode * request) > ipc_proxy_add_provider(client); > #endif > } >- >- free_xml(reply); >- return pcmk_ok; >+ return reply; > } > > static int >@@ -1450,52 +1441,34 @@ process_lrmd_rsc_register(crm_client_t * client, uint32_t id, xmlNode * request) > return rc; > } > >-static void >-process_lrmd_get_rsc_info(crm_client_t * client, uint32_t id, xmlNode * request) >+static xmlNode * >+process_lrmd_get_rsc_info(xmlNode *request, int call_id) > { > int rc = pcmk_ok; >- int send_rc = 0; >- int call_id = 0; > xmlNode *rsc_xml = get_xpath_object("//" F_LRMD_RSC, request, LOG_ERR); > const char *rsc_id = crm_element_value(rsc_xml, F_LRMD_RSC_ID); > xmlNode *reply = NULL; > lrmd_rsc_t *rsc = NULL; > >- crm_element_value_int(request, F_LRMD_CALLID, &call_id); >- >- if (!rsc_id) { >- rc = -ENODEV; >- goto get_rsc_done; >- } >- >- if (!(rsc = g_hash_table_lookup(rsc_list, rsc_id))) { >- crm_info("Resource '%s' not found (%d active resources)", >- rsc_id, g_hash_table_size(rsc_list)); >+ if (rsc_id == NULL) { > rc = -ENODEV; >- goto get_rsc_done; >+ } else { >+ rsc = g_hash_table_lookup(rsc_list, rsc_id); >+ if (rsc == NULL) { >+ crm_info("Resource '%s' not found (%d active resources)", >+ rsc_id, g_hash_table_size(rsc_list)); >+ rc = -ENODEV; >+ } > } > >- get_rsc_done: >- >- reply = create_xml_node(NULL, T_LRMD_REPLY); >- crm_xml_add(reply, F_LRMD_ORIGIN, __FUNCTION__); >- crm_xml_add_int(reply, F_LRMD_RC, rc); >- crm_xml_add_int(reply, F_LRMD_CALLID, call_id); >- >+ reply = create_lrmd_reply(__FUNCTION__, rc, call_id); > if (rsc) { > crm_xml_add(reply, F_LRMD_RSC_ID, rsc->rsc_id); > crm_xml_add(reply, F_LRMD_CLASS, rsc->class); > crm_xml_add(reply, F_LRMD_PROVIDER, rsc->provider); > crm_xml_add(reply, F_LRMD_TYPE, rsc->type); > } >- >- send_rc = lrmd_server_send_reply(client, id, reply); >- >- if (send_rc < 0) { >- crm_warn("LRMD reply to %s failed: %d", client->name, send_rc); >- } >- >- free_xml(reply); >+ return reply; > } > > static int >@@ -1675,6 +1648,7 @@ process_lrmd_message(crm_client_t * client, uint32_t id, xmlNode * request) > const char *op = crm_element_value(request, F_LRMD_OPERATION); > int do_reply = 0; > int do_notify = 0; >+ xmlNode *reply = NULL; > > crm_trace("Processing %s operation from %s", op, client->id); > crm_element_value_int(request, F_LRMD_CALLID, &call_id); >@@ -1685,13 +1659,15 @@ process_lrmd_message(crm_client_t * client, uint32_t id, xmlNode * request) > #endif > do_reply = 1; > } else if (crm_str_eq(op, CRM_OP_REGISTER, TRUE)) { >- rc = process_lrmd_signon(client, id, request); >+ reply = process_lrmd_signon(client, request, call_id); >+ do_reply = 1; > } else if (crm_str_eq(op, LRMD_OP_RSC_REG, TRUE)) { > rc = process_lrmd_rsc_register(client, id, request); > do_notify = 1; > do_reply = 1; > } else if (crm_str_eq(op, LRMD_OP_RSC_INFO, TRUE)) { >- process_lrmd_get_rsc_info(client, id, request); >+ reply = process_lrmd_get_rsc_info(request, call_id); >+ do_reply = 1; > } else if (crm_str_eq(op, LRMD_OP_RSC_UNREG, TRUE)) { > rc = process_lrmd_rsc_unregister(client, id, request); > /* don't notify anyone about failed un-registers */ >@@ -1727,7 +1703,17 @@ process_lrmd_message(crm_client_t * client, uint32_t id, xmlNode * request) > op, client->id, rc, do_reply, do_notify); > > if (do_reply) { >- send_reply(client, rc, id, call_id); >+ int send_rc = pcmk_ok; >+ >+ if (reply == NULL) { >+ reply = create_lrmd_reply(__FUNCTION__, rc, call_id); >+ } >+ send_rc = lrmd_server_send_reply(client, id, reply); >+ free_xml(reply); >+ if (send_rc < 0) { >+ crm_warn("Reply to client %s failed: %s " CRM_XS " %d", >+ client->name, pcmk_strerror(send_rc), send_rc); >+ } > } > > if (do_notify) { >-- >1.8.3.1 > > >From 3e0d13bb6745ec54c6da2eff591460b19f320522 Mon Sep 17 00:00:00 2001 >From: Ken Gaillot <kgaillot@redhat.com> >Date: Fri, 9 Oct 2020 09:56:03 -0500 >Subject: [PATCH 2/8] Log: executor: show CRM_OP_REGISTER rc in debug message > >Previously, process_lrmd_signon() would add the rc to the client reply >but not pass it back to process_lrmd_message(), which would always log "OK" in >its debug message, even if the sign-on was rejected. >--- > lrmd/lrmd.c | 21 +++++++++++---------- > 1 file changed, 11 insertions(+), 10 deletions(-) > >diff --git a/lrmd/lrmd.c b/lrmd/lrmd.c >index ceeb10b..a20f165 100644 >--- a/lrmd/lrmd.c >+++ b/lrmd/lrmd.c >@@ -1388,10 +1388,10 @@ free_rsc(gpointer data) > free(rsc); > } > >-static xmlNode * >-process_lrmd_signon(crm_client_t *client, xmlNode *request, int call_id) >+static int >+process_lrmd_signon(crm_client_t *client, xmlNode *request, int call_id, >+ xmlNode **reply) > { >- xmlNode *reply = NULL; > int rc = pcmk_ok; > const char *is_ipc_provider = crm_element_value(request, F_LRMD_IS_IPC_PROVIDER); > const char *protocol_version = crm_element_value(request, F_LRMD_PROTOCOL_VERSION); >@@ -1402,18 +1402,19 @@ process_lrmd_signon(crm_client_t *client, xmlNode *request, int call_id) > rc = -EPROTO; > } > >- reply = create_lrmd_reply(__FUNCTION__, rc, call_id); >- crm_xml_add(reply, F_LRMD_OPERATION, CRM_OP_REGISTER); >- crm_xml_add(reply, F_LRMD_CLIENTID, client->id); >- crm_xml_add(reply, F_LRMD_PROTOCOL_VERSION, LRMD_PROTOCOL_VERSION); >- > if (crm_is_true(is_ipc_provider)) { > /* this is a remote connection from a cluster nodes crmd */ > #ifdef SUPPORT_REMOTE > ipc_proxy_add_provider(client); > #endif > } >- return reply; >+ >+ *reply = create_lrmd_reply(__func__, rc, call_id); >+ crm_xml_add(*reply, F_LRMD_OPERATION, CRM_OP_REGISTER); >+ crm_xml_add(*reply, F_LRMD_CLIENTID, client->id); >+ crm_xml_add(*reply, F_LRMD_PROTOCOL_VERSION, LRMD_PROTOCOL_VERSION); >+ >+ return rc; > } > > static int >@@ -1659,7 +1660,7 @@ process_lrmd_message(crm_client_t * client, uint32_t id, xmlNode * request) > #endif > do_reply = 1; > } else if (crm_str_eq(op, CRM_OP_REGISTER, TRUE)) { >- reply = process_lrmd_signon(client, request, call_id); >+ rc = process_lrmd_signon(client, request, call_id, &reply); > do_reply = 1; > } else if (crm_str_eq(op, LRMD_OP_RSC_REG, TRUE)) { > rc = process_lrmd_rsc_register(client, id, request); >-- >1.8.3.1 > > >From 878d80a007c6110287e07d8b6a18259c74e41c48 Mon Sep 17 00:00:00 2001 >From: Ken Gaillot <kgaillot@redhat.com> >Date: Fri, 9 Oct 2020 15:16:39 -0500 >Subject: [PATCH 3/8] Low: executor: mark controller connections to > pacemaker-remoted as privileged > >Previously, crm_client_flag_ipc_privileged was only set when local clients connected >(as root or hacluster). Now, set it when pacemaker-remoted successfully >completes the TLS handshake with a remote client (i.e., the controller on a >cluster node). > >This has no effect as of this commit but will with later commits. >--- > lrmd/tls_backend.c | 5 +++++ > 1 file changed, 5 insertions(+) > >diff --git a/lrmd/tls_backend.c b/lrmd/tls_backend.c >index 8934ae3..509f4fa 100644 >--- a/lrmd/tls_backend.c >+++ b/lrmd/tls_backend.c >@@ -84,6 +84,11 @@ remoted__read_handshake_data(crm_client_t *client) > client->remote->tls_handshake_complete = TRUE; > crm_notice("Remote client connection accepted"); > >+ /* Only a client with access to the TLS key can connect, so we can treat >+ * it as privileged. >+ */ >+ set_bit(client->flags, crm_client_flag_ipc_privileged); >+ > // Alert other clients of the new connection > notify_of_new_client(client); > return 0; >-- >1.8.3.1 > > >From 7eff6997995ba09afa85c7eef78ae30834daa38a Mon Sep 17 00:00:00 2001 >From: Ken Gaillot <kgaillot@redhat.com> >Date: Thu, 15 Oct 2020 15:33:13 -0500 >Subject: [PATCH 4/8] Low: executor: return appropriate error code when no > remote support > >--- > lrmd/lrmd.c | 6 +++++- > 1 file changed, 5 insertions(+), 1 deletion(-) > >diff --git a/lrmd/lrmd.c b/lrmd/lrmd.c >index a20f165..07f68ed 100644 >--- a/lrmd/lrmd.c >+++ b/lrmd/lrmd.c >@@ -1403,9 +1403,11 @@ process_lrmd_signon(crm_client_t *client, xmlNode *request, int call_id, > } > > if (crm_is_true(is_ipc_provider)) { >- /* this is a remote connection from a cluster nodes crmd */ > #ifdef SUPPORT_REMOTE >+ // This is a remote connection from a cluster node's controller > ipc_proxy_add_provider(client); >+#else >+ rc = -EPROTONOSUPPORT; > #endif > } > >@@ -1657,6 +1659,8 @@ process_lrmd_message(crm_client_t * client, uint32_t id, xmlNode * request) > if (crm_str_eq(op, CRM_OP_IPC_FWD, TRUE)) { > #ifdef SUPPORT_REMOTE > ipc_proxy_forward_client(client, request); >+#else >+ rc = -EPROTONOSUPPORT; > #endif > do_reply = 1; > } else if (crm_str_eq(op, CRM_OP_REGISTER, TRUE)) { >-- >1.8.3.1 > > >From b16aa136e7e835d5947a9b4c0078cc84e8013b83 Mon Sep 17 00:00:00 2001 >From: Ken Gaillot <kgaillot@redhat.com> >Date: Thu, 15 Oct 2020 15:33:57 -0500 >Subject: [PATCH 5/8] High: executor: restrict certain IPC requests to > Pacemaker daemons > >The executor IPC API allows clients to register resources, request agent >execution, and so forth. > >If ACLs are enabled, this could allow an ACL-restricted user to bypass ACLs and >execute any code as root. (If ACLs are not enabled, users in the haclient group >have full access to the CIB, which already gives them that ability, so there is >no additional exposure in that case.) > >When ACLs are supported, this commit effectively disables the executor IPC API >for clients that aren't connecting as root or hacluster. Such clients can only >register and poke now. >--- > lrmd/lrmd.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++------------- > 1 file changed, 68 insertions(+), 17 deletions(-) > >diff --git a/lrmd/lrmd.c b/lrmd/lrmd.c >index 07f68ed..0c9cba2 100644 >--- a/lrmd/lrmd.c >+++ b/lrmd/lrmd.c >@@ -1404,8 +1404,12 @@ process_lrmd_signon(crm_client_t *client, xmlNode *request, int call_id, > > if (crm_is_true(is_ipc_provider)) { > #ifdef SUPPORT_REMOTE >- // This is a remote connection from a cluster node's controller >- ipc_proxy_add_provider(client); >+ if ((client->remote != NULL) && client->remote->tls_handshake_complete) { >+ // This is a remote connection from a cluster node's controller >+ ipc_proxy_add_provider(client); >+ } else { >+ rc = -EACCES; >+ } > #else > rc = -EPROTONOSUPPORT; > #endif >@@ -1653,12 +1657,26 @@ process_lrmd_message(crm_client_t * client, uint32_t id, xmlNode * request) > int do_notify = 0; > xmlNode *reply = NULL; > >+ bool allowed = true; >+ >+#if ENABLE_ACL >+ /* Certain IPC commands may be done only by privileged users (i.e. root or >+ * hacluster) when ACLs are enabled, because they would otherwise provide a >+ * means of bypassing ACLs. >+ */ >+ allowed = is_set(client->flags, crm_client_flag_ipc_privileged); >+#endif >+ > crm_trace("Processing %s operation from %s", op, client->id); > crm_element_value_int(request, F_LRMD_CALLID, &call_id); > > if (crm_str_eq(op, CRM_OP_IPC_FWD, TRUE)) { > #ifdef SUPPORT_REMOTE >- ipc_proxy_forward_client(client, request); >+ if (allowed) { >+ ipc_proxy_forward_client(client, request); >+ } else { >+ rc = -EACCES; >+ } > #else > rc = -EPROTONOSUPPORT; > #endif >@@ -1667,35 +1685,63 @@ process_lrmd_message(crm_client_t * client, uint32_t id, xmlNode * request) > rc = process_lrmd_signon(client, request, call_id, &reply); > do_reply = 1; > } else if (crm_str_eq(op, LRMD_OP_RSC_REG, TRUE)) { >- rc = process_lrmd_rsc_register(client, id, request); >- do_notify = 1; >+ if (allowed) { >+ rc = process_lrmd_rsc_register(client, id, request); >+ do_notify = 1; >+ } else { >+ rc = -EACCES; >+ } > do_reply = 1; > } else if (crm_str_eq(op, LRMD_OP_RSC_INFO, TRUE)) { >- reply = process_lrmd_get_rsc_info(request, call_id); >+ if (allowed) { >+ reply = process_lrmd_get_rsc_info(request, call_id); >+ } else { >+ rc = -EACCES; >+ } > do_reply = 1; > } else if (crm_str_eq(op, LRMD_OP_RSC_UNREG, TRUE)) { >- rc = process_lrmd_rsc_unregister(client, id, request); >- /* don't notify anyone about failed un-registers */ >- if (rc == pcmk_ok || rc == -EINPROGRESS) { >- do_notify = 1; >+ if (allowed) { >+ rc = process_lrmd_rsc_unregister(client, id, request); >+ /* don't notify anyone about failed un-registers */ >+ if (rc == pcmk_ok || rc == -EINPROGRESS) { >+ do_notify = 1; >+ } >+ } else { >+ rc = -EACCES; > } > do_reply = 1; > } else if (crm_str_eq(op, LRMD_OP_RSC_EXEC, TRUE)) { >- rc = process_lrmd_rsc_exec(client, id, request); >+ if (allowed) { >+ rc = process_lrmd_rsc_exec(client, id, request); >+ } else { >+ rc = -EACCES; >+ } > do_reply = 1; > } else if (crm_str_eq(op, LRMD_OP_RSC_CANCEL, TRUE)) { >- rc = process_lrmd_rsc_cancel(client, id, request); >+ if (allowed) { >+ rc = process_lrmd_rsc_cancel(client, id, request); >+ } else { >+ rc = -EACCES; >+ } > do_reply = 1; > } else if (crm_str_eq(op, LRMD_OP_POKE, TRUE)) { > do_notify = 1; > do_reply = 1; > } else if (crm_str_eq(op, LRMD_OP_CHECK, TRUE)) { >- xmlNode *data = get_message_xml(request, F_LRMD_CALLDATA); >- const char *timeout = crm_element_value(data, F_LRMD_WATCHDOG); >- CRM_LOG_ASSERT(data != NULL); >- check_sbd_timeout(timeout); >+ if (allowed) { >+ xmlNode *data = get_message_xml(request, F_LRMD_CALLDATA); >+ >+ CRM_LOG_ASSERT(data != NULL); >+ check_sbd_timeout(crm_element_value(data, F_LRMD_WATCHDOG)); >+ } else { >+ rc = -EACCES; >+ } > } else if (crm_str_eq(op, LRMD_OP_ALERT_EXEC, TRUE)) { >- rc = process_lrmd_alert_exec(client, id, request); >+ if (allowed) { >+ rc = process_lrmd_alert_exec(client, id, request); >+ } else { >+ rc = -EACCES; >+ } > do_reply = 1; > } else { > rc = -EOPNOTSUPP; >@@ -1704,6 +1750,11 @@ process_lrmd_message(crm_client_t * client, uint32_t id, xmlNode * request) > crm_log_xml_warn(request, "UnknownOp"); > } > >+ if (rc == -EACCES) { >+ crm_warn("Rejecting IPC request '%s' from unprivileged client %s", >+ op, crm_client_name(client)); >+ } >+ > crm_debug("Processed %s operation from %s: rc=%d, reply=%d, notify=%d", > op, client->id, rc, do_reply, do_notify); > >-- >1.8.3.1 > > >From 3b71b8027fc6b5bde2dbb6d8ff7c23703cf5ad49 Mon Sep 17 00:00:00 2001 >From: Ken Gaillot <kgaillot@redhat.com> >Date: Fri, 9 Oct 2020 11:16:43 -0500 >Subject: [PATCH 6/8] Low: pacemakerd: check client for NULL before using it > >... to guard against bugs in client tracking >--- > mcp/pacemaker.c | 5 ++++- > 1 file changed, 4 insertions(+), 1 deletion(-) > >diff --git a/mcp/pacemaker.c b/mcp/pacemaker.c >index 05515c8..736c25c 100644 >--- a/mcp/pacemaker.c >+++ b/mcp/pacemaker.c >@@ -567,9 +567,12 @@ pcmk_ipc_dispatch(qb_ipcs_connection_t * qbc, void *data, size_t size) > uint32_t id = 0; > uint32_t flags = 0; > const char *task = NULL; >+ xmlNode *msg = NULL; > crm_client_t *c = crm_client_get(qbc); >- xmlNode *msg = crm_ipcs_recv(c, data, size, &id, &flags); > >+ CRM_CHECK(c != NULL, return 0); >+ >+ msg = crm_ipcs_recv(c, data, size, &id, &flags); > crm_ipcs_send_ack(c, id, flags, "ack", __FUNCTION__, __LINE__); > if (msg == NULL) { > return 0; >-- >1.8.3.1 > > >From 8e81dca1f505001de043a64f826df4eb71798951 Mon Sep 17 00:00:00 2001 >From: Ken Gaillot <kgaillot@redhat.com> >Date: Fri, 9 Oct 2020 11:17:18 -0500 >Subject: [PATCH 7/8] High: pacemakerd: ignore shutdown requests from > unprivileged users > >The pacemakerd IPC API supports a shutdown request, along with a >command-line interface for using it (pacemakerd --shutdown). > >Only the haclient group has access to the IPC. Without ACLs, that group can >already shut down Pacemaker via the CIB, so there's no security implication. > >However, it might not be desired to allow ACL-restricted users to shut down >Pacemaker, so block users other than root or hacluster if ACLs are supported. >--- > mcp/pacemaker.c | 24 ++++++++++++++++++++---- > 1 file changed, 20 insertions(+), 4 deletions(-) > >diff --git a/mcp/pacemaker.c b/mcp/pacemaker.c >index 736c25c..2232c0b 100644 >--- a/mcp/pacemaker.c >+++ b/mcp/pacemaker.c >@@ -580,10 +580,26 @@ pcmk_ipc_dispatch(qb_ipcs_connection_t * qbc, void *data, size_t size) > > task = crm_element_value(msg, F_CRM_TASK); > if (crm_str_eq(task, CRM_OP_QUIT, TRUE)) { >- /* Time to quit */ >- crm_notice("Shutting down in response to ticket %s (%s)", >- crm_element_value(msg, F_CRM_REFERENCE), crm_element_value(msg, F_CRM_ORIGIN)); >- pcmk_shutdown(15); >+ bool allowed = true; >+ >+#if ENABLE_ACL >+ /* Only allow privileged users (i.e. root or hacluster) >+ * to shut down Pacemaker from the command line (or direct IPC). >+ * >+ * We only check when ACLs are enabled, because without them, any client >+ * with IPC access could shut down Pacemaker via the CIB anyway. >+ */ >+ allowed = is_set(c->flags, crm_client_flag_ipc_privileged); >+#endif >+ if (allowed) { >+ crm_notice("Shutting down in response to IPC request %s from %s", >+ crm_element_value(msg, F_CRM_REFERENCE), >+ crm_element_value(msg, F_CRM_ORIGIN)); >+ pcmk_shutdown(15); >+ } else { >+ crm_warn("Ignoring shutdown request from unprivileged client %s", >+ crm_client_name(c)); >+ } > > } else if (crm_str_eq(task, CRM_OP_RM_NODE_CACHE, TRUE)) { > /* Send to everyone */ >-- >1.8.3.1 > > >From 1e0db7e36788b94202d050b6c52ad74abb55b382 Mon Sep 17 00:00:00 2001 >From: Ken Gaillot <kgaillot@redhat.com> >Date: Fri, 9 Oct 2020 11:55:26 -0500 >Subject: [PATCH 8/8] Fix: fencer: restrict certain IPC requests to privileged > users > >The fencer IPC API allows clients to register fence devices. > >If ACLs are enabled, this could allow an ACL-restricted user to bypass ACLs to >configure fencing. If the user is able to install executables to the standard >fencing agent locations, have arbitrary code executed as root (the standard >locations generally require root for write access, so that is unlikely to be an >issue). > >If ACLs are not enabled, users in the haclient group have full access to the >CIB, which already gives them these capabilities, so there is no additional >exposure in that case. > >This commit does not restrict unprivileged users from using other fencing API, >such as requesting actual fencing. >--- > fencing/commands.c | 41 +++++++++++++++++++++++++++++++++++++---- > 1 file changed, 37 insertions(+), 4 deletions(-) > >diff --git a/fencing/commands.c b/fencing/commands.c >index 26952e9..7097858 100644 >--- a/fencing/commands.c >+++ b/fencing/commands.c >@@ -2575,6 +2575,18 @@ handle_request(crm_client_t * client, uint32_t id, uint32_t flags, xmlNode * req > const char *op = crm_element_value(request, F_STONITH_OPERATION); > const char *client_id = crm_element_value(request, F_STONITH_CLIENTID); > >+ bool allowed = true; >+ >+#if ENABLE_ACL >+ /* IPC commands related to fencing configuration may be done only by >+ * privileged users (i.e. root or hacluster) when ACLs are supported, >+ * because all other users should go through the CIB to have ACLs applied. >+ */ >+ if (client != NULL) { >+ allowed = is_set(client->flags, crm_client_flag_ipc_privileged); >+ } >+#endif >+ > crm_element_value_int(request, F_STONITH_CALLOPTS, &call_options); > > if (is_set(call_options, st_opt_sync_call)) { >@@ -2731,27 +2743,43 @@ handle_request(crm_client_t * client, uint32_t id, uint32_t flags, xmlNode * req > } else if (crm_str_eq(op, STONITH_OP_DEVICE_ADD, TRUE)) { > const char *device_id = NULL; > >- rc = stonith_device_register(request, &device_id, FALSE); >+ if (allowed) { >+ rc = stonith_device_register(request, &device_id, FALSE); >+ } else { >+ rc = -EACCES; >+ } > do_stonith_notify_device(call_options, op, rc, device_id); > > } else if (crm_str_eq(op, STONITH_OP_DEVICE_DEL, TRUE)) { > xmlNode *dev = get_xpath_object("//" F_STONITH_DEVICE, request, LOG_ERR); > const char *device_id = crm_element_value(dev, XML_ATTR_ID); > >- rc = stonith_device_remove(device_id, FALSE); >+ if (allowed) { >+ rc = stonith_device_remove(device_id, FALSE); >+ } else { >+ rc = -EACCES; >+ } > do_stonith_notify_device(call_options, op, rc, device_id); > > } else if (crm_str_eq(op, STONITH_OP_LEVEL_ADD, TRUE)) { > char *device_id = NULL; > >- rc = stonith_level_register(request, &device_id); >+ if (allowed) { >+ rc = stonith_level_register(request, &device_id); >+ } else { >+ rc = -EACCES; >+ } > do_stonith_notify_level(call_options, op, rc, device_id); > free(device_id); > > } else if (crm_str_eq(op, STONITH_OP_LEVEL_DEL, TRUE)) { > char *device_id = NULL; > >- rc = stonith_level_remove(request, &device_id); >+ if (allowed) { >+ rc = stonith_level_remove(request, &device_id); >+ } else { >+ rc = -EACCES; >+ } > do_stonith_notify_level(call_options, op, rc, device_id); > > } else if (crm_str_eq(op, STONITH_OP_CONFIRM, TRUE)) { >@@ -2782,6 +2810,11 @@ handle_request(crm_client_t * client, uint32_t id, uint32_t flags, xmlNode * req > > done: > >+ if (rc == -EACCES) { >+ crm_warn("Rejecting IPC request '%s' from unprivileged client %s", >+ crm_str(op), crm_client_name(client)); >+ } >+ > /* Always reply unless the request is in process still. > * If in progress, a reply will happen async after the request > * processing is finished */ >-- >1.8.3.1 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 1888191
:
1722698
|
1722699
|
1722700
| 1722701