From patchwork Mon Jun 20 14:04:20 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: 9187553 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 BFC1E607D1 for ; Mon, 20 Jun 2016 14:06:59 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AB8CE2711E for ; Mon, 20 Jun 2016 14:06:59 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A05AC27813; Mon, 20 Jun 2016 14:06:59 +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 00D032711E for ; Mon, 20 Jun 2016 14:06:58 +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 1bEzom-0000zl-HK; Mon, 20 Jun 2016 14:04:48 +0000 Received: from mail6.bemta14.messagelabs.com ([193.109.254.103]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1bEzol-0000ws-88 for xen-devel@lists.xen.org; Mon, 20 Jun 2016 14:04:47 +0000 Received: from [193.109.254.147] by server-10.bemta-14.messagelabs.com id 87/5D-10191-EF7F7675; Mon, 20 Jun 2016 14:04:46 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFvrDLMWRWlGSWpSXmKPExsXCoZPKofv3e3q 4wZx9VhZLPi5mcWD0OLr7N1MAYxRrZl5SfkUCa8bDx5dYClabVTz81sDUwLhHq4uRk0NCwE/i 6tmZLCA2p8ByFokNW926GLmA4ucYJd5+WsMG4ggJtDNKzH80FcrZxijx4/E9ZpAWNgFdiQUHV zKB2CIC0hLXPl9mBLGZBbQlmt/NZAexhQUcJU4ue8UKYrMIqEq8P3cdbB2vgJvEmglH2CDOkJ O4ea6TGeIMN4nzX26B2UICrhIXJ99kncDIt4CRYRWjRnFqUVlqka6huV5SUWZ6RkluYmaOrqG hiV5uanFxYnpqTmJSsV5yfu4mRmCo1DMwMO5g/Hna8xCjJAeTkijv9Cfp4UJ8SfkplRmJxRnx RaU5qcWHGGU4OJQkeEu/AuUEi1LTUyvSMnOAQQuTluDgURLhbQJJ8xYXJOYWZ6ZDpE4xKkqJ8 2aBJARAEhmleXBtsEi5xCgrJczLyMDAIMRTkFqUm1mCKv+KUZyDUUmY1+wb0BSezLwSuOmvgB YzAS1e1g+2uCQRISXVwDjzVj2vtaNifYNxM+tzw8DlyiZWjo9Yru+Y8M5ZdAl/4eQ9r73tVPs mL34hLcFcdOL3bceE9/KWt2Mnr9G35IlXjly/h/l/yqSlf5ximgTnJp7Y/+Xve6bmqn+Srau2 bHK4pH/xap6NTKj4gfkzQ61uKtvO12fzF/2t0yN7PHSKz5+8yS/WJSixFGckGmoxFxUnAgDqq /G5jwIAAA== X-Env-Sender: dgdegra@tycho.nsa.gov X-Msg-Ref: server-14.tower-27.messagelabs.com!1466431477!36613602!2 X-Originating-IP: [8.44.101.8] X-SpamReason: No, hits=0.0 required=7.0 tests= X-StarScan-Received: X-StarScan-Version: 8.46; banners=-,-,- X-VirusChecked: Checked Received: (qmail 64125 invoked from network); 20 Jun 2016 14:04:45 -0000 Received: from smtp.nsa.gov (HELO emsm-gh1-uea10.nsa.gov) (8.44.101.8) by server-14.tower-27.messagelabs.com with DHE-RSA-AES256-GCM-SHA384 encrypted SMTP; 20 Jun 2016 14:04:45 -0000 X-IronPort-AV: E=Sophos;i="5.26,498,1459814400"; d="scan'208";a="14811870" IronPort-PHdr: =?us-ascii?q?9a23=3APiJJGxTXqDUZTqKW7RDgmEfcJ9psv+yvbD5Q0YIu?= =?us-ascii?q?jvd0So/mwa64YhWN2/xhgRfzUJnB7Loc0qyN4/GmCDFLv8nJmUtBWaIPfidNsd?= =?us-ascii?q?8RkQ0kDZzNImzAB9muURYHGt9fXkRu5XCxPBsdMs//Y1rPvi/6tmZKSV3BPAZ4?= =?us-ascii?q?bt74BpTVx5zukbviqtuCPk4W23KUWvBbElaflU3prM4YgI9veO4a6yDihT92Qd?= =?us-ascii?q?lQ3n5iPlmJnhzxtY+a9Z9n9DlM6bp6r5YTGZjge+wEaZAQTHF8ayFmrPHs4AnO?= =?us-ascii?q?S06D62URVk0SkwFUGE7V4Re8WY3+4QXgse8o9CCcPMDyBZw5ERu45q5lAEvkhy?= =?us-ascii?q?sKOCQw2H3Ggcx3yqRAqVSuoAIpkN2cW52cKPcrJvCVRtgdX2cUG5wJWg=3D=3D?= X-IPAS-Result: =?us-ascii?q?A2GpAwAy92dX/wHyM5BdGgEBAQGDIIFTuFeECYYXAoExTAE?= =?us-ascii?q?BAQEBAQICYieCMYIbAgQnUhAYOVcZiDDASAEBAQEGAgEkjx6FcQWICQmFY4Eyi?= =?us-ascii?q?U+OKgKJWoVGj3dUHIFsHIFoIDKKSAEBAQ?= Received: from unknown (HELO tarius.tycho.ncsc.mil) ([144.51.242.1]) by emsm-gh1-uea10.nsa.gov with ESMTP; 20 Jun 2016 14:04:31 +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 u5KE4U69018300; Mon, 20 Jun 2016 10:04:30 -0400 From: Daniel De Graaf To: xen-devel@lists.xen.org Date: Mon, 20 Jun 2016 10:04:20 -0400 Message-Id: <1466431466-28055-12-git-send-email-dgdegra@tycho.nsa.gov> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1466431466-28055-1-git-send-email-dgdegra@tycho.nsa.gov> References: <1466431466-28055-1-git-send-email-dgdegra@tycho.nsa.gov> Cc: Daniel De Graaf Subject: [Xen-devel] [PATCH 11/17] 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 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 Reviewed-by: Doug Goldstein --- 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