All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v6 0/9] SELinux support for Infiniband RDMA
@ 2016-11-23 14:17 ` Dan Jurgens
  0 siblings, 0 replies; 51+ messages in thread
From: Dan Jurgens @ 2016-11-23 14:17 UTC (permalink / raw)
  To: chrisw-69jw2NvuJkxg9hUCZPvPmw, paul-r2n+y4ga6xFZroRs9YW3xA,
	sds-+05T5uksL2qpZYMLLGbcSA, eparis-FjpueFixGhCM4zKIHC2jIg,
	dledford-H+wXaHxf7aLQT0dZR+AlfA,
	sean.hefty-ral2JQCrhuEAvxtiuMwx3w,
	hal.rosenstock-Re5JQEeQqe8AvxtiuMwx3w
  Cc: selinux-+05T5uksL2qpZYMLLGbcSA,
	linux-security-module-u79uwXL29TY76Z2rM5mHXA,
	linux-rdma-u79uwXL29TY76Z2rM5mHXA,
	yevgenyp-VPRAkNaXOzVWk0Htik3J/w, Daniel Jurgens

From: Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>

Infiniband applications access HW from user-space -- traffic is generated
directly by HW, bypassing the kernel. Consequently, Infiniband Partitions,
which are associated directly with HW transport endpoints, are a natural
choice for enforcing granular mandatory access control for Infiniband. QPs may
only send or receives packets tagged with the corresponding partition key
(PKey). The PKey is not a cryptographic key; it's a 16 bit number identifying
the partition.

Every Infiniband fabric is controlled by a central Subnet Manager (SM). The SM
provisions the partitions by assigning each port with the partitions it can
access. In addition, the SM tags each port with a subnet prefix, which
identifies the subnet. Determining which users are allowed to access which
partition keys on a given subnet forms an effective policy for isolating users
on the fabric. Any application that attempts to send traffic on a given subnet
is automatically subject to the policy, regardless of which device and port it
uses. SM software configures the subnet through a privileged Subnet Management
Interface (SMI), which is presented by each Infiniband port. Thus, the SMI must
also be controlled to prevent unauthorized changes to fabric configuration and
partitioning. 

To support access control for IB partitions and subnet management, security
contexts must be provided for two new types of objects - PKeys and IB ports.

A PKey label consists of a subnet prefix and a range of PKey values and is
similar to the labeling mechanism for netports. Each Infiniband port can reside
on a different subnet. So labeling the PKey values for specific subnet prefixes
provides the user maximum flexibility, as PKey values may be determined
independently for different subnets. There is a single access vector for PKeys
called "access".

An Infiniband port is labeled by device name and port number. There is a single
access vector for IB ports called "manage_subnet".

Because RDMA allows kernel bypass, enforcement must be done during connection
setup. Communication over RDMA requires a send and receive queue, collectively
known as a Queue Pair (QP). A QP must be initialized by privileged system calls
before it can be used to send or receive data. During initialization the user
must provide the PKey and port the QP will use; at this time access control can
be enforced.

Because there is a possibility that the enforcement settings or security
policy can change, a means of notifying the ib_core module of such changes
is required. To facilitate this a generic notification callback mechanism
is added to the LSM. One callback is registered for checking the QP PKey
associations when the policy changes. Mad agents also register a callback,
they cache the permission to send and receive SMPs to avoid another per
packet call to the LSM.

Because frequent accesses to the same PKey's SID is expected a cache is
implemented which is very similar to the netport cache.

In order to properly enforce security when changes to the PKey table or
security policy or enforcement occur ib_core must track which QPs are
using which port, pkey index, and alternate path for every IB device.
This makes operations that used to be atomic transactional.

When modifying a QP, ib_core must associate it with the PKey index, port,
and alternate path specified. If the QP was already associated with
different settings, the QP is added to the new list prior to the
modification. If the modify succeeds then the old listing is removed. If
the modify fails the new listing is removed and the old listing remains
unchanged.

When destroying a QP the ib_qp structure is freed by the decive specific
driver (i.e. mlx4_ib) if the 'destroy' is successful. This requires storing
security related information in a separate structure. When a 'destroy'
request is in process the ib_qp structure is in an undefined state so if
there are changes to the security policy or PKey table, the security checks
cannot reset the QP if it doesn't have permission for the new setting. If
the 'destroy' fails, security for that QP must be enforced again and its
status in the list is restored. If the 'destroy' succeeds the security info
can be cleaned up and freed.

There are a number of locks required to protect the QP security structure
and the QP to device/port/pkey index lists. If multiple locks are required,
the safe locking order is: QP security structure mutex first, followed by
any list locks needed, which are sorted first by port followed by pkey
index.

---
v2:
- Use void* blobs in the LSM hooks. Paul Moore
- Make the policy change callback generic. Yuval Shaia, Paul Moore
- Squash LSM changes into the patches where the calls are added. Paul Moore
- Don't add new initial SIDs. Stephen Smalley
- Squash MAD agent PKey and SMI patches and move logic to IB security. Dan Jurgens
- Changed ib_end_port to ib_port. Paul Moore
- Changed ib_port access vector from smp to manage_subnet. Paul Moore
- Added pkey and ib_port details to the audit log. Paul Moore
- See individual patches for more detail.

v3:
- ib_port -> ib_endport. Paul Moore
- use notifier chains for LSM notifications. Paul Moore
- reorder parameters in hooks to put security blob first. Paul Moore
- Don't treat device name as untrusted string in audit log. Paul Moore

v4:
- Added separate AVC callback for LSM notifier. Paul Moore
- Removed unneeded braces in ocontext_read. Paul Moore

v5:
- Fix link error when CONFIG_SECURITY is not set. Build Robot
- Strip issue and Gerrit-Id: Leon Romanovsky

v6:
- Whitespace and bracket cleanup. James Morris
- Cleanup error flow in sel_pkey_sid_slow. James Morris

Daniel Jurgens (9):
  IB/core: IB cache enhancements to support Infiniband security
  IB/core: Enforce PKey security on QPs
  selinux lsm IB/core: Implement LSM notification system
  IB/core: Enforce security on management datagrams
  selinux: Create policydb version for Infiniband support
  selinux: Allocate and free infiniband security hooks
  selinux: Implement Infiniband PKey "Access" access vector
  selinux: Add IB Port SMP access vector
  selinux: Add a cache for quicker retreival of PKey SIDs

 drivers/infiniband/core/Makefile     |   3 +-
 drivers/infiniband/core/cache.c      |  57 ++-
 drivers/infiniband/core/core_priv.h  | 115 ++++++
 drivers/infiniband/core/device.c     |  86 +++++
 drivers/infiniband/core/mad.c        |  52 ++-
 drivers/infiniband/core/security.c   | 709 +++++++++++++++++++++++++++++++++++
 drivers/infiniband/core/uverbs_cmd.c |  20 +-
 drivers/infiniband/core/verbs.c      |  27 +-
 include/linux/lsm_audit.h            |  15 +
 include/linux/lsm_hooks.h            |  35 ++
 include/linux/security.h             |  50 +++
 include/rdma/ib_mad.h                |   4 +
 include/rdma/ib_verbs.h              |  49 +++
 security/Kconfig                     |   9 +
 security/lsm_audit.c                 |  16 +
 security/security.c                  |  59 +++
 security/selinux/Makefile            |   2 +-
 security/selinux/hooks.c             |  86 ++++-
 security/selinux/ibpkey.c            | 245 ++++++++++++
 security/selinux/include/classmap.h  |   4 +
 security/selinux/include/ibpkey.h    |  31 ++
 security/selinux/include/objsec.h    |  11 +
 security/selinux/include/security.h  |   7 +-
 security/selinux/selinuxfs.c         |   2 +
 security/selinux/ss/policydb.c       | 129 ++++++-
 security/selinux/ss/policydb.h       |  27 +-
 security/selinux/ss/services.c       |  81 ++++
 27 files changed, 1886 insertions(+), 45 deletions(-)
 create mode 100644 drivers/infiniband/core/security.c
 create mode 100644 security/selinux/ibpkey.c
 create mode 100644 security/selinux/include/ibpkey.h

-- 
2.7.4

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 51+ messages in thread

* [PATCH v6 0/9] SELinux support for Infiniband RDMA
@ 2016-11-23 14:17 ` Dan Jurgens
  0 siblings, 0 replies; 51+ messages in thread
From: Dan Jurgens @ 2016-11-23 14:17 UTC (permalink / raw)
  To: chrisw, paul, sds, eparis, dledford, sean.hefty, hal.rosenstock
  Cc: selinux, linux-security-module, linux-rdma, yevgenyp, Daniel Jurgens

From: Daniel Jurgens <danielj@mellanox.com>

Infiniband applications access HW from user-space -- traffic is generated
directly by HW, bypassing the kernel. Consequently, Infiniband Partitions,
which are associated directly with HW transport endpoints, are a natural
choice for enforcing granular mandatory access control for Infiniband. QPs may
only send or receives packets tagged with the corresponding partition key
(PKey). The PKey is not a cryptographic key; it's a 16 bit number identifying
the partition.

Every Infiniband fabric is controlled by a central Subnet Manager (SM). The SM
provisions the partitions by assigning each port with the partitions it can
access. In addition, the SM tags each port with a subnet prefix, which
identifies the subnet. Determining which users are allowed to access which
partition keys on a given subnet forms an effective policy for isolating users
on the fabric. Any application that attempts to send traffic on a given subnet
is automatically subject to the policy, regardless of which device and port it
uses. SM software configures the subnet through a privileged Subnet Management
Interface (SMI), which is presented by each Infiniband port. Thus, the SMI must
also be controlled to prevent unauthorized changes to fabric configuration and
partitioning. 

To support access control for IB partitions and subnet management, security
contexts must be provided for two new types of objects - PKeys and IB ports.

A PKey label consists of a subnet prefix and a range of PKey values and is
similar to the labeling mechanism for netports. Each Infiniband port can reside
on a different subnet. So labeling the PKey values for specific subnet prefixes
provides the user maximum flexibility, as PKey values may be determined
independently for different subnets. There is a single access vector for PKeys
called "access".

An Infiniband port is labeled by device name and port number. There is a single
access vector for IB ports called "manage_subnet".

Because RDMA allows kernel bypass, enforcement must be done during connection
setup. Communication over RDMA requires a send and receive queue, collectively
known as a Queue Pair (QP). A QP must be initialized by privileged system calls
before it can be used to send or receive data. During initialization the user
must provide the PKey and port the QP will use; at this time access control can
be enforced.

Because there is a possibility that the enforcement settings or security
policy can change, a means of notifying the ib_core module of such changes
is required. To facilitate this a generic notification callback mechanism
is added to the LSM. One callback is registered for checking the QP PKey
associations when the policy changes. Mad agents also register a callback,
they cache the permission to send and receive SMPs to avoid another per
packet call to the LSM.

Because frequent accesses to the same PKey's SID is expected a cache is
implemented which is very similar to the netport cache.

In order to properly enforce security when changes to the PKey table or
security policy or enforcement occur ib_core must track which QPs are
using which port, pkey index, and alternate path for every IB device.
This makes operations that used to be atomic transactional.

When modifying a QP, ib_core must associate it with the PKey index, port,
and alternate path specified. If the QP was already associated with
different settings, the QP is added to the new list prior to the
modification. If the modify succeeds then the old listing is removed. If
the modify fails the new listing is removed and the old listing remains
unchanged.

When destroying a QP the ib_qp structure is freed by the decive specific
driver (i.e. mlx4_ib) if the 'destroy' is successful. This requires storing
security related information in a separate structure. When a 'destroy'
request is in process the ib_qp structure is in an undefined state so if
there are changes to the security policy or PKey table, the security checks
cannot reset the QP if it doesn't have permission for the new setting. If
the 'destroy' fails, security for that QP must be enforced again and its
status in the list is restored. If the 'destroy' succeeds the security info
can be cleaned up and freed.

There are a number of locks required to protect the QP security structure
and the QP to device/port/pkey index lists. If multiple locks are required,
the safe locking order is: QP security structure mutex first, followed by
any list locks needed, which are sorted first by port followed by pkey
index.

---
v2:
- Use void* blobs in the LSM hooks. Paul Moore
- Make the policy change callback generic. Yuval Shaia, Paul Moore
- Squash LSM changes into the patches where the calls are added. Paul Moore
- Don't add new initial SIDs. Stephen Smalley
- Squash MAD agent PKey and SMI patches and move logic to IB security. Dan Jurgens
- Changed ib_end_port to ib_port. Paul Moore
- Changed ib_port access vector from smp to manage_subnet. Paul Moore
- Added pkey and ib_port details to the audit log. Paul Moore
- See individual patches for more detail.

v3:
- ib_port -> ib_endport. Paul Moore
- use notifier chains for LSM notifications. Paul Moore
- reorder parameters in hooks to put security blob first. Paul Moore
- Don't treat device name as untrusted string in audit log. Paul Moore

v4:
- Added separate AVC callback for LSM notifier. Paul Moore
- Removed unneeded braces in ocontext_read. Paul Moore

v5:
- Fix link error when CONFIG_SECURITY is not set. Build Robot
- Strip issue and Gerrit-Id: Leon Romanovsky

v6:
- Whitespace and bracket cleanup. James Morris
- Cleanup error flow in sel_pkey_sid_slow. James Morris

Daniel Jurgens (9):
  IB/core: IB cache enhancements to support Infiniband security
  IB/core: Enforce PKey security on QPs
  selinux lsm IB/core: Implement LSM notification system
  IB/core: Enforce security on management datagrams
  selinux: Create policydb version for Infiniband support
  selinux: Allocate and free infiniband security hooks
  selinux: Implement Infiniband PKey "Access" access vector
  selinux: Add IB Port SMP access vector
  selinux: Add a cache for quicker retreival of PKey SIDs

 drivers/infiniband/core/Makefile     |   3 +-
 drivers/infiniband/core/cache.c      |  57 ++-
 drivers/infiniband/core/core_priv.h  | 115 ++++++
 drivers/infiniband/core/device.c     |  86 +++++
 drivers/infiniband/core/mad.c        |  52 ++-
 drivers/infiniband/core/security.c   | 709 +++++++++++++++++++++++++++++++++++
 drivers/infiniband/core/uverbs_cmd.c |  20 +-
 drivers/infiniband/core/verbs.c      |  27 +-
 include/linux/lsm_audit.h            |  15 +
 include/linux/lsm_hooks.h            |  35 ++
 include/linux/security.h             |  50 +++
 include/rdma/ib_mad.h                |   4 +
 include/rdma/ib_verbs.h              |  49 +++
 security/Kconfig                     |   9 +
 security/lsm_audit.c                 |  16 +
 security/security.c                  |  59 +++
 security/selinux/Makefile            |   2 +-
 security/selinux/hooks.c             |  86 ++++-
 security/selinux/ibpkey.c            | 245 ++++++++++++
 security/selinux/include/classmap.h  |   4 +
 security/selinux/include/ibpkey.h    |  31 ++
 security/selinux/include/objsec.h    |  11 +
 security/selinux/include/security.h  |   7 +-
 security/selinux/selinuxfs.c         |   2 +
 security/selinux/ss/policydb.c       | 129 ++++++-
 security/selinux/ss/policydb.h       |  27 +-
 security/selinux/ss/services.c       |  81 ++++
 27 files changed, 1886 insertions(+), 45 deletions(-)
 create mode 100644 drivers/infiniband/core/security.c
 create mode 100644 security/selinux/ibpkey.c
 create mode 100644 security/selinux/include/ibpkey.h

-- 
2.7.4

^ permalink raw reply	[flat|nested] 51+ messages in thread

* [PATCH v6 1/9] IB/core: IB cache enhancements to support Infiniband security
  2016-11-23 14:17 ` Dan Jurgens
@ 2016-11-23 14:17     ` Dan Jurgens
  -1 siblings, 0 replies; 51+ messages in thread
From: Dan Jurgens @ 2016-11-23 14:17 UTC (permalink / raw)
  To: chrisw-69jw2NvuJkxg9hUCZPvPmw, paul-r2n+y4ga6xFZroRs9YW3xA,
	sds-+05T5uksL2qpZYMLLGbcSA, eparis-FjpueFixGhCM4zKIHC2jIg,
	dledford-H+wXaHxf7aLQT0dZR+AlfA,
	sean.hefty-ral2JQCrhuEAvxtiuMwx3w,
	hal.rosenstock-Re5JQEeQqe8AvxtiuMwx3w
  Cc: selinux-+05T5uksL2qpZYMLLGbcSA,
	linux-security-module-u79uwXL29TY76Z2rM5mHXA,
	linux-rdma-u79uwXL29TY76Z2rM5mHXA,
	yevgenyp-VPRAkNaXOzVWk0Htik3J/w, Daniel Jurgens

From: Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>

Cache the subnet prefix and add a function to access it. Enforcing
security requires frequent queries of the subnet prefix and the pkeys in
the pkey table.

Also removed an unneded pr_warn about memory allocation failure.

Signed-off-by: Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
Reviewed-by: Eli Cohen <eli-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
Reviewed-by: Leon Romanovsky <leonro-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>

---
v2:
- In ib_get_cached_subnet_prefix wait to initialize p until after
  validation.  Yuval Shaia
---
 drivers/infiniband/core/cache.c     | 36 ++++++++++++++++++++++++++++++++++--
 drivers/infiniband/core/core_priv.h |  3 +++
 include/rdma/ib_verbs.h             |  1 +
 3 files changed, 38 insertions(+), 2 deletions(-)

diff --git a/drivers/infiniband/core/cache.c b/drivers/infiniband/core/cache.c
index 1a2984c..affc8ef 100644
--- a/drivers/infiniband/core/cache.c
+++ b/drivers/infiniband/core/cache.c
@@ -934,6 +934,26 @@ int ib_get_cached_pkey(struct ib_device *device,
 }
 EXPORT_SYMBOL(ib_get_cached_pkey);
 
+int ib_get_cached_subnet_prefix(struct ib_device *device,
+				u8                port_num,
+				u64              *sn_pfx)
+{
+	unsigned long flags;
+	int p;
+
+	if (port_num < rdma_start_port(device) ||
+	    port_num > rdma_end_port(device))
+		return -EINVAL;
+
+	p = port_num - rdma_start_port(device);
+	read_lock_irqsave(&device->cache.lock, flags);
+	*sn_pfx = device->cache.subnet_prefix_cache[p];
+	read_unlock_irqrestore(&device->cache.lock, flags);
+
+	return 0;
+}
+EXPORT_SYMBOL(ib_get_cached_subnet_prefix);
+
 int ib_find_cached_pkey(struct ib_device *device,
 			u8                port_num,
 			u16               pkey,
@@ -1110,6 +1130,8 @@ static void ib_cache_update(struct ib_device *device,
 
 	device->cache.lmc_cache[port - rdma_start_port(device)] = tprops->lmc;
 
+	device->cache.subnet_prefix_cache[port - rdma_start_port(device)] =
+							tprops->subnet_prefix;
 	write_unlock_irq(&device->cache.lock);
 
 	kfree(gid_cache);
@@ -1168,9 +1190,18 @@ int ib_cache_setup_one(struct ib_device *device)
 					  (rdma_end_port(device) -
 					   rdma_start_port(device) + 1),
 					  GFP_KERNEL);
+
+	device->cache.subnet_prefix_cache =
+		kcalloc((rdma_end_port(device) - rdma_start_port(device) + 1),
+			sizeof(*device->cache.subnet_prefix_cache),
+			GFP_KERNEL);
+
 	if (!device->cache.pkey_cache ||
-	    !device->cache.lmc_cache) {
-		pr_warn("Couldn't allocate cache for %s\n", device->name);
+	    !device->cache.lmc_cache ||
+	    !device->cache.subnet_prefix_cache) {
+		kfree(device->cache.pkey_cache);
+		kfree(device->cache.lmc_cache);
+		kfree(device->cache.subnet_prefix_cache);
 		return -ENOMEM;
 	}
 
@@ -1213,6 +1244,7 @@ void ib_cache_release_one(struct ib_device *device)
 	gid_table_release_one(device);
 	kfree(device->cache.pkey_cache);
 	kfree(device->cache.lmc_cache);
+	kfree(device->cache.subnet_prefix_cache);
 }
 
 void ib_cache_cleanup_one(struct ib_device *device)
diff --git a/drivers/infiniband/core/core_priv.h b/drivers/infiniband/core/core_priv.h
index 19d499d..ce826e4 100644
--- a/drivers/infiniband/core/core_priv.h
+++ b/drivers/infiniband/core/core_priv.h
@@ -153,4 +153,7 @@ int ib_nl_handle_set_timeout(struct sk_buff *skb,
 int ib_nl_handle_ip_res_resp(struct sk_buff *skb,
 			     struct netlink_callback *cb);
 
+int ib_get_cached_subnet_prefix(struct ib_device *device,
+				u8                port_num,
+				u64              *sn_pfx);
 #endif /* _CORE_PRIV_H */
diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
index 5ad43a4..db178fd 100644
--- a/include/rdma/ib_verbs.h
+++ b/include/rdma/ib_verbs.h
@@ -1761,6 +1761,7 @@ struct ib_cache {
 	struct ib_pkey_cache  **pkey_cache;
 	struct ib_gid_table   **gid_cache;
 	u8                     *lmc_cache;
+	u64                    *subnet_prefix_cache;
 };
 
 struct ib_dma_mapping_ops {
-- 
2.7.4

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH v6 1/9] IB/core: IB cache enhancements to support Infiniband security
@ 2016-11-23 14:17     ` Dan Jurgens
  0 siblings, 0 replies; 51+ messages in thread
From: Dan Jurgens @ 2016-11-23 14:17 UTC (permalink / raw)
  To: chrisw, paul, sds, eparis, dledford, sean.hefty, hal.rosenstock
  Cc: selinux, linux-security-module, linux-rdma, yevgenyp, Daniel Jurgens

From: Daniel Jurgens <danielj@mellanox.com>

Cache the subnet prefix and add a function to access it. Enforcing
security requires frequent queries of the subnet prefix and the pkeys in
the pkey table.

Also removed an unneded pr_warn about memory allocation failure.

Signed-off-by: Daniel Jurgens <danielj@mellanox.com>
Reviewed-by: Eli Cohen <eli@mellanox.com>
Reviewed-by: Leon Romanovsky <leonro@mellanox.com>

---
v2:
- In ib_get_cached_subnet_prefix wait to initialize p until after
  validation.  Yuval Shaia
---
 drivers/infiniband/core/cache.c     | 36 ++++++++++++++++++++++++++++++++++--
 drivers/infiniband/core/core_priv.h |  3 +++
 include/rdma/ib_verbs.h             |  1 +
 3 files changed, 38 insertions(+), 2 deletions(-)

diff --git a/drivers/infiniband/core/cache.c b/drivers/infiniband/core/cache.c
index 1a2984c..affc8ef 100644
--- a/drivers/infiniband/core/cache.c
+++ b/drivers/infiniband/core/cache.c
@@ -934,6 +934,26 @@ int ib_get_cached_pkey(struct ib_device *device,
 }
 EXPORT_SYMBOL(ib_get_cached_pkey);
 
+int ib_get_cached_subnet_prefix(struct ib_device *device,
+				u8                port_num,
+				u64              *sn_pfx)
+{
+	unsigned long flags;
+	int p;
+
+	if (port_num < rdma_start_port(device) ||
+	    port_num > rdma_end_port(device))
+		return -EINVAL;
+
+	p = port_num - rdma_start_port(device);
+	read_lock_irqsave(&device->cache.lock, flags);
+	*sn_pfx = device->cache.subnet_prefix_cache[p];
+	read_unlock_irqrestore(&device->cache.lock, flags);
+
+	return 0;
+}
+EXPORT_SYMBOL(ib_get_cached_subnet_prefix);
+
 int ib_find_cached_pkey(struct ib_device *device,
 			u8                port_num,
 			u16               pkey,
@@ -1110,6 +1130,8 @@ static void ib_cache_update(struct ib_device *device,
 
 	device->cache.lmc_cache[port - rdma_start_port(device)] = tprops->lmc;
 
+	device->cache.subnet_prefix_cache[port - rdma_start_port(device)] =
+							tprops->subnet_prefix;
 	write_unlock_irq(&device->cache.lock);
 
 	kfree(gid_cache);
@@ -1168,9 +1190,18 @@ int ib_cache_setup_one(struct ib_device *device)
 					  (rdma_end_port(device) -
 					   rdma_start_port(device) + 1),
 					  GFP_KERNEL);
+
+	device->cache.subnet_prefix_cache =
+		kcalloc((rdma_end_port(device) - rdma_start_port(device) + 1),
+			sizeof(*device->cache.subnet_prefix_cache),
+			GFP_KERNEL);
+
 	if (!device->cache.pkey_cache ||
-	    !device->cache.lmc_cache) {
-		pr_warn("Couldn't allocate cache for %s\n", device->name);
+	    !device->cache.lmc_cache ||
+	    !device->cache.subnet_prefix_cache) {
+		kfree(device->cache.pkey_cache);
+		kfree(device->cache.lmc_cache);
+		kfree(device->cache.subnet_prefix_cache);
 		return -ENOMEM;
 	}
 
@@ -1213,6 +1244,7 @@ void ib_cache_release_one(struct ib_device *device)
 	gid_table_release_one(device);
 	kfree(device->cache.pkey_cache);
 	kfree(device->cache.lmc_cache);
+	kfree(device->cache.subnet_prefix_cache);
 }
 
 void ib_cache_cleanup_one(struct ib_device *device)
diff --git a/drivers/infiniband/core/core_priv.h b/drivers/infiniband/core/core_priv.h
index 19d499d..ce826e4 100644
--- a/drivers/infiniband/core/core_priv.h
+++ b/drivers/infiniband/core/core_priv.h
@@ -153,4 +153,7 @@ int ib_nl_handle_set_timeout(struct sk_buff *skb,
 int ib_nl_handle_ip_res_resp(struct sk_buff *skb,
 			     struct netlink_callback *cb);
 
+int ib_get_cached_subnet_prefix(struct ib_device *device,
+				u8                port_num,
+				u64              *sn_pfx);
 #endif /* _CORE_PRIV_H */
diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
index 5ad43a4..db178fd 100644
--- a/include/rdma/ib_verbs.h
+++ b/include/rdma/ib_verbs.h
@@ -1761,6 +1761,7 @@ struct ib_cache {
 	struct ib_pkey_cache  **pkey_cache;
 	struct ib_gid_table   **gid_cache;
 	u8                     *lmc_cache;
+	u64                    *subnet_prefix_cache;
 };
 
 struct ib_dma_mapping_ops {
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH v6 2/9] IB/core: Enforce PKey security on QPs
  2016-11-23 14:17 ` Dan Jurgens
  (?)
@ 2016-11-23 14:17 ` Dan Jurgens
  -1 siblings, 0 replies; 51+ messages in thread
From: Dan Jurgens @ 2016-11-23 14:17 UTC (permalink / raw)
  To: chrisw, paul, sds, eparis, dledford, sean.hefty, hal.rosenstock
  Cc: selinux, linux-security-module, linux-rdma, yevgenyp, Daniel Jurgens

From: Daniel Jurgens <danielj@mellanox.com>

Add new LSM hooks to allocate and free security contexts and check for
permission to access a PKey.

Allocate and free a security context when creating and destroying a QP.
This context is used for controlling access to PKeys.

When a request is made to modify a QP that changes the port, PKey index,
or alternate path, check that the QP has permission for the PKey in the
PKey table index on the subnet prefix of the port. If the QP is shared
make sure all handles to the QP also have access.

Store which port and PKey index a QP is using. After the reset to init
transition the user can modify the port, PKey index and alternate path
independently. So port and PKey settings changes can be a merge of the
previous settings and the new ones.

In order to maintain access control if there are PKey table or subnet
prefix change keep a list of all QPs are using each PKey index on
each port. If a change occurs all QPs using that device and port must
have access enforced for the new cache settings.

These changes add a transaction to the QP modify process. Association
with the old port and PKey index must be maintained if the modify fails,
and must be removed if it succeeds. Association with the new port and
PKey index must be established prior to the modify and removed if the
modify fails.

1. When a QP is modified to a particular Port, PKey index or alternate
   path insert that QP into the appropriate lists.

2. Check permission to access the new settings.

3. If step 2 grants access attempt to modify the QP.

4a. If steps 2 and 3 succeed remove any prior associations.

4b. If ether fails remove the new setting associations.

If a PKey table or subnet prefix changes walk the list of QPs and
check that they have permission. If not send the QP to the error state
and raise a fatal error event. If it's a shared QP make sure all the
QPs that share the real_qp have permission as well. If the QP that
owns a security structure is denied access the security structure is
marked as such and the QP is added to an error_list. Once the moving
the QP to error is complete the security structure mark is cleared.

Maintaining the lists correctly turns QP destroy into a transaction.
The hardware driver for the device frees the ib_qp structure, so while
the destroy is in progress the ib_qp pointer in the ib_qp_security
struct is undefined. When the destroy process begins the ib_qp_security
structure is marked as destroying. This prevents any action from being
taken on the QP pointer. After the QP is destroyed successfully it
could still listed on an error_list wait for it to be processed by that
flow before cleaning up the structure.

If the destroy fails the QPs port and PKey settings are reinserted into
the appropriate lists, the destroying flag is cleared, and access control
is enforced, in case there were any cache changes during the destroy
flow.

To keep the security changes isolated a new file is used to hold security
related functionality.

Signed-off-by: Daniel Jurgens <danielj@mellanox.com>

---
v2:
- Squashed LSM hook additions. Paul Moore
- Changed security blobs to void*. Paul Moore

v3:
- Change parameter order of pkey_access hook. Paul Moore
---
 drivers/infiniband/core/Makefile     |   3 +-
 drivers/infiniband/core/cache.c      |  21 +-
 drivers/infiniband/core/core_priv.h  |  77 +++++
 drivers/infiniband/core/device.c     |  33 ++
 drivers/infiniband/core/security.c   | 617 +++++++++++++++++++++++++++++++++++
 drivers/infiniband/core/uverbs_cmd.c |  20 +-
 drivers/infiniband/core/verbs.c      |  27 +-
 include/linux/lsm_hooks.h            |  27 ++
 include/linux/security.h             |  21 ++
 include/rdma/ib_verbs.h              |  48 +++
 security/Kconfig                     |   9 +
 security/security.c                  |  31 ++
 12 files changed, 925 insertions(+), 9 deletions(-)
 create mode 100644 drivers/infiniband/core/security.c

diff --git a/drivers/infiniband/core/Makefile b/drivers/infiniband/core/Makefile
index edaae9f..da4e2c1 100644
--- a/drivers/infiniband/core/Makefile
+++ b/drivers/infiniband/core/Makefile
@@ -10,7 +10,8 @@ obj-$(CONFIG_INFINIBAND_USER_ACCESS) +=	ib_uverbs.o ib_ucm.o \
 ib_core-y :=			packer.o ud_header.o verbs.o cq.o rw.o sysfs.o \
 				device.o fmr_pool.o cache.o netlink.o \
 				roce_gid_mgmt.o mr_pool.o addr.o sa_query.o \
-				multicast.o mad.o smi.o agent.o mad_rmpp.o
+				multicast.o mad.o smi.o agent.o mad_rmpp.o \
+				security.o
 ib_core-$(CONFIG_INFINIBAND_USER_MEM) += umem.o
 ib_core-$(CONFIG_INFINIBAND_ON_DEMAND_PAGING) += umem_odp.o umem_rbtree.o
 
diff --git a/drivers/infiniband/core/cache.c b/drivers/infiniband/core/cache.c
index affc8ef..48eaeca 100644
--- a/drivers/infiniband/core/cache.c
+++ b/drivers/infiniband/core/cache.c
@@ -53,6 +53,7 @@ struct ib_update_work {
 	struct work_struct work;
 	struct ib_device  *device;
 	u8                 port_num;
+	bool		   enforce_security;
 };
 
 union ib_gid zgid;
@@ -1046,7 +1047,8 @@ int ib_get_cached_lmc(struct ib_device *device,
 EXPORT_SYMBOL(ib_get_cached_lmc);
 
 static void ib_cache_update(struct ib_device *device,
-			    u8                port)
+			    u8                port,
+			    bool	      enforce_security)
 {
 	struct ib_port_attr       *tprops = NULL;
 	struct ib_pkey_cache      *pkey_cache = NULL, *old_pkey_cache;
@@ -1134,6 +1136,11 @@ static void ib_cache_update(struct ib_device *device,
 							tprops->subnet_prefix;
 	write_unlock_irq(&device->cache.lock);
 
+	if (enforce_security)
+		ib_security_cache_change(device,
+					 port,
+					 tprops->subnet_prefix);
+
 	kfree(gid_cache);
 	kfree(old_pkey_cache);
 	kfree(tprops);
@@ -1150,7 +1157,9 @@ static void ib_cache_task(struct work_struct *_work)
 	struct ib_update_work *work =
 		container_of(_work, struct ib_update_work, work);
 
-	ib_cache_update(work->device, work->port_num);
+	ib_cache_update(work->device,
+			work->port_num,
+			work->enforce_security);
 	kfree(work);
 }
 
@@ -1171,6 +1180,12 @@ static void ib_cache_event(struct ib_event_handler *handler,
 			INIT_WORK(&work->work, ib_cache_task);
 			work->device   = event->device;
 			work->port_num = event->element.port_num;
+			if (event->event == IB_EVENT_PKEY_CHANGE ||
+			    event->event == IB_EVENT_GID_CHANGE)
+				work->enforce_security = true;
+			else
+				work->enforce_security = false;
+
 			queue_work(ib_wq, &work->work);
 		}
 	}
@@ -1211,7 +1226,7 @@ int ib_cache_setup_one(struct ib_device *device)
 		return err;
 
 	for (p = 0; p <= rdma_end_port(device) - rdma_start_port(device); ++p)
-		ib_cache_update(device, p + rdma_start_port(device));
+		ib_cache_update(device, p + rdma_start_port(device), true);
 
 	INIT_IB_EVENT_HANDLER(&device->cache.event_handler,
 			      device, ib_cache_event);
diff --git a/drivers/infiniband/core/core_priv.h b/drivers/infiniband/core/core_priv.h
index ce826e4..68e3de0 100644
--- a/drivers/infiniband/core/core_priv.h
+++ b/drivers/infiniband/core/core_priv.h
@@ -38,6 +38,14 @@
 
 #include <rdma/ib_verbs.h>
 
+struct pkey_index_qp_list {
+	struct list_head    pkey_index_list;
+	u16                 pkey_index;
+	/* Lock to hold while iterating the qp_list. */
+	spinlock_t          qp_list_lock;
+	struct list_head    qp_list;
+};
+
 #if IS_ENABLED(CONFIG_INFINIBAND_ADDR_TRANS_CONFIGFS)
 int cma_configfs_init(void);
 void cma_configfs_exit(void);
@@ -156,4 +164,73 @@ int ib_nl_handle_ip_res_resp(struct sk_buff *skb,
 int ib_get_cached_subnet_prefix(struct ib_device *device,
 				u8                port_num,
 				u64              *sn_pfx);
+
+#ifdef CONFIG_SECURITY_INFINIBAND
+void ib_security_destroy_port_pkey_list(struct ib_device *device);
+
+void ib_security_cache_change(struct ib_device *device,
+			      u8 port_num,
+			      u64 subnet_prefix);
+
+int ib_security_modify_qp(struct ib_qp *qp,
+			  struct ib_qp_attr *qp_attr,
+			  int qp_attr_mask,
+			  struct ib_udata *udata);
+
+int ib_create_qp_security(struct ib_qp *qp, struct ib_device *dev);
+void ib_destroy_qp_security_begin(struct ib_qp_security *sec);
+void ib_destroy_qp_security_abort(struct ib_qp_security *sec);
+void ib_destroy_qp_security_end(struct ib_qp_security *sec);
+int ib_open_shared_qp_security(struct ib_qp *qp, struct ib_device *dev);
+void ib_close_shared_qp_security(struct ib_qp_security *sec);
+#else
+static inline void ib_security_destroy_port_pkey_list(struct ib_device *device)
+{
+}
+
+static inline void ib_security_cache_change(struct ib_device *device,
+					    u8 port_num,
+					    u64 subnet_prefix)
+{
+}
+
+static inline int ib_security_modify_qp(struct ib_qp *qp,
+					struct ib_qp_attr *qp_attr,
+					int qp_attr_mask,
+					struct ib_udata *udata)
+{
+	return qp->device->modify_qp(qp->real_qp,
+				     qp_attr,
+				     qp_attr_mask,
+				     udata);
+}
+
+static inline int ib_create_qp_security(struct ib_qp *qp,
+					struct ib_device *dev)
+{
+	return 0;
+}
+
+static inline void ib_destroy_qp_security_begin(struct ib_qp_security *sec)
+{
+}
+
+static inline void ib_destroy_qp_security_abort(struct ib_qp_security *sec)
+{
+}
+
+static inline void ib_destroy_qp_security_end(struct ib_qp_security *sec)
+{
+}
+
+static inline int ib_open_shared_qp_security(struct ib_qp *qp,
+					     struct ib_device *dev)
+{
+	return 0;
+}
+
+static inline void ib_close_shared_qp_security(struct ib_qp_security *sec)
+{
+}
+#endif
 #endif /* _CORE_PRIV_H */
diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c
index 760ef60..5b42e83 100644
--- a/drivers/infiniband/core/device.c
+++ b/drivers/infiniband/core/device.c
@@ -320,6 +320,30 @@ void ib_get_device_fw_str(struct ib_device *dev, char *str, size_t str_len)
 }
 EXPORT_SYMBOL(ib_get_device_fw_str);
 
+static int setup_port_pkey_list(struct ib_device *device)
+{
+	int i;
+
+	/**
+	 * device->port_pkey_list is indexed directly by the port number,
+	 * Therefore it is declared as a 1 based array with potential empty
+	 * slots at the beginning.
+	 */
+	device->port_pkey_list = kzalloc(sizeof(*device->port_pkey_list)
+					 * (rdma_end_port(device) + 1),
+					 GFP_KERNEL);
+
+	if (!device->port_pkey_list)
+		return -ENOMEM;
+
+	for (i = 0; i < (rdma_end_port(device) + 1); i++) {
+		spin_lock_init(&device->port_pkey_list[i].list_lock);
+		INIT_LIST_HEAD(&device->port_pkey_list[i].pkey_list);
+	}
+
+	return 0;
+}
+
 /**
  * ib_register_device - Register an IB device with IB core
  * @device:Device to register
@@ -357,6 +381,12 @@ int ib_register_device(struct ib_device *device,
 		goto out;
 	}
 
+	ret = setup_port_pkey_list(device);
+	if (ret) {
+		dev_warn(device->dma_device, "Couldn't create per port_pkey_list\n");
+		goto out;
+	}
+
 	ret = ib_cache_setup_one(device);
 	if (ret) {
 		pr_warn("Couldn't set up InfiniBand P_Key/GID cache\n");
@@ -427,6 +457,9 @@ void ib_unregister_device(struct ib_device *device)
 	ib_device_unregister_sysfs(device);
 	ib_cache_cleanup_one(device);
 
+	ib_security_destroy_port_pkey_list(device);
+	kfree(device->port_pkey_list);
+
 	down_write(&lists_rwsem);
 	spin_lock_irqsave(&device->client_data_lock, flags);
 	list_for_each_entry_safe(context, tmp, &device->client_data_list, list)
diff --git a/drivers/infiniband/core/security.c b/drivers/infiniband/core/security.c
new file mode 100644
index 0000000..45800dd
--- /dev/null
+++ b/drivers/infiniband/core/security.c
@@ -0,0 +1,617 @@
+/*
+ * Copyright (c) 2016 Mellanox Technologies Ltd.  All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifdef CONFIG_SECURITY_INFINIBAND
+
+#include <linux/security.h>
+#include <linux/completion.h>
+#include <linux/list.h>
+
+#include <rdma/ib_verbs.h>
+#include <rdma/ib_cache.h>
+#include "core_priv.h"
+
+static struct pkey_index_qp_list *get_pkey_idx_qp_list(struct ib_port_pkey *pp)
+{
+	struct pkey_index_qp_list *pkey = NULL;
+	struct pkey_index_qp_list *tmp_pkey;
+	struct ib_device *dev = pp->sec->dev;
+
+	spin_lock(&dev->port_pkey_list[pp->port_num].list_lock);
+	list_for_each_entry(tmp_pkey,
+			    &dev->port_pkey_list[pp->port_num].pkey_list,
+			    pkey_index_list) {
+		if (tmp_pkey->pkey_index == pp->pkey_index) {
+			pkey = tmp_pkey;
+			break;
+		}
+	}
+	spin_unlock(&dev->port_pkey_list[pp->port_num].list_lock);
+	return pkey;
+}
+
+static int get_pkey_and_subnet_prefix(struct ib_port_pkey *pp,
+				      u16 *pkey,
+				      u64 *subnet_prefix)
+{
+	struct ib_device *dev = pp->sec->dev;
+	int ret;
+
+	ret = ib_get_cached_pkey(dev, pp->port_num, pp->pkey_index, pkey);
+	if (ret)
+		return ret;
+
+	ret = ib_get_cached_subnet_prefix(dev, pp->port_num, subnet_prefix);
+
+	return ret;
+}
+
+static int enforce_qp_pkey_security(u16 pkey,
+				    u64 subnet_prefix,
+				    struct ib_qp_security *qp_sec)
+{
+	struct ib_qp_security *shared_qp_sec;
+	int ret;
+
+	ret = security_ib_pkey_access(qp_sec->security, subnet_prefix, pkey);
+	if (ret)
+		return ret;
+
+	if (qp_sec->qp == qp_sec->qp->real_qp) {
+		list_for_each_entry(shared_qp_sec,
+				    &qp_sec->shared_qp_list,
+				    shared_qp_list) {
+			ret = security_ib_pkey_access(shared_qp_sec->security,
+						      subnet_prefix,
+						      pkey);
+			if (ret)
+				return ret;
+		}
+	}
+	return 0;
+}
+
+/* The caller of this function must hold the QP security
+ * mutex of the QP of the security structure in *pps.
+ *
+ * It takes separate ports_pkeys and security structure
+ * because in some cases the pps will be for a new settings
+ * or the pps will be for the real QP and security structure
+ * will be for a shared QP.
+ */
+static int check_qp_port_pkey_settings(struct ib_ports_pkeys *pps,
+				       struct ib_qp_security *sec)
+{
+	u64 subnet_prefix;
+	u16 pkey;
+	int ret = 0;
+
+	if (!pps)
+		return 0;
+
+	if (pps->main.state != IB_PORT_PKEY_NOT_VALID) {
+		get_pkey_and_subnet_prefix(&pps->main,
+					   &pkey,
+					   &subnet_prefix);
+
+		ret = enforce_qp_pkey_security(pkey,
+					       subnet_prefix,
+					       sec);
+	}
+	if (ret)
+		goto out;
+
+	if (pps->alt.state != IB_PORT_PKEY_NOT_VALID) {
+		get_pkey_and_subnet_prefix(&pps->alt,
+					   &pkey,
+					   &subnet_prefix);
+
+		ret = enforce_qp_pkey_security(pkey,
+					       subnet_prefix,
+					       sec);
+	}
+
+	if (ret)
+		goto out;
+
+out:
+	return ret;
+}
+
+/* The caller of this function must hold the QP security
+ * mutex.
+ */
+static void qp_to_error(struct ib_qp_security *sec)
+{
+	struct ib_qp_security *shared_qp_sec;
+	struct ib_qp_attr attr = {
+		.qp_state = IB_QPS_ERR
+	};
+	struct ib_event event = {
+		.event = IB_EVENT_QP_FATAL
+	};
+
+	/* If the QP is in the process of being destroyed
+	 * the qp pointer in the security structure is
+	 * undefined.  It cannot be modified now.
+	 */
+	if (sec->destroying)
+		return;
+
+	ib_modify_qp(sec->qp,
+		     &attr,
+		     IB_QP_STATE);
+
+	if (sec->qp->event_handler && sec->qp->qp_context) {
+		event.element.qp = sec->qp;
+		sec->qp->event_handler(&event,
+				       sec->qp->qp_context);
+	}
+
+	list_for_each_entry(shared_qp_sec,
+			    &sec->shared_qp_list,
+			    shared_qp_list) {
+		struct ib_qp *qp = shared_qp_sec->qp;
+
+		if (qp->event_handler && qp->qp_context) {
+			event.element.qp = qp;
+			event.device = qp->device;
+			qp->event_handler(&event,
+					  qp->qp_context);
+		}
+	}
+}
+
+static inline void check_pkey_qps(struct pkey_index_qp_list *pkey,
+				  struct ib_device *device,
+				  u8 port_num,
+				  u64 subnet_prefix)
+{
+	struct ib_port_pkey *pp, *tmp_pp;
+	bool comp;
+	LIST_HEAD(to_error_list);
+	u16 pkey_val;
+
+	if (!ib_get_cached_pkey(device,
+				port_num,
+				pkey->pkey_index,
+				&pkey_val)) {
+		spin_lock(&pkey->qp_list_lock);
+		list_for_each_entry(pp, &pkey->qp_list, qp_list) {
+			if (atomic_read(&pp->sec->error_list_count))
+				continue;
+
+			if (enforce_qp_pkey_security(pkey_val,
+						     subnet_prefix,
+						     pp->sec)) {
+				atomic_inc(&pp->sec->error_list_count);
+				list_add(&pp->to_error_list,
+					 &to_error_list);
+			}
+		}
+		spin_unlock(&pkey->qp_list_lock);
+	}
+
+	list_for_each_entry_safe(pp,
+				 tmp_pp,
+				 &to_error_list,
+				 to_error_list) {
+		mutex_lock(&pp->sec->mutex);
+		qp_to_error(pp->sec);
+		list_del(&pp->to_error_list);
+		atomic_dec(&pp->sec->error_list_count);
+		comp = pp->sec->destroying;
+		mutex_unlock(&pp->sec->mutex);
+
+		if (comp)
+			complete(&pp->sec->error_complete);
+	}
+}
+
+/* The caller of this function must hold the QP security
+ * mutex.
+ */
+static int port_pkey_list_insert(struct ib_port_pkey *pp)
+{
+	struct pkey_index_qp_list *tmp_pkey;
+	struct pkey_index_qp_list *pkey;
+	struct ib_device *dev;
+	u8 port_num = pp->port_num;
+	int ret = 0;
+
+	if (pp->state != IB_PORT_PKEY_VALID)
+		return 0;
+
+	dev = pp->sec->dev;
+
+	pkey = get_pkey_idx_qp_list(pp);
+
+	if (!pkey) {
+		bool found = false;
+
+		pkey = kzalloc(sizeof(*pkey), GFP_KERNEL);
+		if (!pkey)
+			return -ENOMEM;
+
+		spin_lock(&dev->port_pkey_list[port_num].list_lock);
+		/* Check for the PKey again.  A racing process may
+		 * have created it.
+		 */
+		list_for_each_entry(tmp_pkey,
+				    &dev->port_pkey_list[port_num].pkey_list,
+				    pkey_index_list) {
+			if (tmp_pkey->pkey_index == pp->pkey_index) {
+				kfree(pkey);
+				pkey = tmp_pkey;
+				found = true;
+				break;
+			}
+		}
+
+		if (!found) {
+			pkey->pkey_index = pp->pkey_index;
+			spin_lock_init(&pkey->qp_list_lock);
+			INIT_LIST_HEAD(&pkey->qp_list);
+			list_add(&pkey->pkey_index_list,
+				 &dev->port_pkey_list[port_num].pkey_list);
+		}
+		spin_unlock(&dev->port_pkey_list[port_num].list_lock);
+	}
+
+	spin_lock(&pkey->qp_list_lock);
+	list_add(&pp->qp_list, &pkey->qp_list);
+	spin_unlock(&pkey->qp_list_lock);
+
+	pp->state = IB_PORT_PKEY_LISTED;
+
+	return ret;
+}
+
+/* The caller of this function must hold the QP security
+ * mutex.
+ */
+static void port_pkey_list_remove(struct ib_port_pkey *pp)
+{
+	struct pkey_index_qp_list *pkey;
+
+	if (pp->state != IB_PORT_PKEY_LISTED)
+		return;
+
+	pkey = get_pkey_idx_qp_list(pp);
+
+	spin_lock(&pkey->qp_list_lock);
+	list_del(&pp->qp_list);
+	spin_unlock(&pkey->qp_list_lock);
+
+	/* The setting may still be valid, i.e. after
+	 * a destroy has failed for example.
+	 */
+	pp->state = IB_PORT_PKEY_VALID;
+}
+
+static void destroy_qp_security(struct ib_qp_security *sec)
+{
+	security_ib_free_security(sec->security);
+	kfree(sec->ports_pkeys);
+	kfree(sec);
+}
+
+/* The caller of this function must hold the QP security
+ * mutex.
+ */
+static struct ib_ports_pkeys *get_new_pps(const struct ib_qp *qp,
+					  const struct ib_qp_attr *qp_attr,
+					  int qp_attr_mask)
+{
+	struct ib_ports_pkeys *new_pps;
+	struct ib_ports_pkeys *qp_pps = qp->qp_sec->ports_pkeys;
+
+	new_pps = kzalloc(sizeof(*new_pps), GFP_KERNEL);
+	if (!new_pps)
+		return NULL;
+
+	if (qp_attr_mask & (IB_QP_PKEY_INDEX | IB_QP_PORT)) {
+		if (!qp_pps) {
+			new_pps->main.port_num = qp_attr->port_num;
+			new_pps->main.pkey_index = qp_attr->pkey_index;
+		} else {
+			new_pps->main.port_num = (qp_attr_mask & IB_QP_PORT) ?
+						  qp_attr->port_num :
+						  qp_pps->main.port_num;
+
+			new_pps->main.pkey_index =
+					(qp_attr_mask & IB_QP_PKEY_INDEX) ?
+					 qp_attr->pkey_index :
+					 qp_pps->main.pkey_index;
+		}
+		new_pps->main.state = IB_PORT_PKEY_VALID;
+	} else if (qp_pps) {
+		new_pps->main.port_num = qp_pps->main.port_num;
+		new_pps->main.pkey_index = qp_pps->main.pkey_index;
+		if (qp_pps->main.state != IB_PORT_PKEY_NOT_VALID)
+			new_pps->main.state = IB_PORT_PKEY_VALID;
+	}
+
+	if (qp_attr_mask & IB_QP_ALT_PATH) {
+		new_pps->alt.port_num = qp_attr->alt_port_num;
+		new_pps->alt.pkey_index = qp_attr->alt_pkey_index;
+		new_pps->alt.state = IB_PORT_PKEY_VALID;
+	} else if (qp_pps) {
+		new_pps->alt.port_num = qp_pps->alt.port_num;
+		new_pps->alt.pkey_index = qp_pps->alt.pkey_index;
+		if (qp_pps->alt.state != IB_PORT_PKEY_NOT_VALID)
+			new_pps->alt.state = IB_PORT_PKEY_VALID;
+	}
+
+	new_pps->main.sec = qp->qp_sec;
+	new_pps->alt.sec = qp->qp_sec;
+	return new_pps;
+}
+
+int ib_open_shared_qp_security(struct ib_qp *qp, struct ib_device *dev)
+{
+	struct ib_qp *real_qp = qp->real_qp;
+	int ret;
+
+	ret = ib_create_qp_security(qp, dev);
+
+	if (ret)
+		goto out;
+
+	mutex_lock(&real_qp->qp_sec->mutex);
+	ret = check_qp_port_pkey_settings(real_qp->qp_sec->ports_pkeys,
+					  qp->qp_sec);
+
+	if (ret)
+		goto ret;
+
+	if (qp != real_qp)
+		list_add(&qp->qp_sec->shared_qp_list,
+			 &real_qp->qp_sec->shared_qp_list);
+ret:
+	mutex_unlock(&real_qp->qp_sec->mutex);
+	if (ret)
+		destroy_qp_security(qp->qp_sec);
+
+out:
+	return ret;
+}
+
+void ib_close_shared_qp_security(struct ib_qp_security *sec)
+{
+	struct ib_qp *real_qp = sec->qp->real_qp;
+
+	mutex_lock(&real_qp->qp_sec->mutex);
+	list_del(&sec->shared_qp_list);
+	mutex_unlock(&real_qp->qp_sec->mutex);
+
+	destroy_qp_security(sec);
+}
+
+int ib_create_qp_security(struct ib_qp *qp, struct ib_device *dev)
+{
+	int ret;
+
+	qp->qp_sec = kzalloc(sizeof(*qp->qp_sec), GFP_KERNEL);
+	if (!qp->qp_sec)
+		return -ENOMEM;
+
+	qp->qp_sec->qp = qp;
+	qp->qp_sec->dev = dev;
+	mutex_init(&qp->qp_sec->mutex);
+	INIT_LIST_HEAD(&qp->qp_sec->shared_qp_list);
+	atomic_set(&qp->qp_sec->error_list_count, 0);
+	init_completion(&qp->qp_sec->error_complete);
+	ret = security_ib_alloc_security(&qp->qp_sec->security);
+	if (ret)
+		kfree(qp->qp_sec);
+
+	return ret;
+}
+EXPORT_SYMBOL(ib_create_qp_security);
+
+void ib_destroy_qp_security_begin(struct ib_qp_security *sec)
+{
+	mutex_lock(&sec->mutex);
+
+	/* Remove the QP from the lists so it won't get added to
+	 * a to_error_list during the destroy process.
+	 */
+	if (sec->ports_pkeys) {
+		port_pkey_list_remove(&sec->ports_pkeys->main);
+		port_pkey_list_remove(&sec->ports_pkeys->alt);
+	}
+
+	/* If the QP is already in one or more of those lists
+	 * the destroying flag will ensure the to error flow
+	 * doesn't operate on an undefined QP.
+	 */
+	sec->destroying = true;
+
+	/* Record the error list count to know how many completions
+	 * to wait for.
+	 */
+	sec->error_comps_pending = atomic_read(&sec->error_list_count);
+
+	mutex_unlock(&sec->mutex);
+}
+
+void ib_destroy_qp_security_abort(struct ib_qp_security *sec)
+{
+	int ret;
+	int i;
+
+	/* If a concurrent cache update is in progress this
+	 * QP security could be marked for an error state
+	 * transition.  Wait for this to complete.
+	 */
+	for (i = 0; i < sec->error_comps_pending; i++)
+		wait_for_completion(&sec->error_complete);
+
+	mutex_lock(&sec->mutex);
+	sec->destroying = false;
+
+	/* Restore the position in the lists and verify
+	 * access is still allowed in case a cache update
+	 * occurred while attempting to destroy.
+	 *
+	 * Because these setting were listed already
+	 * and removed during ib_destroy_qp_security_begin
+	 * we know the pkey_index_qp_list for the PKey
+	 * already exists so port_pkey_list_insert won't fail.
+	 */
+	if (sec->ports_pkeys) {
+		port_pkey_list_insert(&sec->ports_pkeys->main);
+		port_pkey_list_insert(&sec->ports_pkeys->alt);
+	}
+
+	ret = check_qp_port_pkey_settings(sec->ports_pkeys, sec);
+	if (ret)
+		qp_to_error(sec);
+
+	mutex_unlock(&sec->mutex);
+}
+
+void ib_destroy_qp_security_end(struct ib_qp_security *sec)
+{
+	int i;
+
+	/* If a concurrent cache update is occurring we must
+	 * wait until this QP security structure is processed
+	 * in the QP to error flow before destroying it because
+	 * the to_error_list is in use.
+	 */
+	for (i = 0; i < sec->error_comps_pending; i++)
+		wait_for_completion(&sec->error_complete);
+
+	destroy_qp_security(sec);
+}
+
+void ib_security_cache_change(struct ib_device *device,
+			      u8 port_num,
+			      u64 subnet_prefix)
+{
+	struct pkey_index_qp_list *pkey;
+
+	list_for_each_entry(pkey,
+			    &device->port_pkey_list[port_num].pkey_list,
+			    pkey_index_list) {
+		check_pkey_qps(pkey,
+			       device,
+			       port_num,
+			       subnet_prefix);
+	}
+}
+
+void ib_security_destroy_port_pkey_list(struct ib_device *device)
+{
+	struct pkey_index_qp_list *pkey, *tmp_pkey;
+	int i;
+
+	for (i = rdma_start_port(device); i <= rdma_end_port(device); i++) {
+		spin_lock(&device->port_pkey_list[i].list_lock);
+		list_for_each_entry_safe(pkey,
+					 tmp_pkey,
+					 &device->port_pkey_list[i].pkey_list,
+					 pkey_index_list) {
+			list_del(&pkey->pkey_index_list);
+			kfree(pkey);
+		}
+		spin_unlock(&device->port_pkey_list[i].list_lock);
+	}
+}
+
+int ib_security_modify_qp(struct ib_qp *qp,
+			  struct ib_qp_attr *qp_attr,
+			  int qp_attr_mask,
+			  struct ib_udata *udata)
+{
+	int ret = 0;
+	struct ib_ports_pkeys *tmp_pps;
+	struct ib_ports_pkeys *new_pps;
+	bool special_qp = (qp->qp_type == IB_QPT_SMI ||
+			   qp->qp_type == IB_QPT_GSI);
+	bool pps_change = ((qp_attr_mask & (IB_QP_PKEY_INDEX | IB_QP_PORT)) ||
+			   (qp_attr_mask & IB_QP_ALT_PATH));
+
+	if (pps_change && !special_qp) {
+		mutex_lock(&qp->qp_sec->mutex);
+		new_pps = get_new_pps(qp,
+				      qp_attr,
+				      qp_attr_mask);
+
+		/* Add this QP to the lists for the new port
+		 * and pkey settings before checking for permission
+		 * in case there is a concurrent cache update
+		 * occurring.  Walking the list for a cache change
+		 * doesn't acquire the security mutex unless it's
+		 * sending the QP to error.
+		 */
+		ret = port_pkey_list_insert(&new_pps->main);
+
+		if (!ret)
+			ret = port_pkey_list_insert(&new_pps->alt);
+
+		if (!ret)
+			ret = check_qp_port_pkey_settings(new_pps,
+							  qp->qp_sec);
+	}
+
+	if (!ret)
+		ret = qp->device->modify_qp(qp->real_qp,
+					    qp_attr,
+					    qp_attr_mask,
+					    udata);
+
+	if (pps_change && !special_qp) {
+		/* Clean up the lists and free the appropriate
+		 * ports_pkeys structure.
+		 */
+		if (ret) {
+			tmp_pps = new_pps;
+		} else {
+			tmp_pps = qp->qp_sec->ports_pkeys;
+			qp->qp_sec->ports_pkeys = new_pps;
+		}
+
+		if (tmp_pps) {
+			port_pkey_list_remove(&tmp_pps->main);
+			port_pkey_list_remove(&tmp_pps->alt);
+		}
+		kfree(tmp_pps);
+		mutex_unlock(&qp->qp_sec->mutex);
+	}
+	return ret;
+}
+EXPORT_SYMBOL(ib_security_modify_qp);
+
+#endif /* CONFIG_SECURITY_INFINIBAND */
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c
index cb3f515a..ceb9154 100644
--- a/drivers/infiniband/core/uverbs_cmd.c
+++ b/drivers/infiniband/core/uverbs_cmd.c
@@ -37,7 +37,7 @@
 #include <linux/fs.h>
 #include <linux/slab.h>
 #include <linux/sched.h>
-
+#include <linux/security.h>
 #include <asm/uaccess.h>
 
 #include "uverbs.h"
@@ -1915,6 +1915,10 @@ static int create_qp(struct ib_uverbs_file *file,
 	}
 
 	if (cmd->qp_type != IB_QPT_XRC_TGT) {
+		ret = ib_create_qp_security(qp, device);
+		if (ret)
+			goto err_destroy;
+
 		qp->real_qp	  = qp;
 		qp->device	  = device;
 		qp->pd		  = pd;
@@ -2405,10 +2409,18 @@ ssize_t ib_uverbs_modify_qp(struct ib_uverbs_file *file,
 		ret = ib_resolve_eth_dmac(qp, attr, &cmd.attr_mask);
 		if (ret)
 			goto release_qp;
-		ret = qp->device->modify_qp(qp, attr,
-			modify_qp_mask(qp->qp_type, cmd.attr_mask), &udata);
+
+		ret = ib_security_modify_qp(qp,
+					    attr,
+					    modify_qp_mask(qp->qp_type,
+							   cmd.attr_mask),
+					    &udata);
 	} else {
-		ret = ib_modify_qp(qp, attr, modify_qp_mask(qp->qp_type, cmd.attr_mask));
+		ret = ib_security_modify_qp(qp,
+					    attr,
+					    modify_qp_mask(qp->qp_type,
+							   cmd.attr_mask),
+					    NULL);
 	}
 
 	if (ret)
diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c
index 8368764..9845e37 100644
--- a/drivers/infiniband/core/verbs.c
+++ b/drivers/infiniband/core/verbs.c
@@ -44,6 +44,7 @@
 #include <linux/in.h>
 #include <linux/in6.h>
 #include <net/addrconf.h>
+#include <linux/security.h>
 
 #include <rdma/ib_verbs.h>
 #include <rdma/ib_cache.h>
@@ -708,12 +709,20 @@ static struct ib_qp *__ib_open_qp(struct ib_qp *real_qp,
 {
 	struct ib_qp *qp;
 	unsigned long flags;
+	int err;
 
 	qp = kzalloc(sizeof *qp, GFP_KERNEL);
 	if (!qp)
 		return ERR_PTR(-ENOMEM);
 
 	qp->real_qp = real_qp;
+	err = ib_open_shared_qp_security(qp, real_qp->device);
+	if (err) {
+		kfree(qp);
+		return ERR_PTR(err);
+	}
+
+	qp->real_qp = real_qp;
 	atomic_inc(&real_qp->usecnt);
 	qp->device = real_qp->device;
 	qp->event_handler = event_handler;
@@ -799,6 +808,12 @@ struct ib_qp *ib_create_qp(struct ib_pd *pd,
 	if (IS_ERR(qp))
 		return qp;
 
+	ret = ib_create_qp_security(qp, device);
+	if (ret) {
+		ib_destroy_qp(qp);
+		return ERR_PTR(ret);
+	}
+
 	qp->device     = device;
 	qp->real_qp    = qp;
 	qp->uobject    = NULL;
@@ -1257,7 +1272,7 @@ int ib_modify_qp(struct ib_qp *qp,
 	if (ret)
 		return ret;
 
-	return qp->device->modify_qp(qp->real_qp, qp_attr, qp_attr_mask, NULL);
+	return ib_security_modify_qp(qp->real_qp, qp_attr, qp_attr_mask, NULL);
 }
 EXPORT_SYMBOL(ib_modify_qp);
 
@@ -1286,6 +1301,7 @@ int ib_close_qp(struct ib_qp *qp)
 	spin_unlock_irqrestore(&real_qp->device->event_handler_lock, flags);
 
 	atomic_dec(&real_qp->usecnt);
+	ib_close_shared_qp_security(qp->qp_sec);
 	kfree(qp);
 
 	return 0;
@@ -1326,6 +1342,7 @@ int ib_destroy_qp(struct ib_qp *qp)
 	struct ib_cq *scq, *rcq;
 	struct ib_srq *srq;
 	struct ib_rwq_ind_table *ind_tbl;
+	struct ib_qp_security *sec;
 	int ret;
 
 	WARN_ON_ONCE(qp->mrs_used > 0);
@@ -1341,6 +1358,9 @@ int ib_destroy_qp(struct ib_qp *qp)
 	rcq  = qp->recv_cq;
 	srq  = qp->srq;
 	ind_tbl = qp->rwq_ind_tbl;
+	sec  = qp->qp_sec;
+	if (sec)
+		ib_destroy_qp_security_begin(sec);
 
 	if (!qp->uobject)
 		rdma_rw_cleanup_mrs(qp);
@@ -1357,6 +1377,11 @@ int ib_destroy_qp(struct ib_qp *qp)
 			atomic_dec(&srq->usecnt);
 		if (ind_tbl)
 			atomic_dec(&ind_tbl->usecnt);
+		if (sec)
+			ib_destroy_qp_security_end(sec);
+	} else {
+		if (sec)
+			ib_destroy_qp_security_abort(sec);
 	}
 
 	return ret;
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index 558adfa..d576efc 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -8,6 +8,7 @@
  * Copyright (C) 2001 Silicon Graphics, Inc. (Trust Technology Group)
  * Copyright (C) 2015 Intel Corporation.
  * Copyright (C) 2015 Casey Schaufler <casey@schaufler-ca.com>
+ * Copyright (C) 2016 Mellanox Techonologies
  *
  *	This program is free software; you can redistribute it and/or modify
  *	it under the terms of the GNU General Public License as published by
@@ -903,6 +904,21 @@
  *	associated with the TUN device's security structure.
  *	@security pointer to the TUN devices's security structure.
  *
+ * Security hooks for Infiniband
+ *
+ * @ib_pkey_access:
+ *	Check permission to access a pkey when modifing a QP.
+ *	@subnet_prefix the subnet prefix of the port being used.
+ *	@pkey the pkey to be accessed.
+ *	@sec pointer to a security structure.
+ * @ib_alloc_security:
+ *	Allocate a security structure for Infiniband objects.
+ *	@sec pointer to a security structure pointer.
+ *	Returns 0 on success, non-zero on failure
+ * @ib_free_security:
+ *	Deallocate an Infiniband security structure.
+ *	@sec contains the security structure to be freed.
+ *
  * Security hooks for XFRM operations.
  *
  * @xfrm_policy_alloc_security:
@@ -1611,6 +1627,12 @@ union security_list_options {
 	int (*tun_dev_open)(void *security);
 #endif	/* CONFIG_SECURITY_NETWORK */
 
+#ifdef CONFIG_SECURITY_INFINIBAND
+	int (*ib_pkey_access)(void *sec, u64 subnet_prefix, u16 pkey);
+	int (*ib_alloc_security)(void **sec);
+	void (*ib_free_security)(void *sec);
+#endif	/* CONFIG_SECURITY_INFINIBAND */
+
 #ifdef CONFIG_SECURITY_NETWORK_XFRM
 	int (*xfrm_policy_alloc_security)(struct xfrm_sec_ctx **ctxp,
 					  struct xfrm_user_sec_ctx *sec_ctx,
@@ -1841,6 +1863,11 @@ struct security_hook_heads {
 	struct list_head tun_dev_attach;
 	struct list_head tun_dev_open;
 #endif	/* CONFIG_SECURITY_NETWORK */
+#ifdef CONFIG_SECURITY_INFINIBAND
+	struct list_head ib_pkey_access;
+	struct list_head ib_alloc_security;
+	struct list_head ib_free_security;
+#endif	/* CONFIG_SECURITY_INFINIBAND */
 #ifdef CONFIG_SECURITY_NETWORK_XFRM
 	struct list_head xfrm_policy_alloc_security;
 	struct list_head xfrm_policy_clone_security;
diff --git a/include/linux/security.h b/include/linux/security.h
index c2125e9..342ca4c 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -6,6 +6,7 @@
  * Copyright (C) 2001 Networks Associates Technology, Inc <ssmalley@nai.com>
  * Copyright (C) 2001 James Morris <jmorris@intercode.com.au>
  * Copyright (C) 2001 Silicon Graphics, Inc. (Trust Technology Group)
+ * Copyright (C) 2016 Mellanox Techonologies
  *
  *	This program is free software; you can redistribute it and/or modify
  *	it under the terms of the GNU General Public License as published by
@@ -1393,6 +1394,26 @@ static inline int security_tun_dev_open(void *security)
 }
 #endif	/* CONFIG_SECURITY_NETWORK */
 
+#ifdef CONFIG_SECURITY_INFINIBAND
+int security_ib_pkey_access(void *sec, u64 subnet_prefix, u16 pkey);
+int security_ib_alloc_security(void **sec);
+void security_ib_free_security(void *sec);
+#else	/* CONFIG_SECURITY_INFINIBAND */
+static inline int security_ib_pkey_access(void *sec, u64 subnet_prefix, u16 pkey)
+{
+	return 0;
+}
+
+static inline int security_ib_alloc_security(void **sec)
+{
+	return 0;
+}
+
+static inline void security_ib_free_security(void *sec)
+{
+}
+#endif	/* CONFIG_SECURITY_INFINIBAND */
+
 #ifdef CONFIG_SECURITY_NETWORK_XFRM
 
 int security_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp,
diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
index db178fd..1143586 100644
--- a/include/rdma/ib_verbs.h
+++ b/include/rdma/ib_verbs.h
@@ -1511,6 +1511,45 @@ struct ib_rwq_ind_table_init_attr {
 	struct ib_wq	**ind_tbl;
 };
 
+enum port_pkey_state {
+	IB_PORT_PKEY_NOT_VALID = 0,
+	IB_PORT_PKEY_VALID = 1,
+	IB_PORT_PKEY_LISTED = 2,
+};
+
+struct ib_qp_security;
+
+struct ib_port_pkey {
+	enum port_pkey_state	state;
+	u16			pkey_index;
+	u8			port_num;
+	struct list_head	qp_list;
+	struct list_head	to_error_list;
+	struct ib_qp_security  *sec;
+};
+
+struct ib_ports_pkeys {
+	struct ib_port_pkey	main;
+	struct ib_port_pkey	alt;
+};
+
+struct ib_qp_security {
+	struct ib_qp	       *qp;
+	struct ib_device       *dev;
+	/* Hold this mutex when changing port and pkey settings. */
+	struct mutex		mutex;
+	struct ib_ports_pkeys  *ports_pkeys;
+	/* A list of all open shared QP handles.  Required to enforce security
+	 * properly for all users of a shared QP.
+	 */
+	struct list_head        shared_qp_list;
+	void                   *security;
+	bool			destroying;
+	atomic_t		error_list_count;
+	struct completion	error_complete;
+	int			error_comps_pending;
+};
+
 /*
  * @max_write_sge: Maximum SGE elements per RDMA WRITE request.
  * @max_read_sge:  Maximum SGE elements per RDMA READ request.
@@ -1540,6 +1579,7 @@ struct ib_qp {
 	u32			max_read_sge;
 	enum ib_qp_type		qp_type;
 	struct ib_rwq_ind_table *rwq_ind_tbl;
+	struct ib_qp_security  *qp_sec;
 };
 
 struct ib_mr {
@@ -1820,6 +1860,12 @@ struct ib_port_immutable {
 	u32                           max_mad_size;
 };
 
+struct ib_port_pkey_list {
+	/* Lock to hold while modifying the list. */
+	spinlock_t		      list_lock;
+	struct list_head	      pkey_list;
+};
+
 struct ib_device {
 	struct device                *dma_device;
 
@@ -1842,6 +1888,8 @@ struct ib_device {
 
 	int			      num_comp_vectors;
 
+	struct ib_port_pkey_list     *port_pkey_list;
+
 	struct iw_cm_verbs	     *iwcm;
 
 	/**
diff --git a/security/Kconfig b/security/Kconfig
index 118f454..85cf893 100644
--- a/security/Kconfig
+++ b/security/Kconfig
@@ -49,6 +49,15 @@ config SECURITY_NETWORK
 	  implement socket and networking access controls.
 	  If you are unsure how to answer this question, answer N.
 
+config SECURITY_INFINIBAND
+	bool "Infiniband Security Hooks"
+	depends on SECURITY && INFINIBAND
+	help
+	  This enables the Infiniband security hooks.
+	  If enabled, a security module can use these hooks to
+	  implement Infiniband access controls.
+	  If you are unsure how to answer this question, answer N.
+
 config SECURITY_NETWORK_XFRM
 	bool "XFRM (IPSec) Networking Security Hooks"
 	depends on XFRM && SECURITY_NETWORK
diff --git a/security/security.c b/security/security.c
index f825304..7d3bf2f 100644
--- a/security/security.c
+++ b/security/security.c
@@ -4,6 +4,7 @@
  * Copyright (C) 2001 WireX Communications, Inc <chris@wirex.com>
  * Copyright (C) 2001-2002 Greg Kroah-Hartman <greg@kroah.com>
  * Copyright (C) 2001 Networks Associates Technology, Inc <ssmalley@nai.com>
+ * Copyright (C) 2016 Mellanox Technologies
  *
  *	This program is free software; you can redistribute it and/or modify
  *	it under the terms of the GNU General Public License as published by
@@ -1441,6 +1442,27 @@ EXPORT_SYMBOL(security_tun_dev_open);
 
 #endif	/* CONFIG_SECURITY_NETWORK */
 
+#ifdef CONFIG_SECURITY_INFINIBAND
+
+int security_ib_pkey_access(void *sec, u64 subnet_prefix, u16 pkey)
+{
+	return call_int_hook(ib_pkey_access, 0, sec, subnet_prefix, pkey);
+}
+EXPORT_SYMBOL(security_ib_pkey_access);
+
+int security_ib_alloc_security(void **sec)
+{
+	return call_int_hook(ib_alloc_security, 0, sec);
+}
+EXPORT_SYMBOL(security_ib_alloc_security);
+
+void security_ib_free_security(void *sec)
+{
+	call_void_hook(ib_free_security, sec);
+}
+EXPORT_SYMBOL(security_ib_free_security);
+#endif	/* CONFIG_SECURITY_INFINIBAND */
+
 #ifdef CONFIG_SECURITY_NETWORK_XFRM
 
 int security_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp,
@@ -1898,6 +1920,15 @@ struct security_hook_heads security_hook_heads = {
 		LIST_HEAD_INIT(security_hook_heads.tun_dev_attach),
 	.tun_dev_open =	LIST_HEAD_INIT(security_hook_heads.tun_dev_open),
 #endif	/* CONFIG_SECURITY_NETWORK */
+
+#ifdef CONFIG_SECURITY_INFINIBAND
+	.ib_pkey_access = LIST_HEAD_INIT(security_hook_heads.ib_pkey_access),
+	.ib_alloc_security =
+		LIST_HEAD_INIT(security_hook_heads.ib_alloc_security),
+	.ib_free_security =
+		LIST_HEAD_INIT(security_hook_heads.ib_free_security),
+#endif	/* CONFIG_SECURITY_INFINIBAND */
+
 #ifdef CONFIG_SECURITY_NETWORK_XFRM
 	.xfrm_policy_alloc_security =
 		LIST_HEAD_INIT(security_hook_heads.xfrm_policy_alloc_security),
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH v6 3/9] selinux lsm IB/core: Implement LSM notification system
  2016-11-23 14:17 ` Dan Jurgens
@ 2016-11-23 14:17     ` Dan Jurgens
  -1 siblings, 0 replies; 51+ messages in thread
From: Dan Jurgens @ 2016-11-23 14:17 UTC (permalink / raw)
  To: chrisw-69jw2NvuJkxg9hUCZPvPmw, paul-r2n+y4ga6xFZroRs9YW3xA,
	sds-+05T5uksL2qpZYMLLGbcSA, eparis-FjpueFixGhCM4zKIHC2jIg,
	dledford-H+wXaHxf7aLQT0dZR+AlfA,
	sean.hefty-ral2JQCrhuEAvxtiuMwx3w,
	hal.rosenstock-Re5JQEeQqe8AvxtiuMwx3w
  Cc: selinux-+05T5uksL2qpZYMLLGbcSA,
	linux-security-module-u79uwXL29TY76Z2rM5mHXA,
	linux-rdma-u79uwXL29TY76Z2rM5mHXA,
	yevgenyp-VPRAkNaXOzVWk0Htik3J/w, Daniel Jurgens

From: Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>

Add a generic notificaiton mechanism in the LSM. Interested consumers
can register a callback with the LSM and security modules can produce
events.

Because access to Infiniband QPs are enforced in the setup phase of a
connection security should be enforced again if the policy changes.
Register infiniband devices for policy change notification and check all
QPs on that device when the notification is received.

Add a call to the notification mechanism from SELinux when the AVC
cache changes or setenforce is cleared.

Signed-off-by: Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>

---
v2:
- new patch that has the generic notification, replaces selinux and
  IB/core patches related to the ib_flush callback. Yuval Shaia and Paul
  Moore

v3:
- use notifier chains. Paul Moore

v4:
- Seperate avc callback for LSM notifier. Paul Moore

v5:
- Fix link error when CONFIG_SECURITY is not set. Build Robot
---
 drivers/infiniband/core/device.c | 53 ++++++++++++++++++++++++++++++++++++++++
 include/linux/security.h         | 23 +++++++++++++++++
 security/security.c              | 20 +++++++++++++++
 security/selinux/hooks.c         | 11 +++++++++
 security/selinux/selinuxfs.c     |  2 ++
 5 files changed, 109 insertions(+)

diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c
index 5b42e83..7b6fd06 100644
--- a/drivers/infiniband/core/device.c
+++ b/drivers/infiniband/core/device.c
@@ -39,6 +39,8 @@
 #include <linux/init.h>
 #include <linux/mutex.h>
 #include <linux/netdevice.h>
+#include <linux/security.h>
+#include <linux/notifier.h>
 #include <rdma/rdma_netlink.h>
 #include <rdma/ib_addr.h>
 #include <rdma/ib_cache.h>
@@ -82,6 +84,14 @@ static LIST_HEAD(client_list);
 static DEFINE_MUTEX(device_mutex);
 static DECLARE_RWSEM(lists_rwsem);
 
+static int ib_security_change(struct notifier_block *nb, unsigned long event,
+			      void *lsm_data);
+static void ib_policy_change_task(struct work_struct *work);
+static DECLARE_WORK(ib_policy_change_work, ib_policy_change_task);
+
+static struct notifier_block ibdev_lsm_nb = {
+	.notifier_call = ib_security_change,
+};
 
 static int ib_device_check_mandatory(struct ib_device *device)
 {
@@ -344,6 +354,40 @@ static int setup_port_pkey_list(struct ib_device *device)
 	return 0;
 }
 
+static void ib_policy_change_task(struct work_struct *work)
+{
+	struct ib_device *dev;
+
+	down_read(&lists_rwsem);
+	list_for_each_entry(dev, &device_list, core_list) {
+		int i;
+
+		for (i = rdma_start_port(dev); i <= rdma_end_port(dev); i++) {
+			u64 sp;
+			int ret = ib_get_cached_subnet_prefix(dev,
+							      i,
+							      &sp);
+
+			WARN_ONCE(ret,
+				  "ib_get_cached_subnet_prefix err: %d, this should never happen here\n",
+				  ret);
+			ib_security_cache_change(dev, i, sp);
+		}
+	}
+	up_read(&lists_rwsem);
+}
+
+static int ib_security_change(struct notifier_block *nb, unsigned long event,
+			      void *lsm_data)
+{
+	if (event != LSM_POLICY_CHANGE)
+		return NOTIFY_DONE;
+
+	schedule_work(&ib_policy_change_work);
+
+	return NOTIFY_OK;
+}
+
 /**
  * ib_register_device - Register an IB device with IB core
  * @device:Device to register
@@ -1075,10 +1119,18 @@ static int __init ib_core_init(void)
 		goto err_sa;
 	}
 
+	ret = register_lsm_notifier(&ibdev_lsm_nb);
+	if (ret) {
+		pr_warn("Couldn't register LSM notifier. ret %d\n", ret);
+		goto err_ibnl_clients;
+	}
+
 	ib_cache_setup();
 
 	return 0;
 
+err_ibnl_clients:
+	ib_remove_ibnl_clients();
 err_sa:
 	ib_sa_cleanup();
 err_mad:
@@ -1098,6 +1150,7 @@ static int __init ib_core_init(void)
 
 static void __exit ib_core_cleanup(void)
 {
+	unregister_lsm_notifier(&ibdev_lsm_nb);
 	ib_cache_cleanup();
 	ib_remove_ibnl_clients();
 	ib_sa_cleanup();
diff --git a/include/linux/security.h b/include/linux/security.h
index 342ca4c..0a5de0c 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -69,6 +69,10 @@ struct audit_krule;
 struct user_namespace;
 struct timezone;
 
+enum lsm_event {
+	LSM_POLICY_CHANGE,
+};
+
 /* These functions are in security/commoncap.c */
 extern int cap_capable(const struct cred *cred, struct user_namespace *ns,
 		       int cap, int audit);
@@ -161,6 +165,10 @@ struct security_mnt_opts {
 	int num_mnt_opts;
 };
 
+int call_lsm_notifier(enum lsm_event event, void *data);
+int register_lsm_notifier(struct notifier_block *nb);
+int unregister_lsm_notifier(struct notifier_block *nb);
+
 static inline void security_init_mnt_opts(struct security_mnt_opts *opts)
 {
 	opts->mnt_opts = NULL;
@@ -377,6 +385,21 @@ int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen);
 struct security_mnt_opts {
 };
 
+static inline int call_lsm_notifier(enum lsm_event event, void *data)
+{
+	return 0;
+}
+
+static inline int register_lsm_notifier(struct notifier_block *nb)
+{
+	return 0;
+}
+
+static inline  int unregister_lsm_notifier(struct notifier_block *nb)
+{
+	return 0;
+}
+
 static inline void security_init_mnt_opts(struct security_mnt_opts *opts)
 {
 }
diff --git a/security/security.c b/security/security.c
index 7d3bf2f..40326d4 100644
--- a/security/security.c
+++ b/security/security.c
@@ -33,6 +33,8 @@
 /* Maximum number of letters for an LSM name string */
 #define SECURITY_NAME_MAX	10
 
+static ATOMIC_NOTIFIER_HEAD(lsm_notifier_chain);
+
 /* Boot-time LSM user choice */
 static __initdata char chosen_lsm[SECURITY_NAME_MAX + 1] =
 	CONFIG_DEFAULT_SECURITY;
@@ -98,6 +100,24 @@ int __init security_module_enable(const char *module)
 	return !strcmp(module, chosen_lsm);
 }
 
+int call_lsm_notifier(enum lsm_event event, void *data)
+{
+	return atomic_notifier_call_chain(&lsm_notifier_chain, event, data);
+}
+EXPORT_SYMBOL(call_lsm_notifier);
+
+int register_lsm_notifier(struct notifier_block *nb)
+{
+	return atomic_notifier_chain_register(&lsm_notifier_chain, nb);
+}
+EXPORT_SYMBOL(register_lsm_notifier);
+
+int unregister_lsm_notifier(struct notifier_block *nb)
+{
+	return atomic_notifier_chain_unregister(&lsm_notifier_chain, nb);
+}
+EXPORT_SYMBOL(unregister_lsm_notifier);
+
 /*
  * Hook list operation macros.
  *
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 09fd610..2d7a7c1 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -170,6 +170,14 @@ static int selinux_netcache_avc_callback(u32 event)
 	return 0;
 }
 
+static int selinux_lsm_notifier_avc_callback(u32 event)
+{
+	if (event == AVC_CALLBACK_RESET)
+		call_lsm_notifier(LSM_POLICY_CHANGE, NULL);
+
+	return 0;
+}
+
 /*
  * initialise the security for the init task
  */
@@ -6325,6 +6333,9 @@ static __init int selinux_init(void)
 	if (avc_add_callback(selinux_netcache_avc_callback, AVC_CALLBACK_RESET))
 		panic("SELinux: Unable to register AVC netcache callback\n");
 
+	if (avc_add_callback(selinux_lsm_notifier_avc_callback, AVC_CALLBACK_RESET))
+		panic("SELinux: Unable to register AVC LSM notifier callback\n");
+
 	if (selinux_enforcing)
 		printk(KERN_DEBUG "SELinux:  Starting in enforcing mode\n");
 	else
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index 72c145d..d3f9192 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -177,6 +177,8 @@ static ssize_t sel_write_enforce(struct file *file, const char __user *buf,
 			avc_ss_reset(0);
 		selnl_notify_setenforce(selinux_enforcing);
 		selinux_status_update_setenforce(selinux_enforcing);
+		if (!selinux_enforcing)
+			call_lsm_notifier(LSM_POLICY_CHANGE, NULL);
 	}
 	length = count;
 out:
-- 
2.7.4

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH v6 3/9] selinux lsm IB/core: Implement LSM notification system
@ 2016-11-23 14:17     ` Dan Jurgens
  0 siblings, 0 replies; 51+ messages in thread
From: Dan Jurgens @ 2016-11-23 14:17 UTC (permalink / raw)
  To: chrisw, paul, sds, eparis, dledford, sean.hefty, hal.rosenstock
  Cc: selinux, linux-security-module, linux-rdma, yevgenyp, Daniel Jurgens

From: Daniel Jurgens <danielj@mellanox.com>

Add a generic notificaiton mechanism in the LSM. Interested consumers
can register a callback with the LSM and security modules can produce
events.

Because access to Infiniband QPs are enforced in the setup phase of a
connection security should be enforced again if the policy changes.
Register infiniband devices for policy change notification and check all
QPs on that device when the notification is received.

Add a call to the notification mechanism from SELinux when the AVC
cache changes or setenforce is cleared.

Signed-off-by: Daniel Jurgens <danielj@mellanox.com>

---
v2:
- new patch that has the generic notification, replaces selinux and
  IB/core patches related to the ib_flush callback. Yuval Shaia and Paul
  Moore

v3:
- use notifier chains. Paul Moore

v4:
- Seperate avc callback for LSM notifier. Paul Moore

v5:
- Fix link error when CONFIG_SECURITY is not set. Build Robot
---
 drivers/infiniband/core/device.c | 53 ++++++++++++++++++++++++++++++++++++++++
 include/linux/security.h         | 23 +++++++++++++++++
 security/security.c              | 20 +++++++++++++++
 security/selinux/hooks.c         | 11 +++++++++
 security/selinux/selinuxfs.c     |  2 ++
 5 files changed, 109 insertions(+)

diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c
index 5b42e83..7b6fd06 100644
--- a/drivers/infiniband/core/device.c
+++ b/drivers/infiniband/core/device.c
@@ -39,6 +39,8 @@
 #include <linux/init.h>
 #include <linux/mutex.h>
 #include <linux/netdevice.h>
+#include <linux/security.h>
+#include <linux/notifier.h>
 #include <rdma/rdma_netlink.h>
 #include <rdma/ib_addr.h>
 #include <rdma/ib_cache.h>
@@ -82,6 +84,14 @@ static LIST_HEAD(client_list);
 static DEFINE_MUTEX(device_mutex);
 static DECLARE_RWSEM(lists_rwsem);
 
+static int ib_security_change(struct notifier_block *nb, unsigned long event,
+			      void *lsm_data);
+static void ib_policy_change_task(struct work_struct *work);
+static DECLARE_WORK(ib_policy_change_work, ib_policy_change_task);
+
+static struct notifier_block ibdev_lsm_nb = {
+	.notifier_call = ib_security_change,
+};
 
 static int ib_device_check_mandatory(struct ib_device *device)
 {
@@ -344,6 +354,40 @@ static int setup_port_pkey_list(struct ib_device *device)
 	return 0;
 }
 
+static void ib_policy_change_task(struct work_struct *work)
+{
+	struct ib_device *dev;
+
+	down_read(&lists_rwsem);
+	list_for_each_entry(dev, &device_list, core_list) {
+		int i;
+
+		for (i = rdma_start_port(dev); i <= rdma_end_port(dev); i++) {
+			u64 sp;
+			int ret = ib_get_cached_subnet_prefix(dev,
+							      i,
+							      &sp);
+
+			WARN_ONCE(ret,
+				  "ib_get_cached_subnet_prefix err: %d, this should never happen here\n",
+				  ret);
+			ib_security_cache_change(dev, i, sp);
+		}
+	}
+	up_read(&lists_rwsem);
+}
+
+static int ib_security_change(struct notifier_block *nb, unsigned long event,
+			      void *lsm_data)
+{
+	if (event != LSM_POLICY_CHANGE)
+		return NOTIFY_DONE;
+
+	schedule_work(&ib_policy_change_work);
+
+	return NOTIFY_OK;
+}
+
 /**
  * ib_register_device - Register an IB device with IB core
  * @device:Device to register
@@ -1075,10 +1119,18 @@ static int __init ib_core_init(void)
 		goto err_sa;
 	}
 
+	ret = register_lsm_notifier(&ibdev_lsm_nb);
+	if (ret) {
+		pr_warn("Couldn't register LSM notifier. ret %d\n", ret);
+		goto err_ibnl_clients;
+	}
+
 	ib_cache_setup();
 
 	return 0;
 
+err_ibnl_clients:
+	ib_remove_ibnl_clients();
 err_sa:
 	ib_sa_cleanup();
 err_mad:
@@ -1098,6 +1150,7 @@ static int __init ib_core_init(void)
 
 static void __exit ib_core_cleanup(void)
 {
+	unregister_lsm_notifier(&ibdev_lsm_nb);
 	ib_cache_cleanup();
 	ib_remove_ibnl_clients();
 	ib_sa_cleanup();
diff --git a/include/linux/security.h b/include/linux/security.h
index 342ca4c..0a5de0c 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -69,6 +69,10 @@ struct audit_krule;
 struct user_namespace;
 struct timezone;
 
+enum lsm_event {
+	LSM_POLICY_CHANGE,
+};
+
 /* These functions are in security/commoncap.c */
 extern int cap_capable(const struct cred *cred, struct user_namespace *ns,
 		       int cap, int audit);
@@ -161,6 +165,10 @@ struct security_mnt_opts {
 	int num_mnt_opts;
 };
 
+int call_lsm_notifier(enum lsm_event event, void *data);
+int register_lsm_notifier(struct notifier_block *nb);
+int unregister_lsm_notifier(struct notifier_block *nb);
+
 static inline void security_init_mnt_opts(struct security_mnt_opts *opts)
 {
 	opts->mnt_opts = NULL;
@@ -377,6 +385,21 @@ int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen);
 struct security_mnt_opts {
 };
 
+static inline int call_lsm_notifier(enum lsm_event event, void *data)
+{
+	return 0;
+}
+
+static inline int register_lsm_notifier(struct notifier_block *nb)
+{
+	return 0;
+}
+
+static inline  int unregister_lsm_notifier(struct notifier_block *nb)
+{
+	return 0;
+}
+
 static inline void security_init_mnt_opts(struct security_mnt_opts *opts)
 {
 }
diff --git a/security/security.c b/security/security.c
index 7d3bf2f..40326d4 100644
--- a/security/security.c
+++ b/security/security.c
@@ -33,6 +33,8 @@
 /* Maximum number of letters for an LSM name string */
 #define SECURITY_NAME_MAX	10
 
+static ATOMIC_NOTIFIER_HEAD(lsm_notifier_chain);
+
 /* Boot-time LSM user choice */
 static __initdata char chosen_lsm[SECURITY_NAME_MAX + 1] =
 	CONFIG_DEFAULT_SECURITY;
@@ -98,6 +100,24 @@ int __init security_module_enable(const char *module)
 	return !strcmp(module, chosen_lsm);
 }
 
+int call_lsm_notifier(enum lsm_event event, void *data)
+{
+	return atomic_notifier_call_chain(&lsm_notifier_chain, event, data);
+}
+EXPORT_SYMBOL(call_lsm_notifier);
+
+int register_lsm_notifier(struct notifier_block *nb)
+{
+	return atomic_notifier_chain_register(&lsm_notifier_chain, nb);
+}
+EXPORT_SYMBOL(register_lsm_notifier);
+
+int unregister_lsm_notifier(struct notifier_block *nb)
+{
+	return atomic_notifier_chain_unregister(&lsm_notifier_chain, nb);
+}
+EXPORT_SYMBOL(unregister_lsm_notifier);
+
 /*
  * Hook list operation macros.
  *
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 09fd610..2d7a7c1 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -170,6 +170,14 @@ static int selinux_netcache_avc_callback(u32 event)
 	return 0;
 }
 
+static int selinux_lsm_notifier_avc_callback(u32 event)
+{
+	if (event == AVC_CALLBACK_RESET)
+		call_lsm_notifier(LSM_POLICY_CHANGE, NULL);
+
+	return 0;
+}
+
 /*
  * initialise the security for the init task
  */
@@ -6325,6 +6333,9 @@ static __init int selinux_init(void)
 	if (avc_add_callback(selinux_netcache_avc_callback, AVC_CALLBACK_RESET))
 		panic("SELinux: Unable to register AVC netcache callback\n");
 
+	if (avc_add_callback(selinux_lsm_notifier_avc_callback, AVC_CALLBACK_RESET))
+		panic("SELinux: Unable to register AVC LSM notifier callback\n");
+
 	if (selinux_enforcing)
 		printk(KERN_DEBUG "SELinux:  Starting in enforcing mode\n");
 	else
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index 72c145d..d3f9192 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -177,6 +177,8 @@ static ssize_t sel_write_enforce(struct file *file, const char __user *buf,
 			avc_ss_reset(0);
 		selnl_notify_setenforce(selinux_enforcing);
 		selinux_status_update_setenforce(selinux_enforcing);
+		if (!selinux_enforcing)
+			call_lsm_notifier(LSM_POLICY_CHANGE, NULL);
 	}
 	length = count;
 out:
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH v6 4/9] IB/core: Enforce security on management datagrams
  2016-11-23 14:17 ` Dan Jurgens
  (?)
  (?)
@ 2016-11-23 14:17 ` Dan Jurgens
  -1 siblings, 0 replies; 51+ messages in thread
From: Dan Jurgens @ 2016-11-23 14:17 UTC (permalink / raw)
  To: chrisw, paul, sds, eparis, dledford, sean.hefty, hal.rosenstock
  Cc: selinux, linux-security-module, linux-rdma, yevgenyp, Daniel Jurgens

From: Daniel Jurgens <danielj@mellanox.com>

Allocate and free a security context when creating and destroying a MAD
agent.  This context is used for controlling access to PKeys and sending
and receiving SMPs.

When sending or receiving a MAD check that the agent has permission to
access the PKey for the Subnet Prefix of the port.

During MAD and snoop agent registration for SMI QPs check that the
calling process has permission to access the manage the subnet  and
register a callback with the LSM to be notified of policy changes. When
notificaiton of a policy change occurs recheck permission and set a flag
indicating sending and receiving SMPs is allowed.

When sending and receiving MADs check that the agent has access to the
SMI if it's on an SMI QP.  Because security policy can change it's
possible permission was allowed when creating the agent, but no longer
is.

Signed-off-by: Daniel Jurgens <danielj@mellanox.com>

---
v2:
- Squashed LSM hook additions. Paul Moore
- Changed security blobs to void*. Paul Moore
- Shorten end_port to port. Paul Moore
- Change "smp" to "manage_subnet". Paul Moore
- Use the LSM policy change notification and a flag to track permission
  instead of calling the LSM hook for every SMP. Dan Jurgens
- Squashed PKey and SMP enforcement into the same patch and moved the
  logic into security.c. Dan Jurgens

v3:
- ib_port -> ib_endport. Paul Moore
- Use notifier chains for LSM notification. Paul Moore
- Reorder LSM hook parameters to put sec first. Paul Moore
---
 drivers/infiniband/core/core_priv.h | 35 ++++++++++++++
 drivers/infiniband/core/mad.c       | 52 +++++++++++++++++----
 drivers/infiniband/core/security.c  | 92 +++++++++++++++++++++++++++++++++++++
 include/linux/lsm_hooks.h           |  8 ++++
 include/linux/security.h            |  6 +++
 include/rdma/ib_mad.h               |  4 ++
 security/security.c                 |  8 ++++
 7 files changed, 197 insertions(+), 8 deletions(-)

diff --git a/drivers/infiniband/core/core_priv.h b/drivers/infiniband/core/core_priv.h
index 68e3de0..2c35162 100644
--- a/drivers/infiniband/core/core_priv.h
+++ b/drivers/infiniband/core/core_priv.h
@@ -37,6 +37,8 @@
 #include <linux/spinlock.h>
 
 #include <rdma/ib_verbs.h>
+#include <rdma/ib_mad.h>
+#include "mad_priv.h"
 
 struct pkey_index_qp_list {
 	struct list_head    pkey_index_list;
@@ -166,6 +168,11 @@ int ib_get_cached_subnet_prefix(struct ib_device *device,
 				u64              *sn_pfx);
 
 #ifdef CONFIG_SECURITY_INFINIBAND
+int ib_security_pkey_access(struct ib_device *dev,
+			    u8 port_num,
+			    u16 pkey_index,
+			    void *sec);
+
 void ib_security_destroy_port_pkey_list(struct ib_device *device);
 
 void ib_security_cache_change(struct ib_device *device,
@@ -183,7 +190,19 @@ void ib_destroy_qp_security_abort(struct ib_qp_security *sec);
 void ib_destroy_qp_security_end(struct ib_qp_security *sec);
 int ib_open_shared_qp_security(struct ib_qp *qp, struct ib_device *dev);
 void ib_close_shared_qp_security(struct ib_qp_security *sec);
+int ib_mad_agent_security_setup(struct ib_mad_agent *agent,
+				enum ib_qp_type qp_type);
+void ib_mad_agent_security_cleanup(struct ib_mad_agent *agent);
+int ib_mad_enforce_security(struct ib_mad_agent_private *map, u16 pkey_index);
 #else
+static inline int ib_security_pkey_access(struct ib_device *dev,
+					  u8 port_num,
+					  u16 pkey_index,
+					  void *sec)
+{
+	return 0;
+}
+
 static inline void ib_security_destroy_port_pkey_list(struct ib_device *device)
 {
 }
@@ -232,5 +251,21 @@ static inline int ib_open_shared_qp_security(struct ib_qp *qp,
 static inline void ib_close_shared_qp_security(struct ib_qp_security *sec)
 {
 }
+
+static inline int ib_mad_agent_security_setup(struct ib_mad_agent *agent,
+					      enum ib_qp_type qp_type)
+{
+	return 0;
+}
+
+static inline void ib_mad_agent_security_cleanup(struct ib_mad_agent *agent)
+{
+}
+
+static inline int ib_mad_enforce_security(struct ib_mad_agent_private *map,
+					  u16 pkey_index)
+{
+	return 0;
+}
 #endif
 #endif /* _CORE_PRIV_H */
diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c
index 40cbd6b..b6041ec 100644
--- a/drivers/infiniband/core/mad.c
+++ b/drivers/infiniband/core/mad.c
@@ -40,9 +40,11 @@
 #include <linux/dma-mapping.h>
 #include <linux/slab.h>
 #include <linux/module.h>
+#include <linux/security.h>
 #include <rdma/ib_cache.h>
 
 #include "mad_priv.h"
+#include "core_priv.h"
 #include "mad_rmpp.h"
 #include "smi.h"
 #include "opa_smi.h"
@@ -367,6 +369,12 @@ struct ib_mad_agent *ib_register_mad_agent(struct ib_device *device,
 	atomic_set(&mad_agent_priv->refcount, 1);
 	init_completion(&mad_agent_priv->comp);
 
+	ret2 = ib_mad_agent_security_setup(&mad_agent_priv->agent, qp_type);
+	if (ret2) {
+		ret = ERR_PTR(ret2);
+		goto error4;
+	}
+
 	spin_lock_irqsave(&port_priv->reg_lock, flags);
 	mad_agent_priv->agent.hi_tid = ++ib_mad_client_id;
 
@@ -384,7 +392,7 @@ struct ib_mad_agent *ib_register_mad_agent(struct ib_device *device,
 				if (method) {
 					if (method_in_use(&method,
 							   mad_reg_req))
-						goto error4;
+						goto error5;
 				}
 			}
 			ret2 = add_nonoui_reg_req(mad_reg_req, mad_agent_priv,
@@ -400,14 +408,14 @@ struct ib_mad_agent *ib_register_mad_agent(struct ib_device *device,
 					if (is_vendor_method_in_use(
 							vendor_class,
 							mad_reg_req))
-						goto error4;
+						goto error5;
 				}
 			}
 			ret2 = add_oui_reg_req(mad_reg_req, mad_agent_priv);
 		}
 		if (ret2) {
 			ret = ERR_PTR(ret2);
-			goto error4;
+			goto error5;
 		}
 	}
 
@@ -416,9 +424,10 @@ struct ib_mad_agent *ib_register_mad_agent(struct ib_device *device,
 	spin_unlock_irqrestore(&port_priv->reg_lock, flags);
 
 	return &mad_agent_priv->agent;
-
-error4:
+error5:
 	spin_unlock_irqrestore(&port_priv->reg_lock, flags);
+	ib_mad_agent_security_cleanup(&mad_agent_priv->agent);
+error4:
 	kfree(reg_req);
 error3:
 	kfree(mad_agent_priv);
@@ -489,6 +498,7 @@ struct ib_mad_agent *ib_register_mad_snoop(struct ib_device *device,
 	struct ib_mad_agent *ret;
 	struct ib_mad_snoop_private *mad_snoop_priv;
 	int qpn;
+	int err;
 
 	/* Validate parameters */
 	if ((is_snooping_sends(mad_snoop_flags) && !snoop_handler) ||
@@ -523,17 +533,25 @@ struct ib_mad_agent *ib_register_mad_snoop(struct ib_device *device,
 	mad_snoop_priv->agent.port_num = port_num;
 	mad_snoop_priv->mad_snoop_flags = mad_snoop_flags;
 	init_completion(&mad_snoop_priv->comp);
+
+	err = ib_mad_agent_security_setup(&mad_snoop_priv->agent, qp_type);
+	if (err) {
+		ret = ERR_PTR(err);
+		goto error2;
+	}
+
 	mad_snoop_priv->snoop_index = register_snoop_agent(
 						&port_priv->qp_info[qpn],
 						mad_snoop_priv);
 	if (mad_snoop_priv->snoop_index < 0) {
 		ret = ERR_PTR(mad_snoop_priv->snoop_index);
-		goto error2;
+		goto error3;
 	}
 
 	atomic_set(&mad_snoop_priv->refcount, 1);
 	return &mad_snoop_priv->agent;
-
+error3:
+	ib_mad_agent_security_cleanup(&mad_snoop_priv->agent);
 error2:
 	kfree(mad_snoop_priv);
 error1:
@@ -579,6 +597,8 @@ static void unregister_mad_agent(struct ib_mad_agent_private *mad_agent_priv)
 	deref_mad_agent(mad_agent_priv);
 	wait_for_completion(&mad_agent_priv->comp);
 
+	ib_mad_agent_security_cleanup(&mad_agent_priv->agent);
+
 	kfree(mad_agent_priv->reg_req);
 	kfree(mad_agent_priv);
 }
@@ -597,6 +617,8 @@ static void unregister_mad_snoop(struct ib_mad_snoop_private *mad_snoop_priv)
 	deref_snoop_agent(mad_snoop_priv);
 	wait_for_completion(&mad_snoop_priv->comp);
 
+	ib_mad_agent_security_cleanup(&mad_snoop_priv->agent);
+
 	kfree(mad_snoop_priv);
 }
 
@@ -1219,12 +1241,16 @@ int ib_post_send_mad(struct ib_mad_send_buf *send_buf,
 
 	/* Walk list of send WRs and post each on send list */
 	for (; send_buf; send_buf = next_send_buf) {
-
 		mad_send_wr = container_of(send_buf,
 					   struct ib_mad_send_wr_private,
 					   send_buf);
 		mad_agent_priv = mad_send_wr->mad_agent_priv;
 
+		ret = ib_mad_enforce_security(mad_agent_priv,
+					      mad_send_wr->send_wr.pkey_index);
+		if (ret)
+			goto error;
+
 		if (!send_buf->mad_agent->send_handler ||
 		    (send_buf->timeout_ms &&
 		     !send_buf->mad_agent->recv_handler)) {
@@ -1958,6 +1984,14 @@ static void ib_mad_complete_recv(struct ib_mad_agent_private *mad_agent_priv,
 	struct ib_mad_send_wr_private *mad_send_wr;
 	struct ib_mad_send_wc mad_send_wc;
 	unsigned long flags;
+	int ret;
+
+	ret = ib_mad_enforce_security(mad_agent_priv,
+				      mad_recv_wc->wc->pkey_index);
+	if (ret) {
+		ib_free_recv_mad(mad_recv_wc);
+		deref_mad_agent(mad_agent_priv);
+	}
 
 	INIT_LIST_HEAD(&mad_recv_wc->rmpp_list);
 	list_add(&mad_recv_wc->recv_buf.list, &mad_recv_wc->rmpp_list);
@@ -2015,6 +2049,8 @@ static void ib_mad_complete_recv(struct ib_mad_agent_private *mad_agent_priv,
 						   mad_recv_wc);
 		deref_mad_agent(mad_agent_priv);
 	}
+
+	return;
 }
 
 static enum smi_action handle_ib_smi(const struct ib_mad_port_private *port_priv,
diff --git a/drivers/infiniband/core/security.c b/drivers/infiniband/core/security.c
index 45800dd..bc09af5 100644
--- a/drivers/infiniband/core/security.c
+++ b/drivers/infiniband/core/security.c
@@ -39,6 +39,7 @@
 #include <rdma/ib_verbs.h>
 #include <rdma/ib_cache.h>
 #include "core_priv.h"
+#include "mad_priv.h"
 
 static struct pkey_index_qp_list *get_pkey_idx_qp_list(struct ib_port_pkey *pp)
 {
@@ -614,4 +615,95 @@ int ib_security_modify_qp(struct ib_qp *qp,
 }
 EXPORT_SYMBOL(ib_security_modify_qp);
 
+int ib_security_pkey_access(struct ib_device *dev,
+			    u8 port_num,
+			    u16 pkey_index,
+			    void *sec)
+{
+	u64 subnet_prefix;
+	u16 pkey;
+	int ret;
+
+	ret = ib_get_cached_pkey(dev, port_num, pkey_index, &pkey);
+	if (ret)
+		return ret;
+
+	ret = ib_get_cached_subnet_prefix(dev, port_num, &subnet_prefix);
+
+	if (ret)
+		return ret;
+
+	return security_ib_pkey_access(sec, subnet_prefix, pkey);
+}
+EXPORT_SYMBOL(ib_security_pkey_access);
+
+static int ib_mad_agent_security_change(struct notifier_block *nb,
+					unsigned long event,
+					void *data)
+{
+	struct ib_mad_agent *ag = container_of(nb, struct ib_mad_agent, lsm_nb);
+
+	if (event != LSM_POLICY_CHANGE)
+		return NOTIFY_DONE;
+
+	ag->smp_allowed = !security_ib_endport_manage_subnet(ag->security,
+							     ag->device->name,
+							     ag->port_num);
+
+	return NOTIFY_OK;
+}
+
+int ib_mad_agent_security_setup(struct ib_mad_agent *agent,
+				enum ib_qp_type qp_type)
+{
+	int ret;
+
+	ret = security_ib_alloc_security(&agent->security);
+	if (ret)
+		return ret;
+
+	if (qp_type != IB_QPT_SMI)
+		return 0;
+
+	ret = security_ib_endport_manage_subnet(agent->security,
+						agent->device->name,
+						agent->port_num);
+	if (ret)
+		return ret;
+
+	agent->lsm_nb.notifier_call = ib_mad_agent_security_change;
+	ret = register_lsm_notifier(&agent->lsm_nb);
+	if (ret)
+		return ret;
+
+	agent->smp_allowed = true;
+	agent->lsm_nb_reg = true;
+	return 0;
+}
+
+void ib_mad_agent_security_cleanup(struct ib_mad_agent *agent)
+{
+	security_ib_free_security(agent->security);
+	if (agent->lsm_nb_reg)
+		unregister_lsm_notifier(&agent->lsm_nb);
+}
+
+int ib_mad_enforce_security(struct ib_mad_agent_private *map, u16 pkey_index)
+{
+	int ret;
+
+	if (map->agent.qp->qp_type == IB_QPT_SMI && !map->agent.smp_allowed)
+		return -EACCES;
+
+	ret = ib_security_pkey_access(map->agent.device,
+				      map->agent.port_num,
+				      pkey_index,
+				      map->agent.security);
+
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
 #endif /* CONFIG_SECURITY_INFINIBAND */
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index d576efc..3936216 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -911,6 +911,11 @@
  *	@subnet_prefix the subnet prefix of the port being used.
  *	@pkey the pkey to be accessed.
  *	@sec pointer to a security structure.
+ * @ib_endport_manage_subnet:
+ *	Check permissions to send and receive SMPs on a end port.
+ *	@dev_name the IB device name (i.e. mlx4_0).
+ *	@port_num the port number.
+ *	@sec pointer to a security structure.
  * @ib_alloc_security:
  *	Allocate a security structure for Infiniband objects.
  *	@sec pointer to a security structure pointer.
@@ -1629,6 +1634,8 @@ union security_list_options {
 
 #ifdef CONFIG_SECURITY_INFINIBAND
 	int (*ib_pkey_access)(void *sec, u64 subnet_prefix, u16 pkey);
+	int (*ib_endport_manage_subnet)(void *sec, const char *dev_name,
+					u8 port_num);
 	int (*ib_alloc_security)(void **sec);
 	void (*ib_free_security)(void *sec);
 #endif	/* CONFIG_SECURITY_INFINIBAND */
@@ -1865,6 +1872,7 @@ struct security_hook_heads {
 #endif	/* CONFIG_SECURITY_NETWORK */
 #ifdef CONFIG_SECURITY_INFINIBAND
 	struct list_head ib_pkey_access;
+	struct list_head ib_endport_manage_subnet;
 	struct list_head ib_alloc_security;
 	struct list_head ib_free_security;
 #endif	/* CONFIG_SECURITY_INFINIBAND */
diff --git a/include/linux/security.h b/include/linux/security.h
index 0a5de0c..fbd4bc7 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -1419,6 +1419,7 @@ static inline int security_tun_dev_open(void *security)
 
 #ifdef CONFIG_SECURITY_INFINIBAND
 int security_ib_pkey_access(void *sec, u64 subnet_prefix, u16 pkey);
+int security_ib_endport_manage_subnet(void *sec, const char *name, u8 port_num);
 int security_ib_alloc_security(void **sec);
 void security_ib_free_security(void *sec);
 #else	/* CONFIG_SECURITY_INFINIBAND */
@@ -1427,6 +1428,11 @@ static inline int security_ib_pkey_access(void *sec, u64 subnet_prefix, u16 pkey
 	return 0;
 }
 
+static inline int security_ib_endport_manage_subnet(void *sec, const char *dev_name, u8 port_num)
+{
+	return 0;
+}
+
 static inline int security_ib_alloc_security(void **sec)
 {
 	return 0;
diff --git a/include/rdma/ib_mad.h b/include/rdma/ib_mad.h
index c8a773f..23c4a4e 100644
--- a/include/rdma/ib_mad.h
+++ b/include/rdma/ib_mad.h
@@ -537,6 +537,10 @@ struct ib_mad_agent {
 	u32			flags;
 	u8			port_num;
 	u8			rmpp_version;
+	void			*security;
+	bool			smp_allowed;
+	bool			lsm_nb_reg;
+	struct notifier_block   lsm_nb;
 };
 
 /**
diff --git a/security/security.c b/security/security.c
index 40326d4..e4fd2b6 100644
--- a/security/security.c
+++ b/security/security.c
@@ -1470,6 +1470,12 @@ int security_ib_pkey_access(void *sec, u64 subnet_prefix, u16 pkey)
 }
 EXPORT_SYMBOL(security_ib_pkey_access);
 
+int security_ib_endport_manage_subnet(void *sec, const char *dev_name, u8 port_num)
+{
+	return call_int_hook(ib_endport_manage_subnet, 0, sec, dev_name, port_num);
+}
+EXPORT_SYMBOL(security_ib_endport_manage_subnet);
+
 int security_ib_alloc_security(void **sec)
 {
 	return call_int_hook(ib_alloc_security, 0, sec);
@@ -1943,6 +1949,8 @@ struct security_hook_heads security_hook_heads = {
 
 #ifdef CONFIG_SECURITY_INFINIBAND
 	.ib_pkey_access = LIST_HEAD_INIT(security_hook_heads.ib_pkey_access),
+	.ib_endport_manage_subnet =
+		LIST_HEAD_INIT(security_hook_heads.ib_endport_manage_subnet),
 	.ib_alloc_security =
 		LIST_HEAD_INIT(security_hook_heads.ib_alloc_security),
 	.ib_free_security =
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH v6 5/9] selinux: Create policydb version for Infiniband support
  2016-11-23 14:17 ` Dan Jurgens
                   ` (2 preceding siblings ...)
  (?)
@ 2016-11-23 14:17 ` Dan Jurgens
       [not found]   ` <1479910651-43246-6-git-send-email-danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
  -1 siblings, 1 reply; 51+ messages in thread
From: Dan Jurgens @ 2016-11-23 14:17 UTC (permalink / raw)
  To: chrisw, paul, sds, eparis, dledford, sean.hefty, hal.rosenstock
  Cc: selinux, linux-security-module, linux-rdma, yevgenyp, Daniel Jurgens

From: Daniel Jurgens <danielj@mellanox.com>

Support for Infiniband requires the addition of two new object contexts,
one for infiniband PKeys and another IB Ports. Added handlers to read
and write the new ocontext types when reading or writing a binary policy
representation.

Signed-off-by: Daniel Jurgens <danielj@mellanox.com>
Reviewed-by: Eli Cohen <eli@mellanox.com>

---
v2:
- Shorten ib_end_port to ib_port. Paul Moore
- Added bounds checking to port number. Paul Moore
- Eliminated {} in OCON_PKEY case statement.  Yuval Shaia

v3:
- ib_port -> ib_endport. Paul Moore

v4:
- removed unneeded brackets in ocontext_read. Paul Moore
---
 security/selinux/include/security.h |   3 +-
 security/selinux/ss/policydb.c      | 129 +++++++++++++++++++++++++++++++-----
 security/selinux/ss/policydb.h      |  27 +++++---
 3 files changed, 135 insertions(+), 24 deletions(-)

diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index 308a286..6bb9b0a 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -36,10 +36,11 @@
 #define POLICYDB_VERSION_DEFAULT_TYPE	28
 #define POLICYDB_VERSION_CONSTRAINT_NAMES	29
 #define POLICYDB_VERSION_XPERMS_IOCTL	30
+#define POLICYDB_VERSION_INFINIBAND		31
 
 /* Range of policy versions we understand*/
 #define POLICYDB_VERSION_MIN   POLICYDB_VERSION_BASE
-#define POLICYDB_VERSION_MAX	POLICYDB_VERSION_XPERMS_IOCTL
+#define POLICYDB_VERSION_MAX   POLICYDB_VERSION_INFINIBAND
 
 /* Mask for just the mount related flags */
 #define SE_MNTMASK	0x0f
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index d719db4..24e16da 100644
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -17,6 +17,11 @@
  *
  *      Added support for the policy capability bitmap
  *
+ * Update: Mellanox Techonologies
+ *
+ *	Added Infiniband support
+ *
+ * Copyright (C) 2016 Mellanox Techonologies
  * Copyright (C) 2007 Hewlett-Packard Development Company, L.P.
  * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc.
  * Copyright (C) 2003 - 2004 Tresys Technology, LLC
@@ -76,81 +81,86 @@ static struct policydb_compat_info policydb_compat[] = {
 	{
 		.version	= POLICYDB_VERSION_BASE,
 		.sym_num	= SYM_NUM - 3,
-		.ocon_num	= OCON_NUM - 1,
+		.ocon_num	= OCON_NUM - 3,
 	},
 	{
 		.version	= POLICYDB_VERSION_BOOL,
 		.sym_num	= SYM_NUM - 2,
-		.ocon_num	= OCON_NUM - 1,
+		.ocon_num	= OCON_NUM - 3,
 	},
 	{
 		.version	= POLICYDB_VERSION_IPV6,
 		.sym_num	= SYM_NUM - 2,
-		.ocon_num	= OCON_NUM,
+		.ocon_num	= OCON_NUM - 2,
 	},
 	{
 		.version	= POLICYDB_VERSION_NLCLASS,
 		.sym_num	= SYM_NUM - 2,
-		.ocon_num	= OCON_NUM,
+		.ocon_num	= OCON_NUM - 2,
 	},
 	{
 		.version	= POLICYDB_VERSION_MLS,
 		.sym_num	= SYM_NUM,
-		.ocon_num	= OCON_NUM,
+		.ocon_num	= OCON_NUM - 2,
 	},
 	{
 		.version	= POLICYDB_VERSION_AVTAB,
 		.sym_num	= SYM_NUM,
-		.ocon_num	= OCON_NUM,
+		.ocon_num	= OCON_NUM - 2,
 	},
 	{
 		.version	= POLICYDB_VERSION_RANGETRANS,
 		.sym_num	= SYM_NUM,
-		.ocon_num	= OCON_NUM,
+		.ocon_num	= OCON_NUM - 2,
 	},
 	{
 		.version	= POLICYDB_VERSION_POLCAP,
 		.sym_num	= SYM_NUM,
-		.ocon_num	= OCON_NUM,
+		.ocon_num	= OCON_NUM - 2,
 	},
 	{
 		.version	= POLICYDB_VERSION_PERMISSIVE,
 		.sym_num	= SYM_NUM,
-		.ocon_num	= OCON_NUM,
+		.ocon_num	= OCON_NUM - 2,
 	},
 	{
 		.version	= POLICYDB_VERSION_BOUNDARY,
 		.sym_num	= SYM_NUM,
-		.ocon_num	= OCON_NUM,
+		.ocon_num	= OCON_NUM - 2,
 	},
 	{
 		.version	= POLICYDB_VERSION_FILENAME_TRANS,
 		.sym_num	= SYM_NUM,
-		.ocon_num	= OCON_NUM,
+		.ocon_num	= OCON_NUM - 2,
 	},
 	{
 		.version	= POLICYDB_VERSION_ROLETRANS,
 		.sym_num	= SYM_NUM,
-		.ocon_num	= OCON_NUM,
+		.ocon_num	= OCON_NUM - 2,
 	},
 	{
 		.version	= POLICYDB_VERSION_NEW_OBJECT_DEFAULTS,
 		.sym_num	= SYM_NUM,
-		.ocon_num	= OCON_NUM,
+		.ocon_num	= OCON_NUM - 2,
 	},
 	{
 		.version	= POLICYDB_VERSION_DEFAULT_TYPE,
 		.sym_num	= SYM_NUM,
-		.ocon_num	= OCON_NUM,
+		.ocon_num	= OCON_NUM - 2,
 	},
 	{
 		.version	= POLICYDB_VERSION_CONSTRAINT_NAMES,
 		.sym_num	= SYM_NUM,
-		.ocon_num	= OCON_NUM,
+		.ocon_num	= OCON_NUM - 2,
 	},
 	{
 		.version	= POLICYDB_VERSION_XPERMS_IOCTL,
 		.sym_num	= SYM_NUM,
+		.ocon_num	= OCON_NUM - 2,
+	},
+	{
+		.version	= POLICYDB_VERSION_INFINIBAND,
+		.sym_num	= SYM_NUM,
 		.ocon_num	= OCON_NUM,
 	},
 };
@@ -2222,6 +2232,60 @@ static int ocontext_read(struct policydb *p, struct policydb_compat_info *info,
 					goto out;
 				break;
 			}
+			case OCON_PKEY:
+				rc = next_entry(nodebuf, fp, sizeof(u32) * 6);
+				if (rc)
+					goto out;
+
+				c->u.pkey.subnet_prefix = be64_to_cpu(*((__be64 *)nodebuf));
+				/* The subnet prefix is stored as an IPv6
+				 * address in the policy.
+				 *
+				 * Check that the lower 2 DWORDS are 0.
+				 */
+				if (nodebuf[2] || nodebuf[3]) {
+					rc = -EINVAL;
+					goto out;
+				}
+
+				if (nodebuf[4] > 0xffff ||
+				    nodebuf[5] > 0xffff) {
+					rc = -EINVAL;
+					goto out;
+				}
+
+				c->u.pkey.low_pkey = le32_to_cpu(nodebuf[4]);
+				c->u.pkey.high_pkey = le32_to_cpu(nodebuf[5]);
+
+				rc = context_read_and_validate(&c->context[0],
+							       p,
+							       fp);
+				if (rc)
+					goto out;
+				break;
+			case OCON_IB_ENDPORT:
+				rc = next_entry(buf, fp, sizeof(u32) * 2);
+				if (rc)
+					goto out;
+				len = le32_to_cpu(buf[0]);
+
+				rc = str_read(&c->u.ib_endport.dev_name, GFP_KERNEL, fp, len);
+				if (rc)
+					goto out;
+
+				if (buf[1] > 0xff || buf[1] == 0) {
+					rc = -EINVAL;
+					goto out;
+				}
+
+				c->u.ib_endport.port_num = le32_to_cpu(buf[1]);
+
+				rc = context_read_and_validate(&c->context[0],
+							       p,
+							       fp);
+				if (rc)
+					goto out;
+				break;
 			}
 		}
 	}
@@ -3151,6 +3215,41 @@ static int ocontext_write(struct policydb *p, struct policydb_compat_info *info,
 				if (rc)
 					return rc;
 				break;
+			case OCON_PKEY:
+				*((__be64 *)nodebuf) = cpu_to_be64(c->u.pkey.subnet_prefix);
+
+				/*
+				 * The low order 2 bits were confirmed to be 0
+				 * when the policy was loaded. Write them out
+				 * as zero
+				 */
+				nodebuf[2] = 0;
+				nodebuf[3] = 0;
+
+				nodebuf[4] = cpu_to_le32(c->u.pkey.low_pkey);
+				nodebuf[5] = cpu_to_le32(c->u.pkey.high_pkey);
+
+				rc = put_entry(nodebuf, sizeof(u32), 6, fp);
+				if (rc)
+					return rc;
+				rc = context_write(p, &c->context[0], fp);
+				if (rc)
+					return rc;
+				break;
+			case OCON_IB_ENDPORT:
+				len = strlen(c->u.ib_endport.dev_name);
+				buf[0] = cpu_to_le32(len);
+				buf[1] = cpu_to_le32(c->u.ib_endport.port_num);
+				rc = put_entry(buf, sizeof(u32), 2, fp);
+				if (rc)
+					return rc;
+				rc = put_entry(c->u.ib_endport.dev_name, 1, len, fp);
+				if (rc)
+					return rc;
+				rc = context_write(p, &c->context[0], fp);
+				if (rc)
+					return rc;
+				break;
 			}
 		}
 	}
diff --git a/security/selinux/ss/policydb.h b/security/selinux/ss/policydb.h
index 725d594..edb329d 100644
--- a/security/selinux/ss/policydb.h
+++ b/security/selinux/ss/policydb.h
@@ -187,6 +187,15 @@ struct ocontext {
 			u32 addr[4];
 			u32 mask[4];
 		} node6;        /* IPv6 node information */
+		struct {
+			u64 subnet_prefix;
+			u16 low_pkey;
+			u16 high_pkey;
+		} pkey;
+		struct {
+			char *dev_name;
+			u8 port_num;
+		} ib_endport;
 	} u;
 	union {
 		u32 sclass;  /* security class for genfs */
@@ -215,14 +224,16 @@ struct genfs {
 #define SYM_NUM     8
 
 /* object context array indices */
-#define OCON_ISID  0	/* initial SIDs */
-#define OCON_FS    1	/* unlabeled file systems */
-#define OCON_PORT  2	/* TCP and UDP port numbers */
-#define OCON_NETIF 3	/* network interfaces */
-#define OCON_NODE  4	/* nodes */
-#define OCON_FSUSE 5	/* fs_use */
-#define OCON_NODE6 6	/* IPv6 nodes */
-#define OCON_NUM   7
+#define OCON_ISID	0 /* initial SIDs */
+#define OCON_FS		1 /* unlabeled file systems */
+#define OCON_PORT	2 /* TCP and UDP port numbers */
+#define OCON_NETIF	3 /* network interfaces */
+#define OCON_NODE	4 /* nodes */
+#define OCON_FSUSE	5 /* fs_use */
+#define OCON_NODE6	6 /* IPv6 nodes */
+#define OCON_PKEY	7 /* Infiniband PKeys */
+#define OCON_IB_ENDPORT	8 /* Infiniband end ports */
+#define OCON_NUM	9
 
 /* The policy database */
 struct policydb {
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH v6 6/9] selinux: Allocate and free infiniband security hooks
  2016-11-23 14:17 ` Dan Jurgens
                   ` (3 preceding siblings ...)
  (?)
@ 2016-11-23 14:17 ` Dan Jurgens
  -1 siblings, 0 replies; 51+ messages in thread
From: Dan Jurgens @ 2016-11-23 14:17 UTC (permalink / raw)
  To: chrisw, paul, sds, eparis, dledford, sean.hefty, hal.rosenstock
  Cc: selinux, linux-security-module, linux-rdma, yevgenyp, Daniel Jurgens

From: Daniel Jurgens <danielj@mellanox.com>

Implement and attach hooks to allocate and free Infiniband object
security structures.

Signed-off-by: Daniel Jurgens <danielj@mellanox.com>

---
v2:
- Use void * blobs for security structs.  Paul Moore
- Shorten ib_end_port to ib_port.  Paul Moore
- Allocate memory for security struct with GFP_KERNEL. Yuval Shaia
---
 security/selinux/hooks.c          | 25 ++++++++++++++++++++++++-
 security/selinux/include/objsec.h |  5 +++++
 2 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 2d7a7c1..d87e29d 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -17,6 +17,7 @@
  *	Paul Moore <paul@paul-moore.com>
  *  Copyright (C) 2007 Hitachi Software Engineering Co., Ltd.
  *		       Yuichi Nakamura <ynakam@hitachisoft.jp>
+ *  Copyright (C) 2016 Mellanox Technologies
  *
  *	This program is free software; you can redistribute it and/or modify
  *	it under the terms of the GNU General Public License version 2,
@@ -6082,7 +6083,26 @@ static int selinux_key_getsecurity(struct key *key, char **_buffer)
 	*_buffer = context;
 	return rc;
 }
+#endif
+
+#ifdef CONFIG_SECURITY_INFINIBAND
+static int selinux_ib_alloc_security(void **ib_sec)
+{
+	struct ib_security_struct *sec;
+
+	sec = kzalloc(sizeof(*sec), GFP_KERNEL);
+	if (!sec)
+		return -ENOMEM;
+	sec->sid = current_sid();
+
+	*ib_sec = sec;
+	return 0;
+}
 
+static void selinux_ib_free_security(void *ib_sec)
+{
+	kfree(ib_sec);
+}
 #endif
 
 static struct security_hook_list selinux_hooks[] = {
@@ -6269,7 +6289,10 @@ static struct security_hook_list selinux_hooks[] = {
 	LSM_HOOK_INIT(tun_dev_attach_queue, selinux_tun_dev_attach_queue),
 	LSM_HOOK_INIT(tun_dev_attach, selinux_tun_dev_attach),
 	LSM_HOOK_INIT(tun_dev_open, selinux_tun_dev_open),
-
+#ifdef CONFIG_SECURITY_INFINIBAND
+	LSM_HOOK_INIT(ib_alloc_security, selinux_ib_alloc_security),
+	LSM_HOOK_INIT(ib_free_security, selinux_ib_free_security),
+#endif
 #ifdef CONFIG_SECURITY_NETWORK_XFRM
 	LSM_HOOK_INIT(xfrm_policy_alloc_security, selinux_xfrm_policy_alloc),
 	LSM_HOOK_INIT(xfrm_policy_clone_security, selinux_xfrm_policy_clone),
diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h
index c21e135..8e7db43 100644
--- a/security/selinux/include/objsec.h
+++ b/security/selinux/include/objsec.h
@@ -10,6 +10,7 @@
  *
  *  Copyright (C) 2001,2002 Networks Associates Technology, Inc.
  *  Copyright (C) 2003 Red Hat, Inc., James Morris <jmorris@redhat.com>
+ *  Copyright (C) 2016 Mellanox Technologies
  *
  *	This program is free software; you can redistribute it and/or modify
  *	it under the terms of the GNU General Public License version 2,
@@ -128,6 +129,10 @@ struct key_security_struct {
 	u32 sid;	/* SID of key */
 };
 
+struct ib_security_struct {
+	u32 sid;        /* SID of the queue pair or MAD agent */
+};
+
 extern unsigned int selinux_checkreqprot;
 
 #endif /* _SELINUX_OBJSEC_H_ */
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH v6 7/9] selinux: Implement Infiniband PKey "Access" access vector
  2016-11-23 14:17 ` Dan Jurgens
@ 2016-11-23 14:17     ` Dan Jurgens
  -1 siblings, 0 replies; 51+ messages in thread
From: Dan Jurgens @ 2016-11-23 14:17 UTC (permalink / raw)
  To: chrisw-69jw2NvuJkxg9hUCZPvPmw, paul-r2n+y4ga6xFZroRs9YW3xA,
	sds-+05T5uksL2qpZYMLLGbcSA, eparis-FjpueFixGhCM4zKIHC2jIg,
	dledford-H+wXaHxf7aLQT0dZR+AlfA,
	sean.hefty-ral2JQCrhuEAvxtiuMwx3w,
	hal.rosenstock-Re5JQEeQqe8AvxtiuMwx3w
  Cc: selinux-+05T5uksL2qpZYMLLGbcSA,
	linux-security-module-u79uwXL29TY76Z2rM5mHXA,
	linux-rdma-u79uwXL29TY76Z2rM5mHXA,
	yevgenyp-VPRAkNaXOzVWk0Htik3J/w, Daniel Jurgens

From: Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>

Add a type and access vector for PKeys. Implement the ib_pkey_access
hook to check that the caller has permission to access the PKey on the
given subnet prefix. Add an interface to get the PKey SID. Walk the PKey
ocontexts to find an entry for the given subnet prefix and pkey.

Signed-off-by: Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>

---
v2:
- Use void* blobs for security structs. Paul Moore
- Add pkey specific data to the audit log. Paul Moore
- Don't introduce a new initial sid, use unlabeled. Stephen Smalley

v3:
- Reorder parameters to pkey_access hook. Paul Moore

v6:
- Remove blank lines and brackets on single statement else. James Morris
---
 include/linux/lsm_audit.h           |  7 +++++++
 security/lsm_audit.c                | 11 ++++++++++
 security/selinux/hooks.c            | 22 ++++++++++++++++++++
 security/selinux/include/classmap.h |  2 ++
 security/selinux/include/security.h |  2 ++
 security/selinux/ss/services.c      | 40 +++++++++++++++++++++++++++++++++++++
 6 files changed, 84 insertions(+)

diff --git a/include/linux/lsm_audit.h b/include/linux/lsm_audit.h
index e58e577..402b770 100644
--- a/include/linux/lsm_audit.h
+++ b/include/linux/lsm_audit.h
@@ -45,6 +45,11 @@ struct lsm_ioctlop_audit {
 	u16 cmd;
 };
 
+struct lsm_pkey_audit {
+	u64	subnet_prefix;
+	u16	pkey;
+};
+
 /* Auxiliary data to use in generating the audit record. */
 struct common_audit_data {
 	char type;
@@ -60,6 +65,7 @@ struct common_audit_data {
 #define LSM_AUDIT_DATA_DENTRY	10
 #define LSM_AUDIT_DATA_IOCTL_OP	11
 #define LSM_AUDIT_DATA_FILE	12
+#define LSM_AUDIT_DATA_PKEY	13
 	union 	{
 		struct path path;
 		struct dentry *dentry;
@@ -77,6 +83,7 @@ struct common_audit_data {
 		char *kmod_name;
 		struct lsm_ioctlop_audit *op;
 		struct file *file;
+		struct lsm_pkey_audit *pkey;
 	} u;
 	/* this union contains LSM specific data */
 	union {
diff --git a/security/lsm_audit.c b/security/lsm_audit.c
index 37f04da..8911360 100644
--- a/security/lsm_audit.c
+++ b/security/lsm_audit.c
@@ -410,6 +410,17 @@ static void dump_common_audit_data(struct audit_buffer *ab,
 		audit_log_format(ab, " kmod=");
 		audit_log_untrustedstring(ab, a->u.kmod_name);
 		break;
+	case LSM_AUDIT_DATA_PKEY: {
+		struct in6_addr sbn_pfx;
+
+		memset(&sbn_pfx.s6_addr, 0,
+		       sizeof(sbn_pfx.s6_addr));
+		memcpy(&sbn_pfx.s6_addr, &a->u.pkey->subnet_prefix,
+		       sizeof(a->u.pkey->subnet_prefix));
+		audit_log_format(ab, " pkey=0x%x subnet_prefix=%pI6c",
+				 a->u.pkey->pkey, &sbn_pfx);
+		break;
+	}
 	} /* switch (a->type) */
 }
 
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index d87e29d..94eef1b 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -6086,6 +6086,27 @@ static int selinux_key_getsecurity(struct key *key, char **_buffer)
 #endif
 
 #ifdef CONFIG_SECURITY_INFINIBAND
+static int selinux_ib_pkey_access(void *ib_sec, u64 subnet_prefix, u16 pkey_val)
+{
+	struct common_audit_data ad;
+	int err;
+	u32 sid = 0;
+	struct ib_security_struct *sec = ib_sec;
+	struct lsm_pkey_audit pkey;
+
+	err = security_pkey_sid(subnet_prefix, pkey_val, &sid);
+	if (err)
+		return err;
+
+	ad.type = LSM_AUDIT_DATA_PKEY;
+	pkey.subnet_prefix = subnet_prefix;
+	pkey.pkey = pkey_val;
+	ad.u.pkey = &pkey;
+	return avc_has_perm(sec->sid, sid,
+			    SECCLASS_INFINIBAND_PKEY,
+			    INFINIBAND_PKEY__ACCESS, &ad);
+}
+
 static int selinux_ib_alloc_security(void **ib_sec)
 {
 	struct ib_security_struct *sec;
@@ -6290,6 +6311,7 @@ static struct security_hook_list selinux_hooks[] = {
 	LSM_HOOK_INIT(tun_dev_attach, selinux_tun_dev_attach),
 	LSM_HOOK_INIT(tun_dev_open, selinux_tun_dev_open),
 #ifdef CONFIG_SECURITY_INFINIBAND
+	LSM_HOOK_INIT(ib_pkey_access, selinux_ib_pkey_access),
 	LSM_HOOK_INIT(ib_alloc_security, selinux_ib_alloc_security),
 	LSM_HOOK_INIT(ib_free_security, selinux_ib_free_security),
 #endif
diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h
index 1f1f4b2..d42dd4d 100644
--- a/security/selinux/include/classmap.h
+++ b/security/selinux/include/classmap.h
@@ -165,5 +165,7 @@ struct security_class_mapping secclass_map[] = {
 	  { COMMON_CAP_PERMS, NULL } },
 	{ "cap2_userns",
 	  { COMMON_CAP2_PERMS, NULL } },
+	{ "infiniband_pkey",
+	  { "access", NULL } },
 	{ NULL }
   };
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index 6bb9b0a..17afb7c 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -176,6 +176,8 @@ int security_get_user_sids(u32 callsid, char *username,
 
 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_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 082b20c..9215cf6 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -2203,6 +2203,46 @@ int security_port_sid(u8 protocol, u16 port, u32 *out_sid)
 }
 
 /**
+ * security_pkey_sid - Obtain the SID for a pkey.
+ * @subnet_prefix: Subnet Prefix
+ * @pkey_num: pkey number
+ * @out_sid: security identifier
+ */
+int security_pkey_sid(u64 subnet_prefix, u16 pkey_num, u32 *out_sid)
+{
+	struct ocontext *c;
+	int rc = 0;
+
+	read_lock(&policy_rwlock);
+
+	c = policydb.ocontexts[OCON_PKEY];
+	while (c) {
+		if (c->u.pkey.low_pkey <= pkey_num &&
+		    c->u.pkey.high_pkey >= pkey_num &&
+		    c->u.pkey.subnet_prefix == subnet_prefix)
+			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_UNLABELED;
+
+out:
+	read_unlock(&policy_rwlock);
+	return rc;
+}
+
+/**
  * security_netif_sid - Obtain the SID for a network interface.
  * @name: interface name
  * @if_sid: interface SID
-- 
2.7.4

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH v6 7/9] selinux: Implement Infiniband PKey "Access" access vector
@ 2016-11-23 14:17     ` Dan Jurgens
  0 siblings, 0 replies; 51+ messages in thread
From: Dan Jurgens @ 2016-11-23 14:17 UTC (permalink / raw)
  To: chrisw, paul, sds, eparis, dledford, sean.hefty, hal.rosenstock
  Cc: selinux, linux-security-module, linux-rdma, yevgenyp, Daniel Jurgens

From: Daniel Jurgens <danielj@mellanox.com>

Add a type and access vector for PKeys. Implement the ib_pkey_access
hook to check that the caller has permission to access the PKey on the
given subnet prefix. Add an interface to get the PKey SID. Walk the PKey
ocontexts to find an entry for the given subnet prefix and pkey.

Signed-off-by: Daniel Jurgens <danielj@mellanox.com>

---
v2:
- Use void* blobs for security structs. Paul Moore
- Add pkey specific data to the audit log. Paul Moore
- Don't introduce a new initial sid, use unlabeled. Stephen Smalley

v3:
- Reorder parameters to pkey_access hook. Paul Moore

v6:
- Remove blank lines and brackets on single statement else. James Morris
---
 include/linux/lsm_audit.h           |  7 +++++++
 security/lsm_audit.c                | 11 ++++++++++
 security/selinux/hooks.c            | 22 ++++++++++++++++++++
 security/selinux/include/classmap.h |  2 ++
 security/selinux/include/security.h |  2 ++
 security/selinux/ss/services.c      | 40 +++++++++++++++++++++++++++++++++++++
 6 files changed, 84 insertions(+)

diff --git a/include/linux/lsm_audit.h b/include/linux/lsm_audit.h
index e58e577..402b770 100644
--- a/include/linux/lsm_audit.h
+++ b/include/linux/lsm_audit.h
@@ -45,6 +45,11 @@ struct lsm_ioctlop_audit {
 	u16 cmd;
 };
 
+struct lsm_pkey_audit {
+	u64	subnet_prefix;
+	u16	pkey;
+};
+
 /* Auxiliary data to use in generating the audit record. */
 struct common_audit_data {
 	char type;
@@ -60,6 +65,7 @@ struct common_audit_data {
 #define LSM_AUDIT_DATA_DENTRY	10
 #define LSM_AUDIT_DATA_IOCTL_OP	11
 #define LSM_AUDIT_DATA_FILE	12
+#define LSM_AUDIT_DATA_PKEY	13
 	union 	{
 		struct path path;
 		struct dentry *dentry;
@@ -77,6 +83,7 @@ struct common_audit_data {
 		char *kmod_name;
 		struct lsm_ioctlop_audit *op;
 		struct file *file;
+		struct lsm_pkey_audit *pkey;
 	} u;
 	/* this union contains LSM specific data */
 	union {
diff --git a/security/lsm_audit.c b/security/lsm_audit.c
index 37f04da..8911360 100644
--- a/security/lsm_audit.c
+++ b/security/lsm_audit.c
@@ -410,6 +410,17 @@ static void dump_common_audit_data(struct audit_buffer *ab,
 		audit_log_format(ab, " kmod=");
 		audit_log_untrustedstring(ab, a->u.kmod_name);
 		break;
+	case LSM_AUDIT_DATA_PKEY: {
+		struct in6_addr sbn_pfx;
+
+		memset(&sbn_pfx.s6_addr, 0,
+		       sizeof(sbn_pfx.s6_addr));
+		memcpy(&sbn_pfx.s6_addr, &a->u.pkey->subnet_prefix,
+		       sizeof(a->u.pkey->subnet_prefix));
+		audit_log_format(ab, " pkey=0x%x subnet_prefix=%pI6c",
+				 a->u.pkey->pkey, &sbn_pfx);
+		break;
+	}
 	} /* switch (a->type) */
 }
 
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index d87e29d..94eef1b 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -6086,6 +6086,27 @@ static int selinux_key_getsecurity(struct key *key, char **_buffer)
 #endif
 
 #ifdef CONFIG_SECURITY_INFINIBAND
+static int selinux_ib_pkey_access(void *ib_sec, u64 subnet_prefix, u16 pkey_val)
+{
+	struct common_audit_data ad;
+	int err;
+	u32 sid = 0;
+	struct ib_security_struct *sec = ib_sec;
+	struct lsm_pkey_audit pkey;
+
+	err = security_pkey_sid(subnet_prefix, pkey_val, &sid);
+	if (err)
+		return err;
+
+	ad.type = LSM_AUDIT_DATA_PKEY;
+	pkey.subnet_prefix = subnet_prefix;
+	pkey.pkey = pkey_val;
+	ad.u.pkey = &pkey;
+	return avc_has_perm(sec->sid, sid,
+			    SECCLASS_INFINIBAND_PKEY,
+			    INFINIBAND_PKEY__ACCESS, &ad);
+}
+
 static int selinux_ib_alloc_security(void **ib_sec)
 {
 	struct ib_security_struct *sec;
@@ -6290,6 +6311,7 @@ static struct security_hook_list selinux_hooks[] = {
 	LSM_HOOK_INIT(tun_dev_attach, selinux_tun_dev_attach),
 	LSM_HOOK_INIT(tun_dev_open, selinux_tun_dev_open),
 #ifdef CONFIG_SECURITY_INFINIBAND
+	LSM_HOOK_INIT(ib_pkey_access, selinux_ib_pkey_access),
 	LSM_HOOK_INIT(ib_alloc_security, selinux_ib_alloc_security),
 	LSM_HOOK_INIT(ib_free_security, selinux_ib_free_security),
 #endif
diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h
index 1f1f4b2..d42dd4d 100644
--- a/security/selinux/include/classmap.h
+++ b/security/selinux/include/classmap.h
@@ -165,5 +165,7 @@ struct security_class_mapping secclass_map[] = {
 	  { COMMON_CAP_PERMS, NULL } },
 	{ "cap2_userns",
 	  { COMMON_CAP2_PERMS, NULL } },
+	{ "infiniband_pkey",
+	  { "access", NULL } },
 	{ NULL }
   };
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index 6bb9b0a..17afb7c 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -176,6 +176,8 @@ int security_get_user_sids(u32 callsid, char *username,
 
 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_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 082b20c..9215cf6 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -2203,6 +2203,46 @@ int security_port_sid(u8 protocol, u16 port, u32 *out_sid)
 }
 
 /**
+ * security_pkey_sid - Obtain the SID for a pkey.
+ * @subnet_prefix: Subnet Prefix
+ * @pkey_num: pkey number
+ * @out_sid: security identifier
+ */
+int security_pkey_sid(u64 subnet_prefix, u16 pkey_num, u32 *out_sid)
+{
+	struct ocontext *c;
+	int rc = 0;
+
+	read_lock(&policy_rwlock);
+
+	c = policydb.ocontexts[OCON_PKEY];
+	while (c) {
+		if (c->u.pkey.low_pkey <= pkey_num &&
+		    c->u.pkey.high_pkey >= pkey_num &&
+		    c->u.pkey.subnet_prefix == subnet_prefix)
+			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_UNLABELED;
+
+out:
+	read_unlock(&policy_rwlock);
+	return rc;
+}
+
+/**
  * security_netif_sid - Obtain the SID for a network interface.
  * @name: interface name
  * @if_sid: interface SID
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH v6 8/9] selinux: Add IB Port SMP access vector
  2016-11-23 14:17 ` Dan Jurgens
                   ` (4 preceding siblings ...)
  (?)
@ 2016-11-23 14:17 ` Dan Jurgens
  -1 siblings, 0 replies; 51+ messages in thread
From: Dan Jurgens @ 2016-11-23 14:17 UTC (permalink / raw)
  To: chrisw, paul, sds, eparis, dledford, sean.hefty, hal.rosenstock
  Cc: selinux, linux-security-module, linux-rdma, yevgenyp, Daniel Jurgens

From: Daniel Jurgens <danielj@mellanox.com>

Add a type for Infiniband ports and an access vector for subnet
management packets. Implement the ib_port_smp hook to check that the
caller has permission to send and receive SMPs on the end port specified
by the device name and port. Add interface to query the SID for a IB
port, which walks the IB_PORT ocontexts to find an entry for the
given name and port.

Signed-off-by: Daniel Jurgens <danielj@mellanox.com>

---
v2:
- Shorted ib_end_port. Paul Moore
- Pass void blobs to security hooks. Paul Moore
- Log specific IB port info in audit log. Paul Moore
- Don't create a new intial sid, use unlabeled. Stephen Smalley
- Changed "smp" to "manage_subnet". Paul Moore

v3:
- ib_port -> ib_endport. Paul Moore
- Don't log device name as untrusted string. Paul Moore
- Reorder parameters of LSM hook. Paul Moore

v6:
- Remove brakets around single statement else. James Morris
---
 include/linux/lsm_audit.h           |  8 ++++++++
 security/lsm_audit.c                |  5 +++++
 security/selinux/hooks.c            | 25 ++++++++++++++++++++++
 security/selinux/include/classmap.h |  2 ++
 security/selinux/include/security.h |  2 ++
 security/selinux/ss/services.c      | 41 +++++++++++++++++++++++++++++++++++++
 6 files changed, 83 insertions(+)

diff --git a/include/linux/lsm_audit.h b/include/linux/lsm_audit.h
index 402b770..7047b4c 100644
--- a/include/linux/lsm_audit.h
+++ b/include/linux/lsm_audit.h
@@ -21,6 +21,7 @@
 #include <linux/path.h>
 #include <linux/key.h>
 #include <linux/skbuff.h>
+#include <rdma/ib_verbs.h>
 
 struct lsm_network_audit {
 	int netif;
@@ -50,6 +51,11 @@ struct lsm_pkey_audit {
 	u16	pkey;
 };
 
+struct lsm_ib_endport_audit {
+	char	dev_name[IB_DEVICE_NAME_MAX];
+	u8	port_num;
+};
+
 /* Auxiliary data to use in generating the audit record. */
 struct common_audit_data {
 	char type;
@@ -66,6 +72,7 @@ struct common_audit_data {
 #define LSM_AUDIT_DATA_IOCTL_OP	11
 #define LSM_AUDIT_DATA_FILE	12
 #define LSM_AUDIT_DATA_PKEY	13
+#define LSM_AUDIT_DATA_IB_ENDPORT 14
 	union 	{
 		struct path path;
 		struct dentry *dentry;
@@ -84,6 +91,7 @@ struct common_audit_data {
 		struct lsm_ioctlop_audit *op;
 		struct file *file;
 		struct lsm_pkey_audit *pkey;
+		struct lsm_ib_endport_audit *ib_endport;
 	} u;
 	/* this union contains LSM specific data */
 	union {
diff --git a/security/lsm_audit.c b/security/lsm_audit.c
index 8911360..d8d58ec 100644
--- a/security/lsm_audit.c
+++ b/security/lsm_audit.c
@@ -421,6 +421,11 @@ static void dump_common_audit_data(struct audit_buffer *ab,
 				 a->u.pkey->pkey, &sbn_pfx);
 		break;
 	}
+	case LSM_AUDIT_DATA_IB_ENDPORT:
+		audit_log_format(ab, " device=%s port_num=%u",
+				 a->u.ib_endport->dev_name,
+				 a->u.ib_endport->port_num);
+		break;
 	} /* switch (a->type) */
 }
 
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 94eef1b..55b18b3 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -6107,6 +6107,29 @@ static int selinux_ib_pkey_access(void *ib_sec, u64 subnet_prefix, u16 pkey_val)
 			    INFINIBAND_PKEY__ACCESS, &ad);
 }
 
+static int selinux_ib_endport_manage_subnet(void *ib_sec, const char *dev_name,
+					    u8 port_num)
+{
+	struct common_audit_data ad;
+	int err;
+	u32 sid = 0;
+	struct ib_security_struct *sec = ib_sec;
+	struct lsm_ib_endport_audit ib_endport;
+
+	err = security_ib_endport_sid(dev_name, port_num, &sid);
+
+	if (err)
+		return err;
+
+	ad.type = LSM_AUDIT_DATA_IB_ENDPORT;
+	strncpy(ib_endport.dev_name, dev_name, sizeof(ib_endport.dev_name));
+	ib_endport.port_num = port_num;
+	ad.u.ib_endport = &ib_endport;
+	return avc_has_perm(sec->sid, sid,
+			    SECCLASS_INFINIBAND_ENDPORT,
+			    INFINIBAND_ENDPORT__MANAGE_SUBNET, &ad);
+}
+
 static int selinux_ib_alloc_security(void **ib_sec)
 {
 	struct ib_security_struct *sec;
@@ -6312,6 +6335,8 @@ static struct security_hook_list selinux_hooks[] = {
 	LSM_HOOK_INIT(tun_dev_open, selinux_tun_dev_open),
 #ifdef CONFIG_SECURITY_INFINIBAND
 	LSM_HOOK_INIT(ib_pkey_access, selinux_ib_pkey_access),
+	LSM_HOOK_INIT(ib_endport_manage_subnet,
+		      selinux_ib_endport_manage_subnet),
 	LSM_HOOK_INIT(ib_alloc_security, selinux_ib_alloc_security),
 	LSM_HOOK_INIT(ib_free_security, selinux_ib_free_security),
 #endif
diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h
index d42dd4d..f93b64b 100644
--- a/security/selinux/include/classmap.h
+++ b/security/selinux/include/classmap.h
@@ -167,5 +167,7 @@ struct security_class_mapping secclass_map[] = {
 	  { COMMON_CAP2_PERMS, NULL } },
 	{ "infiniband_pkey",
 	  { "access", NULL } },
+	{ "infiniband_endport",
+	  { "manage_subnet", NULL } },
 	{ NULL }
   };
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index 17afb7c..8a6e5e7 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -178,6 +178,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_ib_endport_sid(const char *dev_name, u8 port_num, 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 9215cf6..2e54285 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -2243,6 +2243,47 @@ int security_pkey_sid(u64 subnet_prefix, u16 pkey_num, u32 *out_sid)
 }
 
 /**
+ * security_ib_endport_sid - Obtain the SID for a subnet management interface.
+ * @dev_name: device name
+ * @port: port number
+ * @out_sid: security identifier
+ */
+int security_ib_endport_sid(const char *dev_name, u8 port_num, u32 *out_sid)
+{
+	struct ocontext *c;
+	int rc = 0;
+
+	read_lock(&policy_rwlock);
+
+	c = policydb.ocontexts[OCON_IB_ENDPORT];
+	while (c) {
+		if (c->u.ib_endport.port_num == port_num &&
+		    !strncmp(c->u.ib_endport.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_UNLABELED;
+
+out:
+	read_unlock(&policy_rwlock);
+	return rc;
+}
+
+/**
  * security_netif_sid - Obtain the SID for a network interface.
  * @name: interface name
  * @if_sid: interface SID
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH v6 9/9] selinux: Add a cache for quicker retreival of PKey SIDs
  2016-11-23 14:17 ` Dan Jurgens
                   ` (5 preceding siblings ...)
  (?)
@ 2016-11-23 14:17 ` Dan Jurgens
  -1 siblings, 0 replies; 51+ messages in thread
From: Dan Jurgens @ 2016-11-23 14:17 UTC (permalink / raw)
  To: chrisw, paul, sds, eparis, dledford, sean.hefty, hal.rosenstock
  Cc: selinux, linux-security-module, linux-rdma, yevgenyp, Daniel Jurgens

From: Daniel Jurgens <danielj@mellanox.com>

It is likely that the SID for the same PKey will be requested many
times. To reduce the time to modify QPs and process MADs use a cache to
store PKey SIDs.

This code is heavily based on the "netif" and "netport" concept
originally developed by James Morris <jmorris@redhat.com> and Paul Moore
<paul@paul-moore.com> (see security/selinux/netif.c and
security/selinux/netport.c for more information)

Signed-off-by: Daniel Jurgens <danielj@mellanox.com>

---
v2:
- Renamed the files to ibpkey. Paul Moore
- Fixed a bracket indentation mismatch in sel_pkey_find. Yuval Shaia
- Change spin_lock_bh to spin_lock_irqsave to resolve HARDIRQ lockdep
  warning.  Dan Jurgens

v6:
- Fixed sel_pkey_sid_slow error handling. James Morris
---
 security/selinux/Makefile         |   2 +-
 security/selinux/hooks.c          |   7 +-
 security/selinux/ibpkey.c         | 245 ++++++++++++++++++++++++++++++++++++++
 security/selinux/include/ibpkey.h |  31 +++++
 security/selinux/include/objsec.h |   6 +
 5 files changed, 288 insertions(+), 3 deletions(-)
 create mode 100644 security/selinux/ibpkey.c
 create mode 100644 security/selinux/include/ibpkey.h

diff --git a/security/selinux/Makefile b/security/selinux/Makefile
index 3411c33..ff5895e 100644
--- a/security/selinux/Makefile
+++ b/security/selinux/Makefile
@@ -5,7 +5,7 @@
 obj-$(CONFIG_SECURITY_SELINUX) := selinux.o
 
 selinux-y := avc.o hooks.o selinuxfs.o netlink.o nlmsgtab.o netif.o \
-	     netnode.o netport.o exports.o \
+	     netnode.o netport.o ibpkey.o exports.o \
 	     ss/ebitmap.o ss/hashtab.o ss/symtab.o ss/sidtab.o ss/avtab.o \
 	     ss/policydb.o ss/services.o ss/conditional.o ss/mls.o ss/status.o
 
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 55b18b3..7ee9854 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -90,6 +90,7 @@
 #include "netif.h"
 #include "netnode.h"
 #include "netport.h"
+#include "ibpkey.h"
 #include "xfrm.h"
 #include "netlabel.h"
 #include "audit.h"
@@ -173,8 +174,10 @@ static int selinux_netcache_avc_callback(u32 event)
 
 static int selinux_lsm_notifier_avc_callback(u32 event)
 {
-	if (event == AVC_CALLBACK_RESET)
+	if (event == AVC_CALLBACK_RESET) {
+		sel_pkey_flush();
 		call_lsm_notifier(LSM_POLICY_CHANGE, NULL);
+	}
 
 	return 0;
 }
@@ -6094,7 +6097,7 @@ static int selinux_ib_pkey_access(void *ib_sec, u64 subnet_prefix, u16 pkey_val)
 	struct ib_security_struct *sec = ib_sec;
 	struct lsm_pkey_audit pkey;
 
-	err = security_pkey_sid(subnet_prefix, pkey_val, &sid);
+	err = sel_pkey_sid(subnet_prefix, pkey_val, &sid);
 	if (err)
 		return err;
 
diff --git a/security/selinux/ibpkey.c b/security/selinux/ibpkey.c
new file mode 100644
index 0000000..2ce12bb
--- /dev/null
+++ b/security/selinux/ibpkey.c
@@ -0,0 +1,245 @@
+/*
+ * Pkey table
+ *
+ * SELinux must keep a mapping of Infinband PKEYs to labels/SIDs.  This
+ * mapping is maintained as part of the normal policy but a fast cache is
+ * needed to reduce the lookup overhead.
+ *
+ * This code is heavily based on the "netif" and "netport" concept originally
+ * developed by
+ * James Morris <jmorris@redhat.com> and
+ * Paul Moore <paul@paul-moore.com>
+ *   (see security/selinux/netif.c and security/selinux/netport.c for more
+ *   information)
+ *
+ */
+
+/*
+ * (c) Mellanox Technologies, 2016
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/types.h>
+#include <linux/rcupdate.h>
+#include <linux/list.h>
+#include <linux/spinlock.h>
+
+#include "ibpkey.h"
+#include "objsec.h"
+
+#define SEL_PKEY_HASH_SIZE       256
+#define SEL_PKEY_HASH_BKT_LIMIT   16
+
+struct sel_pkey_bkt {
+	int size;
+	struct list_head list;
+};
+
+struct sel_pkey {
+	struct pkey_security_struct psec;
+	struct list_head list;
+	struct rcu_head rcu;
+};
+
+static LIST_HEAD(sel_pkey_list);
+static DEFINE_SPINLOCK(sel_pkey_lock);
+static struct sel_pkey_bkt sel_pkey_hash[SEL_PKEY_HASH_SIZE];
+
+/**
+ * sel_pkey_hashfn - Hashing function for the pkey table
+ * @pkey: pkey number
+ *
+ * Description:
+ * This is the hashing function for the pkey table, it returns the bucket
+ * number for the given pkey.
+ *
+ */
+static unsigned int sel_pkey_hashfn(u16 pkey)
+{
+	return (pkey & (SEL_PKEY_HASH_SIZE - 1));
+}
+
+/**
+ * sel_pkey_find - Search for a pkey record
+ * @subnet_prefix: subnet_prefix
+ * @pkey_num: pkey_num
+ *
+ * Description:
+ * Search the pkey table and return the matching record.  If an entry
+ * can not be found in the table return NULL.
+ *
+ */
+static struct sel_pkey *sel_pkey_find(u64 subnet_prefix, u16 pkey_num)
+{
+	unsigned int idx;
+	struct sel_pkey *pkey;
+
+	idx = sel_pkey_hashfn(pkey_num);
+	list_for_each_entry_rcu(pkey, &sel_pkey_hash[idx].list, list) {
+		if (pkey->psec.pkey == pkey_num &&
+		    pkey->psec.subnet_prefix == subnet_prefix)
+			return pkey;
+	}
+
+	return NULL;
+}
+
+/**
+ * sel_pkey_insert - Insert a new pkey into the table
+ * @pkey: the new pkey record
+ *
+ * Description:
+ * Add a new pkey record to the hash table.
+ *
+ */
+static void sel_pkey_insert(struct sel_pkey *pkey)
+{
+	unsigned int idx;
+
+	/* we need to impose a limit on the growth of the hash table so check
+	 * this bucket to make sure it is within the specified bounds
+	 */
+	idx = sel_pkey_hashfn(pkey->psec.pkey);
+	list_add_rcu(&pkey->list, &sel_pkey_hash[idx].list);
+	if (sel_pkey_hash[idx].size == SEL_PKEY_HASH_BKT_LIMIT) {
+		struct sel_pkey *tail;
+
+		tail = list_entry(
+			rcu_dereference_protected(
+				sel_pkey_hash[idx].list.prev,
+				lockdep_is_held(&sel_pkey_lock)),
+			struct sel_pkey, list);
+		list_del_rcu(&tail->list);
+		kfree_rcu(tail, rcu);
+	} else {
+		sel_pkey_hash[idx].size++;
+	}
+}
+
+/**
+ * sel_pkey_sid_slow - Lookup the SID of a pkey using the policy
+ * @subnet_prefix: subnet prefix
+ * @pkey_num: pkey number
+ * @sid: pkey SID
+ *
+ * Description:
+ * This function determines the SID of a pkey by querying the security
+ * policy.  The result is added to the pkey table to speedup future
+ * queries.  Returns zero on success, negative values on failure.
+ *
+ */
+static int sel_pkey_sid_slow(u64 subnet_prefix, u16 pkey_num, u32 *sid)
+{
+	int ret;
+	struct sel_pkey *pkey;
+	struct sel_pkey *new = NULL;
+	unsigned long flags;
+
+	spin_lock_irqsave(&sel_pkey_lock, flags);
+	pkey = sel_pkey_find(subnet_prefix, pkey_num);
+	if (pkey) {
+		*sid = pkey->psec.sid;
+		spin_unlock_irqrestore(&sel_pkey_lock, flags);
+		return 0;
+	}
+
+	ret = security_pkey_sid(subnet_prefix, pkey_num, sid);
+	if (ret)
+		goto out;
+
+	/* If this memory allocation fails still return 0. The SID
+	 * is valid, it just won't be added to the cache.
+	 */
+	new = kzalloc(sizeof(*new), GFP_ATOMIC);
+	if (!new)
+		goto out;
+
+	new->psec.subnet_prefix = subnet_prefix;
+	new->psec.pkey = pkey_num;
+	new->psec.sid = *sid;
+	sel_pkey_insert(new);
+
+out:
+	spin_unlock_irqrestore(&sel_pkey_lock, flags);
+	return ret;
+}
+
+/**
+ * sel_pkey_sid - Lookup the SID of a PKEY
+ * @subnet_prefix: subnet_prefix
+ * @pkey_num: pkey number
+ * @sid: pkey SID
+ *
+ * Description:
+ * This function determines the SID of a PKEY using the fastest method
+ * possible.  First the pkey table is queried, but if an entry can't be found
+ * then the policy is queried and the result is added to the table to speedup
+ * future queries.  Returns zero on success, negative values on failure.
+ *
+ */
+int sel_pkey_sid(u64 subnet_prefix, u16 pkey_num, u32 *sid)
+{
+	struct sel_pkey *pkey;
+
+	rcu_read_lock();
+	pkey = sel_pkey_find(subnet_prefix, pkey_num);
+	if (pkey) {
+		*sid = pkey->psec.sid;
+		rcu_read_unlock();
+		return 0;
+	}
+	rcu_read_unlock();
+
+	return sel_pkey_sid_slow(subnet_prefix, pkey_num, sid);
+}
+
+/**
+ * sel_pkey_flush - Flush the entire pkey table
+ *
+ * Description:
+ * Remove all entries from the pkey table
+ *
+ */
+void sel_pkey_flush(void)
+{
+	unsigned int idx;
+	struct sel_pkey *pkey, *pkey_tmp;
+	unsigned long flags;
+
+	spin_lock_irqsave(&sel_pkey_lock, flags);
+	for (idx = 0; idx < SEL_PKEY_HASH_SIZE; idx++) {
+		list_for_each_entry_safe(pkey, pkey_tmp,
+					 &sel_pkey_hash[idx].list, list) {
+			list_del_rcu(&pkey->list);
+			kfree_rcu(pkey, rcu);
+		}
+		sel_pkey_hash[idx].size = 0;
+	}
+	spin_unlock_irqrestore(&sel_pkey_lock, flags);
+}
+
+static __init int sel_pkey_init(void)
+{
+	int iter;
+
+	if (!selinux_enabled)
+		return 0;
+
+	for (iter = 0; iter < SEL_PKEY_HASH_SIZE; iter++) {
+		INIT_LIST_HEAD(&sel_pkey_hash[iter].list);
+		sel_pkey_hash[iter].size = 0;
+	}
+
+	return 0;
+}
+
+subsys_initcall(sel_pkey_init);
diff --git a/security/selinux/include/ibpkey.h b/security/selinux/include/ibpkey.h
new file mode 100644
index 0000000..387885a
--- /dev/null
+++ b/security/selinux/include/ibpkey.h
@@ -0,0 +1,31 @@
+/*
+ * pkey table
+ *
+ * SELinux must keep a mapping of pkeys to labels/SIDs.  This
+ * mapping is maintained as part of the normal policy but a fast cache is
+ * needed to reduce the lookup overhead.
+ *
+ */
+
+/*
+ * (c) Mellanox Technologies, 2016
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _SELINUX_IB_PKEY_H
+#define _SELINUX_IB_PKEY_H
+
+void sel_pkey_flush(void);
+
+int sel_pkey_sid(u64 subnet_prefix, u16 pkey, u32 *sid);
+
+#endif
diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h
index 8e7db43..4139f28 100644
--- a/security/selinux/include/objsec.h
+++ b/security/selinux/include/objsec.h
@@ -133,6 +133,12 @@ struct ib_security_struct {
 	u32 sid;        /* SID of the queue pair or MAD agent */
 };
 
+struct pkey_security_struct {
+	u64	subnet_prefix; /* Port subnet prefix */
+	u16	pkey;	/* PKey number */
+	u32	sid;	/* SID of pkey */
+};
+
 extern unsigned int selinux_checkreqprot;
 
 #endif /* _SELINUX_OBJSEC_H_ */
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 51+ messages in thread

* Re: [PATCH v6 0/9] SELinux support for Infiniband RDMA
  2016-11-23 14:17 ` Dan Jurgens
@ 2016-12-12 21:38     ` Doug Ledford
  -1 siblings, 0 replies; 51+ messages in thread
From: Doug Ledford @ 2016-12-12 21:38 UTC (permalink / raw)
  To: Dan Jurgens, chrisw-69jw2NvuJkxg9hUCZPvPmw,
	paul-r2n+y4ga6xFZroRs9YW3xA, sds-+05T5uksL2qpZYMLLGbcSA,
	eparis-FjpueFixGhCM4zKIHC2jIg, sean.hefty-ral2JQCrhuEAvxtiuMwx3w,
	hal.rosenstock-Re5JQEeQqe8AvxtiuMwx3w
  Cc: selinux-+05T5uksL2qpZYMLLGbcSA,
	linux-security-module-u79uwXL29TY76Z2rM5mHXA,
	linux-rdma-u79uwXL29TY76Z2rM5mHXA,
	yevgenyp-VPRAkNaXOzVWk0Htik3J/w


[-- Attachment #1.1: Type: text/plain, Size: 8454 bytes --]

On 11/23/2016 9:17 AM, Dan Jurgens wrote:
> From: Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
> 
> Infiniband applications access HW from user-space -- traffic is generated
> directly by HW, bypassing the kernel. Consequently, Infiniband Partitions,
> which are associated directly with HW transport endpoints, are a natural
> choice for enforcing granular mandatory access control for Infiniband. QPs may
> only send or receives packets tagged with the corresponding partition key
> (PKey). The PKey is not a cryptographic key; it's a 16 bit number identifying
> the partition.
> 
> Every Infiniband fabric is controlled by a central Subnet Manager (SM). The SM
> provisions the partitions by assigning each port with the partitions it can
> access. In addition, the SM tags each port with a subnet prefix, which
> identifies the subnet. Determining which users are allowed to access which
> partition keys on a given subnet forms an effective policy for isolating users
> on the fabric. Any application that attempts to send traffic on a given subnet
> is automatically subject to the policy, regardless of which device and port it
> uses. SM software configures the subnet through a privileged Subnet Management
> Interface (SMI), which is presented by each Infiniband port. Thus, the SMI must
> also be controlled to prevent unauthorized changes to fabric configuration and
> partitioning. 
> 
> To support access control for IB partitions and subnet management, security
> contexts must be provided for two new types of objects - PKeys and IB ports.
> 
> A PKey label consists of a subnet prefix and a range of PKey values and is
> similar to the labeling mechanism for netports. Each Infiniband port can reside
> on a different subnet. So labeling the PKey values for specific subnet prefixes
> provides the user maximum flexibility, as PKey values may be determined
> independently for different subnets. There is a single access vector for PKeys
> called "access".
> 
> An Infiniband port is labeled by device name and port number. There is a single
> access vector for IB ports called "manage_subnet".
> 
> Because RDMA allows kernel bypass, enforcement must be done during connection
> setup. Communication over RDMA requires a send and receive queue, collectively
> known as a Queue Pair (QP). A QP must be initialized by privileged system calls
> before it can be used to send or receive data. During initialization the user
> must provide the PKey and port the QP will use; at this time access control can
> be enforced.
> 
> Because there is a possibility that the enforcement settings or security
> policy can change, a means of notifying the ib_core module of such changes
> is required. To facilitate this a generic notification callback mechanism
> is added to the LSM. One callback is registered for checking the QP PKey
> associations when the policy changes. Mad agents also register a callback,
> they cache the permission to send and receive SMPs to avoid another per
> packet call to the LSM.
> 
> Because frequent accesses to the same PKey's SID is expected a cache is
> implemented which is very similar to the netport cache.
> 
> In order to properly enforce security when changes to the PKey table or
> security policy or enforcement occur ib_core must track which QPs are
> using which port, pkey index, and alternate path for every IB device.
> This makes operations that used to be atomic transactional.
> 
> When modifying a QP, ib_core must associate it with the PKey index, port,
> and alternate path specified. If the QP was already associated with
> different settings, the QP is added to the new list prior to the
> modification. If the modify succeeds then the old listing is removed. If
> the modify fails the new listing is removed and the old listing remains
> unchanged.
> 
> When destroying a QP the ib_qp structure is freed by the decive specific
> driver (i.e. mlx4_ib) if the 'destroy' is successful. This requires storing
> security related information in a separate structure. When a 'destroy'
> request is in process the ib_qp structure is in an undefined state so if
> there are changes to the security policy or PKey table, the security checks
> cannot reset the QP if it doesn't have permission for the new setting. If
> the 'destroy' fails, security for that QP must be enforced again and its
> status in the list is restored. If the 'destroy' succeeds the security info
> can be cleaned up and freed.
> 
> There are a number of locks required to protect the QP security structure
> and the QP to device/port/pkey index lists. If multiple locks are required,
> the safe locking order is: QP security structure mutex first, followed by
> any list locks needed, which are sorted first by port followed by pkey
> index.

Ack for the IB parts.  Do we have a vote on the SELinux parts from the
security people?

> ---
> v2:
> - Use void* blobs in the LSM hooks. Paul Moore
> - Make the policy change callback generic. Yuval Shaia, Paul Moore
> - Squash LSM changes into the patches where the calls are added. Paul Moore
> - Don't add new initial SIDs. Stephen Smalley
> - Squash MAD agent PKey and SMI patches and move logic to IB security. Dan Jurgens
> - Changed ib_end_port to ib_port. Paul Moore
> - Changed ib_port access vector from smp to manage_subnet. Paul Moore
> - Added pkey and ib_port details to the audit log. Paul Moore
> - See individual patches for more detail.
> 
> v3:
> - ib_port -> ib_endport. Paul Moore
> - use notifier chains for LSM notifications. Paul Moore
> - reorder parameters in hooks to put security blob first. Paul Moore
> - Don't treat device name as untrusted string in audit log. Paul Moore
> 
> v4:
> - Added separate AVC callback for LSM notifier. Paul Moore
> - Removed unneeded braces in ocontext_read. Paul Moore
> 
> v5:
> - Fix link error when CONFIG_SECURITY is not set. Build Robot
> - Strip issue and Gerrit-Id: Leon Romanovsky
> 
> v6:
> - Whitespace and bracket cleanup. James Morris
> - Cleanup error flow in sel_pkey_sid_slow. James Morris
> 
> Daniel Jurgens (9):
>   IB/core: IB cache enhancements to support Infiniband security
>   IB/core: Enforce PKey security on QPs
>   selinux lsm IB/core: Implement LSM notification system
>   IB/core: Enforce security on management datagrams
>   selinux: Create policydb version for Infiniband support
>   selinux: Allocate and free infiniband security hooks
>   selinux: Implement Infiniband PKey "Access" access vector
>   selinux: Add IB Port SMP access vector
>   selinux: Add a cache for quicker retreival of PKey SIDs
> 
>  drivers/infiniband/core/Makefile     |   3 +-
>  drivers/infiniband/core/cache.c      |  57 ++-
>  drivers/infiniband/core/core_priv.h  | 115 ++++++
>  drivers/infiniband/core/device.c     |  86 +++++
>  drivers/infiniband/core/mad.c        |  52 ++-
>  drivers/infiniband/core/security.c   | 709 +++++++++++++++++++++++++++++++++++
>  drivers/infiniband/core/uverbs_cmd.c |  20 +-
>  drivers/infiniband/core/verbs.c      |  27 +-
>  include/linux/lsm_audit.h            |  15 +
>  include/linux/lsm_hooks.h            |  35 ++
>  include/linux/security.h             |  50 +++
>  include/rdma/ib_mad.h                |   4 +
>  include/rdma/ib_verbs.h              |  49 +++
>  security/Kconfig                     |   9 +
>  security/lsm_audit.c                 |  16 +
>  security/security.c                  |  59 +++
>  security/selinux/Makefile            |   2 +-
>  security/selinux/hooks.c             |  86 ++++-
>  security/selinux/ibpkey.c            | 245 ++++++++++++
>  security/selinux/include/classmap.h  |   4 +
>  security/selinux/include/ibpkey.h    |  31 ++
>  security/selinux/include/objsec.h    |  11 +
>  security/selinux/include/security.h  |   7 +-
>  security/selinux/selinuxfs.c         |   2 +
>  security/selinux/ss/policydb.c       | 129 ++++++-
>  security/selinux/ss/policydb.h       |  27 +-
>  security/selinux/ss/services.c       |  81 ++++
>  27 files changed, 1886 insertions(+), 45 deletions(-)
>  create mode 100644 drivers/infiniband/core/security.c
>  create mode 100644 security/selinux/ibpkey.c
>  create mode 100644 security/selinux/include/ibpkey.h
> 


-- 
Doug Ledford <dledford-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
    GPG Key ID: 0E572FDD


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 884 bytes --]

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH v6 0/9] SELinux support for Infiniband RDMA
@ 2016-12-12 21:38     ` Doug Ledford
  0 siblings, 0 replies; 51+ messages in thread
From: Doug Ledford @ 2016-12-12 21:38 UTC (permalink / raw)
  To: Dan Jurgens, chrisw, paul, sds, eparis, sean.hefty, hal.rosenstock
  Cc: selinux, linux-security-module, linux-rdma, yevgenyp


[-- Attachment #1.1: Type: text/plain, Size: 8398 bytes --]

On 11/23/2016 9:17 AM, Dan Jurgens wrote:
> From: Daniel Jurgens <danielj@mellanox.com>
> 
> Infiniband applications access HW from user-space -- traffic is generated
> directly by HW, bypassing the kernel. Consequently, Infiniband Partitions,
> which are associated directly with HW transport endpoints, are a natural
> choice for enforcing granular mandatory access control for Infiniband. QPs may
> only send or receives packets tagged with the corresponding partition key
> (PKey). The PKey is not a cryptographic key; it's a 16 bit number identifying
> the partition.
> 
> Every Infiniband fabric is controlled by a central Subnet Manager (SM). The SM
> provisions the partitions by assigning each port with the partitions it can
> access. In addition, the SM tags each port with a subnet prefix, which
> identifies the subnet. Determining which users are allowed to access which
> partition keys on a given subnet forms an effective policy for isolating users
> on the fabric. Any application that attempts to send traffic on a given subnet
> is automatically subject to the policy, regardless of which device and port it
> uses. SM software configures the subnet through a privileged Subnet Management
> Interface (SMI), which is presented by each Infiniband port. Thus, the SMI must
> also be controlled to prevent unauthorized changes to fabric configuration and
> partitioning. 
> 
> To support access control for IB partitions and subnet management, security
> contexts must be provided for two new types of objects - PKeys and IB ports.
> 
> A PKey label consists of a subnet prefix and a range of PKey values and is
> similar to the labeling mechanism for netports. Each Infiniband port can reside
> on a different subnet. So labeling the PKey values for specific subnet prefixes
> provides the user maximum flexibility, as PKey values may be determined
> independently for different subnets. There is a single access vector for PKeys
> called "access".
> 
> An Infiniband port is labeled by device name and port number. There is a single
> access vector for IB ports called "manage_subnet".
> 
> Because RDMA allows kernel bypass, enforcement must be done during connection
> setup. Communication over RDMA requires a send and receive queue, collectively
> known as a Queue Pair (QP). A QP must be initialized by privileged system calls
> before it can be used to send or receive data. During initialization the user
> must provide the PKey and port the QP will use; at this time access control can
> be enforced.
> 
> Because there is a possibility that the enforcement settings or security
> policy can change, a means of notifying the ib_core module of such changes
> is required. To facilitate this a generic notification callback mechanism
> is added to the LSM. One callback is registered for checking the QP PKey
> associations when the policy changes. Mad agents also register a callback,
> they cache the permission to send and receive SMPs to avoid another per
> packet call to the LSM.
> 
> Because frequent accesses to the same PKey's SID is expected a cache is
> implemented which is very similar to the netport cache.
> 
> In order to properly enforce security when changes to the PKey table or
> security policy or enforcement occur ib_core must track which QPs are
> using which port, pkey index, and alternate path for every IB device.
> This makes operations that used to be atomic transactional.
> 
> When modifying a QP, ib_core must associate it with the PKey index, port,
> and alternate path specified. If the QP was already associated with
> different settings, the QP is added to the new list prior to the
> modification. If the modify succeeds then the old listing is removed. If
> the modify fails the new listing is removed and the old listing remains
> unchanged.
> 
> When destroying a QP the ib_qp structure is freed by the decive specific
> driver (i.e. mlx4_ib) if the 'destroy' is successful. This requires storing
> security related information in a separate structure. When a 'destroy'
> request is in process the ib_qp structure is in an undefined state so if
> there are changes to the security policy or PKey table, the security checks
> cannot reset the QP if it doesn't have permission for the new setting. If
> the 'destroy' fails, security for that QP must be enforced again and its
> status in the list is restored. If the 'destroy' succeeds the security info
> can be cleaned up and freed.
> 
> There are a number of locks required to protect the QP security structure
> and the QP to device/port/pkey index lists. If multiple locks are required,
> the safe locking order is: QP security structure mutex first, followed by
> any list locks needed, which are sorted first by port followed by pkey
> index.

Ack for the IB parts.  Do we have a vote on the SELinux parts from the
security people?

> ---
> v2:
> - Use void* blobs in the LSM hooks. Paul Moore
> - Make the policy change callback generic. Yuval Shaia, Paul Moore
> - Squash LSM changes into the patches where the calls are added. Paul Moore
> - Don't add new initial SIDs. Stephen Smalley
> - Squash MAD agent PKey and SMI patches and move logic to IB security. Dan Jurgens
> - Changed ib_end_port to ib_port. Paul Moore
> - Changed ib_port access vector from smp to manage_subnet. Paul Moore
> - Added pkey and ib_port details to the audit log. Paul Moore
> - See individual patches for more detail.
> 
> v3:
> - ib_port -> ib_endport. Paul Moore
> - use notifier chains for LSM notifications. Paul Moore
> - reorder parameters in hooks to put security blob first. Paul Moore
> - Don't treat device name as untrusted string in audit log. Paul Moore
> 
> v4:
> - Added separate AVC callback for LSM notifier. Paul Moore
> - Removed unneeded braces in ocontext_read. Paul Moore
> 
> v5:
> - Fix link error when CONFIG_SECURITY is not set. Build Robot
> - Strip issue and Gerrit-Id: Leon Romanovsky
> 
> v6:
> - Whitespace and bracket cleanup. James Morris
> - Cleanup error flow in sel_pkey_sid_slow. James Morris
> 
> Daniel Jurgens (9):
>   IB/core: IB cache enhancements to support Infiniband security
>   IB/core: Enforce PKey security on QPs
>   selinux lsm IB/core: Implement LSM notification system
>   IB/core: Enforce security on management datagrams
>   selinux: Create policydb version for Infiniband support
>   selinux: Allocate and free infiniband security hooks
>   selinux: Implement Infiniband PKey "Access" access vector
>   selinux: Add IB Port SMP access vector
>   selinux: Add a cache for quicker retreival of PKey SIDs
> 
>  drivers/infiniband/core/Makefile     |   3 +-
>  drivers/infiniband/core/cache.c      |  57 ++-
>  drivers/infiniband/core/core_priv.h  | 115 ++++++
>  drivers/infiniband/core/device.c     |  86 +++++
>  drivers/infiniband/core/mad.c        |  52 ++-
>  drivers/infiniband/core/security.c   | 709 +++++++++++++++++++++++++++++++++++
>  drivers/infiniband/core/uverbs_cmd.c |  20 +-
>  drivers/infiniband/core/verbs.c      |  27 +-
>  include/linux/lsm_audit.h            |  15 +
>  include/linux/lsm_hooks.h            |  35 ++
>  include/linux/security.h             |  50 +++
>  include/rdma/ib_mad.h                |   4 +
>  include/rdma/ib_verbs.h              |  49 +++
>  security/Kconfig                     |   9 +
>  security/lsm_audit.c                 |  16 +
>  security/security.c                  |  59 +++
>  security/selinux/Makefile            |   2 +-
>  security/selinux/hooks.c             |  86 ++++-
>  security/selinux/ibpkey.c            | 245 ++++++++++++
>  security/selinux/include/classmap.h  |   4 +
>  security/selinux/include/ibpkey.h    |  31 ++
>  security/selinux/include/objsec.h    |  11 +
>  security/selinux/include/security.h  |   7 +-
>  security/selinux/selinuxfs.c         |   2 +
>  security/selinux/ss/policydb.c       | 129 ++++++-
>  security/selinux/ss/policydb.h       |  27 +-
>  security/selinux/ss/services.c       |  81 ++++
>  27 files changed, 1886 insertions(+), 45 deletions(-)
>  create mode 100644 drivers/infiniband/core/security.c
>  create mode 100644 security/selinux/ibpkey.c
>  create mode 100644 security/selinux/include/ibpkey.h
> 


-- 
Doug Ledford <dledford@redhat.com>
    GPG Key ID: 0E572FDD


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 884 bytes --]

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH v6 3/9] selinux lsm IB/core: Implement LSM notification system
  2016-11-23 14:17     ` Dan Jurgens
@ 2016-12-13 14:29         ` Stephen Smalley
  -1 siblings, 0 replies; 51+ messages in thread
From: Stephen Smalley @ 2016-12-13 14:29 UTC (permalink / raw)
  To: Dan Jurgens, chrisw-69jw2NvuJkxg9hUCZPvPmw,
	paul-r2n+y4ga6xFZroRs9YW3xA, eparis-FjpueFixGhCM4zKIHC2jIg,
	dledford-H+wXaHxf7aLQT0dZR+AlfA,
	sean.hefty-ral2JQCrhuEAvxtiuMwx3w,
	hal.rosenstock-Re5JQEeQqe8AvxtiuMwx3w
  Cc: linux-rdma-u79uwXL29TY76Z2rM5mHXA,
	linux-security-module-u79uwXL29TY76Z2rM5mHXA,
	selinux-+05T5uksL2qpZYMLLGbcSA

On 11/23/2016 09:17 AM, Dan Jurgens wrote:
> From: Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
> 
> Add a generic notificaiton mechanism in the LSM. Interested consumers
> can register a callback with the LSM and security modules can produce
> events.
> 
> Because access to Infiniband QPs are enforced in the setup phase of a
> connection security should be enforced again if the policy changes.
> Register infiniband devices for policy change notification and check all
> QPs on that device when the notification is received.
> 
> Add a call to the notification mechanism from SELinux when the AVC
> cache changes or setenforce is cleared.
> 
> Signed-off-by: Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
> 
> ---
> v2:
> - new patch that has the generic notification, replaces selinux and
>   IB/core patches related to the ib_flush callback. Yuval Shaia and Paul
>   Moore
> 
> v3:
> - use notifier chains. Paul Moore
> 
> v4:
> - Seperate avc callback for LSM notifier. Paul Moore
> 
> v5:
> - Fix link error when CONFIG_SECURITY is not set. Build Robot
> ---
>  drivers/infiniband/core/device.c | 53 ++++++++++++++++++++++++++++++++++++++++
>  include/linux/security.h         | 23 +++++++++++++++++
>  security/security.c              | 20 +++++++++++++++
>  security/selinux/hooks.c         | 11 +++++++++
>  security/selinux/selinuxfs.c     |  2 ++
>  5 files changed, 109 insertions(+)
> 
> diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c
> index 5b42e83..7b6fd06 100644
> --- a/drivers/infiniband/core/device.c
> +++ b/drivers/infiniband/core/device.c
> @@ -39,6 +39,8 @@
>  #include <linux/init.h>
>  #include <linux/mutex.h>
>  #include <linux/netdevice.h>
> +#include <linux/security.h>
> +#include <linux/notifier.h>
>  #include <rdma/rdma_netlink.h>
>  #include <rdma/ib_addr.h>
>  #include <rdma/ib_cache.h>
> @@ -82,6 +84,14 @@ static LIST_HEAD(client_list);
>  static DEFINE_MUTEX(device_mutex);
>  static DECLARE_RWSEM(lists_rwsem);
>  
> +static int ib_security_change(struct notifier_block *nb, unsigned long event,
> +			      void *lsm_data);
> +static void ib_policy_change_task(struct work_struct *work);
> +static DECLARE_WORK(ib_policy_change_work, ib_policy_change_task);
> +
> +static struct notifier_block ibdev_lsm_nb = {
> +	.notifier_call = ib_security_change,
> +};
>  
>  static int ib_device_check_mandatory(struct ib_device *device)
>  {
> @@ -344,6 +354,40 @@ static int setup_port_pkey_list(struct ib_device *device)
>  	return 0;
>  }
>  
> +static void ib_policy_change_task(struct work_struct *work)
> +{
> +	struct ib_device *dev;
> +
> +	down_read(&lists_rwsem);
> +	list_for_each_entry(dev, &device_list, core_list) {
> +		int i;
> +
> +		for (i = rdma_start_port(dev); i <= rdma_end_port(dev); i++) {
> +			u64 sp;
> +			int ret = ib_get_cached_subnet_prefix(dev,
> +							      i,
> +							      &sp);
> +
> +			WARN_ONCE(ret,
> +				  "ib_get_cached_subnet_prefix err: %d, this should never happen here\n",
> +				  ret);
> +			ib_security_cache_change(dev, i, sp);
> +		}
> +	}
> +	up_read(&lists_rwsem);
> +}
> +
> +static int ib_security_change(struct notifier_block *nb, unsigned long event,
> +			      void *lsm_data)
> +{
> +	if (event != LSM_POLICY_CHANGE)
> +		return NOTIFY_DONE;
> +
> +	schedule_work(&ib_policy_change_work);
> +
> +	return NOTIFY_OK;
> +}
> +
>  /**
>   * ib_register_device - Register an IB device with IB core
>   * @device:Device to register
> @@ -1075,10 +1119,18 @@ static int __init ib_core_init(void)
>  		goto err_sa;
>  	}
>  
> +	ret = register_lsm_notifier(&ibdev_lsm_nb);
> +	if (ret) {
> +		pr_warn("Couldn't register LSM notifier. ret %d\n", ret);
> +		goto err_ibnl_clients;
> +	}
> +
>  	ib_cache_setup();
>  
>  	return 0;
>  
> +err_ibnl_clients:
> +	ib_remove_ibnl_clients();
>  err_sa:
>  	ib_sa_cleanup();
>  err_mad:
> @@ -1098,6 +1150,7 @@ static int __init ib_core_init(void)
>  
>  static void __exit ib_core_cleanup(void)
>  {
> +	unregister_lsm_notifier(&ibdev_lsm_nb);
>  	ib_cache_cleanup();
>  	ib_remove_ibnl_clients();
>  	ib_sa_cleanup();
> diff --git a/include/linux/security.h b/include/linux/security.h
> index 342ca4c..0a5de0c 100644
> --- a/include/linux/security.h
> +++ b/include/linux/security.h
> @@ -69,6 +69,10 @@ struct audit_krule;
>  struct user_namespace;
>  struct timezone;
>  
> +enum lsm_event {
> +	LSM_POLICY_CHANGE,
> +};
> +
>  /* These functions are in security/commoncap.c */
>  extern int cap_capable(const struct cred *cred, struct user_namespace *ns,
>  		       int cap, int audit);
> @@ -161,6 +165,10 @@ struct security_mnt_opts {
>  	int num_mnt_opts;
>  };
>  
> +int call_lsm_notifier(enum lsm_event event, void *data);
> +int register_lsm_notifier(struct notifier_block *nb);
> +int unregister_lsm_notifier(struct notifier_block *nb);
> +
>  static inline void security_init_mnt_opts(struct security_mnt_opts *opts)
>  {
>  	opts->mnt_opts = NULL;
> @@ -377,6 +385,21 @@ int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen);
>  struct security_mnt_opts {
>  };
>  
> +static inline int call_lsm_notifier(enum lsm_event event, void *data)
> +{
> +	return 0;
> +}
> +
> +static inline int register_lsm_notifier(struct notifier_block *nb)
> +{
> +	return 0;
> +}
> +
> +static inline  int unregister_lsm_notifier(struct notifier_block *nb)
> +{
> +	return 0;
> +}
> +
>  static inline void security_init_mnt_opts(struct security_mnt_opts *opts)
>  {
>  }
> diff --git a/security/security.c b/security/security.c
> index 7d3bf2f..40326d4 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -33,6 +33,8 @@
>  /* Maximum number of letters for an LSM name string */
>  #define SECURITY_NAME_MAX	10
>  
> +static ATOMIC_NOTIFIER_HEAD(lsm_notifier_chain);
> +
>  /* Boot-time LSM user choice */
>  static __initdata char chosen_lsm[SECURITY_NAME_MAX + 1] =
>  	CONFIG_DEFAULT_SECURITY;
> @@ -98,6 +100,24 @@ int __init security_module_enable(const char *module)
>  	return !strcmp(module, chosen_lsm);
>  }
>  
> +int call_lsm_notifier(enum lsm_event event, void *data)
> +{
> +	return atomic_notifier_call_chain(&lsm_notifier_chain, event, data);
> +}
> +EXPORT_SYMBOL(call_lsm_notifier);
> +
> +int register_lsm_notifier(struct notifier_block *nb)
> +{
> +	return atomic_notifier_chain_register(&lsm_notifier_chain, nb);
> +}
> +EXPORT_SYMBOL(register_lsm_notifier);
> +
> +int unregister_lsm_notifier(struct notifier_block *nb)
> +{
> +	return atomic_notifier_chain_unregister(&lsm_notifier_chain, nb);
> +}
> +EXPORT_SYMBOL(unregister_lsm_notifier);
> +
>  /*
>   * Hook list operation macros.
>   *
> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index 09fd610..2d7a7c1 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -170,6 +170,14 @@ static int selinux_netcache_avc_callback(u32 event)
>  	return 0;
>  }
>  
> +static int selinux_lsm_notifier_avc_callback(u32 event)
> +{
> +	if (event == AVC_CALLBACK_RESET)
> +		call_lsm_notifier(LSM_POLICY_CHANGE, NULL);
> +
> +	return 0;
> +}
> +
>  /*
>   * initialise the security for the init task
>   */
> @@ -6325,6 +6333,9 @@ static __init int selinux_init(void)
>  	if (avc_add_callback(selinux_netcache_avc_callback, AVC_CALLBACK_RESET))
>  		panic("SELinux: Unable to register AVC netcache callback\n");
>  
> +	if (avc_add_callback(selinux_lsm_notifier_avc_callback, AVC_CALLBACK_RESET))
> +		panic("SELinux: Unable to register AVC LSM notifier callback\n");
> +
>  	if (selinux_enforcing)
>  		printk(KERN_DEBUG "SELinux:  Starting in enforcing mode\n");
>  	else
> diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
> index 72c145d..d3f9192 100644
> --- a/security/selinux/selinuxfs.c
> +++ b/security/selinux/selinuxfs.c
> @@ -177,6 +177,8 @@ static ssize_t sel_write_enforce(struct file *file, const char __user *buf,
>  			avc_ss_reset(0);
>  		selnl_notify_setenforce(selinux_enforcing);
>  		selinux_status_update_setenforce(selinux_enforcing);
> +		if (!selinux_enforcing)
> +			call_lsm_notifier(LSM_POLICY_CHANGE, NULL);

Why do you need this notification?  When switching from permissive to
enforcing, you need (and already get) a notification since you may need
to revoke previously granted permissions.  But what action do you need
to take on switching to permissive?

>  	}
>  	length = count;
>  out:
> 

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH v6 3/9] selinux lsm IB/core: Implement LSM notification system
@ 2016-12-13 14:29         ` Stephen Smalley
  0 siblings, 0 replies; 51+ messages in thread
From: Stephen Smalley @ 2016-12-13 14:29 UTC (permalink / raw)
  To: Dan Jurgens, chrisw, paul, eparis, dledford, sean.hefty, hal.rosenstock
  Cc: linux-rdma, linux-security-module, selinux

On 11/23/2016 09:17 AM, Dan Jurgens wrote:
> From: Daniel Jurgens <danielj@mellanox.com>
> 
> Add a generic notificaiton mechanism in the LSM. Interested consumers
> can register a callback with the LSM and security modules can produce
> events.
> 
> Because access to Infiniband QPs are enforced in the setup phase of a
> connection security should be enforced again if the policy changes.
> Register infiniband devices for policy change notification and check all
> QPs on that device when the notification is received.
> 
> Add a call to the notification mechanism from SELinux when the AVC
> cache changes or setenforce is cleared.
> 
> Signed-off-by: Daniel Jurgens <danielj@mellanox.com>
> 
> ---
> v2:
> - new patch that has the generic notification, replaces selinux and
>   IB/core patches related to the ib_flush callback. Yuval Shaia and Paul
>   Moore
> 
> v3:
> - use notifier chains. Paul Moore
> 
> v4:
> - Seperate avc callback for LSM notifier. Paul Moore
> 
> v5:
> - Fix link error when CONFIG_SECURITY is not set. Build Robot
> ---
>  drivers/infiniband/core/device.c | 53 ++++++++++++++++++++++++++++++++++++++++
>  include/linux/security.h         | 23 +++++++++++++++++
>  security/security.c              | 20 +++++++++++++++
>  security/selinux/hooks.c         | 11 +++++++++
>  security/selinux/selinuxfs.c     |  2 ++
>  5 files changed, 109 insertions(+)
> 
> diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c
> index 5b42e83..7b6fd06 100644
> --- a/drivers/infiniband/core/device.c
> +++ b/drivers/infiniband/core/device.c
> @@ -39,6 +39,8 @@
>  #include <linux/init.h>
>  #include <linux/mutex.h>
>  #include <linux/netdevice.h>
> +#include <linux/security.h>
> +#include <linux/notifier.h>
>  #include <rdma/rdma_netlink.h>
>  #include <rdma/ib_addr.h>
>  #include <rdma/ib_cache.h>
> @@ -82,6 +84,14 @@ static LIST_HEAD(client_list);
>  static DEFINE_MUTEX(device_mutex);
>  static DECLARE_RWSEM(lists_rwsem);
>  
> +static int ib_security_change(struct notifier_block *nb, unsigned long event,
> +			      void *lsm_data);
> +static void ib_policy_change_task(struct work_struct *work);
> +static DECLARE_WORK(ib_policy_change_work, ib_policy_change_task);
> +
> +static struct notifier_block ibdev_lsm_nb = {
> +	.notifier_call = ib_security_change,
> +};
>  
>  static int ib_device_check_mandatory(struct ib_device *device)
>  {
> @@ -344,6 +354,40 @@ static int setup_port_pkey_list(struct ib_device *device)
>  	return 0;
>  }
>  
> +static void ib_policy_change_task(struct work_struct *work)
> +{
> +	struct ib_device *dev;
> +
> +	down_read(&lists_rwsem);
> +	list_for_each_entry(dev, &device_list, core_list) {
> +		int i;
> +
> +		for (i = rdma_start_port(dev); i <= rdma_end_port(dev); i++) {
> +			u64 sp;
> +			int ret = ib_get_cached_subnet_prefix(dev,
> +							      i,
> +							      &sp);
> +
> +			WARN_ONCE(ret,
> +				  "ib_get_cached_subnet_prefix err: %d, this should never happen here\n",
> +				  ret);
> +			ib_security_cache_change(dev, i, sp);
> +		}
> +	}
> +	up_read(&lists_rwsem);
> +}
> +
> +static int ib_security_change(struct notifier_block *nb, unsigned long event,
> +			      void *lsm_data)
> +{
> +	if (event != LSM_POLICY_CHANGE)
> +		return NOTIFY_DONE;
> +
> +	schedule_work(&ib_policy_change_work);
> +
> +	return NOTIFY_OK;
> +}
> +
>  /**
>   * ib_register_device - Register an IB device with IB core
>   * @device:Device to register
> @@ -1075,10 +1119,18 @@ static int __init ib_core_init(void)
>  		goto err_sa;
>  	}
>  
> +	ret = register_lsm_notifier(&ibdev_lsm_nb);
> +	if (ret) {
> +		pr_warn("Couldn't register LSM notifier. ret %d\n", ret);
> +		goto err_ibnl_clients;
> +	}
> +
>  	ib_cache_setup();
>  
>  	return 0;
>  
> +err_ibnl_clients:
> +	ib_remove_ibnl_clients();
>  err_sa:
>  	ib_sa_cleanup();
>  err_mad:
> @@ -1098,6 +1150,7 @@ static int __init ib_core_init(void)
>  
>  static void __exit ib_core_cleanup(void)
>  {
> +	unregister_lsm_notifier(&ibdev_lsm_nb);
>  	ib_cache_cleanup();
>  	ib_remove_ibnl_clients();
>  	ib_sa_cleanup();
> diff --git a/include/linux/security.h b/include/linux/security.h
> index 342ca4c..0a5de0c 100644
> --- a/include/linux/security.h
> +++ b/include/linux/security.h
> @@ -69,6 +69,10 @@ struct audit_krule;
>  struct user_namespace;
>  struct timezone;
>  
> +enum lsm_event {
> +	LSM_POLICY_CHANGE,
> +};
> +
>  /* These functions are in security/commoncap.c */
>  extern int cap_capable(const struct cred *cred, struct user_namespace *ns,
>  		       int cap, int audit);
> @@ -161,6 +165,10 @@ struct security_mnt_opts {
>  	int num_mnt_opts;
>  };
>  
> +int call_lsm_notifier(enum lsm_event event, void *data);
> +int register_lsm_notifier(struct notifier_block *nb);
> +int unregister_lsm_notifier(struct notifier_block *nb);
> +
>  static inline void security_init_mnt_opts(struct security_mnt_opts *opts)
>  {
>  	opts->mnt_opts = NULL;
> @@ -377,6 +385,21 @@ int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen);
>  struct security_mnt_opts {
>  };
>  
> +static inline int call_lsm_notifier(enum lsm_event event, void *data)
> +{
> +	return 0;
> +}
> +
> +static inline int register_lsm_notifier(struct notifier_block *nb)
> +{
> +	return 0;
> +}
> +
> +static inline  int unregister_lsm_notifier(struct notifier_block *nb)
> +{
> +	return 0;
> +}
> +
>  static inline void security_init_mnt_opts(struct security_mnt_opts *opts)
>  {
>  }
> diff --git a/security/security.c b/security/security.c
> index 7d3bf2f..40326d4 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -33,6 +33,8 @@
>  /* Maximum number of letters for an LSM name string */
>  #define SECURITY_NAME_MAX	10
>  
> +static ATOMIC_NOTIFIER_HEAD(lsm_notifier_chain);
> +
>  /* Boot-time LSM user choice */
>  static __initdata char chosen_lsm[SECURITY_NAME_MAX + 1] =
>  	CONFIG_DEFAULT_SECURITY;
> @@ -98,6 +100,24 @@ int __init security_module_enable(const char *module)
>  	return !strcmp(module, chosen_lsm);
>  }
>  
> +int call_lsm_notifier(enum lsm_event event, void *data)
> +{
> +	return atomic_notifier_call_chain(&lsm_notifier_chain, event, data);
> +}
> +EXPORT_SYMBOL(call_lsm_notifier);
> +
> +int register_lsm_notifier(struct notifier_block *nb)
> +{
> +	return atomic_notifier_chain_register(&lsm_notifier_chain, nb);
> +}
> +EXPORT_SYMBOL(register_lsm_notifier);
> +
> +int unregister_lsm_notifier(struct notifier_block *nb)
> +{
> +	return atomic_notifier_chain_unregister(&lsm_notifier_chain, nb);
> +}
> +EXPORT_SYMBOL(unregister_lsm_notifier);
> +
>  /*
>   * Hook list operation macros.
>   *
> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index 09fd610..2d7a7c1 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -170,6 +170,14 @@ static int selinux_netcache_avc_callback(u32 event)
>  	return 0;
>  }
>  
> +static int selinux_lsm_notifier_avc_callback(u32 event)
> +{
> +	if (event == AVC_CALLBACK_RESET)
> +		call_lsm_notifier(LSM_POLICY_CHANGE, NULL);
> +
> +	return 0;
> +}
> +
>  /*
>   * initialise the security for the init task
>   */
> @@ -6325,6 +6333,9 @@ static __init int selinux_init(void)
>  	if (avc_add_callback(selinux_netcache_avc_callback, AVC_CALLBACK_RESET))
>  		panic("SELinux: Unable to register AVC netcache callback\n");
>  
> +	if (avc_add_callback(selinux_lsm_notifier_avc_callback, AVC_CALLBACK_RESET))
> +		panic("SELinux: Unable to register AVC LSM notifier callback\n");
> +
>  	if (selinux_enforcing)
>  		printk(KERN_DEBUG "SELinux:  Starting in enforcing mode\n");
>  	else
> diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
> index 72c145d..d3f9192 100644
> --- a/security/selinux/selinuxfs.c
> +++ b/security/selinux/selinuxfs.c
> @@ -177,6 +177,8 @@ static ssize_t sel_write_enforce(struct file *file, const char __user *buf,
>  			avc_ss_reset(0);
>  		selnl_notify_setenforce(selinux_enforcing);
>  		selinux_status_update_setenforce(selinux_enforcing);
> +		if (!selinux_enforcing)
> +			call_lsm_notifier(LSM_POLICY_CHANGE, NULL);

Why do you need this notification?  When switching from permissive to
enforcing, you need (and already get) a notification since you may need
to revoke previously granted permissions.  But what action do you need
to take on switching to permissive?

>  	}
>  	length = count;
>  out:
> 

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH v6 5/9] selinux: Create policydb version for Infiniband support
  2016-11-23 14:17 ` [PATCH v6 5/9] selinux: Create policydb version for Infiniband support Dan Jurgens
@ 2016-12-13 14:38       ` Stephen Smalley
  0 siblings, 0 replies; 51+ messages in thread
From: Stephen Smalley @ 2016-12-13 14:38 UTC (permalink / raw)
  To: Dan Jurgens, chrisw-69jw2NvuJkxg9hUCZPvPmw,
	paul-r2n+y4ga6xFZroRs9YW3xA, eparis-FjpueFixGhCM4zKIHC2jIg,
	dledford-H+wXaHxf7aLQT0dZR+AlfA,
	sean.hefty-ral2JQCrhuEAvxtiuMwx3w,
	hal.rosenstock-Re5JQEeQqe8AvxtiuMwx3w
  Cc: linux-rdma-u79uwXL29TY76Z2rM5mHXA,
	linux-security-module-u79uwXL29TY76Z2rM5mHXA,
	selinux-+05T5uksL2qpZYMLLGbcSA

On 11/23/2016 09:17 AM, Dan Jurgens wrote:
> From: Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
> 
> Support for Infiniband requires the addition of two new object contexts,
> one for infiniband PKeys and another IB Ports. Added handlers to read
> and write the new ocontext types when reading or writing a binary policy
> representation.
> 
> Signed-off-by: Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
> Reviewed-by: Eli Cohen <eli-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>

I assume you have libsepol/checkpolicy patches for this as well?

> 
> ---
> v2:
> - Shorten ib_end_port to ib_port. Paul Moore
> - Added bounds checking to port number. Paul Moore
> - Eliminated {} in OCON_PKEY case statement.  Yuval Shaia
> 
> v3:
> - ib_port -> ib_endport. Paul Moore
> 
> v4:
> - removed unneeded brackets in ocontext_read. Paul Moore
> ---
>  security/selinux/include/security.h |   3 +-
>  security/selinux/ss/policydb.c      | 129 +++++++++++++++++++++++++++++++-----
>  security/selinux/ss/policydb.h      |  27 +++++---
>  3 files changed, 135 insertions(+), 24 deletions(-)
> 
> diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
> index 308a286..6bb9b0a 100644
> --- a/security/selinux/include/security.h
> +++ b/security/selinux/include/security.h
> @@ -36,10 +36,11 @@
>  #define POLICYDB_VERSION_DEFAULT_TYPE	28
>  #define POLICYDB_VERSION_CONSTRAINT_NAMES	29
>  #define POLICYDB_VERSION_XPERMS_IOCTL	30
> +#define POLICYDB_VERSION_INFINIBAND		31
>  
>  /* Range of policy versions we understand*/
>  #define POLICYDB_VERSION_MIN   POLICYDB_VERSION_BASE
> -#define POLICYDB_VERSION_MAX	POLICYDB_VERSION_XPERMS_IOCTL
> +#define POLICYDB_VERSION_MAX   POLICYDB_VERSION_INFINIBAND
>  
>  /* Mask for just the mount related flags */
>  #define SE_MNTMASK	0x0f
> diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
> index d719db4..24e16da 100644
> --- a/security/selinux/ss/policydb.c
> +++ b/security/selinux/ss/policydb.c
> @@ -17,6 +17,11 @@
>   *
>   *      Added support for the policy capability bitmap
>   *
> + * Update: Mellanox Techonologies
> + *
> + *	Added Infiniband support
> + *
> + * Copyright (C) 2016 Mellanox Techonologies
>   * Copyright (C) 2007 Hewlett-Packard Development Company, L.P.
>   * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc.
>   * Copyright (C) 2003 - 2004 Tresys Technology, LLC
> @@ -76,81 +81,86 @@ static struct policydb_compat_info policydb_compat[] = {
>  	{
>  		.version	= POLICYDB_VERSION_BASE,
>  		.sym_num	= SYM_NUM - 3,
> -		.ocon_num	= OCON_NUM - 1,
> +		.ocon_num	= OCON_NUM - 3,
>  	},
>  	{
>  		.version	= POLICYDB_VERSION_BOOL,
>  		.sym_num	= SYM_NUM - 2,
> -		.ocon_num	= OCON_NUM - 1,
> +		.ocon_num	= OCON_NUM - 3,
>  	},
>  	{
>  		.version	= POLICYDB_VERSION_IPV6,
>  		.sym_num	= SYM_NUM - 2,
> -		.ocon_num	= OCON_NUM,
> +		.ocon_num	= OCON_NUM - 2,
>  	},
>  	{
>  		.version	= POLICYDB_VERSION_NLCLASS,
>  		.sym_num	= SYM_NUM - 2,
> -		.ocon_num	= OCON_NUM,
> +		.ocon_num	= OCON_NUM - 2,
>  	},
>  	{
>  		.version	= POLICYDB_VERSION_MLS,
>  		.sym_num	= SYM_NUM,
> -		.ocon_num	= OCON_NUM,
> +		.ocon_num	= OCON_NUM - 2,
>  	},
>  	{
>  		.version	= POLICYDB_VERSION_AVTAB,
>  		.sym_num	= SYM_NUM,
> -		.ocon_num	= OCON_NUM,
> +		.ocon_num	= OCON_NUM - 2,
>  	},
>  	{
>  		.version	= POLICYDB_VERSION_RANGETRANS,
>  		.sym_num	= SYM_NUM,
> -		.ocon_num	= OCON_NUM,
> +		.ocon_num	= OCON_NUM - 2,
>  	},
>  	{
>  		.version	= POLICYDB_VERSION_POLCAP,
>  		.sym_num	= SYM_NUM,
> -		.ocon_num	= OCON_NUM,
> +		.ocon_num	= OCON_NUM - 2,
>  	},
>  	{
>  		.version	= POLICYDB_VERSION_PERMISSIVE,
>  		.sym_num	= SYM_NUM,
> -		.ocon_num	= OCON_NUM,
> +		.ocon_num	= OCON_NUM - 2,
>  	},
>  	{
>  		.version	= POLICYDB_VERSION_BOUNDARY,
>  		.sym_num	= SYM_NUM,
> -		.ocon_num	= OCON_NUM,
> +		.ocon_num	= OCON_NUM - 2,
>  	},
>  	{
>  		.version	= POLICYDB_VERSION_FILENAME_TRANS,
>  		.sym_num	= SYM_NUM,
> -		.ocon_num	= OCON_NUM,
> +		.ocon_num	= OCON_NUM - 2,
>  	},
>  	{
>  		.version	= POLICYDB_VERSION_ROLETRANS,
>  		.sym_num	= SYM_NUM,
> -		.ocon_num	= OCON_NUM,
> +		.ocon_num	= OCON_NUM - 2,
>  	},
>  	{
>  		.version	= POLICYDB_VERSION_NEW_OBJECT_DEFAULTS,
>  		.sym_num	= SYM_NUM,
> -		.ocon_num	= OCON_NUM,
> +		.ocon_num	= OCON_NUM - 2,
>  	},
>  	{
>  		.version	= POLICYDB_VERSION_DEFAULT_TYPE,
>  		.sym_num	= SYM_NUM,
> -		.ocon_num	= OCON_NUM,
> +		.ocon_num	= OCON_NUM - 2,
>  	},
>  	{
>  		.version	= POLICYDB_VERSION_CONSTRAINT_NAMES,
>  		.sym_num	= SYM_NUM,
> -		.ocon_num	= OCON_NUM,
> +		.ocon_num	= OCON_NUM - 2,
>  	},
>  	{
>  		.version	= POLICYDB_VERSION_XPERMS_IOCTL,
>  		.sym_num	= SYM_NUM,
> +		.ocon_num	= OCON_NUM - 2,
> +	},
> +	{
> +		.version	= POLICYDB_VERSION_INFINIBAND,
> +		.sym_num	= SYM_NUM,
>  		.ocon_num	= OCON_NUM,
>  	},
>  };
> @@ -2222,6 +2232,60 @@ static int ocontext_read(struct policydb *p, struct policydb_compat_info *info,
>  					goto out;
>  				break;
>  			}
> +			case OCON_PKEY:
> +				rc = next_entry(nodebuf, fp, sizeof(u32) * 6);
> +				if (rc)
> +					goto out;
> +
> +				c->u.pkey.subnet_prefix = be64_to_cpu(*((__be64 *)nodebuf));
> +				/* The subnet prefix is stored as an IPv6
> +				 * address in the policy.
> +				 *
> +				 * Check that the lower 2 DWORDS are 0.
> +				 */
> +				if (nodebuf[2] || nodebuf[3]) {
> +					rc = -EINVAL;
> +					goto out;
> +				}
> +
> +				if (nodebuf[4] > 0xffff ||
> +				    nodebuf[5] > 0xffff) {
> +					rc = -EINVAL;
> +					goto out;
> +				}
> +
> +				c->u.pkey.low_pkey = le32_to_cpu(nodebuf[4]);
> +				c->u.pkey.high_pkey = le32_to_cpu(nodebuf[5]);
> +
> +				rc = context_read_and_validate(&c->context[0],
> +							       p,
> +							       fp);
> +				if (rc)
> +					goto out;
> +				break;
> +			case OCON_IB_ENDPORT:
> +				rc = next_entry(buf, fp, sizeof(u32) * 2);
> +				if (rc)
> +					goto out;
> +				len = le32_to_cpu(buf[0]);
> +
> +				rc = str_read(&c->u.ib_endport.dev_name, GFP_KERNEL, fp, len);
> +				if (rc)
> +					goto out;
> +
> +				if (buf[1] > 0xff || buf[1] == 0) {
> +					rc = -EINVAL;
> +					goto out;
> +				}
> +
> +				c->u.ib_endport.port_num = le32_to_cpu(buf[1]);
> +
> +				rc = context_read_and_validate(&c->context[0],
> +							       p,
> +							       fp);
> +				if (rc)
> +					goto out;
> +				break;
>  			}
>  		}
>  	}
> @@ -3151,6 +3215,41 @@ static int ocontext_write(struct policydb *p, struct policydb_compat_info *info,
>  				if (rc)
>  					return rc;
>  				break;
> +			case OCON_PKEY:
> +				*((__be64 *)nodebuf) = cpu_to_be64(c->u.pkey.subnet_prefix);
> +
> +				/*
> +				 * The low order 2 bits were confirmed to be 0
> +				 * when the policy was loaded. Write them out
> +				 * as zero
> +				 */
> +				nodebuf[2] = 0;
> +				nodebuf[3] = 0;
> +
> +				nodebuf[4] = cpu_to_le32(c->u.pkey.low_pkey);
> +				nodebuf[5] = cpu_to_le32(c->u.pkey.high_pkey);
> +
> +				rc = put_entry(nodebuf, sizeof(u32), 6, fp);
> +				if (rc)
> +					return rc;
> +				rc = context_write(p, &c->context[0], fp);
> +				if (rc)
> +					return rc;
> +				break;
> +			case OCON_IB_ENDPORT:
> +				len = strlen(c->u.ib_endport.dev_name);
> +				buf[0] = cpu_to_le32(len);
> +				buf[1] = cpu_to_le32(c->u.ib_endport.port_num);
> +				rc = put_entry(buf, sizeof(u32), 2, fp);
> +				if (rc)
> +					return rc;
> +				rc = put_entry(c->u.ib_endport.dev_name, 1, len, fp);
> +				if (rc)
> +					return rc;
> +				rc = context_write(p, &c->context[0], fp);
> +				if (rc)
> +					return rc;
> +				break;
>  			}
>  		}
>  	}
> diff --git a/security/selinux/ss/policydb.h b/security/selinux/ss/policydb.h
> index 725d594..edb329d 100644
> --- a/security/selinux/ss/policydb.h
> +++ b/security/selinux/ss/policydb.h
> @@ -187,6 +187,15 @@ struct ocontext {
>  			u32 addr[4];
>  			u32 mask[4];
>  		} node6;        /* IPv6 node information */
> +		struct {
> +			u64 subnet_prefix;
> +			u16 low_pkey;
> +			u16 high_pkey;
> +		} pkey;
> +		struct {
> +			char *dev_name;
> +			u8 port_num;
> +		} ib_endport;
>  	} u;
>  	union {
>  		u32 sclass;  /* security class for genfs */
> @@ -215,14 +224,16 @@ struct genfs {
>  #define SYM_NUM     8
>  
>  /* object context array indices */
> -#define OCON_ISID  0	/* initial SIDs */
> -#define OCON_FS    1	/* unlabeled file systems */
> -#define OCON_PORT  2	/* TCP and UDP port numbers */
> -#define OCON_NETIF 3	/* network interfaces */
> -#define OCON_NODE  4	/* nodes */
> -#define OCON_FSUSE 5	/* fs_use */
> -#define OCON_NODE6 6	/* IPv6 nodes */
> -#define OCON_NUM   7
> +#define OCON_ISID	0 /* initial SIDs */
> +#define OCON_FS		1 /* unlabeled file systems */
> +#define OCON_PORT	2 /* TCP and UDP port numbers */
> +#define OCON_NETIF	3 /* network interfaces */
> +#define OCON_NODE	4 /* nodes */
> +#define OCON_FSUSE	5 /* fs_use */
> +#define OCON_NODE6	6 /* IPv6 nodes */
> +#define OCON_PKEY	7 /* Infiniband PKeys */
> +#define OCON_IB_ENDPORT	8 /* Infiniband end ports */
> +#define OCON_NUM	9
>  
>  /* The policy database */
>  struct policydb {
> 

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH v6 5/9] selinux: Create policydb version for Infiniband support
@ 2016-12-13 14:38       ` Stephen Smalley
  0 siblings, 0 replies; 51+ messages in thread
From: Stephen Smalley @ 2016-12-13 14:38 UTC (permalink / raw)
  To: Dan Jurgens, chrisw, paul, eparis, dledford, sean.hefty, hal.rosenstock
  Cc: linux-rdma, linux-security-module, selinux

On 11/23/2016 09:17 AM, Dan Jurgens wrote:
> From: Daniel Jurgens <danielj@mellanox.com>
> 
> Support for Infiniband requires the addition of two new object contexts,
> one for infiniband PKeys and another IB Ports. Added handlers to read
> and write the new ocontext types when reading or writing a binary policy
> representation.
> 
> Signed-off-by: Daniel Jurgens <danielj@mellanox.com>
> Reviewed-by: Eli Cohen <eli@mellanox.com>

I assume you have libsepol/checkpolicy patches for this as well?

> 
> ---
> v2:
> - Shorten ib_end_port to ib_port. Paul Moore
> - Added bounds checking to port number. Paul Moore
> - Eliminated {} in OCON_PKEY case statement.  Yuval Shaia
> 
> v3:
> - ib_port -> ib_endport. Paul Moore
> 
> v4:
> - removed unneeded brackets in ocontext_read. Paul Moore
> ---
>  security/selinux/include/security.h |   3 +-
>  security/selinux/ss/policydb.c      | 129 +++++++++++++++++++++++++++++++-----
>  security/selinux/ss/policydb.h      |  27 +++++---
>  3 files changed, 135 insertions(+), 24 deletions(-)
> 
> diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
> index 308a286..6bb9b0a 100644
> --- a/security/selinux/include/security.h
> +++ b/security/selinux/include/security.h
> @@ -36,10 +36,11 @@
>  #define POLICYDB_VERSION_DEFAULT_TYPE	28
>  #define POLICYDB_VERSION_CONSTRAINT_NAMES	29
>  #define POLICYDB_VERSION_XPERMS_IOCTL	30
> +#define POLICYDB_VERSION_INFINIBAND		31
>  
>  /* Range of policy versions we understand*/
>  #define POLICYDB_VERSION_MIN   POLICYDB_VERSION_BASE
> -#define POLICYDB_VERSION_MAX	POLICYDB_VERSION_XPERMS_IOCTL
> +#define POLICYDB_VERSION_MAX   POLICYDB_VERSION_INFINIBAND
>  
>  /* Mask for just the mount related flags */
>  #define SE_MNTMASK	0x0f
> diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
> index d719db4..24e16da 100644
> --- a/security/selinux/ss/policydb.c
> +++ b/security/selinux/ss/policydb.c
> @@ -17,6 +17,11 @@
>   *
>   *      Added support for the policy capability bitmap
>   *
> + * Update: Mellanox Techonologies
> + *
> + *	Added Infiniband support
> + *
> + * Copyright (C) 2016 Mellanox Techonologies
>   * Copyright (C) 2007 Hewlett-Packard Development Company, L.P.
>   * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc.
>   * Copyright (C) 2003 - 2004 Tresys Technology, LLC
> @@ -76,81 +81,86 @@ static struct policydb_compat_info policydb_compat[] = {
>  	{
>  		.version	= POLICYDB_VERSION_BASE,
>  		.sym_num	= SYM_NUM - 3,
> -		.ocon_num	= OCON_NUM - 1,
> +		.ocon_num	= OCON_NUM - 3,
>  	},
>  	{
>  		.version	= POLICYDB_VERSION_BOOL,
>  		.sym_num	= SYM_NUM - 2,
> -		.ocon_num	= OCON_NUM - 1,
> +		.ocon_num	= OCON_NUM - 3,
>  	},
>  	{
>  		.version	= POLICYDB_VERSION_IPV6,
>  		.sym_num	= SYM_NUM - 2,
> -		.ocon_num	= OCON_NUM,
> +		.ocon_num	= OCON_NUM - 2,
>  	},
>  	{
>  		.version	= POLICYDB_VERSION_NLCLASS,
>  		.sym_num	= SYM_NUM - 2,
> -		.ocon_num	= OCON_NUM,
> +		.ocon_num	= OCON_NUM - 2,
>  	},
>  	{
>  		.version	= POLICYDB_VERSION_MLS,
>  		.sym_num	= SYM_NUM,
> -		.ocon_num	= OCON_NUM,
> +		.ocon_num	= OCON_NUM - 2,
>  	},
>  	{
>  		.version	= POLICYDB_VERSION_AVTAB,
>  		.sym_num	= SYM_NUM,
> -		.ocon_num	= OCON_NUM,
> +		.ocon_num	= OCON_NUM - 2,
>  	},
>  	{
>  		.version	= POLICYDB_VERSION_RANGETRANS,
>  		.sym_num	= SYM_NUM,
> -		.ocon_num	= OCON_NUM,
> +		.ocon_num	= OCON_NUM - 2,
>  	},
>  	{
>  		.version	= POLICYDB_VERSION_POLCAP,
>  		.sym_num	= SYM_NUM,
> -		.ocon_num	= OCON_NUM,
> +		.ocon_num	= OCON_NUM - 2,
>  	},
>  	{
>  		.version	= POLICYDB_VERSION_PERMISSIVE,
>  		.sym_num	= SYM_NUM,
> -		.ocon_num	= OCON_NUM,
> +		.ocon_num	= OCON_NUM - 2,
>  	},
>  	{
>  		.version	= POLICYDB_VERSION_BOUNDARY,
>  		.sym_num	= SYM_NUM,
> -		.ocon_num	= OCON_NUM,
> +		.ocon_num	= OCON_NUM - 2,
>  	},
>  	{
>  		.version	= POLICYDB_VERSION_FILENAME_TRANS,
>  		.sym_num	= SYM_NUM,
> -		.ocon_num	= OCON_NUM,
> +		.ocon_num	= OCON_NUM - 2,
>  	},
>  	{
>  		.version	= POLICYDB_VERSION_ROLETRANS,
>  		.sym_num	= SYM_NUM,
> -		.ocon_num	= OCON_NUM,
> +		.ocon_num	= OCON_NUM - 2,
>  	},
>  	{
>  		.version	= POLICYDB_VERSION_NEW_OBJECT_DEFAULTS,
>  		.sym_num	= SYM_NUM,
> -		.ocon_num	= OCON_NUM,
> +		.ocon_num	= OCON_NUM - 2,
>  	},
>  	{
>  		.version	= POLICYDB_VERSION_DEFAULT_TYPE,
>  		.sym_num	= SYM_NUM,
> -		.ocon_num	= OCON_NUM,
> +		.ocon_num	= OCON_NUM - 2,
>  	},
>  	{
>  		.version	= POLICYDB_VERSION_CONSTRAINT_NAMES,
>  		.sym_num	= SYM_NUM,
> -		.ocon_num	= OCON_NUM,
> +		.ocon_num	= OCON_NUM - 2,
>  	},
>  	{
>  		.version	= POLICYDB_VERSION_XPERMS_IOCTL,
>  		.sym_num	= SYM_NUM,
> +		.ocon_num	= OCON_NUM - 2,
> +	},
> +	{
> +		.version	= POLICYDB_VERSION_INFINIBAND,
> +		.sym_num	= SYM_NUM,
>  		.ocon_num	= OCON_NUM,
>  	},
>  };
> @@ -2222,6 +2232,60 @@ static int ocontext_read(struct policydb *p, struct policydb_compat_info *info,
>  					goto out;
>  				break;
>  			}
> +			case OCON_PKEY:
> +				rc = next_entry(nodebuf, fp, sizeof(u32) * 6);
> +				if (rc)
> +					goto out;
> +
> +				c->u.pkey.subnet_prefix = be64_to_cpu(*((__be64 *)nodebuf));
> +				/* The subnet prefix is stored as an IPv6
> +				 * address in the policy.
> +				 *
> +				 * Check that the lower 2 DWORDS are 0.
> +				 */
> +				if (nodebuf[2] || nodebuf[3]) {
> +					rc = -EINVAL;
> +					goto out;
> +				}
> +
> +				if (nodebuf[4] > 0xffff ||
> +				    nodebuf[5] > 0xffff) {
> +					rc = -EINVAL;
> +					goto out;
> +				}
> +
> +				c->u.pkey.low_pkey = le32_to_cpu(nodebuf[4]);
> +				c->u.pkey.high_pkey = le32_to_cpu(nodebuf[5]);
> +
> +				rc = context_read_and_validate(&c->context[0],
> +							       p,
> +							       fp);
> +				if (rc)
> +					goto out;
> +				break;
> +			case OCON_IB_ENDPORT:
> +				rc = next_entry(buf, fp, sizeof(u32) * 2);
> +				if (rc)
> +					goto out;
> +				len = le32_to_cpu(buf[0]);
> +
> +				rc = str_read(&c->u.ib_endport.dev_name, GFP_KERNEL, fp, len);
> +				if (rc)
> +					goto out;
> +
> +				if (buf[1] > 0xff || buf[1] == 0) {
> +					rc = -EINVAL;
> +					goto out;
> +				}
> +
> +				c->u.ib_endport.port_num = le32_to_cpu(buf[1]);
> +
> +				rc = context_read_and_validate(&c->context[0],
> +							       p,
> +							       fp);
> +				if (rc)
> +					goto out;
> +				break;
>  			}
>  		}
>  	}
> @@ -3151,6 +3215,41 @@ static int ocontext_write(struct policydb *p, struct policydb_compat_info *info,
>  				if (rc)
>  					return rc;
>  				break;
> +			case OCON_PKEY:
> +				*((__be64 *)nodebuf) = cpu_to_be64(c->u.pkey.subnet_prefix);
> +
> +				/*
> +				 * The low order 2 bits were confirmed to be 0
> +				 * when the policy was loaded. Write them out
> +				 * as zero
> +				 */
> +				nodebuf[2] = 0;
> +				nodebuf[3] = 0;
> +
> +				nodebuf[4] = cpu_to_le32(c->u.pkey.low_pkey);
> +				nodebuf[5] = cpu_to_le32(c->u.pkey.high_pkey);
> +
> +				rc = put_entry(nodebuf, sizeof(u32), 6, fp);
> +				if (rc)
> +					return rc;
> +				rc = context_write(p, &c->context[0], fp);
> +				if (rc)
> +					return rc;
> +				break;
> +			case OCON_IB_ENDPORT:
> +				len = strlen(c->u.ib_endport.dev_name);
> +				buf[0] = cpu_to_le32(len);
> +				buf[1] = cpu_to_le32(c->u.ib_endport.port_num);
> +				rc = put_entry(buf, sizeof(u32), 2, fp);
> +				if (rc)
> +					return rc;
> +				rc = put_entry(c->u.ib_endport.dev_name, 1, len, fp);
> +				if (rc)
> +					return rc;
> +				rc = context_write(p, &c->context[0], fp);
> +				if (rc)
> +					return rc;
> +				break;
>  			}
>  		}
>  	}
> diff --git a/security/selinux/ss/policydb.h b/security/selinux/ss/policydb.h
> index 725d594..edb329d 100644
> --- a/security/selinux/ss/policydb.h
> +++ b/security/selinux/ss/policydb.h
> @@ -187,6 +187,15 @@ struct ocontext {
>  			u32 addr[4];
>  			u32 mask[4];
>  		} node6;        /* IPv6 node information */
> +		struct {
> +			u64 subnet_prefix;
> +			u16 low_pkey;
> +			u16 high_pkey;
> +		} pkey;
> +		struct {
> +			char *dev_name;
> +			u8 port_num;
> +		} ib_endport;
>  	} u;
>  	union {
>  		u32 sclass;  /* security class for genfs */
> @@ -215,14 +224,16 @@ struct genfs {
>  #define SYM_NUM     8
>  
>  /* object context array indices */
> -#define OCON_ISID  0	/* initial SIDs */
> -#define OCON_FS    1	/* unlabeled file systems */
> -#define OCON_PORT  2	/* TCP and UDP port numbers */
> -#define OCON_NETIF 3	/* network interfaces */
> -#define OCON_NODE  4	/* nodes */
> -#define OCON_FSUSE 5	/* fs_use */
> -#define OCON_NODE6 6	/* IPv6 nodes */
> -#define OCON_NUM   7
> +#define OCON_ISID	0 /* initial SIDs */
> +#define OCON_FS		1 /* unlabeled file systems */
> +#define OCON_PORT	2 /* TCP and UDP port numbers */
> +#define OCON_NETIF	3 /* network interfaces */
> +#define OCON_NODE	4 /* nodes */
> +#define OCON_FSUSE	5 /* fs_use */
> +#define OCON_NODE6	6 /* IPv6 nodes */
> +#define OCON_PKEY	7 /* Infiniband PKeys */
> +#define OCON_IB_ENDPORT	8 /* Infiniband end ports */
> +#define OCON_NUM	9
>  
>  /* The policy database */
>  struct policydb {
> 

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH v6 3/9] selinux lsm IB/core: Implement LSM notification system
  2016-12-13 14:29         ` Stephen Smalley
@ 2016-12-13 14:38           ` Daniel Jurgens
  -1 siblings, 0 replies; 51+ messages in thread
From: Daniel Jurgens @ 2016-12-13 14:38 UTC (permalink / raw)
  To: Stephen Smalley, chrisw-69jw2NvuJkxg9hUCZPvPmw,
	paul-r2n+y4ga6xFZroRs9YW3xA, eparis-FjpueFixGhCM4zKIHC2jIg,
	dledford-H+wXaHxf7aLQT0dZR+AlfA,
	sean.hefty-ral2JQCrhuEAvxtiuMwx3w,
	hal.rosenstock-Re5JQEeQqe8AvxtiuMwx3w
  Cc: linux-rdma-u79uwXL29TY76Z2rM5mHXA,
	linux-security-module-u79uwXL29TY76Z2rM5mHXA,
	selinux-+05T5uksL2qpZYMLLGbcSA

On 12/13/2016 8:26 AM, Stephen Smalley wrote:
> On 11/23/2016 09:17 AM, Dan Jurgens wrote:
>> @@ -177,6 +177,8 @@ static ssize_t sel_write_enforce(struct file *file, const char __user *buf,
>>  			avc_ss_reset(0);
>>  		selnl_notify_setenforce(selinux_enforcing);
>>  		selinux_status_update_setenforce(selinux_enforcing);
>> +		if (!selinux_enforcing)
>> +			call_lsm_notifier(LSM_POLICY_CHANGE, NULL);
> Why do you need this notification?  When switching from permissive to
> enforcing, you need (and already get) a notification since you may need
> to revoke previously granted permissions.  But what action do you need
> to take on switching to permissive?
MAD (management datagram) Agents cache if they are allowed to send and receive subnet management protocol (SMP) datagrams.  Without this notification they will still drop all SMPs in permissive mode if they weren't allowed in enforcing mode.  This is handled in [PATCH v6 4/9] IB/core: Enforce security on management datagrams.


_______________________________________________
Selinux mailing list
Selinux-+05T5uksL2qpZYMLLGbcSA@public.gmane.org
To unsubscribe, send email to Selinux-leave-+05T5uksL2pAGbPMOrvdOA@public.gmane.org
To get help, send an email containing "help" to Selinux-request-+05T5uksL2pAGbPMOrvdOA@public.gmane.org

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH v6 3/9] selinux lsm IB/core: Implement LSM notification system
@ 2016-12-13 14:38           ` Daniel Jurgens
  0 siblings, 0 replies; 51+ messages in thread
From: Daniel Jurgens @ 2016-12-13 14:38 UTC (permalink / raw)
  To: Stephen Smalley, chrisw, paul, eparis, dledford, sean.hefty,
	hal.rosenstock
  Cc: linux-rdma, linux-security-module, selinux

On 12/13/2016 8:26 AM, Stephen Smalley wrote:
> On 11/23/2016 09:17 AM, Dan Jurgens wrote:
>> @@ -177,6 +177,8 @@ static ssize_t sel_write_enforce(struct file *file, const char __user *buf,
>>  			avc_ss_reset(0);
>>  		selnl_notify_setenforce(selinux_enforcing);
>>  		selinux_status_update_setenforce(selinux_enforcing);
>> +		if (!selinux_enforcing)
>> +			call_lsm_notifier(LSM_POLICY_CHANGE, NULL);
> Why do you need this notification?  When switching from permissive to
> enforcing, you need (and already get) a notification since you may need
> to revoke previously granted permissions.  But what action do you need
> to take on switching to permissive?
MAD (management datagram) Agents cache if they are allowed to send and receive subnet management protocol (SMP) datagrams.  Without this notification they will still drop all SMPs in permissive mode if they weren't allowed in enforcing mode.  This is handled in [PATCH v6 4/9] IB/core: Enforce security on management datagrams.

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH v6 5/9] selinux: Create policydb version for Infiniband support
  2016-12-13 14:38       ` Stephen Smalley
@ 2016-12-13 14:40         ` Daniel Jurgens
  -1 siblings, 0 replies; 51+ messages in thread
From: Daniel Jurgens @ 2016-12-13 14:40 UTC (permalink / raw)
  To: Stephen Smalley, chrisw-69jw2NvuJkxg9hUCZPvPmw,
	paul-r2n+y4ga6xFZroRs9YW3xA, eparis-FjpueFixGhCM4zKIHC2jIg,
	dledford-H+wXaHxf7aLQT0dZR+AlfA,
	sean.hefty-ral2JQCrhuEAvxtiuMwx3w,
	hal.rosenstock-Re5JQEeQqe8AvxtiuMwx3w
  Cc: linux-rdma-u79uwXL29TY76Z2rM5mHXA,
	linux-security-module-u79uwXL29TY76Z2rM5mHXA,
	selinux-+05T5uksL2qpZYMLLGbcSA

On 12/13/2016 8:35 AM, Stephen Smalley wrote:
> On 11/23/2016 09:17 AM, Dan Jurgens wrote:
>> From: Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
>>
>> Support for Infiniband requires the addition of two new object contexts,
>> one for infiniband PKeys and another IB Ports. Added handlers to read
>> and write the new ocontext types when reading or writing a binary policy
>> representation.
>>
>> Signed-off-by: Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
>> Reviewed-by: Eli Cohen <eli-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
> I assume you have libsepol/checkpolicy patches for this as well?
>
Yes, I plan to submit them once the kernel changes are accepted.

_______________________________________________
Selinux mailing list
Selinux-+05T5uksL2qpZYMLLGbcSA@public.gmane.org
To unsubscribe, send email to Selinux-leave-+05T5uksL2pAGbPMOrvdOA@public.gmane.org
To get help, send an email containing "help" to Selinux-request-+05T5uksL2pAGbPMOrvdOA@public.gmane.org

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH v6 5/9] selinux: Create policydb version for Infiniband support
@ 2016-12-13 14:40         ` Daniel Jurgens
  0 siblings, 0 replies; 51+ messages in thread
From: Daniel Jurgens @ 2016-12-13 14:40 UTC (permalink / raw)
  To: Stephen Smalley, chrisw, paul, eparis, dledford, sean.hefty,
	hal.rosenstock
  Cc: linux-rdma, linux-security-module, selinux

On 12/13/2016 8:35 AM, Stephen Smalley wrote:
> On 11/23/2016 09:17 AM, Dan Jurgens wrote:
>> From: Daniel Jurgens <danielj@mellanox.com>
>>
>> Support for Infiniband requires the addition of two new object contexts,
>> one for infiniband PKeys and another IB Ports. Added handlers to read
>> and write the new ocontext types when reading or writing a binary policy
>> representation.
>>
>> Signed-off-by: Daniel Jurgens <danielj@mellanox.com>
>> Reviewed-by: Eli Cohen <eli@mellanox.com>
> I assume you have libsepol/checkpolicy patches for this as well?
>
Yes, I plan to submit them once the kernel changes are accepted.

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH v6 0/9] SELinux support for Infiniband RDMA
  2016-11-23 14:17 ` Dan Jurgens
@ 2016-12-13 15:04     ` Stephen Smalley
  -1 siblings, 0 replies; 51+ messages in thread
From: Stephen Smalley @ 2016-12-13 15:04 UTC (permalink / raw)
  To: Dan Jurgens, chrisw-69jw2NvuJkxg9hUCZPvPmw,
	paul-r2n+y4ga6xFZroRs9YW3xA, eparis-FjpueFixGhCM4zKIHC2jIg,
	dledford-H+wXaHxf7aLQT0dZR+AlfA,
	sean.hefty-ral2JQCrhuEAvxtiuMwx3w,
	hal.rosenstock-Re5JQEeQqe8AvxtiuMwx3w
  Cc: linux-rdma-u79uwXL29TY76Z2rM5mHXA,
	linux-security-module-u79uwXL29TY76Z2rM5mHXA,
	selinux-+05T5uksL2qpZYMLLGbcSA

On 11/23/2016 09:17 AM, Dan Jurgens wrote:
> From: Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
> 
> Infiniband applications access HW from user-space -- traffic is generated
> directly by HW, bypassing the kernel. Consequently, Infiniband Partitions,
> which are associated directly with HW transport endpoints, are a natural
> choice for enforcing granular mandatory access control for Infiniband. QPs may
> only send or receives packets tagged with the corresponding partition key
> (PKey). The PKey is not a cryptographic key; it's a 16 bit number identifying
> the partition.
> 
> Every Infiniband fabric is controlled by a central Subnet Manager (SM). The SM
> provisions the partitions by assigning each port with the partitions it can
> access. In addition, the SM tags each port with a subnet prefix, which
> identifies the subnet. Determining which users are allowed to access which
> partition keys on a given subnet forms an effective policy for isolating users
> on the fabric. Any application that attempts to send traffic on a given subnet
> is automatically subject to the policy, regardless of which device and port it
> uses. SM software configures the subnet through a privileged Subnet Management
> Interface (SMI), which is presented by each Infiniband port. Thus, the SMI must
> also be controlled to prevent unauthorized changes to fabric configuration and
> partitioning. 
> 
> To support access control for IB partitions and subnet management, security
> contexts must be provided for two new types of objects - PKeys and IB ports.
> 
> A PKey label consists of a subnet prefix and a range of PKey values and is
> similar to the labeling mechanism for netports. Each Infiniband port can reside
> on a different subnet. So labeling the PKey values for specific subnet prefixes
> provides the user maximum flexibility, as PKey values may be determined
> independently for different subnets. There is a single access vector for PKeys
> called "access".
> 
> An Infiniband port is labeled by device name and port number. There is a single
> access vector for IB ports called "manage_subnet".
> 
> Because RDMA allows kernel bypass, enforcement must be done during connection
> setup. Communication over RDMA requires a send and receive queue, collectively
> known as a Queue Pair (QP). A QP must be initialized by privileged system calls
> before it can be used to send or receive data. During initialization the user
> must provide the PKey and port the QP will use; at this time access control can
> be enforced.
> 
> Because there is a possibility that the enforcement settings or security
> policy can change, a means of notifying the ib_core module of such changes
> is required. To facilitate this a generic notification callback mechanism
> is added to the LSM. One callback is registered for checking the QP PKey
> associations when the policy changes. Mad agents also register a callback,
> they cache the permission to send and receive SMPs to avoid another per
> packet call to the LSM.
> 
> Because frequent accesses to the same PKey's SID is expected a cache is
> implemented which is very similar to the netport cache.
> 
> In order to properly enforce security when changes to the PKey table or
> security policy or enforcement occur ib_core must track which QPs are
> using which port, pkey index, and alternate path for every IB device.
> This makes operations that used to be atomic transactional.
> 
> When modifying a QP, ib_core must associate it with the PKey index, port,
> and alternate path specified. If the QP was already associated with
> different settings, the QP is added to the new list prior to the
> modification. If the modify succeeds then the old listing is removed. If
> the modify fails the new listing is removed and the old listing remains
> unchanged.
> 
> When destroying a QP the ib_qp structure is freed by the decive specific
> driver (i.e. mlx4_ib) if the 'destroy' is successful. This requires storing
> security related information in a separate structure. When a 'destroy'
> request is in process the ib_qp structure is in an undefined state so if
> there are changes to the security policy or PKey table, the security checks
> cannot reset the QP if it doesn't have permission for the new setting. If
> the 'destroy' fails, security for that QP must be enforced again and its
> status in the list is restored. If the 'destroy' succeeds the security info
> can be cleaned up and freed.
> 
> There are a number of locks required to protect the QP security structure
> and the QP to device/port/pkey index lists. If multiple locks are required,
> the safe locking order is: QP security structure mutex first, followed by
> any list locks needed, which are sorted first by port followed by pkey
> index.
> 
> ---
> v2:
> - Use void* blobs in the LSM hooks. Paul Moore
> - Make the policy change callback generic. Yuval Shaia, Paul Moore
> - Squash LSM changes into the patches where the calls are added. Paul Moore
> - Don't add new initial SIDs. Stephen Smalley
> - Squash MAD agent PKey and SMI patches and move logic to IB security. Dan Jurgens
> - Changed ib_end_port to ib_port. Paul Moore
> - Changed ib_port access vector from smp to manage_subnet. Paul Moore
> - Added pkey and ib_port details to the audit log. Paul Moore
> - See individual patches for more detail.
> 
> v3:
> - ib_port -> ib_endport. Paul Moore
> - use notifier chains for LSM notifications. Paul Moore
> - reorder parameters in hooks to put security blob first. Paul Moore
> - Don't treat device name as untrusted string in audit log. Paul Moore
> 
> v4:
> - Added separate AVC callback for LSM notifier. Paul Moore
> - Removed unneeded braces in ocontext_read. Paul Moore
> 
> v5:
> - Fix link error when CONFIG_SECURITY is not set. Build Robot
> - Strip issue and Gerrit-Id: Leon Romanovsky
> 
> v6:
> - Whitespace and bracket cleanup. James Morris
> - Cleanup error flow in sel_pkey_sid_slow. James Morris
> 
> Daniel Jurgens (9):
>   IB/core: IB cache enhancements to support Infiniband security
>   IB/core: Enforce PKey security on QPs
>   selinux lsm IB/core: Implement LSM notification system
>   IB/core: Enforce security on management datagrams
>   selinux: Create policydb version for Infiniband support
>   selinux: Allocate and free infiniband security hooks
>   selinux: Implement Infiniband PKey "Access" access vector
>   selinux: Add IB Port SMP access vector
>   selinux: Add a cache for quicker retreival of PKey SIDs
> 
>  drivers/infiniband/core/Makefile     |   3 +-
>  drivers/infiniband/core/cache.c      |  57 ++-
>  drivers/infiniband/core/core_priv.h  | 115 ++++++
>  drivers/infiniband/core/device.c     |  86 +++++
>  drivers/infiniband/core/mad.c        |  52 ++-
>  drivers/infiniband/core/security.c   | 709 +++++++++++++++++++++++++++++++++++
>  drivers/infiniband/core/uverbs_cmd.c |  20 +-
>  drivers/infiniband/core/verbs.c      |  27 +-
>  include/linux/lsm_audit.h            |  15 +
>  include/linux/lsm_hooks.h            |  35 ++
>  include/linux/security.h             |  50 +++
>  include/rdma/ib_mad.h                |   4 +
>  include/rdma/ib_verbs.h              |  49 +++
>  security/Kconfig                     |   9 +
>  security/lsm_audit.c                 |  16 +
>  security/security.c                  |  59 +++
>  security/selinux/Makefile            |   2 +-
>  security/selinux/hooks.c             |  86 ++++-
>  security/selinux/ibpkey.c            | 245 ++++++++++++
>  security/selinux/include/classmap.h  |   4 +
>  security/selinux/include/ibpkey.h    |  31 ++
>  security/selinux/include/objsec.h    |  11 +
>  security/selinux/include/security.h  |   7 +-
>  security/selinux/selinuxfs.c         |   2 +
>  security/selinux/ss/policydb.c       | 129 ++++++-
>  security/selinux/ss/policydb.h       |  27 +-
>  security/selinux/ss/services.c       |  81 ++++
>  27 files changed, 1886 insertions(+), 45 deletions(-)
>  create mode 100644 drivers/infiniband/core/security.c
>  create mode 100644 security/selinux/ibpkey.c
>  create mode 100644 security/selinux/include/ibpkey.h

For the LSM/SELinux bits,
Acked-by: Stephen Smalley <sds-+05T5uksL2qpZYMLLGbcSA@public.gmane.org>

Note that there will be a merge conflict on classmap.h due to commits in
the selinux next branch, but that should be easy to resolve.

We'll need the patches for the selinux userspace and refpolicy.
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH v6 0/9] SELinux support for Infiniband RDMA
@ 2016-12-13 15:04     ` Stephen Smalley
  0 siblings, 0 replies; 51+ messages in thread
From: Stephen Smalley @ 2016-12-13 15:04 UTC (permalink / raw)
  To: Dan Jurgens, chrisw, paul, eparis, dledford, sean.hefty, hal.rosenstock
  Cc: linux-rdma, linux-security-module, selinux

On 11/23/2016 09:17 AM, Dan Jurgens wrote:
> From: Daniel Jurgens <danielj@mellanox.com>
> 
> Infiniband applications access HW from user-space -- traffic is generated
> directly by HW, bypassing the kernel. Consequently, Infiniband Partitions,
> which are associated directly with HW transport endpoints, are a natural
> choice for enforcing granular mandatory access control for Infiniband. QPs may
> only send or receives packets tagged with the corresponding partition key
> (PKey). The PKey is not a cryptographic key; it's a 16 bit number identifying
> the partition.
> 
> Every Infiniband fabric is controlled by a central Subnet Manager (SM). The SM
> provisions the partitions by assigning each port with the partitions it can
> access. In addition, the SM tags each port with a subnet prefix, which
> identifies the subnet. Determining which users are allowed to access which
> partition keys on a given subnet forms an effective policy for isolating users
> on the fabric. Any application that attempts to send traffic on a given subnet
> is automatically subject to the policy, regardless of which device and port it
> uses. SM software configures the subnet through a privileged Subnet Management
> Interface (SMI), which is presented by each Infiniband port. Thus, the SMI must
> also be controlled to prevent unauthorized changes to fabric configuration and
> partitioning. 
> 
> To support access control for IB partitions and subnet management, security
> contexts must be provided for two new types of objects - PKeys and IB ports.
> 
> A PKey label consists of a subnet prefix and a range of PKey values and is
> similar to the labeling mechanism for netports. Each Infiniband port can reside
> on a different subnet. So labeling the PKey values for specific subnet prefixes
> provides the user maximum flexibility, as PKey values may be determined
> independently for different subnets. There is a single access vector for PKeys
> called "access".
> 
> An Infiniband port is labeled by device name and port number. There is a single
> access vector for IB ports called "manage_subnet".
> 
> Because RDMA allows kernel bypass, enforcement must be done during connection
> setup. Communication over RDMA requires a send and receive queue, collectively
> known as a Queue Pair (QP). A QP must be initialized by privileged system calls
> before it can be used to send or receive data. During initialization the user
> must provide the PKey and port the QP will use; at this time access control can
> be enforced.
> 
> Because there is a possibility that the enforcement settings or security
> policy can change, a means of notifying the ib_core module of such changes
> is required. To facilitate this a generic notification callback mechanism
> is added to the LSM. One callback is registered for checking the QP PKey
> associations when the policy changes. Mad agents also register a callback,
> they cache the permission to send and receive SMPs to avoid another per
> packet call to the LSM.
> 
> Because frequent accesses to the same PKey's SID is expected a cache is
> implemented which is very similar to the netport cache.
> 
> In order to properly enforce security when changes to the PKey table or
> security policy or enforcement occur ib_core must track which QPs are
> using which port, pkey index, and alternate path for every IB device.
> This makes operations that used to be atomic transactional.
> 
> When modifying a QP, ib_core must associate it with the PKey index, port,
> and alternate path specified. If the QP was already associated with
> different settings, the QP is added to the new list prior to the
> modification. If the modify succeeds then the old listing is removed. If
> the modify fails the new listing is removed and the old listing remains
> unchanged.
> 
> When destroying a QP the ib_qp structure is freed by the decive specific
> driver (i.e. mlx4_ib) if the 'destroy' is successful. This requires storing
> security related information in a separate structure. When a 'destroy'
> request is in process the ib_qp structure is in an undefined state so if
> there are changes to the security policy or PKey table, the security checks
> cannot reset the QP if it doesn't have permission for the new setting. If
> the 'destroy' fails, security for that QP must be enforced again and its
> status in the list is restored. If the 'destroy' succeeds the security info
> can be cleaned up and freed.
> 
> There are a number of locks required to protect the QP security structure
> and the QP to device/port/pkey index lists. If multiple locks are required,
> the safe locking order is: QP security structure mutex first, followed by
> any list locks needed, which are sorted first by port followed by pkey
> index.
> 
> ---
> v2:
> - Use void* blobs in the LSM hooks. Paul Moore
> - Make the policy change callback generic. Yuval Shaia, Paul Moore
> - Squash LSM changes into the patches where the calls are added. Paul Moore
> - Don't add new initial SIDs. Stephen Smalley
> - Squash MAD agent PKey and SMI patches and move logic to IB security. Dan Jurgens
> - Changed ib_end_port to ib_port. Paul Moore
> - Changed ib_port access vector from smp to manage_subnet. Paul Moore
> - Added pkey and ib_port details to the audit log. Paul Moore
> - See individual patches for more detail.
> 
> v3:
> - ib_port -> ib_endport. Paul Moore
> - use notifier chains for LSM notifications. Paul Moore
> - reorder parameters in hooks to put security blob first. Paul Moore
> - Don't treat device name as untrusted string in audit log. Paul Moore
> 
> v4:
> - Added separate AVC callback for LSM notifier. Paul Moore
> - Removed unneeded braces in ocontext_read. Paul Moore
> 
> v5:
> - Fix link error when CONFIG_SECURITY is not set. Build Robot
> - Strip issue and Gerrit-Id: Leon Romanovsky
> 
> v6:
> - Whitespace and bracket cleanup. James Morris
> - Cleanup error flow in sel_pkey_sid_slow. James Morris
> 
> Daniel Jurgens (9):
>   IB/core: IB cache enhancements to support Infiniband security
>   IB/core: Enforce PKey security on QPs
>   selinux lsm IB/core: Implement LSM notification system
>   IB/core: Enforce security on management datagrams
>   selinux: Create policydb version for Infiniband support
>   selinux: Allocate and free infiniband security hooks
>   selinux: Implement Infiniband PKey "Access" access vector
>   selinux: Add IB Port SMP access vector
>   selinux: Add a cache for quicker retreival of PKey SIDs
> 
>  drivers/infiniband/core/Makefile     |   3 +-
>  drivers/infiniband/core/cache.c      |  57 ++-
>  drivers/infiniband/core/core_priv.h  | 115 ++++++
>  drivers/infiniband/core/device.c     |  86 +++++
>  drivers/infiniband/core/mad.c        |  52 ++-
>  drivers/infiniband/core/security.c   | 709 +++++++++++++++++++++++++++++++++++
>  drivers/infiniband/core/uverbs_cmd.c |  20 +-
>  drivers/infiniband/core/verbs.c      |  27 +-
>  include/linux/lsm_audit.h            |  15 +
>  include/linux/lsm_hooks.h            |  35 ++
>  include/linux/security.h             |  50 +++
>  include/rdma/ib_mad.h                |   4 +
>  include/rdma/ib_verbs.h              |  49 +++
>  security/Kconfig                     |   9 +
>  security/lsm_audit.c                 |  16 +
>  security/security.c                  |  59 +++
>  security/selinux/Makefile            |   2 +-
>  security/selinux/hooks.c             |  86 ++++-
>  security/selinux/ibpkey.c            | 245 ++++++++++++
>  security/selinux/include/classmap.h  |   4 +
>  security/selinux/include/ibpkey.h    |  31 ++
>  security/selinux/include/objsec.h    |  11 +
>  security/selinux/include/security.h  |   7 +-
>  security/selinux/selinuxfs.c         |   2 +
>  security/selinux/ss/policydb.c       | 129 ++++++-
>  security/selinux/ss/policydb.h       |  27 +-
>  security/selinux/ss/services.c       |  81 ++++
>  27 files changed, 1886 insertions(+), 45 deletions(-)
>  create mode 100644 drivers/infiniband/core/security.c
>  create mode 100644 security/selinux/ibpkey.c
>  create mode 100644 security/selinux/include/ibpkey.h

For the LSM/SELinux bits,
Acked-by: Stephen Smalley <sds@tycho.nsa.gov>

Note that there will be a merge conflict on classmap.h due to commits in
the selinux next branch, but that should be easy to resolve.

We'll need the patches for the selinux userspace and refpolicy.

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH v6 0/9] SELinux support for Infiniband RDMA
  2016-12-13 15:04     ` Stephen Smalley
@ 2016-12-13 16:25       ` Daniel Jurgens
  -1 siblings, 0 replies; 51+ messages in thread
From: Daniel Jurgens @ 2016-12-13 16:25 UTC (permalink / raw)
  To: Stephen Smalley, chrisw-69jw2NvuJkxg9hUCZPvPmw,
	paul-r2n+y4ga6xFZroRs9YW3xA, eparis-FjpueFixGhCM4zKIHC2jIg,
	dledford-H+wXaHxf7aLQT0dZR+AlfA,
	sean.hefty-ral2JQCrhuEAvxtiuMwx3w,
	hal.rosenstock-Re5JQEeQqe8AvxtiuMwx3w
  Cc: linux-rdma-u79uwXL29TY76Z2rM5mHXA,
	linux-security-module-u79uwXL29TY76Z2rM5mHXA,
	selinux-+05T5uksL2qpZYMLLGbcSA

On 12/13/2016 9:01 AM, Stephen Smalley wrote:
> On 11/23/2016 09:17 AM, Dan Jurgens wrote:
>> From: Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
>>
>> Infiniband applications access HW from user-space -- traffic is generated
>> directly by HW, bypassing the kernel. Consequently, Infiniband Partitions,
>> which are associated directly with HW transport endpoints, are a natural
>> choice for enforcing granular mandatory access control for Infiniband. QPs may
>> only send or receives packets tagged with the corresponding partition key
>> (PKey). The PKey is not a cryptographic key; it's a 16 bit number identifying
>> the partition.
>>
>> Every Infiniband fabric is controlled by a central Subnet Manager (SM). The SM
>> provisions the partitions by assigning each port with the partitions it can
>> access. In addition, the SM tags each port with a subnet prefix, which
>> identifies the subnet. Determining which users are allowed to access which
>> partition keys on a given subnet forms an effective policy for isolating users
>> on the fabric. Any application that attempts to send traffic on a given subnet
>> is automatically subject to the policy, regardless of which device and port it
>> uses. SM software configures the subnet through a privileged Subnet Management
>> Interface (SMI), which is presented by each Infiniband port. Thus, the SMI must
>> also be controlled to prevent unauthorized changes to fabric configuration and
>> partitioning. 
>>
>> To support access control for IB partitions and subnet management, security
>> contexts must be provided for two new types of objects - PKeys and IB ports.
>>
>> A PKey label consists of a subnet prefix and a range of PKey values and is
>> similar to the labeling mechanism for netports. Each Infiniband port can reside
>> on a different subnet. So labeling the PKey values for specific subnet prefixes
>> provides the user maximum flexibility, as PKey values may be determined
>> independently for different subnets. There is a single access vector for PKeys
>> called "access".
>>
>> An Infiniband port is labeled by device name and port number. There is a single
>> access vector for IB ports called "manage_subnet".
>>
>> Because RDMA allows kernel bypass, enforcement must be done during connection
>> setup. Communication over RDMA requires a send and receive queue, collectively
>> known as a Queue Pair (QP). A QP must be initialized by privileged system calls
>> before it can be used to send or receive data. During initialization the user
>> must provide the PKey and port the QP will use; at this time access control can
>> be enforced.
>>
>> Because there is a possibility that the enforcement settings or security
>> policy can change, a means of notifying the ib_core module of such changes
>> is required. To facilitate this a generic notification callback mechanism
>> is added to the LSM. One callback is registered for checking the QP PKey
>> associations when the policy changes. Mad agents also register a callback,
>> they cache the permission to send and receive SMPs to avoid another per
>> packet call to the LSM.
>>
>> Because frequent accesses to the same PKey's SID is expected a cache is
>> implemented which is very similar to the netport cache.
>>
>> In order to properly enforce security when changes to the PKey table or
>> security policy or enforcement occur ib_core must track which QPs are
>> using which port, pkey index, and alternate path for every IB device.
>> This makes operations that used to be atomic transactional.
>>
>> When modifying a QP, ib_core must associate it with the PKey index, port,
>> and alternate path specified. If the QP was already associated with
>> different settings, the QP is added to the new list prior to the
>> modification. If the modify succeeds then the old listing is removed. If
>> the modify fails the new listing is removed and the old listing remains
>> unchanged.
>>
>> When destroying a QP the ib_qp structure is freed by the decive specific
>> driver (i.e. mlx4_ib) if the 'destroy' is successful. This requires storing
>> security related information in a separate structure. When a 'destroy'
>> request is in process the ib_qp structure is in an undefined state so if
>> there are changes to the security policy or PKey table, the security checks
>> cannot reset the QP if it doesn't have permission for the new setting. If
>> the 'destroy' fails, security for that QP must be enforced again and its
>> status in the list is restored. If the 'destroy' succeeds the security info
>> can be cleaned up and freed.
>>
>> There are a number of locks required to protect the QP security structure
>> and the QP to device/port/pkey index lists. If multiple locks are required,
>> the safe locking order is: QP security structure mutex first, followed by
>> any list locks needed, which are sorted first by port followed by pkey
>> index.
>>
>> ---
>> v2:
>> - Use void* blobs in the LSM hooks. Paul Moore
>> - Make the policy change callback generic. Yuval Shaia, Paul Moore
>> - Squash LSM changes into the patches where the calls are added. Paul Moore
>> - Don't add new initial SIDs. Stephen Smalley
>> - Squash MAD agent PKey and SMI patches and move logic to IB security. Dan Jurgens
>> - Changed ib_end_port to ib_port. Paul Moore
>> - Changed ib_port access vector from smp to manage_subnet. Paul Moore
>> - Added pkey and ib_port details to the audit log. Paul Moore
>> - See individual patches for more detail.
>>
>> v3:
>> - ib_port -> ib_endport. Paul Moore
>> - use notifier chains for LSM notifications. Paul Moore
>> - reorder parameters in hooks to put security blob first. Paul Moore
>> - Don't treat device name as untrusted string in audit log. Paul Moore
>>
>> v4:
>> - Added separate AVC callback for LSM notifier. Paul Moore
>> - Removed unneeded braces in ocontext_read. Paul Moore
>>
>> v5:
>> - Fix link error when CONFIG_SECURITY is not set. Build Robot
>> - Strip issue and Gerrit-Id: Leon Romanovsky
>>
>> v6:
>> - Whitespace and bracket cleanup. James Morris
>> - Cleanup error flow in sel_pkey_sid_slow. James Morris
>>
>> Daniel Jurgens (9):
>>   IB/core: IB cache enhancements to support Infiniband security
>>   IB/core: Enforce PKey security on QPs
>>   selinux lsm IB/core: Implement LSM notification system
>>   IB/core: Enforce security on management datagrams
>>   selinux: Create policydb version for Infiniband support
>>   selinux: Allocate and free infiniband security hooks
>>   selinux: Implement Infiniband PKey "Access" access vector
>>   selinux: Add IB Port SMP access vector
>>   selinux: Add a cache for quicker retreival of PKey SIDs
>>
>>  drivers/infiniband/core/Makefile     |   3 +-
>>  drivers/infiniband/core/cache.c      |  57 ++-
>>  drivers/infiniband/core/core_priv.h  | 115 ++++++
>>  drivers/infiniband/core/device.c     |  86 +++++
>>  drivers/infiniband/core/mad.c        |  52 ++-
>>  drivers/infiniband/core/security.c   | 709 +++++++++++++++++++++++++++++++++++
>>  drivers/infiniband/core/uverbs_cmd.c |  20 +-
>>  drivers/infiniband/core/verbs.c      |  27 +-
>>  include/linux/lsm_audit.h            |  15 +
>>  include/linux/lsm_hooks.h            |  35 ++
>>  include/linux/security.h             |  50 +++
>>  include/rdma/ib_mad.h                |   4 +
>>  include/rdma/ib_verbs.h              |  49 +++
>>  security/Kconfig                     |   9 +
>>  security/lsm_audit.c                 |  16 +
>>  security/security.c                  |  59 +++
>>  security/selinux/Makefile            |   2 +-
>>  security/selinux/hooks.c             |  86 ++++-
>>  security/selinux/ibpkey.c            | 245 ++++++++++++
>>  security/selinux/include/classmap.h  |   4 +
>>  security/selinux/include/ibpkey.h    |  31 ++
>>  security/selinux/include/objsec.h    |  11 +
>>  security/selinux/include/security.h  |   7 +-
>>  security/selinux/selinuxfs.c         |   2 +
>>  security/selinux/ss/policydb.c       | 129 ++++++-
>>  security/selinux/ss/policydb.h       |  27 +-
>>  security/selinux/ss/services.c       |  81 ++++
>>  27 files changed, 1886 insertions(+), 45 deletions(-)
>>  create mode 100644 drivers/infiniband/core/security.c
>>  create mode 100644 security/selinux/ibpkey.c
>>  create mode 100644 security/selinux/include/ibpkey.h
> For the LSM/SELinux bits,
> Acked-by: Stephen Smalley <sds-+05T5uksL2qpZYMLLGbcSA@public.gmane.org>
>
> Note that there will be a merge conflict on classmap.h due to commits in
> the selinux next branch, but that should be easy to resolve.
>
> We'll need the patches for the selinux userspace and refpolicy.
Thanks Stephen, I need to rebase the user space and do some patch breakup.  I'll start on that soon.

> --
> To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>


_______________________________________________
Selinux mailing list
Selinux-+05T5uksL2qpZYMLLGbcSA@public.gmane.org
To unsubscribe, send email to Selinux-leave-+05T5uksL2pAGbPMOrvdOA@public.gmane.org
To get help, send an email containing "help" to Selinux-request-+05T5uksL2pAGbPMOrvdOA@public.gmane.org

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH v6 0/9] SELinux support for Infiniband RDMA
@ 2016-12-13 16:25       ` Daniel Jurgens
  0 siblings, 0 replies; 51+ messages in thread
From: Daniel Jurgens @ 2016-12-13 16:25 UTC (permalink / raw)
  To: Stephen Smalley, chrisw, paul, eparis, dledford, sean.hefty,
	hal.rosenstock
  Cc: linux-rdma, linux-security-module, selinux

On 12/13/2016 9:01 AM, Stephen Smalley wrote:
> On 11/23/2016 09:17 AM, Dan Jurgens wrote:
>> From: Daniel Jurgens <danielj@mellanox.com>
>>
>> Infiniband applications access HW from user-space -- traffic is generated
>> directly by HW, bypassing the kernel. Consequently, Infiniband Partitions,
>> which are associated directly with HW transport endpoints, are a natural
>> choice for enforcing granular mandatory access control for Infiniband. QPs may
>> only send or receives packets tagged with the corresponding partition key
>> (PKey). The PKey is not a cryptographic key; it's a 16 bit number identifying
>> the partition.
>>
>> Every Infiniband fabric is controlled by a central Subnet Manager (SM). The SM
>> provisions the partitions by assigning each port with the partitions it can
>> access. In addition, the SM tags each port with a subnet prefix, which
>> identifies the subnet. Determining which users are allowed to access which
>> partition keys on a given subnet forms an effective policy for isolating users
>> on the fabric. Any application that attempts to send traffic on a given subnet
>> is automatically subject to the policy, regardless of which device and port it
>> uses. SM software configures the subnet through a privileged Subnet Management
>> Interface (SMI), which is presented by each Infiniband port. Thus, the SMI must
>> also be controlled to prevent unauthorized changes to fabric configuration and
>> partitioning. 
>>
>> To support access control for IB partitions and subnet management, security
>> contexts must be provided for two new types of objects - PKeys and IB ports.
>>
>> A PKey label consists of a subnet prefix and a range of PKey values and is
>> similar to the labeling mechanism for netports. Each Infiniband port can reside
>> on a different subnet. So labeling the PKey values for specific subnet prefixes
>> provides the user maximum flexibility, as PKey values may be determined
>> independently for different subnets. There is a single access vector for PKeys
>> called "access".
>>
>> An Infiniband port is labeled by device name and port number. There is a single
>> access vector for IB ports called "manage_subnet".
>>
>> Because RDMA allows kernel bypass, enforcement must be done during connection
>> setup. Communication over RDMA requires a send and receive queue, collectively
>> known as a Queue Pair (QP). A QP must be initialized by privileged system calls
>> before it can be used to send or receive data. During initialization the user
>> must provide the PKey and port the QP will use; at this time access control can
>> be enforced.
>>
>> Because there is a possibility that the enforcement settings or security
>> policy can change, a means of notifying the ib_core module of such changes
>> is required. To facilitate this a generic notification callback mechanism
>> is added to the LSM. One callback is registered for checking the QP PKey
>> associations when the policy changes. Mad agents also register a callback,
>> they cache the permission to send and receive SMPs to avoid another per
>> packet call to the LSM.
>>
>> Because frequent accesses to the same PKey's SID is expected a cache is
>> implemented which is very similar to the netport cache.
>>
>> In order to properly enforce security when changes to the PKey table or
>> security policy or enforcement occur ib_core must track which QPs are
>> using which port, pkey index, and alternate path for every IB device.
>> This makes operations that used to be atomic transactional.
>>
>> When modifying a QP, ib_core must associate it with the PKey index, port,
>> and alternate path specified. If the QP was already associated with
>> different settings, the QP is added to the new list prior to the
>> modification. If the modify succeeds then the old listing is removed. If
>> the modify fails the new listing is removed and the old listing remains
>> unchanged.
>>
>> When destroying a QP the ib_qp structure is freed by the decive specific
>> driver (i.e. mlx4_ib) if the 'destroy' is successful. This requires storing
>> security related information in a separate structure. When a 'destroy'
>> request is in process the ib_qp structure is in an undefined state so if
>> there are changes to the security policy or PKey table, the security checks
>> cannot reset the QP if it doesn't have permission for the new setting. If
>> the 'destroy' fails, security for that QP must be enforced again and its
>> status in the list is restored. If the 'destroy' succeeds the security info
>> can be cleaned up and freed.
>>
>> There are a number of locks required to protect the QP security structure
>> and the QP to device/port/pkey index lists. If multiple locks are required,
>> the safe locking order is: QP security structure mutex first, followed by
>> any list locks needed, which are sorted first by port followed by pkey
>> index.
>>
>> ---
>> v2:
>> - Use void* blobs in the LSM hooks. Paul Moore
>> - Make the policy change callback generic. Yuval Shaia, Paul Moore
>> - Squash LSM changes into the patches where the calls are added. Paul Moore
>> - Don't add new initial SIDs. Stephen Smalley
>> - Squash MAD agent PKey and SMI patches and move logic to IB security. Dan Jurgens
>> - Changed ib_end_port to ib_port. Paul Moore
>> - Changed ib_port access vector from smp to manage_subnet. Paul Moore
>> - Added pkey and ib_port details to the audit log. Paul Moore
>> - See individual patches for more detail.
>>
>> v3:
>> - ib_port -> ib_endport. Paul Moore
>> - use notifier chains for LSM notifications. Paul Moore
>> - reorder parameters in hooks to put security blob first. Paul Moore
>> - Don't treat device name as untrusted string in audit log. Paul Moore
>>
>> v4:
>> - Added separate AVC callback for LSM notifier. Paul Moore
>> - Removed unneeded braces in ocontext_read. Paul Moore
>>
>> v5:
>> - Fix link error when CONFIG_SECURITY is not set. Build Robot
>> - Strip issue and Gerrit-Id: Leon Romanovsky
>>
>> v6:
>> - Whitespace and bracket cleanup. James Morris
>> - Cleanup error flow in sel_pkey_sid_slow. James Morris
>>
>> Daniel Jurgens (9):
>>   IB/core: IB cache enhancements to support Infiniband security
>>   IB/core: Enforce PKey security on QPs
>>   selinux lsm IB/core: Implement LSM notification system
>>   IB/core: Enforce security on management datagrams
>>   selinux: Create policydb version for Infiniband support
>>   selinux: Allocate and free infiniband security hooks
>>   selinux: Implement Infiniband PKey "Access" access vector
>>   selinux: Add IB Port SMP access vector
>>   selinux: Add a cache for quicker retreival of PKey SIDs
>>
>>  drivers/infiniband/core/Makefile     |   3 +-
>>  drivers/infiniband/core/cache.c      |  57 ++-
>>  drivers/infiniband/core/core_priv.h  | 115 ++++++
>>  drivers/infiniband/core/device.c     |  86 +++++
>>  drivers/infiniband/core/mad.c        |  52 ++-
>>  drivers/infiniband/core/security.c   | 709 +++++++++++++++++++++++++++++++++++
>>  drivers/infiniband/core/uverbs_cmd.c |  20 +-
>>  drivers/infiniband/core/verbs.c      |  27 +-
>>  include/linux/lsm_audit.h            |  15 +
>>  include/linux/lsm_hooks.h            |  35 ++
>>  include/linux/security.h             |  50 +++
>>  include/rdma/ib_mad.h                |   4 +
>>  include/rdma/ib_verbs.h              |  49 +++
>>  security/Kconfig                     |   9 +
>>  security/lsm_audit.c                 |  16 +
>>  security/security.c                  |  59 +++
>>  security/selinux/Makefile            |   2 +-
>>  security/selinux/hooks.c             |  86 ++++-
>>  security/selinux/ibpkey.c            | 245 ++++++++++++
>>  security/selinux/include/classmap.h  |   4 +
>>  security/selinux/include/ibpkey.h    |  31 ++
>>  security/selinux/include/objsec.h    |  11 +
>>  security/selinux/include/security.h  |   7 +-
>>  security/selinux/selinuxfs.c         |   2 +
>>  security/selinux/ss/policydb.c       | 129 ++++++-
>>  security/selinux/ss/policydb.h       |  27 +-
>>  security/selinux/ss/services.c       |  81 ++++
>>  27 files changed, 1886 insertions(+), 45 deletions(-)
>>  create mode 100644 drivers/infiniband/core/security.c
>>  create mode 100644 security/selinux/ibpkey.c
>>  create mode 100644 security/selinux/include/ibpkey.h
> For the LSM/SELinux bits,
> Acked-by: Stephen Smalley <sds@tycho.nsa.gov>
>
> Note that there will be a merge conflict on classmap.h due to commits in
> the selinux next branch, but that should be easy to resolve.
>
> We'll need the patches for the selinux userspace and refpolicy.
Thanks Stephen, I need to rebase the user space and do some patch breakup.  I'll start on that soon.

> --
> To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH v6 0/9] SELinux support for Infiniband RDMA
  2016-12-13 16:25       ` Daniel Jurgens
  (?)
@ 2016-12-13 22:17       ` Paul Moore
  2017-01-24 21:40         ` Doug Ledford
  -1 siblings, 1 reply; 51+ messages in thread
From: Paul Moore @ 2016-12-13 22:17 UTC (permalink / raw)
  To: Daniel Jurgens
  Cc: Stephen Smalley, chrisw, eparis, dledford, sean.hefty,
	hal.rosenstock, linux-rdma, linux-security-module, selinux

On Tue, Dec 13, 2016 at 11:25 AM, Daniel Jurgens <danielj@mellanox.com> wrote:
> On 12/13/2016 9:01 AM, Stephen Smalley wrote:
>> For the LSM/SELinux bits,
>> Acked-by: Stephen Smalley <sds@tycho.nsa.gov>
>>
>> Note that there will be a merge conflict on classmap.h due to commits in
>> the selinux next branch, but that should be easy to resolve.
>>
>> We'll need the patches for the selinux userspace and refpolicy.
>
> Thanks Stephen, I need to rebase the user space and do some patch breakup.  I'll start on that soon.

Sorry, I haven't had a chance to look at v6, but considering all our
discussions on the previous versions I don't expect any issues from
me.  I was hoping for some more generic hooks/controls, but that
doesn't look to be possible given the nature of RDMA.  I also want to
mention again the need for tests; we've talked about this in the past
and while it isn't possible to run the tests without IB hardware, I
would like to see us merge tests into the selinux-testsuite so that
those who do have the required h/w available could run the tests.

Assuming we can sort out the SELinux userspace and and tests by the
end of January, I see no reason why this couldn't go in for v4.11.

-- 
paul moore
www.paul-moore.com

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH v6 0/9] SELinux support for Infiniband RDMA
  2016-12-13 22:17       ` Paul Moore
@ 2017-01-24 21:40         ` Doug Ledford
       [not found]           ` <1485294015.43764.91.camel-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
  0 siblings, 1 reply; 51+ messages in thread
From: Doug Ledford @ 2017-01-24 21:40 UTC (permalink / raw)
  To: Paul Moore, Daniel Jurgens
  Cc: Stephen Smalley, chrisw, eparis, sean.hefty, hal.rosenstock,
	linux-rdma, linux-security-module, selinux

[-- Attachment #1: Type: text/plain, Size: 1839 bytes --]

On Tue, 2016-12-13 at 17:17 -0500, Paul Moore wrote:
> On Tue, Dec 13, 2016 at 11:25 AM, Daniel Jurgens <danielj@mellanox.co
> m> wrote:
> > 
> > On 12/13/2016 9:01 AM, Stephen Smalley wrote:
> > > 
> > > For the LSM/SELinux bits,
> > > Acked-by: Stephen Smalley <sds@tycho.nsa.gov>
> > > 
> > > Note that there will be a merge conflict on classmap.h due to
> > > commits in
> > > the selinux next branch, but that should be easy to resolve.
> > > 
> > > We'll need the patches for the selinux userspace and refpolicy.
> > 
> > Thanks Stephen, I need to rebase the user space and do some patch
> > breakup.  I'll start on that soon.
> 
> Sorry, I haven't had a chance to look at v6, but considering all our
> discussions on the previous versions I don't expect any issues from
> me.  I was hoping for some more generic hooks/controls, but that
> doesn't look to be possible given the nature of RDMA.  I also want to
> mention again the need for tests; we've talked about this in the past
> and while it isn't possible to run the tests without IB hardware, I
> would like to see us merge tests into the selinux-testsuite so that
> those who do have the required h/w available could run the tests.
> 
> Assuming we can sort out the SELinux userspace and and tests by the
> end of January, I see no reason why this couldn't go in for v4.11.

Daniel, can you work with people on the userspace and tests?  I'll pull
this into a branch (I assume by Paul's and Stephen's comments that they
expect it to go through my tree) ready to go, but hold actually
submitting it in the merge window until I've heard more from you all
that userspace is ready.

-- 
Doug Ledford <dledford@redhat.com>
    GPG KeyID: B826A3330E572FDD
   
Key fingerprint = AE6B 1BDA 122B 23B4 265B  1274 B826 A333 0E57 2FDD

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH v6 0/9] SELinux support for Infiniband RDMA
  2017-01-24 21:40         ` Doug Ledford
@ 2017-01-24 21:45               ` Doug Ledford
  0 siblings, 0 replies; 51+ messages in thread
From: Doug Ledford @ 2017-01-24 21:45 UTC (permalink / raw)
  To: Paul Moore, Daniel Jurgens
  Cc: Stephen Smalley, chrisw-69jw2NvuJkxg9hUCZPvPmw,
	eparis-FjpueFixGhCM4zKIHC2jIg, sean.hefty-ral2JQCrhuEAvxtiuMwx3w,
	hal.rosenstock-Re5JQEeQqe8AvxtiuMwx3w,
	linux-rdma-u79uwXL29TY76Z2rM5mHXA,
	linux-security-module-u79uwXL29TY76Z2rM5mHXA,
	selinux-+05T5uksL2qpZYMLLGbcSA

[-- Attachment #1: Type: text/plain, Size: 2184 bytes --]

On Tue, 2017-01-24 at 16:40 -0500, Doug Ledford wrote:
> On Tue, 2016-12-13 at 17:17 -0500, Paul Moore wrote:
> > 
> > On Tue, Dec 13, 2016 at 11:25 AM, Daniel Jurgens <danielj@mellanox.
> > co
> > m> wrote:
> > > 
> > > 
> > > On 12/13/2016 9:01 AM, Stephen Smalley wrote:
> > > > 
> > > > 
> > > > For the LSM/SELinux bits,
> > > > Acked-by: Stephen Smalley <sds-+05T5uksL2qpZYMLLGbcSA@public.gmane.org>
> > > > 
> > > > Note that there will be a merge conflict on classmap.h due to
> > > > commits in
> > > > the selinux next branch, but that should be easy to resolve.
> > > > 
> > > > We'll need the patches for the selinux userspace and refpolicy.
> > > 
> > > Thanks Stephen, I need to rebase the user space and do some patch
> > > breakup.  I'll start on that soon.
> > 
> > Sorry, I haven't had a chance to look at v6, but considering all
> > our
> > discussions on the previous versions I don't expect any issues from
> > me.  I was hoping for some more generic hooks/controls, but that
> > doesn't look to be possible given the nature of RDMA.  I also want
> > to
> > mention again the need for tests; we've talked about this in the
> > past
> > and while it isn't possible to run the tests without IB hardware, I
> > would like to see us merge tests into the selinux-testsuite so that
> > those who do have the required h/w available could run the tests.
> > 
> > Assuming we can sort out the SELinux userspace and and tests by the
> > end of January, I see no reason why this couldn't go in for v4.11.
> 
> Daniel, can you work with people on the userspace and tests?  I'll
> pull
> this into a branch (I assume by Paul's and Stephen's comments that
> they
> expect it to go through my tree) ready to go, but hold actually
> submitting it in the merge window until I've heard more from you all
> that userspace is ready.

Although it would also be helpful if you could rebase on a current tree
(preferably my k.o/for-4.11 branch).

-- 
Doug Ledford <dledford-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
    GPG KeyID: B826A3330E572FDD
   
Key fingerprint = AE6B 1BDA 122B 23B4 265B  1274 B826 A333 0E57 2FDD

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH v6 0/9] SELinux support for Infiniband RDMA
@ 2017-01-24 21:45               ` Doug Ledford
  0 siblings, 0 replies; 51+ messages in thread
From: Doug Ledford @ 2017-01-24 21:45 UTC (permalink / raw)
  To: Paul Moore, Daniel Jurgens
  Cc: Stephen Smalley, chrisw, eparis, sean.hefty, hal.rosenstock,
	linux-rdma, linux-security-module, selinux

[-- Attachment #1: Type: text/plain, Size: 2129 bytes --]

On Tue, 2017-01-24 at 16:40 -0500, Doug Ledford wrote:
> On Tue, 2016-12-13 at 17:17 -0500, Paul Moore wrote:
> > 
> > On Tue, Dec 13, 2016 at 11:25 AM, Daniel Jurgens <danielj@mellanox.
> > co
> > m> wrote:
> > > 
> > > 
> > > On 12/13/2016 9:01 AM, Stephen Smalley wrote:
> > > > 
> > > > 
> > > > For the LSM/SELinux bits,
> > > > Acked-by: Stephen Smalley <sds@tycho.nsa.gov>
> > > > 
> > > > Note that there will be a merge conflict on classmap.h due to
> > > > commits in
> > > > the selinux next branch, but that should be easy to resolve.
> > > > 
> > > > We'll need the patches for the selinux userspace and refpolicy.
> > > 
> > > Thanks Stephen, I need to rebase the user space and do some patch
> > > breakup.  I'll start on that soon.
> > 
> > Sorry, I haven't had a chance to look at v6, but considering all
> > our
> > discussions on the previous versions I don't expect any issues from
> > me.  I was hoping for some more generic hooks/controls, but that
> > doesn't look to be possible given the nature of RDMA.  I also want
> > to
> > mention again the need for tests; we've talked about this in the
> > past
> > and while it isn't possible to run the tests without IB hardware, I
> > would like to see us merge tests into the selinux-testsuite so that
> > those who do have the required h/w available could run the tests.
> > 
> > Assuming we can sort out the SELinux userspace and and tests by the
> > end of January, I see no reason why this couldn't go in for v4.11.
> 
> Daniel, can you work with people on the userspace and tests?  I'll
> pull
> this into a branch (I assume by Paul's and Stephen's comments that
> they
> expect it to go through my tree) ready to go, but hold actually
> submitting it in the merge window until I've heard more from you all
> that userspace is ready.

Although it would also be helpful if you could rebase on a current tree
(preferably my k.o/for-4.11 branch).

-- 
Doug Ledford <dledford@redhat.com>
    GPG KeyID: B826A3330E572FDD
   
Key fingerprint = AE6B 1BDA 122B 23B4 265B  1274 B826 A333 0E57 2FDD

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH v6 0/9] SELinux support for Infiniband RDMA
  2017-01-24 21:45               ` Doug Ledford
  (?)
@ 2017-01-24 22:40               ` Daniel Jurgens
       [not found]                 ` <VI1PR0501MB242933AC0EC458EAD2792560C4750-o1MPJYiShEyB6Z+oivrBG8DSnupUy6xnnBOFsp37pqbUKgpGm//BTAC/G2K4zDHf@public.gmane.org>
  -1 siblings, 1 reply; 51+ messages in thread
From: Daniel Jurgens @ 2017-01-24 22:40 UTC (permalink / raw)
  To: Doug Ledford, Paul Moore
  Cc: Stephen Smalley, chrisw, eparis, sean.hefty, hal.rosenstock,
	linux-rdma, linux-security-module, selinux

On 1/24/2017 3:45 PM, Doug Ledford wrote:
> On Tue, 2017-01-24 at 16:40 -0500, Doug Ledford wrote:
>> On Tue, 2016-12-13 at 17:17 -0500, Paul Moore wrote:
>>> On Tue, Dec 13, 2016 at 11:25 AM, Daniel Jurgens <danielj@mellanox.
>>> co
>>> m> wrote:
>>>>
>>>> On 12/13/2016 9:01 AM, Stephen Smalley wrote:
>>>>>
>>>>> For the LSM/SELinux bits,
>>>>> Acked-by: Stephen Smalley <sds@tycho.nsa.gov>
>>>>>
>>>>> Note that there will be a merge conflict on classmap.h due to
>>>>> commits in
>>>>> the selinux next branch, but that should be easy to resolve.
>>>>>
>>>>> We'll need the patches for the selinux userspace and refpolicy.
>>>> Thanks Stephen, I need to rebase the user space and do some patch
>>>> breakup.  I'll start on that soon.
>>> Sorry, I haven't had a chance to look at v6, but considering all
>>> our
>>> discussions on the previous versions I don't expect any issues from
>>> me.  I was hoping for some more generic hooks/controls, but that
>>> doesn't look to be possible given the nature of RDMA.  I also want
>>> to
>>> mention again the need for tests; we've talked about this in the
>>> past
>>> and while it isn't possible to run the tests without IB hardware, I
>>> would like to see us merge tests into the selinux-testsuite so that
>>> those who do have the required h/w available could run the tests.
>>>
>>> Assuming we can sort out the SELinux userspace and and tests by the
>>> end of January, I see no reason why this couldn't go in for v4.11.
>> Daniel, can you work with people on the userspace and tests?  I'll
>> pull
>> this into a branch (I assume by Paul's and Stephen's comments that
>> they
>> expect it to go through my tree) ready to go, but hold actually
>> submitting it in the merge window until I've heard more from you all
>> that userspace is ready.
> Although it would also be helpful if you could rebase on a current tree
> (preferably my k.o/for-4.11 branch).
>
Doug, I'm working on the user space patches, hope to be ready to submit in the next 1-2 weeks.  Do you want me to rebase now or wait until those are submitted?


^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH v6 0/9] SELinux support for Infiniband RDMA
  2017-01-24 22:40               ` Daniel Jurgens
@ 2017-01-25  3:08                     ` Doug Ledford
  0 siblings, 0 replies; 51+ messages in thread
From: Doug Ledford @ 2017-01-25  3:08 UTC (permalink / raw)
  To: Daniel Jurgens, Paul Moore
  Cc: Stephen Smalley, chrisw-69jw2NvuJkxg9hUCZPvPmw,
	eparis-FjpueFixGhCM4zKIHC2jIg, sean.hefty-ral2JQCrhuEAvxtiuMwx3w,
	hal.rosenstock-Re5JQEeQqe8AvxtiuMwx3w,
	linux-rdma-u79uwXL29TY76Z2rM5mHXA,
	linux-security-module-u79uwXL29TY76Z2rM5mHXA,
	selinux-+05T5uksL2qpZYMLLGbcSA

[-- Attachment #1: Type: text/plain, Size: 731 bytes --]

On Tue, 2017-01-24 at 22:40 +0000, Daniel Jurgens wrote:
> On 1/24/2017 3:45 PM, Doug Ledford wrote:
> > 
> > Although it would also be helpful if you could rebase on a current
> > tree
> > (preferably my k.o/for-4.11 branch).
> > 
> Doug, I'm working on the user space patches, hope to be ready to
> submit in the next 1-2 weeks.  Do you want me to rebase now or wait
> until those are submitted?

I would suggest moving the rebase up just so I can provide you with an
upstream branch to test against with your user space stuff.

-- 
Doug Ledford <dledford-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
    GPG KeyID: B826A3330E572FDD
   
Key fingerprint = AE6B 1BDA 122B 23B4 265B  1274 B826 A333 0E57 2FDD

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH v6 0/9] SELinux support for Infiniband RDMA
@ 2017-01-25  3:08                     ` Doug Ledford
  0 siblings, 0 replies; 51+ messages in thread
From: Doug Ledford @ 2017-01-25  3:08 UTC (permalink / raw)
  To: Daniel Jurgens, Paul Moore
  Cc: Stephen Smalley, chrisw, eparis, sean.hefty, hal.rosenstock,
	linux-rdma, linux-security-module, selinux

[-- Attachment #1: Type: text/plain, Size: 702 bytes --]

On Tue, 2017-01-24 at 22:40 +0000, Daniel Jurgens wrote:
> On 1/24/2017 3:45 PM, Doug Ledford wrote:
> > 
> > Although it would also be helpful if you could rebase on a current
> > tree
> > (preferably my k.o/for-4.11 branch).
> > 
> Doug, I'm working on the user space patches, hope to be ready to
> submit in the next 1-2 weeks.  Do you want me to rebase now or wait
> until those are submitted?

I would suggest moving the rebase up just so I can provide you with an
upstream branch to test against with your user space stuff.

-- 
Doug Ledford <dledford@redhat.com>
    GPG KeyID: B826A3330E572FDD
   
Key fingerprint = AE6B 1BDA 122B 23B4 265B  1274 B826 A333 0E57 2FDD

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH v6 0/9] SELinux support for Infiniband RDMA
  2017-01-24 21:40         ` Doug Ledford
@ 2017-01-25  7:58               ` Paul Moore
  0 siblings, 0 replies; 51+ messages in thread
From: Paul Moore @ 2017-01-25  7:58 UTC (permalink / raw)
  To: Doug Ledford
  Cc: Daniel Jurgens, Stephen Smalley, chrisw-69jw2NvuJkxg9hUCZPvPmw,
	eparis-FjpueFixGhCM4zKIHC2jIg, sean.hefty-ral2JQCrhuEAvxtiuMwx3w,
	hal.rosenstock-Re5JQEeQqe8AvxtiuMwx3w,
	linux-rdma-u79uwXL29TY76Z2rM5mHXA,
	linux-security-module-u79uwXL29TY76Z2rM5mHXA,
	selinux-+05T5uksL2qpZYMLLGbcSA

On Tue, Jan 24, 2017 at 4:40 PM, Doug Ledford <dledford-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote:
> On Tue, 2016-12-13 at 17:17 -0500, Paul Moore wrote:
>> On Tue, Dec 13, 2016 at 11:25 AM, Daniel Jurgens <danielj-VPRAkNaXOzXQFizaE/u3fw@public.gmane.org
>> m> wrote:
>> >
>> > On 12/13/2016 9:01 AM, Stephen Smalley wrote:
>> > >
>> > > For the LSM/SELinux bits,
>> > > Acked-by: Stephen Smalley <sds-+05T5uksL2qpZYMLLGbcSA@public.gmane.org>
>> > >
>> > > Note that there will be a merge conflict on classmap.h due to
>> > > commits in
>> > > the selinux next branch, but that should be easy to resolve.
>> > >
>> > > We'll need the patches for the selinux userspace and refpolicy.
>> >
>> > Thanks Stephen, I need to rebase the user space and do some patch
>> > breakup.  I'll start on that soon.
>>
>> Sorry, I haven't had a chance to look at v6, but considering all our
>> discussions on the previous versions I don't expect any issues from
>> me.  I was hoping for some more generic hooks/controls, but that
>> doesn't look to be possible given the nature of RDMA.  I also want to
>> mention again the need for tests; we've talked about this in the past
>> and while it isn't possible to run the tests without IB hardware, I
>> would like to see us merge tests into the selinux-testsuite so that
>> those who do have the required h/w available could run the tests.
>>
>> Assuming we can sort out the SELinux userspace and and tests by the
>> end of January, I see no reason why this couldn't go in for v4.11.
>
> Daniel, can you work with people on the userspace and tests?  I'll pull
> this into a branch (I assume by Paul's and Stephen's comments that they
> expect it to go through my tree) ready to go, but hold actually
> submitting it in the merge window until I've heard more from you all
> that userspace is ready.

I don't have a problem pulling this in via the SELinux tree, assuming
you are okay with that Doug.  I'm just waiting to see tests for the
selinux-testsuite first.

-- 
paul moore
www.paul-moore.com
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH v6 0/9] SELinux support for Infiniband RDMA
@ 2017-01-25  7:58               ` Paul Moore
  0 siblings, 0 replies; 51+ messages in thread
From: Paul Moore @ 2017-01-25  7:58 UTC (permalink / raw)
  To: Doug Ledford
  Cc: Daniel Jurgens, Stephen Smalley, chrisw, eparis, sean.hefty,
	hal.rosenstock, linux-rdma, linux-security-module, selinux

On Tue, Jan 24, 2017 at 4:40 PM, Doug Ledford <dledford@redhat.com> wrote:
> On Tue, 2016-12-13 at 17:17 -0500, Paul Moore wrote:
>> On Tue, Dec 13, 2016 at 11:25 AM, Daniel Jurgens <danielj@mellanox.co
>> m> wrote:
>> >
>> > On 12/13/2016 9:01 AM, Stephen Smalley wrote:
>> > >
>> > > For the LSM/SELinux bits,
>> > > Acked-by: Stephen Smalley <sds@tycho.nsa.gov>
>> > >
>> > > Note that there will be a merge conflict on classmap.h due to
>> > > commits in
>> > > the selinux next branch, but that should be easy to resolve.
>> > >
>> > > We'll need the patches for the selinux userspace and refpolicy.
>> >
>> > Thanks Stephen, I need to rebase the user space and do some patch
>> > breakup.  I'll start on that soon.
>>
>> Sorry, I haven't had a chance to look at v6, but considering all our
>> discussions on the previous versions I don't expect any issues from
>> me.  I was hoping for some more generic hooks/controls, but that
>> doesn't look to be possible given the nature of RDMA.  I also want to
>> mention again the need for tests; we've talked about this in the past
>> and while it isn't possible to run the tests without IB hardware, I
>> would like to see us merge tests into the selinux-testsuite so that
>> those who do have the required h/w available could run the tests.
>>
>> Assuming we can sort out the SELinux userspace and and tests by the
>> end of January, I see no reason why this couldn't go in for v4.11.
>
> Daniel, can you work with people on the userspace and tests?  I'll pull
> this into a branch (I assume by Paul's and Stephen's comments that they
> expect it to go through my tree) ready to go, but hold actually
> submitting it in the merge window until I've heard more from you all
> that userspace is ready.

I don't have a problem pulling this in via the SELinux tree, assuming
you are okay with that Doug.  I'm just waiting to see tests for the
selinux-testsuite first.

-- 
paul moore
www.paul-moore.com

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH v6 0/9] SELinux support for Infiniband RDMA
  2017-01-25  7:58               ` Paul Moore
@ 2017-01-25 17:25                   ` Doug Ledford
  -1 siblings, 0 replies; 51+ messages in thread
From: Doug Ledford @ 2017-01-25 17:25 UTC (permalink / raw)
  To: Paul Moore
  Cc: Daniel Jurgens, Stephen Smalley, chrisw-69jw2NvuJkxg9hUCZPvPmw,
	eparis-FjpueFixGhCM4zKIHC2jIg, sean.hefty-ral2JQCrhuEAvxtiuMwx3w,
	hal.rosenstock-Re5JQEeQqe8AvxtiuMwx3w,
	linux-rdma-u79uwXL29TY76Z2rM5mHXA,
	linux-security-module-u79uwXL29TY76Z2rM5mHXA,
	selinux-+05T5uksL2qpZYMLLGbcSA

[-- Attachment #1: Type: text/plain, Size: 2913 bytes --]

On Wed, 2017-01-25 at 02:58 -0500, Paul Moore wrote:
> On Tue, Jan 24, 2017 at 4:40 PM, Doug Ledford <dledford-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> wrote:
> > 
> > On Tue, 2016-12-13 at 17:17 -0500, Paul Moore wrote:
> > > 
> > > On Tue, Dec 13, 2016 at 11:25 AM, Daniel Jurgens <danielj@mellano
> > > x.co
> > > m> wrote:
> > > > 
> > > > 
> > > > On 12/13/2016 9:01 AM, Stephen Smalley wrote:
> > > > > 
> > > > > 
> > > > > For the LSM/SELinux bits,
> > > > > Acked-by: Stephen Smalley <sds-+05T5uksL2qpZYMLLGbcSA@public.gmane.org>
> > > > > 
> > > > > Note that there will be a merge conflict on classmap.h due to
> > > > > commits in
> > > > > the selinux next branch, but that should be easy to resolve.
> > > > > 
> > > > > We'll need the patches for the selinux userspace and
> > > > > refpolicy.
> > > > 
> > > > Thanks Stephen, I need to rebase the user space and do some
> > > > patch
> > > > breakup.  I'll start on that soon.
> > > 
> > > Sorry, I haven't had a chance to look at v6, but considering all
> > > our
> > > discussions on the previous versions I don't expect any issues
> > > from
> > > me.  I was hoping for some more generic hooks/controls, but that
> > > doesn't look to be possible given the nature of RDMA.  I also
> > > want to
> > > mention again the need for tests; we've talked about this in the
> > > past
> > > and while it isn't possible to run the tests without IB hardware,
> > > I
> > > would like to see us merge tests into the selinux-testsuite so
> > > that
> > > those who do have the required h/w available could run the tests.
> > > 
> > > Assuming we can sort out the SELinux userspace and and tests by
> > > the
> > > end of January, I see no reason why this couldn't go in for
> > > v4.11.
> > 
> > Daniel, can you work with people on the userspace and tests?  I'll
> > pull
> > this into a branch (I assume by Paul's and Stephen's comments that
> > they
> > expect it to go through my tree) ready to go, but hold actually
> > submitting it in the merge window until I've heard more from you
> > all
> > that userspace is ready.
> 
> I don't have a problem pulling this in via the SELinux tree, assuming
> you are okay with that Doug.  I'm just waiting to see tests for the
> selinux-testsuite first.

When I tried to apply the patchset, the conflicts started on the very
first file of the very first patch.  It can go through your tree, but I
suspect there will be lots of conflicts that way as this upcoming
release has been touching the cache area of the IB stack and so does
this code.  There might be significant SELinux conflicts too, I don't
know, but we know there are IB ones so far.

-- 
Doug Ledford <dledford-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
    GPG KeyID: B826A3330E572FDD
   
Key fingerprint = AE6B 1BDA 122B 23B4 265B  1274 B826 A333 0E57 2FDD

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH v6 0/9] SELinux support for Infiniband RDMA
@ 2017-01-25 17:25                   ` Doug Ledford
  0 siblings, 0 replies; 51+ messages in thread
From: Doug Ledford @ 2017-01-25 17:25 UTC (permalink / raw)
  To: Paul Moore
  Cc: Daniel Jurgens, Stephen Smalley, chrisw, eparis, sean.hefty,
	hal.rosenstock, linux-rdma, linux-security-module, selinux

[-- Attachment #1: Type: text/plain, Size: 2829 bytes --]

On Wed, 2017-01-25 at 02:58 -0500, Paul Moore wrote:
> On Tue, Jan 24, 2017 at 4:40 PM, Doug Ledford <dledford@redhat.com>
> wrote:
> > 
> > On Tue, 2016-12-13 at 17:17 -0500, Paul Moore wrote:
> > > 
> > > On Tue, Dec 13, 2016 at 11:25 AM, Daniel Jurgens <danielj@mellano
> > > x.co
> > > m> wrote:
> > > > 
> > > > 
> > > > On 12/13/2016 9:01 AM, Stephen Smalley wrote:
> > > > > 
> > > > > 
> > > > > For the LSM/SELinux bits,
> > > > > Acked-by: Stephen Smalley <sds@tycho.nsa.gov>
> > > > > 
> > > > > Note that there will be a merge conflict on classmap.h due to
> > > > > commits in
> > > > > the selinux next branch, but that should be easy to resolve.
> > > > > 
> > > > > We'll need the patches for the selinux userspace and
> > > > > refpolicy.
> > > > 
> > > > Thanks Stephen, I need to rebase the user space and do some
> > > > patch
> > > > breakup.  I'll start on that soon.
> > > 
> > > Sorry, I haven't had a chance to look at v6, but considering all
> > > our
> > > discussions on the previous versions I don't expect any issues
> > > from
> > > me.  I was hoping for some more generic hooks/controls, but that
> > > doesn't look to be possible given the nature of RDMA.  I also
> > > want to
> > > mention again the need for tests; we've talked about this in the
> > > past
> > > and while it isn't possible to run the tests without IB hardware,
> > > I
> > > would like to see us merge tests into the selinux-testsuite so
> > > that
> > > those who do have the required h/w available could run the tests.
> > > 
> > > Assuming we can sort out the SELinux userspace and and tests by
> > > the
> > > end of January, I see no reason why this couldn't go in for
> > > v4.11.
> > 
> > Daniel, can you work with people on the userspace and tests?  I'll
> > pull
> > this into a branch (I assume by Paul's and Stephen's comments that
> > they
> > expect it to go through my tree) ready to go, but hold actually
> > submitting it in the merge window until I've heard more from you
> > all
> > that userspace is ready.
> 
> I don't have a problem pulling this in via the SELinux tree, assuming
> you are okay with that Doug.  I'm just waiting to see tests for the
> selinux-testsuite first.

When I tried to apply the patchset, the conflicts started on the very
first file of the very first patch.  It can go through your tree, but I
suspect there will be lots of conflicts that way as this upcoming
release has been touching the cache area of the IB stack and so does
this code.  There might be significant SELinux conflicts too, I don't
know, but we know there are IB ones so far.

-- 
Doug Ledford <dledford@redhat.com>
    GPG KeyID: B826A3330E572FDD
   
Key fingerprint = AE6B 1BDA 122B 23B4 265B  1274 B826 A333 0E57 2FDD

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH v6 0/9] SELinux support for Infiniband RDMA
  2017-01-25 17:25                   ` Doug Ledford
@ 2017-01-25 22:14                       ` Paul Moore
  -1 siblings, 0 replies; 51+ messages in thread
From: Paul Moore @ 2017-01-25 22:14 UTC (permalink / raw)
  To: Doug Ledford
  Cc: Daniel Jurgens, Stephen Smalley, chrisw-69jw2NvuJkxg9hUCZPvPmw,
	eparis-FjpueFixGhCM4zKIHC2jIg, sean.hefty-ral2JQCrhuEAvxtiuMwx3w,
	hal.rosenstock-Re5JQEeQqe8AvxtiuMwx3w,
	linux-rdma-u79uwXL29TY76Z2rM5mHXA,
	linux-security-module-u79uwXL29TY76Z2rM5mHXA,
	selinux-+05T5uksL2qpZYMLLGbcSA

On Wed, Jan 25, 2017 at 12:25 PM, Doug Ledford <dledford-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote:
> On Wed, 2017-01-25 at 02:58 -0500, Paul Moore wrote:
>> On Tue, Jan 24, 2017 at 4:40 PM, Doug Ledford <dledford-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
>> wrote:
>> >
>> > On Tue, 2016-12-13 at 17:17 -0500, Paul Moore wrote:
>> > >
>> > > On Tue, Dec 13, 2016 at 11:25 AM, Daniel Jurgens <danielj@mellano
>> > > x.co
>> > > m> wrote:
>> > > >
>> > > >
>> > > > On 12/13/2016 9:01 AM, Stephen Smalley wrote:
>> > > > >
>> > > > >
>> > > > > For the LSM/SELinux bits,
>> > > > > Acked-by: Stephen Smalley <sds-+05T5uksL2qpZYMLLGbcSA@public.gmane.org>
>> > > > >
>> > > > > Note that there will be a merge conflict on classmap.h due to
>> > > > > commits in
>> > > > > the selinux next branch, but that should be easy to resolve.
>> > > > >
>> > > > > We'll need the patches for the selinux userspace and
>> > > > > refpolicy.
>> > > >
>> > > > Thanks Stephen, I need to rebase the user space and do some
>> > > > patch
>> > > > breakup.  I'll start on that soon.
>> > >
>> > > Sorry, I haven't had a chance to look at v6, but considering all
>> > > our
>> > > discussions on the previous versions I don't expect any issues
>> > > from
>> > > me.  I was hoping for some more generic hooks/controls, but that
>> > > doesn't look to be possible given the nature of RDMA.  I also
>> > > want to
>> > > mention again the need for tests; we've talked about this in the
>> > > past
>> > > and while it isn't possible to run the tests without IB hardware,
>> > > I
>> > > would like to see us merge tests into the selinux-testsuite so
>> > > that
>> > > those who do have the required h/w available could run the tests.
>> > >
>> > > Assuming we can sort out the SELinux userspace and and tests by
>> > > the
>> > > end of January, I see no reason why this couldn't go in for
>> > > v4.11.
>> >
>> > Daniel, can you work with people on the userspace and tests?  I'll
>> > pull
>> > this into a branch (I assume by Paul's and Stephen's comments that
>> > they
>> > expect it to go through my tree) ready to go, but hold actually
>> > submitting it in the merge window until I've heard more from you
>> > all
>> > that userspace is ready.
>>
>> I don't have a problem pulling this in via the SELinux tree, assuming
>> you are okay with that Doug.  I'm just waiting to see tests for the
>> selinux-testsuite first.
>
> When I tried to apply the patchset, the conflicts started on the very
> first file of the very first patch.  It can go through your tree, but I
> suspect there will be lots of conflicts that way as this upcoming
> release has been touching the cache area of the IB stack and so does
> this code.  There might be significant SELinux conflicts too, I don't
> know, but we know there are IB ones so far.

My apologies, I should have been more clear.  What I meant to say is
that I have no objection to merging this patchset via the SELinux
tree, in principle.  If there are significant merge conflicts they
will need to be resolved first; I have no problem dealing with small
fixups as part of the merge process, but any substantial changes would
need a respin.  Also, while I haven't looked at this latest patchset,
I would still want to review it for obvious reasons, although having
discussed previous drafts in detail I don't expect to see anything
objectionable.

However, my biggest concern remains the lack of working tests; without
those this patchset doesn't get my ACK.  We need to have some basic
method of regression testing this, even if it does require IB
hardware, to have any hope of maintaining this long term.

-- 
paul moore
www.paul-moore.com
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH v6 0/9] SELinux support for Infiniband RDMA
@ 2017-01-25 22:14                       ` Paul Moore
  0 siblings, 0 replies; 51+ messages in thread
From: Paul Moore @ 2017-01-25 22:14 UTC (permalink / raw)
  To: Doug Ledford
  Cc: Daniel Jurgens, Stephen Smalley, chrisw, eparis, sean.hefty,
	hal.rosenstock, linux-rdma, linux-security-module, selinux

On Wed, Jan 25, 2017 at 12:25 PM, Doug Ledford <dledford@redhat.com> wrote:
> On Wed, 2017-01-25 at 02:58 -0500, Paul Moore wrote:
>> On Tue, Jan 24, 2017 at 4:40 PM, Doug Ledford <dledford@redhat.com>
>> wrote:
>> >
>> > On Tue, 2016-12-13 at 17:17 -0500, Paul Moore wrote:
>> > >
>> > > On Tue, Dec 13, 2016 at 11:25 AM, Daniel Jurgens <danielj@mellano
>> > > x.co
>> > > m> wrote:
>> > > >
>> > > >
>> > > > On 12/13/2016 9:01 AM, Stephen Smalley wrote:
>> > > > >
>> > > > >
>> > > > > For the LSM/SELinux bits,
>> > > > > Acked-by: Stephen Smalley <sds@tycho.nsa.gov>
>> > > > >
>> > > > > Note that there will be a merge conflict on classmap.h due to
>> > > > > commits in
>> > > > > the selinux next branch, but that should be easy to resolve.
>> > > > >
>> > > > > We'll need the patches for the selinux userspace and
>> > > > > refpolicy.
>> > > >
>> > > > Thanks Stephen, I need to rebase the user space and do some
>> > > > patch
>> > > > breakup.  I'll start on that soon.
>> > >
>> > > Sorry, I haven't had a chance to look at v6, but considering all
>> > > our
>> > > discussions on the previous versions I don't expect any issues
>> > > from
>> > > me.  I was hoping for some more generic hooks/controls, but that
>> > > doesn't look to be possible given the nature of RDMA.  I also
>> > > want to
>> > > mention again the need for tests; we've talked about this in the
>> > > past
>> > > and while it isn't possible to run the tests without IB hardware,
>> > > I
>> > > would like to see us merge tests into the selinux-testsuite so
>> > > that
>> > > those who do have the required h/w available could run the tests.
>> > >
>> > > Assuming we can sort out the SELinux userspace and and tests by
>> > > the
>> > > end of January, I see no reason why this couldn't go in for
>> > > v4.11.
>> >
>> > Daniel, can you work with people on the userspace and tests?  I'll
>> > pull
>> > this into a branch (I assume by Paul's and Stephen's comments that
>> > they
>> > expect it to go through my tree) ready to go, but hold actually
>> > submitting it in the merge window until I've heard more from you
>> > all
>> > that userspace is ready.
>>
>> I don't have a problem pulling this in via the SELinux tree, assuming
>> you are okay with that Doug.  I'm just waiting to see tests for the
>> selinux-testsuite first.
>
> When I tried to apply the patchset, the conflicts started on the very
> first file of the very first patch.  It can go through your tree, but I
> suspect there will be lots of conflicts that way as this upcoming
> release has been touching the cache area of the IB stack and so does
> this code.  There might be significant SELinux conflicts too, I don't
> know, but we know there are IB ones so far.

My apologies, I should have been more clear.  What I meant to say is
that I have no objection to merging this patchset via the SELinux
tree, in principle.  If there are significant merge conflicts they
will need to be resolved first; I have no problem dealing with small
fixups as part of the merge process, but any substantial changes would
need a respin.  Also, while I haven't looked at this latest patchset,
I would still want to review it for obvious reasons, although having
discussed previous drafts in detail I don't expect to see anything
objectionable.

However, my biggest concern remains the lack of working tests; without
those this patchset doesn't get my ACK.  We need to have some basic
method of regression testing this, even if it does require IB
hardware, to have any hope of maintaining this long term.

-- 
paul moore
www.paul-moore.com

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH v6 0/9] SELinux support for Infiniband RDMA
  2016-11-23 14:17 ` Dan Jurgens
  (?)
@ 2017-05-03 14:41     ` Paul Moore
  -1 siblings, 0 replies; 51+ messages in thread
From: Paul Moore @ 2017-05-03 14:41 UTC (permalink / raw)
  To: Dan Jurgens
  Cc: chrisw-69jw2NvuJkxg9hUCZPvPmw, Stephen Smalley, Eric Paris,
	dledford-H+wXaHxf7aLQT0dZR+AlfA,
	sean.hefty-ral2JQCrhuEAvxtiuMwx3w,
	hal.rosenstock-Re5JQEeQqe8AvxtiuMwx3w,
	selinux-+05T5uksL2qpZYMLLGbcSA,
	linux-security-module-u79uwXL29TY76Z2rM5mHXA,
	linux-rdma-u79uwXL29TY76Z2rM5mHXA,
	yevgenyp-VPRAkNaXOzVWk0Htik3J/w

On Wed, Nov 23, 2016 at 9:17 AM, Dan Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org> wrote:
> From: Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
>
> Infiniband applications access HW from user-space -- traffic is generated
> directly by HW, bypassing the kernel. Consequently, Infiniband Partitions,
> which are associated directly with HW transport endpoints, are a natural
> choice for enforcing granular mandatory access control for Infiniband. QPs may
> only send or receives packets tagged with the corresponding partition key
> (PKey). The PKey is not a cryptographic key; it's a 16 bit number identifying
> the partition.
>
> Every Infiniband fabric is controlled by a central Subnet Manager (SM). The SM
> provisions the partitions by assigning each port with the partitions it can
> access. In addition, the SM tags each port with a subnet prefix, which
> identifies the subnet. Determining which users are allowed to access which
> partition keys on a given subnet forms an effective policy for isolating users
> on the fabric. Any application that attempts to send traffic on a given subnet
> is automatically subject to the policy, regardless of which device and port it
> uses. SM software configures the subnet through a privileged Subnet Management
> Interface (SMI), which is presented by each Infiniband port. Thus, the SMI must
> also be controlled to prevent unauthorized changes to fabric configuration and
> partitioning.
>
> To support access control for IB partitions and subnet management, security
> contexts must be provided for two new types of objects - PKeys and IB ports.
>
> A PKey label consists of a subnet prefix and a range of PKey values and is
> similar to the labeling mechanism for netports. Each Infiniband port can reside
> on a different subnet. So labeling the PKey values for specific subnet prefixes
> provides the user maximum flexibility, as PKey values may be determined
> independently for different subnets. There is a single access vector for PKeys
> called "access".
>
> An Infiniband port is labeled by device name and port number. There is a single
> access vector for IB ports called "manage_subnet".
>
> Because RDMA allows kernel bypass, enforcement must be done during connection
> setup. Communication over RDMA requires a send and receive queue, collectively
> known as a Queue Pair (QP). A QP must be initialized by privileged system calls
> before it can be used to send or receive data. During initialization the user
> must provide the PKey and port the QP will use; at this time access control can
> be enforced.
>
> Because there is a possibility that the enforcement settings or security
> policy can change, a means of notifying the ib_core module of such changes
> is required. To facilitate this a generic notification callback mechanism
> is added to the LSM. One callback is registered for checking the QP PKey
> associations when the policy changes. Mad agents also register a callback,
> they cache the permission to send and receive SMPs to avoid another per
> packet call to the LSM.
>
> Because frequent accesses to the same PKey's SID is expected a cache is
> implemented which is very similar to the netport cache.
>
> In order to properly enforce security when changes to the PKey table or
> security policy or enforcement occur ib_core must track which QPs are
> using which port, pkey index, and alternate path for every IB device.
> This makes operations that used to be atomic transactional.
>
> When modifying a QP, ib_core must associate it with the PKey index, port,
> and alternate path specified. If the QP was already associated with
> different settings, the QP is added to the new list prior to the
> modification. If the modify succeeds then the old listing is removed. If
> the modify fails the new listing is removed and the old listing remains
> unchanged.
>
> When destroying a QP the ib_qp structure is freed by the decive specific
> driver (i.e. mlx4_ib) if the 'destroy' is successful. This requires storing
> security related information in a separate structure. When a 'destroy'
> request is in process the ib_qp structure is in an undefined state so if
> there are changes to the security policy or PKey table, the security checks
> cannot reset the QP if it doesn't have permission for the new setting. If
> the 'destroy' fails, security for that QP must be enforced again and its
> status in the list is restored. If the 'destroy' succeeds the security info
> can be cleaned up and freed.
>
> There are a number of locks required to protect the QP security structure
> and the QP to device/port/pkey index lists. If multiple locks are required,
> the safe locking order is: QP security structure mutex first, followed by
> any list locks needed, which are sorted first by port followed by pkey
> index.

Hi Dan,

I haven't heard anything from you in a while, where do things stand
with this effort?  Unless I missed them, I believe we are still
waiting on the userspace, SELinux reference policy, and
selinux-testsuite patches.

-- 
paul moore
www.paul-moore.com
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH v6 0/9] SELinux support for Infiniband RDMA
@ 2017-05-03 14:41     ` Paul Moore
  0 siblings, 0 replies; 51+ messages in thread
From: Paul Moore @ 2017-05-03 14:41 UTC (permalink / raw)
  To: Dan Jurgens
  Cc: chrisw, Stephen Smalley, Eric Paris, dledford, sean.hefty,
	hal.rosenstock, selinux, linux-security-module, linux-rdma,
	yevgenyp

On Wed, Nov 23, 2016 at 9:17 AM, Dan Jurgens <danielj@mellanox.com> wrote:
> From: Daniel Jurgens <danielj@mellanox.com>
>
> Infiniband applications access HW from user-space -- traffic is generated
> directly by HW, bypassing the kernel. Consequently, Infiniband Partitions,
> which are associated directly with HW transport endpoints, are a natural
> choice for enforcing granular mandatory access control for Infiniband. QPs may
> only send or receives packets tagged with the corresponding partition key
> (PKey). The PKey is not a cryptographic key; it's a 16 bit number identifying
> the partition.
>
> Every Infiniband fabric is controlled by a central Subnet Manager (SM). The SM
> provisions the partitions by assigning each port with the partitions it can
> access. In addition, the SM tags each port with a subnet prefix, which
> identifies the subnet. Determining which users are allowed to access which
> partition keys on a given subnet forms an effective policy for isolating users
> on the fabric. Any application that attempts to send traffic on a given subnet
> is automatically subject to the policy, regardless of which device and port it
> uses. SM software configures the subnet through a privileged Subnet Management
> Interface (SMI), which is presented by each Infiniband port. Thus, the SMI must
> also be controlled to prevent unauthorized changes to fabric configuration and
> partitioning.
>
> To support access control for IB partitions and subnet management, security
> contexts must be provided for two new types of objects - PKeys and IB ports.
>
> A PKey label consists of a subnet prefix and a range of PKey values and is
> similar to the labeling mechanism for netports. Each Infiniband port can reside
> on a different subnet. So labeling the PKey values for specific subnet prefixes
> provides the user maximum flexibility, as PKey values may be determined
> independently for different subnets. There is a single access vector for PKeys
> called "access".
>
> An Infiniband port is labeled by device name and port number. There is a single
> access vector for IB ports called "manage_subnet".
>
> Because RDMA allows kernel bypass, enforcement must be done during connection
> setup. Communication over RDMA requires a send and receive queue, collectively
> known as a Queue Pair (QP). A QP must be initialized by privileged system calls
> before it can be used to send or receive data. During initialization the user
> must provide the PKey and port the QP will use; at this time access control can
> be enforced.
>
> Because there is a possibility that the enforcement settings or security
> policy can change, a means of notifying the ib_core module of such changes
> is required. To facilitate this a generic notification callback mechanism
> is added to the LSM. One callback is registered for checking the QP PKey
> associations when the policy changes. Mad agents also register a callback,
> they cache the permission to send and receive SMPs to avoid another per
> packet call to the LSM.
>
> Because frequent accesses to the same PKey's SID is expected a cache is
> implemented which is very similar to the netport cache.
>
> In order to properly enforce security when changes to the PKey table or
> security policy or enforcement occur ib_core must track which QPs are
> using which port, pkey index, and alternate path for every IB device.
> This makes operations that used to be atomic transactional.
>
> When modifying a QP, ib_core must associate it with the PKey index, port,
> and alternate path specified. If the QP was already associated with
> different settings, the QP is added to the new list prior to the
> modification. If the modify succeeds then the old listing is removed. If
> the modify fails the new listing is removed and the old listing remains
> unchanged.
>
> When destroying a QP the ib_qp structure is freed by the decive specific
> driver (i.e. mlx4_ib) if the 'destroy' is successful. This requires storing
> security related information in a separate structure. When a 'destroy'
> request is in process the ib_qp structure is in an undefined state so if
> there are changes to the security policy or PKey table, the security checks
> cannot reset the QP if it doesn't have permission for the new setting. If
> the 'destroy' fails, security for that QP must be enforced again and its
> status in the list is restored. If the 'destroy' succeeds the security info
> can be cleaned up and freed.
>
> There are a number of locks required to protect the QP security structure
> and the QP to device/port/pkey index lists. If multiple locks are required,
> the safe locking order is: QP security structure mutex first, followed by
> any list locks needed, which are sorted first by port followed by pkey
> index.

Hi Dan,

I haven't heard anything from you in a while, where do things stand
with this effort?  Unless I missed them, I believe we are still
waiting on the userspace, SELinux reference policy, and
selinux-testsuite patches.

-- 
paul moore
www.paul-moore.com

^ permalink raw reply	[flat|nested] 51+ messages in thread

* [PATCH v6 0/9] SELinux support for Infiniband RDMA
@ 2017-05-03 14:41     ` Paul Moore
  0 siblings, 0 replies; 51+ messages in thread
From: Paul Moore @ 2017-05-03 14:41 UTC (permalink / raw)
  To: linux-security-module

On Wed, Nov 23, 2016 at 9:17 AM, Dan Jurgens <danielj@mellanox.com> wrote:
> From: Daniel Jurgens <danielj@mellanox.com>
>
> Infiniband applications access HW from user-space -- traffic is generated
> directly by HW, bypassing the kernel. Consequently, Infiniband Partitions,
> which are associated directly with HW transport endpoints, are a natural
> choice for enforcing granular mandatory access control for Infiniband. QPs may
> only send or receives packets tagged with the corresponding partition key
> (PKey). The PKey is not a cryptographic key; it's a 16 bit number identifying
> the partition.
>
> Every Infiniband fabric is controlled by a central Subnet Manager (SM). The SM
> provisions the partitions by assigning each port with the partitions it can
> access. In addition, the SM tags each port with a subnet prefix, which
> identifies the subnet. Determining which users are allowed to access which
> partition keys on a given subnet forms an effective policy for isolating users
> on the fabric. Any application that attempts to send traffic on a given subnet
> is automatically subject to the policy, regardless of which device and port it
> uses. SM software configures the subnet through a privileged Subnet Management
> Interface (SMI), which is presented by each Infiniband port. Thus, the SMI must
> also be controlled to prevent unauthorized changes to fabric configuration and
> partitioning.
>
> To support access control for IB partitions and subnet management, security
> contexts must be provided for two new types of objects - PKeys and IB ports.
>
> A PKey label consists of a subnet prefix and a range of PKey values and is
> similar to the labeling mechanism for netports. Each Infiniband port can reside
> on a different subnet. So labeling the PKey values for specific subnet prefixes
> provides the user maximum flexibility, as PKey values may be determined
> independently for different subnets. There is a single access vector for PKeys
> called "access".
>
> An Infiniband port is labeled by device name and port number. There is a single
> access vector for IB ports called "manage_subnet".
>
> Because RDMA allows kernel bypass, enforcement must be done during connection
> setup. Communication over RDMA requires a send and receive queue, collectively
> known as a Queue Pair (QP). A QP must be initialized by privileged system calls
> before it can be used to send or receive data. During initialization the user
> must provide the PKey and port the QP will use; at this time access control can
> be enforced.
>
> Because there is a possibility that the enforcement settings or security
> policy can change, a means of notifying the ib_core module of such changes
> is required. To facilitate this a generic notification callback mechanism
> is added to the LSM. One callback is registered for checking the QP PKey
> associations when the policy changes. Mad agents also register a callback,
> they cache the permission to send and receive SMPs to avoid another per
> packet call to the LSM.
>
> Because frequent accesses to the same PKey's SID is expected a cache is
> implemented which is very similar to the netport cache.
>
> In order to properly enforce security when changes to the PKey table or
> security policy or enforcement occur ib_core must track which QPs are
> using which port, pkey index, and alternate path for every IB device.
> This makes operations that used to be atomic transactional.
>
> When modifying a QP, ib_core must associate it with the PKey index, port,
> and alternate path specified. If the QP was already associated with
> different settings, the QP is added to the new list prior to the
> modification. If the modify succeeds then the old listing is removed. If
> the modify fails the new listing is removed and the old listing remains
> unchanged.
>
> When destroying a QP the ib_qp structure is freed by the decive specific
> driver (i.e. mlx4_ib) if the 'destroy' is successful. This requires storing
> security related information in a separate structure. When a 'destroy'
> request is in process the ib_qp structure is in an undefined state so if
> there are changes to the security policy or PKey table, the security checks
> cannot reset the QP if it doesn't have permission for the new setting. If
> the 'destroy' fails, security for that QP must be enforced again and its
> status in the list is restored. If the 'destroy' succeeds the security info
> can be cleaned up and freed.
>
> There are a number of locks required to protect the QP security structure
> and the QP to device/port/pkey index lists. If multiple locks are required,
> the safe locking order is: QP security structure mutex first, followed by
> any list locks needed, which are sorted first by port followed by pkey
> index.

Hi Dan,

I haven't heard anything from you in a while, where do things stand
with this effort?  Unless I missed them, I believe we are still
waiting on the userspace, SELinux reference policy, and
selinux-testsuite patches.

-- 
paul moore
www.paul-moore.com
--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH v6 0/9] SELinux support for Infiniband RDMA
  2017-05-03 14:41     ` Paul Moore
@ 2017-05-03 19:45       ` Daniel Jurgens
  -1 siblings, 0 replies; 51+ messages in thread
From: Daniel Jurgens @ 2017-05-03 19:45 UTC (permalink / raw)
  To: Paul Moore
  Cc: chrisw, Stephen Smalley, Eric Paris, dledford, sean.hefty,
	hal.rosenstock, selinux, linux-security-module, linux-rdma,
	Yevgeny Petrilin

On 5/3/2017 9:41 AM, Paul Moore wrote:
> On Wed, Nov 23, 2016 at 9:17 AM, Dan Jurgens <danielj@mellanox.com> wrote:
>> From: Daniel Jurgens <danielj@mellanox.com>
>>
>> Infiniband applications access HW from user-space -- traffic is generated
>> directly by HW, bypassing the kernel. Consequently, Infiniband Partitions,
>> which are associated directly with HW transport endpoints, are a natural
>> choice for enforcing granular mandatory access control for Infiniband. QPs may
>> only send or receives packets tagged with the corresponding partition key
>> (PKey). The PKey is not a cryptographic key; it's a 16 bit number identifying
>> the partition.
>>
>> Every Infiniband fabric is controlled by a central Subnet Manager (SM). The SM
>> provisions the partitions by assigning each port with the partitions it can
>> access. In addition, the SM tags each port with a subnet prefix, which
>> identifies the subnet. Determining which users are allowed to access which
>> partition keys on a given subnet forms an effective policy for isolating users
>> on the fabric. Any application that attempts to send traffic on a given subnet
>> is automatically subject to the policy, regardless of which device and port it
>> uses. SM software configures the subnet through a privileged Subnet Management
>> Interface (SMI), which is presented by each Infiniband port. Thus, the SMI must
>> also be controlled to prevent unauthorized changes to fabric configuration and
>> partitioning.
>>
>> To support access control for IB partitions and subnet management, security
>> contexts must be provided for two new types of objects - PKeys and IB ports.
>>
>> A PKey label consists of a subnet prefix and a range of PKey values and is
>> similar to the labeling mechanism for netports. Each Infiniband port can reside
>> on a different subnet. So labeling the PKey values for specific subnet prefixes
>> provides the user maximum flexibility, as PKey values may be determined
>> independently for different subnets. There is a single access vector for PKeys
>> called "access".
>>
>> An Infiniband port is labeled by device name and port number. There is a single
>> access vector for IB ports called "manage_subnet".
>>
>> Because RDMA allows kernel bypass, enforcement must be done during connection
>> setup. Communication over RDMA requires a send and receive queue, collectively
>> known as a Queue Pair (QP). A QP must be initialized by privileged system calls
>> before it can be used to send or receive data. During initialization the user
>> must provide the PKey and port the QP will use; at this time access control can
>> be enforced.
>>
>> Because there is a possibility that the enforcement settings or security
>> policy can change, a means of notifying the ib_core module of such changes
>> is required. To facilitate this a generic notification callback mechanism
>> is added to the LSM. One callback is registered for checking the QP PKey
>> associations when the policy changes. Mad agents also register a callback,
>> they cache the permission to send and receive SMPs to avoid another per
>> packet call to the LSM.
>>
>> Because frequent accesses to the same PKey's SID is expected a cache is
>> implemented which is very similar to the netport cache.
>>
>> In order to properly enforce security when changes to the PKey table or
>> security policy or enforcement occur ib_core must track which QPs are
>> using which port, pkey index, and alternate path for every IB device.
>> This makes operations that used to be atomic transactional.
>>
>> When modifying a QP, ib_core must associate it with the PKey index, port,
>> and alternate path specified. If the QP was already associated with
>> different settings, the QP is added to the new list prior to the
>> modification. If the modify succeeds then the old listing is removed. If
>> the modify fails the new listing is removed and the old listing remains
>> unchanged.
>>
>> When destroying a QP the ib_qp structure is freed by the decive specific
>> driver (i.e. mlx4_ib) if the 'destroy' is successful. This requires storing
>> security related information in a separate structure. When a 'destroy'
>> request is in process the ib_qp structure is in an undefined state so if
>> there are changes to the security policy or PKey table, the security checks
>> cannot reset the QP if it doesn't have permission for the new setting. If
>> the 'destroy' fails, security for that QP must be enforced again and its
>> status in the list is restored. If the 'destroy' succeeds the security info
>> can be cleaned up and freed.
>>
>> There are a number of locks required to protect the QP security structure
>> and the QP to device/port/pkey index lists. If multiple locks are required,
>> the safe locking order is: QP security structure mutex first, followed by
>> any list locks needed, which are sorted first by port followed by pkey
>> index.
> Hi Dan,
>
> I haven't heard anything from you in a while, where do things stand
> with this effort?  Unless I missed them, I believe we are still
> waiting on the userspace, SELinux reference policy, and
> selinux-testsuite patches.
>
Hi Paul,

    I got distracted for a while.  I've just rebased the kernel and userspace.  I'll do some testing and submit the userspace code in the next couple days.  I still have to write the selinux-testsuite tests, I'll work on those concurrently with the userspace review cycle.


^ permalink raw reply	[flat|nested] 51+ messages in thread

* [PATCH v6 0/9] SELinux support for Infiniband RDMA
@ 2017-05-03 19:45       ` Daniel Jurgens
  0 siblings, 0 replies; 51+ messages in thread
From: Daniel Jurgens @ 2017-05-03 19:45 UTC (permalink / raw)
  To: linux-security-module

On 5/3/2017 9:41 AM, Paul Moore wrote:
> On Wed, Nov 23, 2016 at 9:17 AM, Dan Jurgens <danielj@mellanox.com> wrote:
>> From: Daniel Jurgens <danielj@mellanox.com>
>>
>> Infiniband applications access HW from user-space -- traffic is generated
>> directly by HW, bypassing the kernel. Consequently, Infiniband Partitions,
>> which are associated directly with HW transport endpoints, are a natural
>> choice for enforcing granular mandatory access control for Infiniband. QPs may
>> only send or receives packets tagged with the corresponding partition key
>> (PKey). The PKey is not a cryptographic key; it's a 16 bit number identifying
>> the partition.
>>
>> Every Infiniband fabric is controlled by a central Subnet Manager (SM). The SM
>> provisions the partitions by assigning each port with the partitions it can
>> access. In addition, the SM tags each port with a subnet prefix, which
>> identifies the subnet. Determining which users are allowed to access which
>> partition keys on a given subnet forms an effective policy for isolating users
>> on the fabric. Any application that attempts to send traffic on a given subnet
>> is automatically subject to the policy, regardless of which device and port it
>> uses. SM software configures the subnet through a privileged Subnet Management
>> Interface (SMI), which is presented by each Infiniband port. Thus, the SMI must
>> also be controlled to prevent unauthorized changes to fabric configuration and
>> partitioning.
>>
>> To support access control for IB partitions and subnet management, security
>> contexts must be provided for two new types of objects - PKeys and IB ports.
>>
>> A PKey label consists of a subnet prefix and a range of PKey values and is
>> similar to the labeling mechanism for netports. Each Infiniband port can reside
>> on a different subnet. So labeling the PKey values for specific subnet prefixes
>> provides the user maximum flexibility, as PKey values may be determined
>> independently for different subnets. There is a single access vector for PKeys
>> called "access".
>>
>> An Infiniband port is labeled by device name and port number. There is a single
>> access vector for IB ports called "manage_subnet".
>>
>> Because RDMA allows kernel bypass, enforcement must be done during connection
>> setup. Communication over RDMA requires a send and receive queue, collectively
>> known as a Queue Pair (QP). A QP must be initialized by privileged system calls
>> before it can be used to send or receive data. During initialization the user
>> must provide the PKey and port the QP will use; at this time access control can
>> be enforced.
>>
>> Because there is a possibility that the enforcement settings or security
>> policy can change, a means of notifying the ib_core module of such changes
>> is required. To facilitate this a generic notification callback mechanism
>> is added to the LSM. One callback is registered for checking the QP PKey
>> associations when the policy changes. Mad agents also register a callback,
>> they cache the permission to send and receive SMPs to avoid another per
>> packet call to the LSM.
>>
>> Because frequent accesses to the same PKey's SID is expected a cache is
>> implemented which is very similar to the netport cache.
>>
>> In order to properly enforce security when changes to the PKey table or
>> security policy or enforcement occur ib_core must track which QPs are
>> using which port, pkey index, and alternate path for every IB device.
>> This makes operations that used to be atomic transactional.
>>
>> When modifying a QP, ib_core must associate it with the PKey index, port,
>> and alternate path specified. If the QP was already associated with
>> different settings, the QP is added to the new list prior to the
>> modification. If the modify succeeds then the old listing is removed. If
>> the modify fails the new listing is removed and the old listing remains
>> unchanged.
>>
>> When destroying a QP the ib_qp structure is freed by the decive specific
>> driver (i.e. mlx4_ib) if the 'destroy' is successful. This requires storing
>> security related information in a separate structure. When a 'destroy'
>> request is in process the ib_qp structure is in an undefined state so if
>> there are changes to the security policy or PKey table, the security checks
>> cannot reset the QP if it doesn't have permission for the new setting. If
>> the 'destroy' fails, security for that QP must be enforced again and its
>> status in the list is restored. If the 'destroy' succeeds the security info
>> can be cleaned up and freed.
>>
>> There are a number of locks required to protect the QP security structure
>> and the QP to device/port/pkey index lists. If multiple locks are required,
>> the safe locking order is: QP security structure mutex first, followed by
>> any list locks needed, which are sorted first by port followed by pkey
>> index.
> Hi Dan,
>
> I haven't heard anything from you in a while, where do things stand
> with this effort?  Unless I missed them, I believe we are still
> waiting on the userspace, SELinux reference policy, and
> selinux-testsuite patches.
>
Hi Paul,

    I got distracted for a while.  I've just rebased the kernel and userspace.  I'll do some testing and submit the userspace code in the next couple days.  I still have to write the selinux-testsuite tests, I'll work on those concurrently with the userspace review cycle.

--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH v6 0/9] SELinux support for Infiniband RDMA
  2017-05-03 19:45       ` Daniel Jurgens
@ 2017-05-04 15:51         ` Paul Moore
  -1 siblings, 0 replies; 51+ messages in thread
From: Paul Moore @ 2017-05-04 15:51 UTC (permalink / raw)
  To: Daniel Jurgens
  Cc: chrisw, Stephen Smalley, Eric Paris, dledford, sean.hefty,
	hal.rosenstock, selinux, linux-security-module, linux-rdma,
	Yevgeny Petrilin

On Wed, May 3, 2017 at 3:45 PM, Daniel Jurgens <danielj@mellanox.com> wrote:
> On 5/3/2017 9:41 AM, Paul Moore wrote:
>> On Wed, Nov 23, 2016 at 9:17 AM, Dan Jurgens <danielj@mellanox.com> wrote:
>>> From: Daniel Jurgens <danielj@mellanox.com>
>>>
>>> Infiniband applications access HW from user-space -- traffic is generated
>>> directly by HW, bypassing the kernel. Consequently, Infiniband Partitions,
>>> which are associated directly with HW transport endpoints, are a natural
>>> choice for enforcing granular mandatory access control for Infiniband. QPs may
>>> only send or receives packets tagged with the corresponding partition key
>>> (PKey). The PKey is not a cryptographic key; it's a 16 bit number identifying
>>> the partition ...
>>>
>> Hi Dan,
>>
>> I haven't heard anything from you in a while, where do things stand
>> with this effort?  Unless I missed them, I believe we are still
>> waiting on the userspace, SELinux reference policy, and
>> selinux-testsuite patches.
>>
> Hi Paul,
>
>     I got distracted for a while.  I've just rebased the kernel and userspace.  I'll do some testing and submit the userspace code in the next couple days.  I still have to write the selinux-testsuite tests, I'll work on those concurrently with the userspace review cycle.

Great, thanks for the update.  We'll look forward to the patches.

-- 
paul moore
www.paul-moore.com

^ permalink raw reply	[flat|nested] 51+ messages in thread

* [PATCH v6 0/9] SELinux support for Infiniband RDMA
@ 2017-05-04 15:51         ` Paul Moore
  0 siblings, 0 replies; 51+ messages in thread
From: Paul Moore @ 2017-05-04 15:51 UTC (permalink / raw)
  To: linux-security-module

On Wed, May 3, 2017 at 3:45 PM, Daniel Jurgens <danielj@mellanox.com> wrote:
> On 5/3/2017 9:41 AM, Paul Moore wrote:
>> On Wed, Nov 23, 2016 at 9:17 AM, Dan Jurgens <danielj@mellanox.com> wrote:
>>> From: Daniel Jurgens <danielj@mellanox.com>
>>>
>>> Infiniband applications access HW from user-space -- traffic is generated
>>> directly by HW, bypassing the kernel. Consequently, Infiniband Partitions,
>>> which are associated directly with HW transport endpoints, are a natural
>>> choice for enforcing granular mandatory access control for Infiniband. QPs may
>>> only send or receives packets tagged with the corresponding partition key
>>> (PKey). The PKey is not a cryptographic key; it's a 16 bit number identifying
>>> the partition ...
>>>
>> Hi Dan,
>>
>> I haven't heard anything from you in a while, where do things stand
>> with this effort?  Unless I missed them, I believe we are still
>> waiting on the userspace, SELinux reference policy, and
>> selinux-testsuite patches.
>>
> Hi Paul,
>
>     I got distracted for a while.  I've just rebased the kernel and userspace.  I'll do some testing and submit the userspace code in the next couple days.  I still have to write the selinux-testsuite tests, I'll work on those concurrently with the userspace review cycle.

Great, thanks for the update.  We'll look forward to the patches.

-- 
paul moore
www.paul-moore.com
--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH v6 0/9] SELinux support for Infiniband RDMA
  2017-05-04 15:51         ` Paul Moore
  (?)
@ 2017-05-17 21:23           ` Paul Moore
  -1 siblings, 0 replies; 51+ messages in thread
From: Paul Moore @ 2017-05-17 21:23 UTC (permalink / raw)
  To: Daniel Jurgens
  Cc: Stephen Smalley, Eric Paris, dledford-H+wXaHxf7aLQT0dZR+AlfA,
	sean.hefty-ral2JQCrhuEAvxtiuMwx3w,
	hal.rosenstock-Re5JQEeQqe8AvxtiuMwx3w,
	selinux-+05T5uksL2qpZYMLLGbcSA,
	linux-security-module-u79uwXL29TY76Z2rM5mHXA,
	linux-rdma-u79uwXL29TY76Z2rM5mHXA, Yevgeny Petrilin

On Thu, May 4, 2017 at 11:51 AM, Paul Moore <paul-r2n+y4ga6xFZroRs9YW3xA@public.gmane.org> wrote:
> On Wed, May 3, 2017 at 3:45 PM, Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org> wrote:
>> On 5/3/2017 9:41 AM, Paul Moore wrote:
>>> On Wed, Nov 23, 2016 at 9:17 AM, Dan Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org> wrote:
>>>> From: Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
>>>>
>>>> Infiniband applications access HW from user-space -- traffic is generated
>>>> directly by HW, bypassing the kernel. Consequently, Infiniband Partitions,
>>>> which are associated directly with HW transport endpoints, are a natural
>>>> choice for enforcing granular mandatory access control for Infiniband. QPs may
>>>> only send or receives packets tagged with the corresponding partition key
>>>> (PKey). The PKey is not a cryptographic key; it's a 16 bit number identifying
>>>> the partition ...
>>>>
>>> Hi Dan,
>>>
>>> I haven't heard anything from you in a while, where do things stand
>>> with this effort?  Unless I missed them, I believe we are still
>>> waiting on the userspace, SELinux reference policy, and
>>> selinux-testsuite patches.
>>>
>> Hi Paul,
>>
>>     I got distracted for a while.  I've just rebased the kernel and userspace.  I'll do some testing and submit the userspace code in the next couple days.  I still have to write the selinux-testsuite tests, I'll work on those concurrently with the userspace review cycle.
>
> Great, thanks for the update.  We'll look forward to the patches.

I took a closer look at the patchset and I think it looks fine,
coupled with the recent progress on the SELinux userspace and test
suite I think it would be good to get this into the selinux/next tree
so we can start playing with it.  Dan, I know there were some IB merge
conflicts with this patch could you do a respin against the current
selinux/next tree?

* git://git.infradead.org/users/pcmoore/selinux
* http://git.infradead.org/users/pcmoore/selinux

Thanks.

-- 
paul moore
www.paul-moore.com
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH v6 0/9] SELinux support for Infiniband RDMA
@ 2017-05-17 21:23           ` Paul Moore
  0 siblings, 0 replies; 51+ messages in thread
From: Paul Moore @ 2017-05-17 21:23 UTC (permalink / raw)
  To: Daniel Jurgens
  Cc: Stephen Smalley, Eric Paris, dledford, sean.hefty,
	hal.rosenstock, selinux, linux-security-module, linux-rdma,
	Yevgeny Petrilin

On Thu, May 4, 2017 at 11:51 AM, Paul Moore <paul@paul-moore.com> wrote:
> On Wed, May 3, 2017 at 3:45 PM, Daniel Jurgens <danielj@mellanox.com> wrote:
>> On 5/3/2017 9:41 AM, Paul Moore wrote:
>>> On Wed, Nov 23, 2016 at 9:17 AM, Dan Jurgens <danielj@mellanox.com> wrote:
>>>> From: Daniel Jurgens <danielj@mellanox.com>
>>>>
>>>> Infiniband applications access HW from user-space -- traffic is generated
>>>> directly by HW, bypassing the kernel. Consequently, Infiniband Partitions,
>>>> which are associated directly with HW transport endpoints, are a natural
>>>> choice for enforcing granular mandatory access control for Infiniband. QPs may
>>>> only send or receives packets tagged with the corresponding partition key
>>>> (PKey). The PKey is not a cryptographic key; it's a 16 bit number identifying
>>>> the partition ...
>>>>
>>> Hi Dan,
>>>
>>> I haven't heard anything from you in a while, where do things stand
>>> with this effort?  Unless I missed them, I believe we are still
>>> waiting on the userspace, SELinux reference policy, and
>>> selinux-testsuite patches.
>>>
>> Hi Paul,
>>
>>     I got distracted for a while.  I've just rebased the kernel and userspace.  I'll do some testing and submit the userspace code in the next couple days.  I still have to write the selinux-testsuite tests, I'll work on those concurrently with the userspace review cycle.
>
> Great, thanks for the update.  We'll look forward to the patches.

I took a closer look at the patchset and I think it looks fine,
coupled with the recent progress on the SELinux userspace and test
suite I think it would be good to get this into the selinux/next tree
so we can start playing with it.  Dan, I know there were some IB merge
conflicts with this patch could you do a respin against the current
selinux/next tree?

* git://git.infradead.org/users/pcmoore/selinux
* http://git.infradead.org/users/pcmoore/selinux

Thanks.

-- 
paul moore
www.paul-moore.com

^ permalink raw reply	[flat|nested] 51+ messages in thread

* [PATCH v6 0/9] SELinux support for Infiniband RDMA
@ 2017-05-17 21:23           ` Paul Moore
  0 siblings, 0 replies; 51+ messages in thread
From: Paul Moore @ 2017-05-17 21:23 UTC (permalink / raw)
  To: linux-security-module

On Thu, May 4, 2017 at 11:51 AM, Paul Moore <paul@paul-moore.com> wrote:
> On Wed, May 3, 2017 at 3:45 PM, Daniel Jurgens <danielj@mellanox.com> wrote:
>> On 5/3/2017 9:41 AM, Paul Moore wrote:
>>> On Wed, Nov 23, 2016 at 9:17 AM, Dan Jurgens <danielj@mellanox.com> wrote:
>>>> From: Daniel Jurgens <danielj@mellanox.com>
>>>>
>>>> Infiniband applications access HW from user-space -- traffic is generated
>>>> directly by HW, bypassing the kernel. Consequently, Infiniband Partitions,
>>>> which are associated directly with HW transport endpoints, are a natural
>>>> choice for enforcing granular mandatory access control for Infiniband. QPs may
>>>> only send or receives packets tagged with the corresponding partition key
>>>> (PKey). The PKey is not a cryptographic key; it's a 16 bit number identifying
>>>> the partition ...
>>>>
>>> Hi Dan,
>>>
>>> I haven't heard anything from you in a while, where do things stand
>>> with this effort?  Unless I missed them, I believe we are still
>>> waiting on the userspace, SELinux reference policy, and
>>> selinux-testsuite patches.
>>>
>> Hi Paul,
>>
>>     I got distracted for a while.  I've just rebased the kernel and userspace.  I'll do some testing and submit the userspace code in the next couple days.  I still have to write the selinux-testsuite tests, I'll work on those concurrently with the userspace review cycle.
>
> Great, thanks for the update.  We'll look forward to the patches.

I took a closer look at the patchset and I think it looks fine,
coupled with the recent progress on the SELinux userspace and test
suite I think it would be good to get this into the selinux/next tree
so we can start playing with it.  Dan, I know there were some IB merge
conflicts with this patch could you do a respin against the current
selinux/next tree?

* git://git.infradead.org/users/pcmoore/selinux
* http://git.infradead.org/users/pcmoore/selinux

Thanks.

-- 
paul moore
www.paul-moore.com
--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 51+ messages in thread

end of thread, other threads:[~2017-05-17 21:23 UTC | newest]

Thread overview: 51+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-11-23 14:17 [PATCH v6 0/9] SELinux support for Infiniband RDMA Dan Jurgens
2016-11-23 14:17 ` Dan Jurgens
2016-11-23 14:17 ` [PATCH v6 2/9] IB/core: Enforce PKey security on QPs Dan Jurgens
2016-11-23 14:17 ` [PATCH v6 4/9] IB/core: Enforce security on management datagrams Dan Jurgens
2016-11-23 14:17 ` [PATCH v6 5/9] selinux: Create policydb version for Infiniband support Dan Jurgens
     [not found]   ` <1479910651-43246-6-git-send-email-danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
2016-12-13 14:38     ` Stephen Smalley
2016-12-13 14:38       ` Stephen Smalley
2016-12-13 14:40       ` Daniel Jurgens
2016-12-13 14:40         ` Daniel Jurgens
2016-11-23 14:17 ` [PATCH v6 6/9] selinux: Allocate and free infiniband security hooks Dan Jurgens
2016-11-23 14:17 ` [PATCH v6 8/9] selinux: Add IB Port SMP access vector Dan Jurgens
2016-11-23 14:17 ` [PATCH v6 9/9] selinux: Add a cache for quicker retreival of PKey SIDs Dan Jurgens
     [not found] ` <1479910651-43246-1-git-send-email-danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
2016-11-23 14:17   ` [PATCH v6 1/9] IB/core: IB cache enhancements to support Infiniband security Dan Jurgens
2016-11-23 14:17     ` Dan Jurgens
2016-11-23 14:17   ` [PATCH v6 3/9] selinux lsm IB/core: Implement LSM notification system Dan Jurgens
2016-11-23 14:17     ` Dan Jurgens
     [not found]     ` <1479910651-43246-4-git-send-email-danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
2016-12-13 14:29       ` Stephen Smalley
2016-12-13 14:29         ` Stephen Smalley
2016-12-13 14:38         ` Daniel Jurgens
2016-12-13 14:38           ` Daniel Jurgens
2016-11-23 14:17   ` [PATCH v6 7/9] selinux: Implement Infiniband PKey "Access" access vector Dan Jurgens
2016-11-23 14:17     ` Dan Jurgens
2016-12-12 21:38   ` [PATCH v6 0/9] SELinux support for Infiniband RDMA Doug Ledford
2016-12-12 21:38     ` Doug Ledford
2016-12-13 15:04   ` Stephen Smalley
2016-12-13 15:04     ` Stephen Smalley
2016-12-13 16:25     ` Daniel Jurgens
2016-12-13 16:25       ` Daniel Jurgens
2016-12-13 22:17       ` Paul Moore
2017-01-24 21:40         ` Doug Ledford
     [not found]           ` <1485294015.43764.91.camel-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2017-01-24 21:45             ` Doug Ledford
2017-01-24 21:45               ` Doug Ledford
2017-01-24 22:40               ` Daniel Jurgens
     [not found]                 ` <VI1PR0501MB242933AC0EC458EAD2792560C4750-o1MPJYiShEyB6Z+oivrBG8DSnupUy6xnnBOFsp37pqbUKgpGm//BTAC/G2K4zDHf@public.gmane.org>
2017-01-25  3:08                   ` Doug Ledford
2017-01-25  3:08                     ` Doug Ledford
2017-01-25  7:58             ` Paul Moore
2017-01-25  7:58               ` Paul Moore
     [not found]               ` <CAHC9VhTfuftm1oyiBOa4Fx4L-12eX8MCySiS1H98yroCuuoieA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2017-01-25 17:25                 ` Doug Ledford
2017-01-25 17:25                   ` Doug Ledford
     [not found]                   ` <1485365121.2432.6.camel-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2017-01-25 22:14                     ` Paul Moore
2017-01-25 22:14                       ` Paul Moore
2017-05-03 14:41   ` Paul Moore
2017-05-03 14:41     ` Paul Moore
2017-05-03 14:41     ` Paul Moore
2017-05-03 19:45     ` Daniel Jurgens
2017-05-03 19:45       ` Daniel Jurgens
2017-05-04 15:51       ` Paul Moore
2017-05-04 15:51         ` Paul Moore
2017-05-17 21:23         ` Paul Moore
2017-05-17 21:23           ` Paul Moore
2017-05-17 21:23           ` Paul Moore

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.