|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 11/15] 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 bit is
off by default, but it can be set by using checkpolicy -U allow when
compiling the policy. 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 | 44 +++++++++++++++++++++++++---------------
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, 42 insertions(+), 16 deletions(-)
diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c
index a8d45e7..3ab3fbf 100644
--- a/xen/xsm/flask/hooks.c
+++ b/xen/xsm/flask/hooks.c
@@ -136,6 +136,23 @@ 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 +288,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 +440,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 +472,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 +538,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 +553,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 +750,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 +825,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 +1142,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 +1415,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 +1446,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 +1550,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 8aa88c1..46574c3 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 50e22f3..eb1e44d 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 c9b27a0..ce880e9 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
--
2.5.5
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |