[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen master] flask: improve unknown permission handling



commit 56fef9e367b250a3c6ff16b6c4494c5103ac4871
Author:     Daniel De Graaf <dgdegra@xxxxxxxxxxxxx>
AuthorDate: Mon Jun 20 10:04:20 2016 -0400
Commit:     Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
CommitDate: Tue Jun 21 15:56:00 2016 +0100

    flask: improve unknown permission handling
    
    When an unknown domctl, sysctl, or other operation is encountered in the
    FLASK security server, use the allow_unknown bit in the security policy
    to decide if the permission should be allowed or denied.  This allows
    new operations to be tested without needing to immediately add security
    checks; however, it is not flexible enough to avoid adding the actual
    permission checks.  An error message is printed to the hypervisor
    console when this fallback is encountered.
    
    This patch will allow operations that are not handled by the existing
    hooks only if the policy was compiled with "checkpolicy -U allow".  In
    previous releases, this bit did nothing, and the default remains to deny
    the unknown operations.
    
    Signed-off-by: Daniel De Graaf <dgdegra@xxxxxxxxxxxxx>
    Reviewed-by: Doug Goldstein <cardoe@xxxxxxxxxx>
---
 xen/xsm/flask/hooks.c            | 45 ++++++++++++++++++++++++++--------------
 xen/xsm/flask/include/security.h |  2 ++
 xen/xsm/flask/ss/policydb.c      |  1 +
 xen/xsm/flask/ss/policydb.h      |  6 ++++++
 xen/xsm/flask/ss/services.c      |  5 +++++
 5 files changed, 43 insertions(+), 16 deletions(-)

diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c
index a8d45e7..543406b 100644
--- a/xen/xsm/flask/hooks.c
+++ b/xen/xsm/flask/hooks.c
@@ -136,6 +136,24 @@ static int get_irq_sid(int irq, u32 *sid, struct 
avc_audit_data *ad)
     return 0;
 }
 
+static int avc_unknown_permission(const char *name, int id)
+{
+    int rc;
+
+    if ( !flask_enforcing || security_get_allow_unknown() )
+    {
+        printk(XENLOG_G_WARNING "FLASK: Allowing unknown %s: %d.\n", name, id);
+        rc = 0;
+    }
+    else
+    {
+        printk(XENLOG_G_ERR "FLASK: Denying unknown %s: %d.\n", name, id);
+        rc = -EPERM;
+    }
+
+    return rc;
+}
+
 static int flask_domain_alloc_security(struct domain *d)
 {
     struct domain_security_struct *dsec;
@@ -271,7 +289,7 @@ static int flask_evtchn_send(struct domain *d, struct 
evtchn *chn)
         rc = 0;
         break;
     default:
-        rc = -EPERM;
+        rc = avc_unknown_permission("event channel state", chn->state);
     }
 
     return rc;
@@ -423,7 +441,7 @@ static int flask_console_io(struct domain *d, int cmd)
         perm = XEN__WRITECONSOLE;
         break;
     default:
-        return -EPERM;
+        return avc_unknown_permission("console_io", cmd);
     }
 
     return domain_has_xen(d, perm);
@@ -455,7 +473,7 @@ static int flask_profile(struct domain *d, int op)
         perm = XEN__PRIVPROFILE;
         break;
     default:
-        return -EPERM;
+        return avc_unknown_permission("xenoprof op", op);
     }
 
     return domain_has_xen(d, perm);
@@ -521,8 +539,7 @@ static int flask_domctl_scheduler_op(struct domain *d, int 
op)
         return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__GETSCHEDULER);
 
     default:
-        printk("flask_domctl_scheduler_op: Unknown op %d\n", op);
-        return -EPERM;
+        return avc_unknown_permission("domctl_scheduler_op", op);
     }
 }
 
@@ -537,8 +554,7 @@ static int flask_sysctl_scheduler_op(int op)
         return domain_has_xen(current->domain, XEN__GETSCHEDULER);
 
     default:
-        printk("flask_sysctl_scheduler_op: Unknown op %d\n", op);
-        return -EPERM;
+        return avc_unknown_permission("sysctl_scheduler_op", op);
     }
 }
 
@@ -735,8 +751,7 @@ static int flask_domctl(struct domain *d, int cmd)
         return current_has_perm(d, SECCLASS_DOMAIN2, DOMAIN2__SOFT_RESET);
 
     default:
-        printk("flask_domctl: Unknown op %d\n", cmd);
-        return -EPERM;
+        return avc_unknown_permission("domctl", cmd);
     }
 }
 
@@ -811,8 +826,7 @@ static int flask_sysctl(int cmd)
                                     XEN2__LIVEPATCH_OP, NULL);
 
     default:
-        printk("flask_sysctl: Unknown op %d\n", cmd);
-        return -EPERM;
+        return avc_unknown_permission("sysctl", cmd);
     }
 }
 
@@ -1129,7 +1143,7 @@ static inline int flask_page_offline(uint32_t cmd)
     case sysctl_query_page_offline:
         return flask_resource_use_core();
     default:
-        return -EPERM;
+        return avc_unknown_permission("page_offline", cmd);
     }
 }
 
@@ -1402,8 +1416,7 @@ static int flask_platform_op(uint32_t op)
                             SECCLASS_XEN2, XEN2__GET_SYMBOL, NULL);
 
     default:
-        printk("flask_platform_op: Unknown op %d\n", op);
-        return -EPERM;
+        return avc_unknown_permission("platform_op", op);
     }
 }
 
@@ -1434,7 +1447,7 @@ static int flask_shadow_control(struct domain *d, 
uint32_t op)
         perm = SHADOW__LOGDIRTY;
         break;
     default:
-        return -EPERM;
+        return avc_unknown_permission("shadow_control", op);
     }
 
     return current_has_perm(d, SECCLASS_SHADOW, perm);
@@ -1538,7 +1551,7 @@ static int flask_apic(struct domain *d, int cmd)
         perm = XEN__WRITEAPIC;
         break;
     default:
-        return -EPERM;
+        return avc_unknown_permission("apic", cmd);
     }
 
     return domain_has_xen(d, perm);
diff --git a/xen/xsm/flask/include/security.h b/xen/xsm/flask/include/security.h
index 2b00177..1da020d 100644
--- a/xen/xsm/flask/include/security.h
+++ b/xen/xsm/flask/include/security.h
@@ -78,6 +78,8 @@ int security_sid_to_context(u32 sid, char **scontext, u32 
*scontext_len);
 
 int security_context_to_sid(char *scontext, u32 scontext_len, u32 *out_sid);
 
+int security_get_allow_unknown(void);
+
 int security_irq_sid(int pirq, u32 *out_sid);
 
 int security_iomem_sid(unsigned long, u32 *out_sid);
diff --git a/xen/xsm/flask/ss/policydb.c b/xen/xsm/flask/ss/policydb.c
index 00b5390..3a12d96 100644
--- a/xen/xsm/flask/ss/policydb.c
+++ b/xen/xsm/flask/ss/policydb.c
@@ -1843,6 +1843,7 @@ int policydb_read(struct policydb *p, void *fp)
             goto bad;
         }
     }
+    p->allow_unknown = !!(le32_to_cpu(buf[1]) & ALLOW_UNKNOWN);
 
     if ( p->policyvers >= POLICYDB_VERSION_POLCAP &&
          ebitmap_read(&p->policycaps, fp) != 0 )
diff --git a/xen/xsm/flask/ss/policydb.h b/xen/xsm/flask/ss/policydb.h
index f158ce3..238a042 100644
--- a/xen/xsm/flask/ss/policydb.h
+++ b/xen/xsm/flask/ss/policydb.h
@@ -246,6 +246,8 @@ struct policydb {
 
     unsigned int policyvers;
 
+    unsigned int allow_unknown : 1;
+
     u16 target_type;
 };
 
@@ -261,6 +263,10 @@ extern int policydb_read(struct policydb *p, void *fp);
 
 #define POLICYDB_CONFIG_MLS    1
 
+/* the config flags related to unknown classes/perms are bits 2 and 3 */
+#define REJECT_UNKNOWN 0x00000002
+#define ALLOW_UNKNOWN  0x00000004
+
 #define OBJECT_R "object_r"
 #define OBJECT_R_VAL 1
 
diff --git a/xen/xsm/flask/ss/services.c b/xen/xsm/flask/ss/services.c
index 6a07fc0..86f94c9 100644
--- a/xen/xsm/flask/ss/services.c
+++ b/xen/xsm/flask/ss/services.c
@@ -1465,6 +1465,11 @@ err:
 
 }
 
+int security_get_allow_unknown(void)
+{
+    return policydb.allow_unknown;
+}
+
 /**
  * security_irq_sid - Obtain the SID for a physical irq.
  * @pirq: physical irq
--
generated by git-patchbot for /home/xen/git/xen.git#master

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.