From patchwork Wed Apr 6 23:33:51 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Jurgens X-Patchwork-Id: 8767241 Return-Path: X-Original-To: patchwork-linux-rdma@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id AB06A9FC89 for ; Wed, 6 Apr 2016 23:34:51 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 9AE89201C7 for ; Wed, 6 Apr 2016 23:34:50 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 8C3FA201CD for ; Wed, 6 Apr 2016 23:34:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754606AbcDFXes (ORCPT ); Wed, 6 Apr 2016 19:34:48 -0400 Received: from [193.47.165.129] ([193.47.165.129]:33841 "EHLO mellanox.co.il" rhost-flags-FAIL-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1754485AbcDFXer (ORCPT ); Wed, 6 Apr 2016 19:34:47 -0400 Received: from Internal Mail-Server by MTLPINE1 (envelope-from danielj@mellanox.com) with ESMTPS (AES256-SHA encrypted); 7 Apr 2016 02:34:15 +0300 Received: from x-vnc01.mtx.labs.mlnx (x-vnc01.mtx.labs.mlnx [10.12.150.16]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id u36NY4Tl002830; Thu, 7 Apr 2016 02:34:14 +0300 From: Dan Jurgens To: selinux@tycho.nsa.gov, linux-security-module@vger.kernel.org, linux-rdma@vger.kernel.org Cc: yevgenyp@mellanox.com, Daniel Jurgens Subject: [RFC PATCH v2 06/13] selinux: Add IB Device SMI access vector Date: Thu, 7 Apr 2016 02:33:51 +0300 Message-Id: <1459985638-37233-7-git-send-email-danielj@mellanox.com> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1459985638-37233-1-git-send-email-danielj@mellanox.com> References: <1459985638-37233-1-git-send-email-danielj@mellanox.com> Sender: linux-rdma-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-rdma@vger.kernel.org X-Spam-Status: No, score=-7.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Daniel Jurgens Add a type and access vector for infiniband devices and their subnet management interface. Implement the ibdev_smi hook to check that the caller has permission to access the SMI specified by the device name and port. Add interface to query the SID for a IB device, which walks the IBDEV ocontexts to find an entry for the given name and port. Signed-off-by: Daniel Jurgens Reviewed-by: Eli Cohen --- include/linux/lsm_audit.h | 8 ++++ security/selinux/hooks.c | 27 ++++++++++++++ security/selinux/include/classmap.h | 2 + security/selinux/include/initial_sid_to_string.h | 1 + security/selinux/include/security.h | 2 + security/selinux/ss/services.c | 43 ++++++++++++++++++++++ 6 files changed, 83 insertions(+), 0 deletions(-) diff --git a/include/linux/lsm_audit.h b/include/linux/lsm_audit.h index 8ff7eae..9177ed3 100644 --- a/include/linux/lsm_audit.h +++ b/include/linux/lsm_audit.h @@ -21,6 +21,7 @@ #include #include #include +#include struct lsm_network_audit { int netif; @@ -50,6 +51,11 @@ struct lsm_pkey_audit { u16 pkey; }; +struct lsm_ibdev_audit { + char dev_name[IB_DEVICE_NAME_MAX]; + u8 port; +}; + /* Auxiliary data to use in generating the audit record. */ struct common_audit_data { char type; @@ -65,6 +71,7 @@ struct common_audit_data { #define LSM_AUDIT_DATA_DENTRY 10 #define LSM_AUDIT_DATA_IOCTL_OP 11 #define LSM_AUDIT_DATA_PKEY 12 +#define LSM_AUDIT_DATA_IBDEV 13 union { struct path path; struct dentry *dentry; @@ -82,6 +89,7 @@ struct common_audit_data { char *kmod_name; struct lsm_ioctlop_audit *op; struct lsm_pkey_audit *pkey; + struct lsm_ibdev_audit *ibdev; } u; /* this union contains LSM specific data */ union { diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index aa62f72..15c0671 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -6040,6 +6040,32 @@ static int selinux_mad_agent_pkey_access(u64 subnet_prefix, u16 pkey_val, mad_agent->m_security); } +static int selinux_ibdev_smi(const char *dev_name, u8 port, + struct ib_mad_agent *mad_agent) +{ + struct common_audit_data ad; + int err; + u32 sid = 0; + struct ib_security_struct *sec = mad_agent->m_security; + struct lsm_ibdev_audit ibdev; + + err = security_ibdev_sid(dev_name, port, &sid); + + if (err) + goto out; + + ad.type = LSM_AUDIT_DATA_IBDEV; + strncpy(ibdev.dev_name, dev_name, sizeof(ibdev.dev_name)); + ibdev.port = port; + ad.u.ibdev = &ibdev; + err = avc_has_perm(sec->sid, sid, + SECCLASS_INFINIBAND_DEVICE, + INFINIBAND_DEVICE__SMI, &ad); + +out: + return err; +} + static int selinux_ib_qp_alloc_security(struct ib_qp_security *qp_sec) { struct ib_security_struct *sec; @@ -6272,6 +6298,7 @@ static struct security_hook_list selinux_hooks[] = { selinux_unregister_ib_flush_callback), LSM_HOOK_INIT(qp_pkey_access, selinux_qp_pkey_access), LSM_HOOK_INIT(mad_agent_pkey_access, selinux_mad_agent_pkey_access), + LSM_HOOK_INIT(ibdev_smi, selinux_ibdev_smi), LSM_HOOK_INIT(ib_qp_alloc_security, selinux_ib_qp_alloc_security), LSM_HOOK_INIT(ib_qp_free_security, diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h index 322b56c..4521261 100644 --- a/security/selinux/include/classmap.h +++ b/security/selinux/include/classmap.h @@ -159,5 +159,7 @@ struct security_class_mapping secclass_map[] = { NULL } }, { "infiniband_pkey", { "access", NULL } }, + { "infiniband_device", + { "smi", NULL } }, { NULL } }; diff --git a/security/selinux/include/initial_sid_to_string.h b/security/selinux/include/initial_sid_to_string.h index 8f2eefc..56737c3 100644 --- a/security/selinux/include/initial_sid_to_string.h +++ b/security/selinux/include/initial_sid_to_string.h @@ -30,5 +30,6 @@ static const char *initial_sid_to_string[] = "scmp_packet", "devnull", "pkey", + "ibdev", }; diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h index 8f1a66e..692c3ce 100644 --- a/security/selinux/include/security.h +++ b/security/selinux/include/security.h @@ -182,6 +182,8 @@ int security_port_sid(u8 protocol, u16 port, u32 *out_sid); int security_pkey_sid(u64 subnet_prefix, u16 pkey_num, u32 *out_sid); +int security_ibdev_sid(const char *dev_name, u8 port, u32 *out_sid); + int security_netif_sid(char *name, u32 *if_sid); int security_node_sid(u16 domain, void *addr, u32 addrlen, diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index 2fc48c5..e49d276 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -53,6 +53,7 @@ #include #include #include +#include #include "flask.h" #include "avc.h" @@ -2270,6 +2271,48 @@ out: } /** + * security_ibdev_sid - Obtain the SID for a subnet management interface. + * @dev_name: device name + * @port: port number + * @out_sid: security identifier + */ +int security_ibdev_sid(const char *dev_name, u8 port, u32 *out_sid) +{ + struct ocontext *c; + int rc = 0; + + read_lock(&policy_rwlock); + + c = policydb.ocontexts[OCON_IBDEV]; + while (c) { + if (c->u.ibdev.port == port && + !strncmp(c->u.ibdev.dev_name, + dev_name, + IB_DEVICE_NAME_MAX)) + break; + + c = c->next; + } + + if (c) { + if (!c->sid[0]) { + rc = sidtab_context_to_sid(&sidtab, + &c->context[0], + &c->sid[0]); + if (rc) + goto out; + } + *out_sid = c->sid[0]; + } else { + *out_sid = SECINITSID_IBDEV; + } + +out: + read_unlock(&policy_rwlock); + return rc; +} + +/** * security_netif_sid - Obtain the SID for a network interface. * @name: interface name * @if_sid: interface SID