import pacemaker-2.0.4-6.el8_3.1
This commit is contained in:
		
							parent
							
								
									c6b88556ad
								
							
						
					
					
						commit
						a79d3dfd81
					
				
							
								
								
									
										513
									
								
								SOURCES/016-CVE-2020-25654.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										513
									
								
								SOURCES/016-CVE-2020-25654.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,513 @@ | |||||||
|  | From 3aa33bcc9c70d197b5ed0760b12d65dfab4d4da5 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Ken Gaillot <kgaillot@redhat.com> | ||||||
|  | Date: Fri, 9 Oct 2020 09:56:03 -0500 | ||||||
|  | Subject: [PATCH 1/7] 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. | ||||||
|  | ---
 | ||||||
|  |  daemons/execd/execd_commands.c | 21 +++++++++++---------- | ||||||
|  |  1 file changed, 11 insertions(+), 10 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/daemons/execd/execd_commands.c b/daemons/execd/execd_commands.c
 | ||||||
|  | index 4d0e457..8487dd4 100644
 | ||||||
|  | --- a/daemons/execd/execd_commands.c
 | ||||||
|  | +++ b/daemons/execd/execd_commands.c
 | ||||||
|  | @@ -1494,10 +1494,10 @@ free_rsc(gpointer data)
 | ||||||
|  |      free(rsc); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | -static xmlNode *
 | ||||||
|  | -process_lrmd_signon(pcmk__client_t *client, xmlNode *request, int call_id)
 | ||||||
|  | +static int
 | ||||||
|  | +process_lrmd_signon(pcmk__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); | ||||||
|  | @@ -1508,18 +1508,19 @@ process_lrmd_signon(pcmk__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 node's controller | ||||||
|  |  #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 | ||||||
|  | @@ -1832,7 +1833,7 @@ process_lrmd_message(pcmk__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 d0002343faa4595e42b790119b7f3037db1130c4 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Ken Gaillot <kgaillot@redhat.com> | ||||||
|  | Date: Fri, 9 Oct 2020 15:16:39 -0500 | ||||||
|  | Subject: [PATCH 2/7] Low: executor: mark controller connections to | ||||||
|  |  pacemaker-remoted as privileged | ||||||
|  | 
 | ||||||
|  | Previously, pcmk__client_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. | ||||||
|  | ---
 | ||||||
|  |  daemons/execd/remoted_tls.c | 5 +++++ | ||||||
|  |  1 file changed, 5 insertions(+) | ||||||
|  | 
 | ||||||
|  | diff --git a/daemons/execd/remoted_tls.c b/daemons/execd/remoted_tls.c
 | ||||||
|  | index 1a1f8b2..c835549 100644
 | ||||||
|  | --- a/daemons/execd/remoted_tls.c
 | ||||||
|  | +++ b/daemons/execd/remoted_tls.c
 | ||||||
|  | @@ -72,6 +72,11 @@ remoted__read_handshake_data(pcmk__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, pcmk__client_privileged);
 | ||||||
|  | +
 | ||||||
|  |      // Alert other clients of the new connection | ||||||
|  |      notify_of_new_client(client); | ||||||
|  |      return 0; | ||||||
|  | -- 
 | ||||||
|  | 1.8.3.1 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | From 3db100d775aee214fff8f54eae0076a5fcc41c56 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Ken Gaillot <kgaillot@redhat.com> | ||||||
|  | Date: Thu, 15 Oct 2020 15:33:13 -0500 | ||||||
|  | Subject: [PATCH 3/7] Low: executor: return appropriate error code when no | ||||||
|  |  remote support | ||||||
|  | 
 | ||||||
|  | ---
 | ||||||
|  |  daemons/execd/execd_commands.c | 6 +++++- | ||||||
|  |  1 file changed, 5 insertions(+), 1 deletion(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/daemons/execd/execd_commands.c b/daemons/execd/execd_commands.c
 | ||||||
|  | index 8487dd4..41c8169 100644
 | ||||||
|  | --- a/daemons/execd/execd_commands.c
 | ||||||
|  | +++ b/daemons/execd/execd_commands.c
 | ||||||
|  | @@ -1509,9 +1509,11 @@ process_lrmd_signon(pcmk__client_t *client, xmlNode *request, int call_id,
 | ||||||
|  |      } | ||||||
|  |   | ||||||
|  |      if (crm_is_true(is_ipc_provider)) { | ||||||
|  | -        // This is a remote connection from a cluster node's controller
 | ||||||
|  |  #ifdef SUPPORT_REMOTE | ||||||
|  | +        // This is a remote connection from a cluster node's controller
 | ||||||
|  |          ipc_proxy_add_provider(client); | ||||||
|  | +#else
 | ||||||
|  | +        rc = -EPROTONOSUPPORT;
 | ||||||
|  |  #endif | ||||||
|  |      } | ||||||
|  |   | ||||||
|  | @@ -1830,6 +1832,8 @@ process_lrmd_message(pcmk__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 f273f1c16f21ff96983797ed5ceb2978dafe545a Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Ken Gaillot <kgaillot@redhat.com> | ||||||
|  | Date: Thu, 15 Oct 2020 15:33:57 -0500 | ||||||
|  | Subject: [PATCH 4/7] 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. | ||||||
|  | ---
 | ||||||
|  |  daemons/execd/execd_commands.c | 91 +++++++++++++++++++++++++++++++++--------- | ||||||
|  |  1 file changed, 73 insertions(+), 18 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/daemons/execd/execd_commands.c b/daemons/execd/execd_commands.c
 | ||||||
|  | index 41c8169..207eb6a 100644
 | ||||||
|  | --- a/daemons/execd/execd_commands.c
 | ||||||
|  | +++ b/daemons/execd/execd_commands.c
 | ||||||
|  | @@ -1510,8 +1510,12 @@ process_lrmd_signon(pcmk__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 | ||||||
|  | @@ -1826,12 +1830,26 @@ process_lrmd_message(pcmk__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, pcmk__client_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 | ||||||
|  | @@ -1840,38 +1858,70 @@ process_lrmd_message(pcmk__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);
 | ||||||
|  | -        pcmk__valid_sbd_timeout(timeout);
 | ||||||
|  | +        if (allowed) {
 | ||||||
|  | +            xmlNode *data = get_message_xml(request, F_LRMD_CALLDATA);
 | ||||||
|  | +
 | ||||||
|  | +            CRM_LOG_ASSERT(data != NULL);
 | ||||||
|  | +            pcmk__valid_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 if (crm_str_eq(op, LRMD_OP_GET_RECURRING, TRUE)) { | ||||||
|  | -        reply = process_lrmd_get_recurring(request, call_id);
 | ||||||
|  | +        if (allowed) {
 | ||||||
|  | +            reply = process_lrmd_get_recurring(request, call_id);
 | ||||||
|  | +        } else {
 | ||||||
|  | +            rc = -EACCES;
 | ||||||
|  | +        }
 | ||||||
|  |          do_reply = 1; | ||||||
|  |      } else { | ||||||
|  |          rc = -EOPNOTSUPP; | ||||||
|  | @@ -1879,6 +1929,11 @@ process_lrmd_message(pcmk__client_t *client, uint32_t id, xmlNode *request)
 | ||||||
|  |          crm_err("Unknown IPC request '%s' from %s", op, client->name); | ||||||
|  |      } | ||||||
|  |   | ||||||
|  | +    if (rc == -EACCES) {
 | ||||||
|  | +        crm_warn("Rejecting IPC request '%s' from unprivileged client %s",
 | ||||||
|  | +                 op, pcmk__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 f13759f6971402dac3bea1aac45214a84d838728 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Ken Gaillot <kgaillot@redhat.com> | ||||||
|  | Date: Fri, 9 Oct 2020 11:16:43 -0500 | ||||||
|  | Subject: [PATCH 5/7] Low: pacemakerd: check client for NULL before using it | ||||||
|  | 
 | ||||||
|  | ... to guard against bugs in client tracking | ||||||
|  | ---
 | ||||||
|  |  daemons/pacemakerd/pacemakerd.c | 5 ++++- | ||||||
|  |  1 file changed, 4 insertions(+), 1 deletion(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/daemons/pacemakerd/pacemakerd.c b/daemons/pacemakerd/pacemakerd.c
 | ||||||
|  | index 5ed4626..573ea5a 100644
 | ||||||
|  | --- a/daemons/pacemakerd/pacemakerd.c
 | ||||||
|  | +++ b/daemons/pacemakerd/pacemakerd.c
 | ||||||
|  | @@ -553,9 +553,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;
 | ||||||
|  |      pcmk__client_t *c = pcmk__find_client(qbc); | ||||||
|  | -    xmlNode *msg = pcmk__client_data2xml(c, data, &id, &flags);
 | ||||||
|  |   | ||||||
|  | +    CRM_CHECK(c != NULL, return 0);
 | ||||||
|  | +
 | ||||||
|  | +    msg = pcmk__client_data2xml(c, data, &id, &flags);
 | ||||||
|  |      pcmk__ipc_send_ack(c, id, flags, "ack"); | ||||||
|  |      if (msg == NULL) { | ||||||
|  |          return 0; | ||||||
|  | -- 
 | ||||||
|  | 1.8.3.1 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | From 021081c1e28b254a0f68143fa55e517f0fcc4edb Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Ken Gaillot <kgaillot@redhat.com> | ||||||
|  | Date: Fri, 9 Oct 2020 11:17:18 -0500 | ||||||
|  | Subject: [PATCH 6/7] 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. | ||||||
|  | ---
 | ||||||
|  |  daemons/pacemakerd/pacemakerd.c | 24 ++++++++++++++++++++---- | ||||||
|  |  1 file changed, 20 insertions(+), 4 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/daemons/pacemakerd/pacemakerd.c b/daemons/pacemakerd/pacemakerd.c
 | ||||||
|  | index 573ea5a..2e69bd1 100644
 | ||||||
|  | --- a/daemons/pacemakerd/pacemakerd.c
 | ||||||
|  | +++ b/daemons/pacemakerd/pacemakerd.c
 | ||||||
|  | @@ -566,9 +566,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)) { | ||||||
|  | -        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);
 | ||||||
|  | +        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, pcmk__client_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",
 | ||||||
|  | +                     pcmk__client_name(c));
 | ||||||
|  | +        }
 | ||||||
|  |   | ||||||
|  |      } else if (crm_str_eq(task, CRM_OP_RM_NODE_CACHE, TRUE)) { | ||||||
|  |          crm_trace("Ignoring IPC request to purge node " | ||||||
|  | -- 
 | ||||||
|  | 1.8.3.1 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | From 80eb5ddfd529be02214f38669f1b177535186fbc Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Ken Gaillot <kgaillot@redhat.com> | ||||||
|  | Date: Fri, 9 Oct 2020 11:55:26 -0500 | ||||||
|  | Subject: [PATCH 7/7] 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. | ||||||
|  | ---
 | ||||||
|  |  daemons/fenced/fenced_commands.c | 41 ++++++++++++++++++++++++++++++++++++---- | ||||||
|  |  1 file changed, 37 insertions(+), 4 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/daemons/fenced/fenced_commands.c b/daemons/fenced/fenced_commands.c
 | ||||||
|  | index 859e7b7..a8c90a6 100644
 | ||||||
|  | --- a/daemons/fenced/fenced_commands.c
 | ||||||
|  | +++ b/daemons/fenced/fenced_commands.c
 | ||||||
|  | @@ -2531,6 +2531,18 @@ handle_request(pcmk__client_t *client, uint32_t id, uint32_t flags,
 | ||||||
|  |      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, pcmk__client_privileged);
 | ||||||
|  | +    }
 | ||||||
|  | +#endif
 | ||||||
|  | +
 | ||||||
|  |      crm_element_value_int(request, F_STONITH_CALLOPTS, &call_options); | ||||||
|  |   | ||||||
|  |      if (is_set(call_options, st_opt_sync_call)) { | ||||||
|  | @@ -2687,27 +2699,43 @@ handle_request(pcmk__client_t *client, uint32_t id, uint32_t flags,
 | ||||||
|  |      } 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(safe_str_eq(op, CRM_OP_RM_NODE_CACHE)) { | ||||||
|  | @@ -2727,6 +2755,11 @@ handle_request(pcmk__client_t *client, uint32_t id, uint32_t flags,
 | ||||||
|  |   | ||||||
|  |    done: | ||||||
|  |   | ||||||
|  | +    if (rc == -EACCES) {
 | ||||||
|  | +        crm_warn("Rejecting IPC request '%s' from unprivileged client %s",
 | ||||||
|  | +                 crm_str(op), pcmk__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 | ||||||
|  | 
 | ||||||
| @ -227,7 +227,7 @@ | |||||||
| Name:          pacemaker | Name:          pacemaker | ||||||
| Summary:       Scalable High-Availability cluster resource manager | Summary:       Scalable High-Availability cluster resource manager | ||||||
| Version:       %{pcmkversion} | Version:       %{pcmkversion} | ||||||
| Release:       %{pcmk_release}%{?dist} | Release:       %{pcmk_release}%{?dist}.1 | ||||||
| %if %{defined _unitdir} | %if %{defined _unitdir} | ||||||
| License:       GPLv2+ and LGPLv2+ | License:       GPLv2+ and LGPLv2+ | ||||||
| %else | %else | ||||||
| @ -264,6 +264,7 @@ Patch12:        012-ipc_fix.patch | |||||||
| Patch13:        013-pacemakerd.patch | Patch13:        013-pacemakerd.patch | ||||||
| Patch14:        014-sbd.patch | Patch14:        014-sbd.patch | ||||||
| Patch15:        015-cibsecret.patch | Patch15:        015-cibsecret.patch | ||||||
|  | Patch16:        016-CVE-2020-25654.patch | ||||||
| 
 | 
 | ||||||
| # downstream-only commits | # downstream-only commits | ||||||
| #Patch100:      xxx.patch | #Patch100:      xxx.patch | ||||||
| @ -961,6 +962,10 @@ exit 0 | |||||||
| %license %{nagios_name}-%{nagios_hash}/COPYING | %license %{nagios_name}-%{nagios_hash}/COPYING | ||||||
| 
 | 
 | ||||||
| %changelog | %changelog | ||||||
|  | * Mon Oct 26 2020 Ken Gaillot <kgaillot@redhat.com> - 2.0.4-6.1 | ||||||
|  | - Prevent users from bypassing ACLs by using IPC directly (CVE-2020-25654) | ||||||
|  | - Resolves: rhbz1891528 | ||||||
|  | 
 | ||||||
| * Thu Aug 20 2020 Ken Gaillot <kgaillot@redhat.com> - 2.0.4-6 | * Thu Aug 20 2020 Ken Gaillot <kgaillot@redhat.com> - 2.0.4-6 | ||||||
| - Fix cibsecret bug when node name is different from hostname | - Fix cibsecret bug when node name is different from hostname | ||||||
| - Resolves: rhbz1870873 | - Resolves: rhbz1870873 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user