[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH] xsm/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 (set by running checkpolicy -U allow) 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. Signed-off-by: Daniel De Graaf <dgdegra@xxxxxxxxxxxxx> --- xen/xsm/flask/hooks.c | 40 ++++++++++++++++++++++++---------------- 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, 38 insertions(+), 16 deletions(-) diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c index 0ba2ce9..4c8a1d2 100644 --- a/xen/xsm/flask/hooks.c +++ b/xen/xsm/flask/hooks.c @@ -135,6 +135,19 @@ 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) +{ + /* A guest making an invalid hypercall can trigger this message, so it can't + * be an ASSERT or BUG_ON, but normally it is caused by a missing case in + * one of the switch statements below. + */ + printk(XENLOG_G_ERR "FLASK: Unknown %s: %d.\n", name, id); + if ( !flask_enforcing || security_get_allow_unknown() ) + return 0; + else + return -EPERM; +} + static int flask_domain_alloc_security(struct domain *d) { struct domain_security_struct *dsec; @@ -270,7 +283,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; @@ -422,7 +435,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); @@ -454,7 +467,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); @@ -520,8 +533,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); } } @@ -536,8 +548,7 @@ static int flask_sysctl_scheduler_op(int op) return domain_has_xen(current->domain, XEN__GETSCHEDULER); default: - printk("flask_domctl_scheduler_op: Unknown op %d\n", op); - return -EPERM; + return avc_unknown_permission("sysctl_scheduler_op", op); } } @@ -731,8 +742,7 @@ static int flask_domctl(struct domain *d, int cmd) return current_has_perm(d, SECCLASS_DOMAIN2, DOMAIN2__CONFIGURE_DOMAIN); default: - printk("flask_domctl: Unknown op %d\n", cmd); - return -EPERM; + return avc_unknown_permission("domctl", cmd); } } @@ -790,8 +800,7 @@ static int flask_sysctl(int cmd) XEN2__PSR_CMT_OP, NULL); default: - printk("flask_sysctl: Unknown op %d\n", cmd); - return -EPERM; + return avc_unknown_permission("sysctl", cmd); } } @@ -1078,7 +1087,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); } } @@ -1240,7 +1249,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); @@ -1344,7 +1353,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); @@ -1409,8 +1418,7 @@ static int flask_platform_op(uint32_t op) XEN2__RESOURCE_OP, NULL); default: - printk("flask_platform_op: Unknown op %d\n", op); - return -EPERM; + return avc_unknown_permission("platform_op", op); } } diff --git a/xen/xsm/flask/include/security.h b/xen/xsm/flask/include/security.h index 348f018..a93f14a 100644 --- a/xen/xsm/flask/include/security.h +++ b/xen/xsm/flask/include/security.h @@ -71,6 +71,8 @@ int security_context_to_sid(char *scontext, u32 scontext_len, u32 *out_sid); int security_get_user_sids(u32 callsid, char *username, u32 **sids, u32 *nel); +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 50b2c78..b648f05 100644 --- a/xen/xsm/flask/ss/policydb.c +++ b/xen/xsm/flask/ss/policydb.c @@ -1802,6 +1802,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 b176300..aeaf69b 100644 --- a/xen/xsm/flask/ss/policydb.h +++ b/xen/xsm/flask/ss/policydb.h @@ -245,6 +245,8 @@ struct policydb { unsigned int policyvers; + unsigned int allow_unknown : 1; + u16 target_type; }; @@ -260,6 +262,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 f0e459a..9b18509 100644 --- a/xen/xsm/flask/ss/services.c +++ b/xen/xsm/flask/ss/services.c @@ -1464,6 +1464,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 -- 1.9.3 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |