From patchwork Thu Jun 9 14:47:14 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel De Graaf X-Patchwork-Id: 9167209 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 4019C604DB for ; Thu, 9 Jun 2016 14:49:47 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 32726264F4 for ; Thu, 9 Jun 2016 14:49:47 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 273DD2834F; Thu, 9 Jun 2016 14:49:47 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id A2DED264F4 for ; Thu, 9 Jun 2016 14:49:46 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1bB1FB-00054Y-L5; Thu, 09 Jun 2016 14:47:37 +0000 Received: from mail6.bemta6.messagelabs.com ([85.158.143.247]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1bB1F9-0004tz-AY for xen-devel@lists.xen.org; Thu, 09 Jun 2016 14:47:35 +0000 Received: from [85.158.143.35] by server-1.bemta-6.messagelabs.com id 03/34-30266-78189575; Thu, 09 Jun 2016 14:47:35 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFvrFLMWRWlGSWpSXmKPExsXCoZPKqdvWGBl u8GOvosWSj4tZHBg9ju7+zRTAGMWamZeUX5HAmjGrawJzwSLTikdPZjA1MJ7Q7GLk5JAQ8JPY 9egcWxcjFwenwHwWieO7LrCDOBIC5xgl9t37zALiCAksZZRou/6eDaRFSGAro8TdXfogNpuAr sSCgyuZQGwRAWmJa58vM4LYzALaEs3vZrKD2MICjhIT1x0Eq2ERUJX4OPM3mM0r4Cpxb8VxVo gz5CS2bdkD1ssJFH9z/iXQLg6gXS4SC396TWDkW8DIsIpRvTi1qCy1SNdIL6koMz2jJDcxM0f X0MBMLze1uDgxPTUnMalYLzk/dxMjMEwYgGAH47K/TocYJTmYlER5vUsiw4X4kvJTKjMSizPi i0pzUosPMcpwcChJ8JY0AOUEi1LTUyvSMnOAAQuTluDgURLhXQKS5i0uSMwtzkyHSJ1iVJQS5 7UASQiAJDJK8+DaYFFyiVFWSpiXEegQIZ6C1KLczBJU+VeM4hyMSsK8VSBTeDLzSuCmvwJazA S0ePmRcJDFJYkIKakGRlG5BPYwJoOjVf9WPtjwOs5IrbRIUnF5mXlvutY74x5HFbljp7X0euf kKkx4ce/VbYtNbL/6wrie8EpyzupJ8vmvldm4bcbmoIfq/Unz9FcwzWmpN+oKujE34dmjXdEh qR4Xs5tc25Ou/+uxObDp0deoLaftbm0X0uH5/OX9/erVOcXsNhZ7lViKMxINtZiLihMBIlgOp 40CAAA= X-Env-Sender: dgdegra@tycho.nsa.gov X-Msg-Ref: server-12.tower-21.messagelabs.com!1465483650!18280129!7 X-Originating-IP: [8.44.101.9] X-SpamReason: No, hits=0.0 required=7.0 tests= X-StarScan-Received: X-StarScan-Version: 8.46; banners=-,-,- X-VirusChecked: Checked Received: (qmail 16377 invoked from network); 9 Jun 2016 14:47:34 -0000 Received: from emsm-gh1-uea11.nsa.gov (HELO emsm-gh1-uea11.nsa.gov) (8.44.101.9) by server-12.tower-21.messagelabs.com with DHE-RSA-AES256-GCM-SHA384 encrypted SMTP; 9 Jun 2016 14:47:34 -0000 X-IronPort-AV: E=Sophos;i="5.26,445,1459814400"; d="scan'208";a="16783291" IronPort-PHdr: =?us-ascii?q?9a23=3AMXZI5xexbIasB/fp1AyHNDH0lGMj4u6mDksu8pMi?= =?us-ascii?q?zoh2WeGdxc68ZR7h7PlgxGXEQZ/co6odzbGG4ua/BCdfu96oizMrTt9lb1c9k8?= =?us-ascii?q?IYnggtUoauKHbQC7rUVRE8B9lIT1R//nu2YgB/Ecf6YEDO8DXptWZBUiv2OQc9?= =?us-ascii?q?HOnpAIma153xjLDjvcKOKFoSzBOGIppMbzyO5T3LsccXhYYwYo0Q8TDu5kVyRu?= =?us-ascii?q?JN2GlzLkiSlRuvru25/Zpk7jgC86l5r50IbL/+N5gcYfQYSW5+cjN92Mq+pRTF?= =?us-ascii?q?CAeC+HYYemEXiQZTRRjI6lf9RJiinDH9s79R0S+bMMm+Yb18di6r5qkjHBPnhC?= =?us-ascii?q?oILTcR7HDciss2irlS5h2muUoskMbvfIiJOa8mLevmdtQASD8EBJ5c?= X-IPAS-Result: =?us-ascii?q?A2HIAwBJgFlX/wHyM5BeGgEBAQGDIIFTuQiECYYTAoE1TAE?= =?us-ascii?q?BAQEBAQICYieCMIIWAgQnUhAYOVcZiC++KgEBAQEGAgEkjx6FcAWIAwWFYoEyi?= =?us-ascii?q?TmOJwKJWYVFj2VUHIFrHIFnIDKKCAEBAQ?= Received: from unknown (HELO tarius.tycho.ncsc.mil) ([144.51.242.1]) by emsm-gh1-uea11.nsa.gov with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 09 Jun 2016 14:47:29 +0000 Received: from moss-nexus.infosec.tycho.ncsc.mil (moss-nexus [192.168.25.48]) by tarius.tycho.ncsc.mil (8.14.4/8.14.4) with ESMTP id u59ElSND018061; Thu, 9 Jun 2016 10:47:28 -0400 From: Daniel De Graaf To: xen-devel@lists.xen.org Date: Thu, 9 Jun 2016 10:47:14 -0400 Message-Id: <1465483638-9489-12-git-send-email-dgdegra@tycho.nsa.gov> X-Mailer: git-send-email 2.5.5 In-Reply-To: <1465483638-9489-1-git-send-email-dgdegra@tycho.nsa.gov> References: <1465483638-9489-1-git-send-email-dgdegra@tycho.nsa.gov> Cc: Daniel De Graaf Subject: [Xen-devel] [PATCH 11/15] flask: improve unknown permission handling X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: xen-devel-bounces@lists.xen.org Sender: "Xen-devel" X-Virus-Scanned: ClamAV using ClamSMTP 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 --- 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