Vulnerability: Pacemaker before 1.1.13 does not properly evaluate added nodes, which allows remote read-only users to gain privileges via an acl command.
Vulnerability ID: CVE-2015-1867
CWE: CWE-264
Severity score: 6.4
Project: https://github.com/ClusterLabs/pacemaker
Published: 2015-08-12
File: lib/common/xml.c
Commit message: Fix: acl: Do not delay evaluation of added nodes in some situations

It is not appropriate when the node has no children as it is not a
placeholder
Commit author: Andrew Beekhof

Vulnerable version (before fix):
 __xml_acl_post_process(xmlNode * xml)      if(is_set(p->flags, xpf_created)) {         xmlAttr *xIter = NULL;          /* Always allow new scaffolding, ie. node with no attributes or only an 'id' */          for (xIter = crm_first_attr(xml); xIter != NULL; xIter = xIter->next) {             const char *prop_name = (const char *)xIter->name;              if (strcmp(prop_name, XML_ATTR_ID) == 0) {                 /* Delay the acl check */                 continue;  __xml_acl_post_process(xmlNode * xml)                 break;              } else {                 char *path = xml_get_path(xml);                 crm_trace("Cannot add new node %s at %s", crm_element_name(xml), path);                  if(xml != xmlDocGetRootElement(xml->doc)) { __xml_acl_post_process(xmlNode * xml)                 return;             }         }     }      while (cIter != NULL) {

Fixed version (after fix):
 __xml_acl_post_process(xmlNode * xml)      if(is_set(p->flags, xpf_created)) {         xmlAttr *xIter = NULL;         char *path = xml_get_path(xml);          /* Always allow new scaffolding, ie. node with no attributes or only an 'id'          * Except in the ACLs section          */          for (xIter = crm_first_attr(xml); xIter != NULL; xIter = xIter->next) {             const char *prop_name = (const char *)xIter->name;              if (strcmp(prop_name, XML_ATTR_ID) == 0 && strstr(path, "/"XML_CIB_TAG_ACLS"/") == NULL) {                 /* Delay the acl check */                 continue;  __xml_acl_post_process(xmlNode * xml)                 break;              } else {                 crm_trace("Cannot add new node %s at %s", crm_element_name(xml), path);                  if(xml != xmlDocGetRootElement(xml->doc)) { __xml_acl_post_process(xmlNode * xml)                 return;             }         }         free(path);     }      while (cIter != NULL) {

Patch:
patch: @@ -1020,13 +1020,16 @@ __xml_acl_post_process(xmlNode * xml)
 
     if(is_set(p->flags, xpf_created)) {
         xmlAttr *xIter = NULL;
+        char *path = xml_get_path(xml);
 
-        /* Always allow new scaffolding, ie. node with no attributes or only an 'id' */
+        /* Always allow new scaffolding, ie. node with no attributes or only an 'id'
+         * Except in the ACLs section
+         */
 
         for (xIter = crm_first_attr(xml); xIter != NULL; xIter = xIter->next) {
             const char *prop_name = (const char *)xIter->name;
 
-            if (strcmp(prop_name, XML_ATTR_ID) == 0) {
+            if (strcmp(prop_name, XML_ATTR_ID) == 0 && strstr(path, "/"XML_CIB_TAG_ACLS"/") == NULL) {
                 /* Delay the acl check */
                 continue;
 
@@ -1035,7 +1038,6 @@ __xml_acl_post_process(xmlNode * xml)
                 break;
 
             } else {
-                char *path = xml_get_path(xml);
                 crm_trace("Cannot add new node %s at %s", crm_element_name(xml), path);
 
                 if(xml != xmlDocGetRootElement(xml->doc)) {
@@ -1046,6 +1048,7 @@ __xml_acl_post_process(xmlNode * xml)
                 return;
             }
         }
+        free(path);
     }
 
     while (cIter != NULL) {
path: lib/common/xml.c