All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 0/9] SELinux support for Infiniband RDMA
@ 2016-07-29 13:53 ` Dan Jurgens
  0 siblings, 0 replies; 79+ messages in thread
From: Dan Jurgens @ 2016-07-29 13:53 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>

The selinux next tree is missing some patches for IB/core.  This series
applies cleanly to ib-next, and should apply cleanly to selinux-next once
the IB patches are merged.

Currently there is no way to provide granular access control to an
Infiniband fabric. By providing an ability to restrict user access to
specific virtual subfabrics, administrators can limit access to bandwidth
and isolate users on the fabric.

The approach for controlling access for Infiniband is to control access to
partitions. A partition is similar in concept to a VLAN where each data
packet carries the partition key (PKey) in its header and isolation is
enforced by the hardware. The partition key is not a cryptographic key,
it's a 16 bit number identifying the partition. By controlling access to
PKeys, users can be isolated on the fabric.

Every Infiniband fabric must have a subnet manager. The subnet manager
provisions the partitions and configures the end nodes. Each end port has
a PKey table containing the partitions it can access. In order to enforce
access to partitions, the subnet management interface (SMI) must also be
controlled to prevent unauthorized changes to the fabric configuration. 

In order to support this there must be a capability to provide security
contexts 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, labeling the PKey values for specific subnet
prefixes provides the user maximum flexibility. There is a single access
vector for PKeys called "access".

An Infiniband port is labeled by 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 called a  queue pair (QP). During the creation of a QP it is
initialized 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 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. 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

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            |  37 +-
 include/linux/lsm_hooks.h            |  35 ++
 include/linux/security.h             |  35 ++
 include/rdma/ib_mad.h                |   4 +
 include/rdma/ib_verbs.h              |  49 +++
 security/Kconfig                     |   9 +
 security/lsm_audit.c                 |  18 +
 security/security.c                  |  59 +++
 security/selinux/Makefile            |   2 +-
 security/selinux/hooks.c             |  80 +++-
 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       | 130 ++++++-
 security/selinux/ss/policydb.h       |  27 +-
 security/selinux/ss/services.c       |  83 ++++
 27 files changed, 1879 insertions(+), 58 deletions(-)
 create mode 100644 drivers/infiniband/core/security.c
 create mode 100644 security/selinux/ibpkey.c
 create mode 100644 security/selinux/include/ibpkey.h

-- 
1.8.3.1

--
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] 79+ messages in thread

* [PATCH v3 0/9] SELinux support for Infiniband RDMA
@ 2016-07-29 13:53 ` Dan Jurgens
  0 siblings, 0 replies; 79+ messages in thread
From: Dan Jurgens @ 2016-07-29 13:53 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>

The selinux next tree is missing some patches for IB/core.  This series
applies cleanly to ib-next, and should apply cleanly to selinux-next once
the IB patches are merged.

Currently there is no way to provide granular access control to an
Infiniband fabric. By providing an ability to restrict user access to
specific virtual subfabrics, administrators can limit access to bandwidth
and isolate users on the fabric.

The approach for controlling access for Infiniband is to control access to
partitions. A partition is similar in concept to a VLAN where each data
packet carries the partition key (PKey) in its header and isolation is
enforced by the hardware. The partition key is not a cryptographic key,
it's a 16 bit number identifying the partition. By controlling access to
PKeys, users can be isolated on the fabric.

Every Infiniband fabric must have a subnet manager. The subnet manager
provisions the partitions and configures the end nodes. Each end port has
a PKey table containing the partitions it can access. In order to enforce
access to partitions, the subnet management interface (SMI) must also be
controlled to prevent unauthorized changes to the fabric configuration. 

In order to support this there must be a capability to provide security
contexts 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, labeling the PKey values for specific subnet
prefixes provides the user maximum flexibility. There is a single access
vector for PKeys called "access".

An Infiniband port is labeled by 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 called a  queue pair (QP). During the creation of a QP it is
initialized 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 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. 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

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            |  37 +-
 include/linux/lsm_hooks.h            |  35 ++
 include/linux/security.h             |  35 ++
 include/rdma/ib_mad.h                |   4 +
 include/rdma/ib_verbs.h              |  49 +++
 security/Kconfig                     |   9 +
 security/lsm_audit.c                 |  18 +
 security/security.c                  |  59 +++
 security/selinux/Makefile            |   2 +-
 security/selinux/hooks.c             |  80 +++-
 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       | 130 ++++++-
 security/selinux/ss/policydb.h       |  27 +-
 security/selinux/ss/services.c       |  83 ++++
 27 files changed, 1879 insertions(+), 58 deletions(-)
 create mode 100644 drivers/infiniband/core/security.c
 create mode 100644 security/selinux/ibpkey.c
 create mode 100644 security/selinux/include/ibpkey.h

-- 
1.8.3.1

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

* [PATCH v3 1/9] IB/core: IB cache enhancements to support Infiniband security
  2016-07-29 13:53 ` Dan Jurgens
  (?)
@ 2016-07-29 13:53 ` Dan Jurgens
  -1 siblings, 0 replies; 79+ messages in thread
From: Dan Jurgens @ 2016-07-29 13:53 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 0409667..8a44894 100644
--- a/drivers/infiniband/core/cache.c
+++ b/drivers/infiniband/core/cache.c
@@ -932,6 +932,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,
@@ -1108,6 +1128,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);
@@ -1166,9 +1188,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;
 	}
 
@@ -1211,6 +1242,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 156673a..205ea09 100644
--- a/include/rdma/ib_verbs.h
+++ b/include/rdma/ib_verbs.h
@@ -1709,6 +1709,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 {
-- 
1.8.3.1


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

* [PATCH v3 2/9] IB/core: Enforce PKey security on QPs
  2016-07-29 13:53 ` Dan Jurgens
@ 2016-07-29 13:53     ` Dan Jurgens
  -1 siblings, 0 replies; 79+ messages in thread
From: Dan Jurgens @ 2016-07-29 13:53 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 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-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>

---
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 8a44894..ebe0337 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;
@@ -1044,7 +1045,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;
@@ -1132,6 +1134,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);
@@ -1148,7 +1155,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);
 }
 
@@ -1169,6 +1178,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);
 		}
 	}
@@ -1209,7 +1224,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 f664731..abeb391 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 6916d5c..e783f54 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>
@@ -682,12 +683,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;
@@ -773,6 +782,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;
@@ -1222,7 +1237,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);
 
@@ -1251,6 +1266,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;
@@ -1291,6 +1307,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);
@@ -1306,6 +1323,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);
@@ -1322,6 +1342,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 7ae3976..c3a7328 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-iSGtlc1asvQWG2LlvL+J4A@public.gmane.org>
+ * 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
@@ -876,6 +877,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:
@@ -1579,6 +1595,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,
@@ -1806,6 +1828,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 14df373..0bd8319 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -6,6 +6,7 @@
  * Copyright (C) 2001 Networks Associates Technology, Inc <ssmalley-M06CiZnz2FM@public.gmane.org>
  * Copyright (C) 2001 James Morris <jmorris-G2x6lROWQUcJY7gZg3T8ig@public.gmane.org>
  * 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
@@ -1370,6 +1371,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 205ea09..9042ba3 100644
--- a/include/rdma/ib_verbs.h
+++ b/include/rdma/ib_verbs.h
@@ -1490,6 +1490,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;
+};
+
 struct ib_qp {
 	struct ib_device       *device;
 	struct ib_pd	       *pd;
@@ -1513,6 +1552,7 @@ struct ib_qp {
 	u32			qp_num;
 	enum ib_qp_type		qp_type;
 	struct ib_rwq_ind_table *rwq_ind_tbl;
+	struct ib_qp_security  *qp_sec;
 };
 
 struct ib_mr {
@@ -1760,6 +1800,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;
 
@@ -1782,6 +1828,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 176758c..ce965c6 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 7095693..45b6dc0 100644
--- a/security/security.c
+++ b/security/security.c
@@ -4,6 +4,7 @@
  * Copyright (C) 2001 WireX Communications, Inc <chris-ZMHXrckZAt0AvxtiuMwx3w@public.gmane.org>
  * Copyright (C) 2001-2002 Greg Kroah-Hartman <greg-U8xfFu+wG4EAvxtiuMwx3w@public.gmane.org>
  * Copyright (C) 2001 Networks Associates Technology, Inc <ssmalley-M06CiZnz2FM@public.gmane.org>
+ * 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
@@ -1399,6 +1400,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,
@@ -1850,6 +1872,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),
-- 
1.8.3.1

--
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] 79+ messages in thread

* [PATCH v3 2/9] IB/core: Enforce PKey security on QPs
@ 2016-07-29 13:53     ` Dan Jurgens
  0 siblings, 0 replies; 79+ messages in thread
From: Dan Jurgens @ 2016-07-29 13:53 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 8a44894..ebe0337 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;
@@ -1044,7 +1045,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;
@@ -1132,6 +1134,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);
@@ -1148,7 +1155,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);
 }
 
@@ -1169,6 +1178,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);
 		}
 	}
@@ -1209,7 +1224,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 f664731..abeb391 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 6916d5c..e783f54 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>
@@ -682,12 +683,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;
@@ -773,6 +782,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;
@@ -1222,7 +1237,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);
 
@@ -1251,6 +1266,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;
@@ -1291,6 +1307,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);
@@ -1306,6 +1323,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);
@@ -1322,6 +1342,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 7ae3976..c3a7328 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
@@ -876,6 +877,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:
@@ -1579,6 +1595,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,
@@ -1806,6 +1828,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 14df373..0bd8319 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
@@ -1370,6 +1371,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 205ea09..9042ba3 100644
--- a/include/rdma/ib_verbs.h
+++ b/include/rdma/ib_verbs.h
@@ -1490,6 +1490,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;
+};
+
 struct ib_qp {
 	struct ib_device       *device;
 	struct ib_pd	       *pd;
@@ -1513,6 +1552,7 @@ struct ib_qp {
 	u32			qp_num;
 	enum ib_qp_type		qp_type;
 	struct ib_rwq_ind_table *rwq_ind_tbl;
+	struct ib_qp_security  *qp_sec;
 };
 
 struct ib_mr {
@@ -1760,6 +1800,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;
 
@@ -1782,6 +1828,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 176758c..ce965c6 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 7095693..45b6dc0 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
@@ -1399,6 +1400,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,
@@ -1850,6 +1872,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),
-- 
1.8.3.1

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

* [PATCH v3 3/9] selinux lsm IB/core: Implement LSM notification system
  2016-07-29 13:53 ` Dan Jurgens
@ 2016-07-29 13:53     ` Dan Jurgens
  -1 siblings, 0 replies; 79+ messages in thread
From: Dan Jurgens @ 2016-07-29 13:53 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

 drivers/infiniband/core/device.c | 53 ++++++++++++++++++++++++++++++++++++++++
 include/linux/security.h         |  8 ++++++
 security/security.c              | 20 +++++++++++++++
 security/selinux/hooks.c         |  5 ++--
 security/selinux/selinuxfs.c     |  2 ++
 5 files changed, 86 insertions(+), 2 deletions(-)

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 @@ err:
 
 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 0bd8319..84abc05 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -69,6 +69,14 @@ struct audit_krule;
 struct user_namespace;
 struct timezone;
 
+enum lsm_event {
+	LSM_POLICY_CHANGE,
+};
+
+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);
+
 /* These functions are in security/commoncap.c */
 extern int cap_capable(const struct cred *cred, struct user_namespace *ns,
 		       int cap, int audit);
diff --git a/security/security.c b/security/security.c
index 45b6dc0..8b8ddb2 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 a86d537..7c22703 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -159,13 +159,14 @@ static int selinux_peerlbl_enabled(void)
 	return (selinux_policycap_alwaysnetwork || netlbl_enabled() || selinux_xfrm_enabled());
 }
 
-static int selinux_netcache_avc_callback(u32 event)
+static int selinux_cache_avc_callback(u32 event)
 {
 	if (event == AVC_CALLBACK_RESET) {
 		sel_netif_flush();
 		sel_netnode_flush();
 		sel_netport_flush();
 		synchronize_net();
+		call_lsm_notifier(LSM_POLICY_CHANGE, NULL);
 	}
 	return 0;
 }
@@ -6235,7 +6236,7 @@ static __init int selinux_init(void)
 
 	security_add_hooks(selinux_hooks, ARRAY_SIZE(selinux_hooks));
 
-	if (avc_add_callback(selinux_netcache_avc_callback, AVC_CALLBACK_RESET))
+	if (avc_add_callback(selinux_cache_avc_callback, AVC_CALLBACK_RESET))
 		panic("SELinux: Unable to register AVC netcache callback\n");
 
 	if (selinux_enforcing)
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index 1b1fd27..983bf2a 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:
-- 
1.8.3.1

--
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] 79+ messages in thread

* [PATCH v3 3/9] selinux lsm IB/core: Implement LSM notification system
@ 2016-07-29 13:53     ` Dan Jurgens
  0 siblings, 0 replies; 79+ messages in thread
From: Dan Jurgens @ 2016-07-29 13:53 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

 drivers/infiniband/core/device.c | 53 ++++++++++++++++++++++++++++++++++++++++
 include/linux/security.h         |  8 ++++++
 security/security.c              | 20 +++++++++++++++
 security/selinux/hooks.c         |  5 ++--
 security/selinux/selinuxfs.c     |  2 ++
 5 files changed, 86 insertions(+), 2 deletions(-)

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 @@ err:
 
 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 0bd8319..84abc05 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -69,6 +69,14 @@ struct audit_krule;
 struct user_namespace;
 struct timezone;
 
+enum lsm_event {
+	LSM_POLICY_CHANGE,
+};
+
+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);
+
 /* These functions are in security/commoncap.c */
 extern int cap_capable(const struct cred *cred, struct user_namespace *ns,
 		       int cap, int audit);
diff --git a/security/security.c b/security/security.c
index 45b6dc0..8b8ddb2 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 a86d537..7c22703 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -159,13 +159,14 @@ static int selinux_peerlbl_enabled(void)
 	return (selinux_policycap_alwaysnetwork || netlbl_enabled() || selinux_xfrm_enabled());
 }
 
-static int selinux_netcache_avc_callback(u32 event)
+static int selinux_cache_avc_callback(u32 event)
 {
 	if (event == AVC_CALLBACK_RESET) {
 		sel_netif_flush();
 		sel_netnode_flush();
 		sel_netport_flush();
 		synchronize_net();
+		call_lsm_notifier(LSM_POLICY_CHANGE, NULL);
 	}
 	return 0;
 }
@@ -6235,7 +6236,7 @@ static __init int selinux_init(void)
 
 	security_add_hooks(selinux_hooks, ARRAY_SIZE(selinux_hooks));
 
-	if (avc_add_callback(selinux_netcache_avc_callback, AVC_CALLBACK_RESET))
+	if (avc_add_callback(selinux_cache_avc_callback, AVC_CALLBACK_RESET))
 		panic("SELinux: Unable to register AVC netcache callback\n");
 
 	if (selinux_enforcing)
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index 1b1fd27..983bf2a 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:
-- 
1.8.3.1

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

* [PATCH v3 4/9] IB/core: Enforce security on management datagrams
  2016-07-29 13:53 ` Dan Jurgens
@ 2016-07-29 13:53     ` Dan Jurgens
  -1 siblings, 0 replies; 79+ messages in thread
From: Dan Jurgens @ 2016-07-29 13:53 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>

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-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>

---
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 2d49228..94ebc3e 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 c3a7328..942556d 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -884,6 +884,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.
@@ -1597,6 +1602,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 */
@@ -1830,6 +1837,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 84abc05..cb35cb9 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -1381,6 +1381,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 */
@@ -1389,6 +1390,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 8b8ddb2..a853727 100644
--- a/security/security.c
+++ b/security/security.c
@@ -1428,6 +1428,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);
@@ -1895,6 +1901,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 =
-- 
1.8.3.1

--
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] 79+ messages in thread

* [PATCH v3 4/9] IB/core: Enforce security on management datagrams
@ 2016-07-29 13:53     ` Dan Jurgens
  0 siblings, 0 replies; 79+ messages in thread
From: Dan Jurgens @ 2016-07-29 13:53 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 2d49228..94ebc3e 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 c3a7328..942556d 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -884,6 +884,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.
@@ -1597,6 +1602,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 */
@@ -1830,6 +1837,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 84abc05..cb35cb9 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -1381,6 +1381,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 */
@@ -1389,6 +1390,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 8b8ddb2..a853727 100644
--- a/security/security.c
+++ b/security/security.c
@@ -1428,6 +1428,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);
@@ -1895,6 +1901,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 =
-- 
1.8.3.1

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

* [PATCH v3 5/9] selinux: Create policydb version for Infiniband support
  2016-07-29 13:53 ` Dan Jurgens
@ 2016-07-29 13:53     ` Dan Jurgens
  -1 siblings, 0 replies; 79+ messages in thread
From: Dan Jurgens @ 2016-07-29 13:53 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>

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>

---
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

 security/selinux/include/security.h |   3 +-
 security/selinux/ss/policydb.c      | 130 +++++++++++++++++++++++++++++++-----
 security/selinux/ss/policydb.h      |  27 +++++---
 3 files changed, 136 insertions(+), 24 deletions(-)

diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index 38feb55..a7e6ed2 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -36,13 +36,14 @@
 #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
 #ifdef CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX
 #define POLICYDB_VERSION_MAX	CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE
 #else
-#define POLICYDB_VERSION_MAX	POLICYDB_VERSION_XPERMS_IOCTL
+#define POLICYDB_VERSION_MAX	POLICYDB_VERSION_INFINIBAND
 #endif
 
 /* Mask for just the mount related flags */
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index 992a315..6056c2c 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,
 	},
 };
@@ -2219,6 +2229,61 @@ 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;
 			}
 		}
 	}
@@ -3147,6 +3212,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 {
-- 
1.8.3.1

--
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] 79+ messages in thread

* [PATCH v3 5/9] selinux: Create policydb version for Infiniband support
@ 2016-07-29 13:53     ` Dan Jurgens
  0 siblings, 0 replies; 79+ messages in thread
From: Dan Jurgens @ 2016-07-29 13:53 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

 security/selinux/include/security.h |   3 +-
 security/selinux/ss/policydb.c      | 130 +++++++++++++++++++++++++++++++-----
 security/selinux/ss/policydb.h      |  27 +++++---
 3 files changed, 136 insertions(+), 24 deletions(-)

diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index 38feb55..a7e6ed2 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -36,13 +36,14 @@
 #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
 #ifdef CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX
 #define POLICYDB_VERSION_MAX	CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE
 #else
-#define POLICYDB_VERSION_MAX	POLICYDB_VERSION_XPERMS_IOCTL
+#define POLICYDB_VERSION_MAX	POLICYDB_VERSION_INFINIBAND
 #endif
 
 /* Mask for just the mount related flags */
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index 992a315..6056c2c 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,
 	},
 };
@@ -2219,6 +2229,61 @@ 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;
 			}
 		}
 	}
@@ -3147,6 +3212,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 {
-- 
1.8.3.1

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

* [PATCH v3 6/9] selinux: Allocate and free infiniband security hooks
  2016-07-29 13:53 ` Dan Jurgens
                   ` (2 preceding siblings ...)
  (?)
@ 2016-07-29 13:53 ` Dan Jurgens
  -1 siblings, 0 replies; 79+ messages in thread
From: Dan Jurgens @ 2016-07-29 13:53 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 7c22703..ef1088c 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,
@@ -5991,7 +5992,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[] = {
@@ -6175,7 +6195,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_ */
-- 
1.8.3.1


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

* [PATCH v3 7/9] selinux: Implement Infiniband PKey "Access" access vector
  2016-07-29 13:53 ` Dan Jurgens
                   ` (3 preceding siblings ...)
  (?)
@ 2016-07-29 13:53 ` Dan Jurgens
  -1 siblings, 0 replies; 79+ messages in thread
From: Dan Jurgens @ 2016-07-29 13:53 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

 include/linux/lsm_audit.h           |  7 +++++++
 security/lsm_audit.c                | 13 ++++++++++++
 security/selinux/hooks.c            | 23 +++++++++++++++++++++
 security/selinux/include/classmap.h |  2 ++
 security/selinux/include/security.h |  2 ++
 security/selinux/ss/services.c      | 41 +++++++++++++++++++++++++++++++++++++
 6 files changed, 88 insertions(+)

diff --git a/include/linux/lsm_audit.h b/include/linux/lsm_audit.h
index ffb9c9d..8ff7eae 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;
@@ -59,6 +64,7 @@ struct common_audit_data {
 #define LSM_AUDIT_DATA_INODE	9
 #define LSM_AUDIT_DATA_DENTRY	10
 #define LSM_AUDIT_DATA_IOCTL_OP	11
+#define LSM_AUDIT_DATA_PKEY	12
 	union 	{
 		struct path path;
 		struct dentry *dentry;
@@ -75,6 +81,7 @@ struct common_audit_data {
 #endif
 		char *kmod_name;
 		struct lsm_ioctlop_audit *op;
+		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 cccbf30..2546d82 100644
--- a/security/lsm_audit.c
+++ b/security/lsm_audit.c
@@ -397,6 +397,19 @@ 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 ef1088c..101ea82 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -5995,6 +5995,28 @@ 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;
@@ -6196,6 +6218,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 a7e6ed2..8f1a66e 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -180,6 +180,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 89df646..ba346da 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -2229,6 +2229,47 @@ out:
 }
 
 /**
+ * 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
-- 
1.8.3.1


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

* [PATCH v3 8/9] selinux: Add IB Port SMP access vector
  2016-07-29 13:53 ` Dan Jurgens
                   ` (4 preceding siblings ...)
  (?)
@ 2016-07-29 13:53 ` Dan Jurgens
  -1 siblings, 0 replies; 79+ messages in thread
From: Dan Jurgens @ 2016-07-29 13:53 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

 include/linux/lsm_audit.h           | 32 +++++++++++++++++-----------
 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      | 42 +++++++++++++++++++++++++++++++++++++
 6 files changed, 96 insertions(+), 12 deletions(-)

diff --git a/include/linux/lsm_audit.h b/include/linux/lsm_audit.h
index 8ff7eae..4f82e52 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,21 +51,27 @@ 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;
-#define LSM_AUDIT_DATA_PATH	1
-#define LSM_AUDIT_DATA_NET	2
-#define LSM_AUDIT_DATA_CAP	3
-#define LSM_AUDIT_DATA_IPC	4
-#define LSM_AUDIT_DATA_TASK	5
-#define LSM_AUDIT_DATA_KEY	6
-#define LSM_AUDIT_DATA_NONE	7
-#define LSM_AUDIT_DATA_KMOD	8
-#define LSM_AUDIT_DATA_INODE	9
-#define LSM_AUDIT_DATA_DENTRY	10
-#define LSM_AUDIT_DATA_IOCTL_OP	11
-#define LSM_AUDIT_DATA_PKEY	12
+#define LSM_AUDIT_DATA_PATH		1
+#define LSM_AUDIT_DATA_NET		2
+#define LSM_AUDIT_DATA_CAP		3
+#define LSM_AUDIT_DATA_IPC		4
+#define LSM_AUDIT_DATA_TASK		5
+#define LSM_AUDIT_DATA_KEY		6
+#define LSM_AUDIT_DATA_NONE		7
+#define LSM_AUDIT_DATA_KMOD		8
+#define LSM_AUDIT_DATA_INODE		9
+#define LSM_AUDIT_DATA_DENTRY		10
+#define LSM_AUDIT_DATA_IOCTL_OP		11
+#define LSM_AUDIT_DATA_PKEY		12
+#define LSM_AUDIT_DATA_IB_ENDPORT	13
 	union 	{
 		struct path path;
 		struct dentry *dentry;
@@ -82,6 +89,7 @@ struct common_audit_data {
 		char *kmod_name;
 		struct lsm_ioctlop_audit *op;
 		struct lsm_pkey_audit *pkey;
+		struct lsm_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 2546d82..ffb077b 100644
--- a/security/lsm_audit.c
+++ b/security/lsm_audit.c
@@ -410,6 +410,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 101ea82..5aa345f 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -6017,6 +6017,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;
@@ -6219,6 +6242,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 8f1a66e..1b575b7 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -182,6 +182,8 @@ int security_port_sid(u8 protocol, u16 port, u32 *out_sid);
 
 int security_pkey_sid(u64 subnet_prefix, u16 pkey_num, u32 *out_sid);
 
+int security_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 ba346da..1b5f693 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -2270,6 +2270,48 @@ out:
 }
 
 /**
+ * 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
-- 
1.8.3.1


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

* [PATCH v3 9/9] selinux: Add a cache for quicker retreival of PKey SIDs
  2016-07-29 13:53 ` Dan Jurgens
@ 2016-07-29 13:53     ` Dan Jurgens
  -1 siblings, 0 replies; 79+ messages in thread
From: Dan Jurgens @ 2016-07-29 13:53 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>

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-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> and Paul Moore
<paul-r2n+y4ga6xFZroRs9YW3xA@public.gmane.org> (see security/selinux/netif.c and
security/selinux/netport.c for more information)

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

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

 security/selinux/Makefile         |   2 +-
 security/selinux/hooks.c          |   4 +-
 security/selinux/ibpkey.c         | 245 ++++++++++++++++++++++++++++++++++++++
 security/selinux/include/ibpkey.h |  31 +++++
 security/selinux/include/objsec.h |   6 +
 5 files changed, 286 insertions(+), 2 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 5aa345f..a6088a1 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"
@@ -167,6 +168,7 @@ static int selinux_cache_avc_callback(u32 event)
 		sel_netnode_flush();
 		sel_netport_flush();
 		synchronize_net();
+		sel_pkey_flush();
 		call_lsm_notifier(LSM_POLICY_CHANGE, NULL);
 	}
 	return 0;
@@ -6003,7 +6005,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..6e52c54
--- /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-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> and
+ * Paul Moore <paul-r2n+y4ga6xFZroRs9YW3xA@public.gmane.org>
+ *   (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 = -ENOMEM;
+	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 != 0)
+		goto out;
+
+	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);
+	if (unlikely(ret))
+		kfree(new);
+
+	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_ */
-- 
1.8.3.1

--
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] 79+ messages in thread

* [PATCH v3 9/9] selinux: Add a cache for quicker retreival of PKey SIDs
@ 2016-07-29 13:53     ` Dan Jurgens
  0 siblings, 0 replies; 79+ messages in thread
From: Dan Jurgens @ 2016-07-29 13:53 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 braket indentation mismatch in sel_pkey_find. Yuval Shaia
- Change spin_lock_bh to spin_lock_irqsave to resolve HARDIRQ lockdep
  warning.  Dan Jurgens

 security/selinux/Makefile         |   2 +-
 security/selinux/hooks.c          |   4 +-
 security/selinux/ibpkey.c         | 245 ++++++++++++++++++++++++++++++++++++++
 security/selinux/include/ibpkey.h |  31 +++++
 security/selinux/include/objsec.h |   6 +
 5 files changed, 286 insertions(+), 2 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 5aa345f..a6088a1 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"
@@ -167,6 +168,7 @@ static int selinux_cache_avc_callback(u32 event)
 		sel_netnode_flush();
 		sel_netport_flush();
 		synchronize_net();
+		sel_pkey_flush();
 		call_lsm_notifier(LSM_POLICY_CHANGE, NULL);
 	}
 	return 0;
@@ -6003,7 +6005,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..6e52c54
--- /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 = -ENOMEM;
+	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 != 0)
+		goto out;
+
+	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);
+	if (unlikely(ret))
+		kfree(new);
+
+	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_ */
-- 
1.8.3.1

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

* Re: [PATCH v3 3/9] selinux lsm IB/core: Implement LSM notification system
  2016-07-29 13:53     ` Dan Jurgens
@ 2016-07-29 22:40         ` kbuild test robot
  -1 siblings, 0 replies; 79+ messages in thread
From: kbuild test robot @ 2016-07-29 22:40 UTC (permalink / raw)
  Cc: kbuild-all-JC7UmRfGjtg, chrisw-69jw2NvuJkxg9hUCZPvPmw,
	paul-r2n+y4ga6xFZroRs9YW3xA, sds-+05T5uksL2qpZYMLLGbcSA,
	eparis-FjpueFixGhCM4zKIHC2jIg, dledford-H+wXaHxf7aLQT0dZR+AlfA,
	sean.hefty-ral2JQCrhuEAvxtiuMwx3w,
	hal.rosenstock-Re5JQEeQqe8AvxtiuMwx3w,
	selinux-+05T5uksL2qpZYMLLGbcSA,
	linux-security-module-u79uwXL29TY76Z2rM5mHXA,
	linux-rdma-u79uwXL29TY76Z2rM5mHXA,
	yevgenyp-VPRAkNaXOzVWk0Htik3J/w, Daniel Jurgens

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

Hi,

[auto build test ERROR on next-20160729]
[cannot apply to pcmoore-selinux/next rdma/master linus/master v4.7-rc7 v4.7-rc6 v4.7-rc5 v4.7]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Dan-Jurgens/SELinux-support-for-Infiniband-RDMA/20160729-220959
config: ia64-defconfig (attached as .config)
compiler: ia64-linux-gcc (GCC) 4.9.0
reproduce:
        wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        make.cross ARCH=ia64 

All errors (new ones prefixed by >>):

>> ERROR: "unregister_lsm_notifier" [drivers/infiniband/core/ib_core.ko] undefined!
>> ERROR: "register_lsm_notifier" [drivers/infiniband/core/ib_core.ko] undefined!

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/octet-stream, Size: 17857 bytes --]

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

* Re: [PATCH v3 3/9] selinux lsm IB/core: Implement LSM notification system
@ 2016-07-29 22:40         ` kbuild test robot
  0 siblings, 0 replies; 79+ messages in thread
From: kbuild test robot @ 2016-07-29 22:40 UTC (permalink / raw)
  To: Dan Jurgens
  Cc: kbuild-all, chrisw, paul, sds, eparis, dledford, sean.hefty,
	hal.rosenstock, selinux, linux-security-module, linux-rdma,
	yevgenyp, Daniel Jurgens

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

Hi,

[auto build test ERROR on next-20160729]
[cannot apply to pcmoore-selinux/next rdma/master linus/master v4.7-rc7 v4.7-rc6 v4.7-rc5 v4.7]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Dan-Jurgens/SELinux-support-for-Infiniband-RDMA/20160729-220959
config: ia64-defconfig (attached as .config)
compiler: ia64-linux-gcc (GCC) 4.9.0
reproduce:
        wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        make.cross ARCH=ia64 

All errors (new ones prefixed by >>):

>> ERROR: "unregister_lsm_notifier" [drivers/infiniband/core/ib_core.ko] undefined!
>> ERROR: "register_lsm_notifier" [drivers/infiniband/core/ib_core.ko] undefined!

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/octet-stream, Size: 17857 bytes --]

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

* Re: [PATCH v3 0/9] SELinux support for Infiniband RDMA
  2016-07-29 13:53 ` Dan Jurgens
                   ` (5 preceding siblings ...)
  (?)
@ 2016-08-29 21:40 ` Paul Moore
  2016-08-29 21:48   ` Daniel Jurgens
  -1 siblings, 1 reply; 79+ messages in thread
From: Paul Moore @ 2016-08-29 21:40 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 Fri, Jul 29, 2016 at 9:53 AM, Dan Jurgens <danielj@mellanox.com> wrote:
> From: Daniel Jurgens <danielj@mellanox.com>

...

> 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

Hi Daniel,

My apologies for such a long delay in responding to this latest
patchset; conferences, travel, and vacation have made for a very busy
August.  After you posted the v2 patchset we had an off-list
discussion regarding testing the SELinux/IB integration; unfortunately
we realized that IB hardware would be needed to test this (no IB
loopback device), but we agreed that having tests would be beneficial.

Have you done any work yet towards adding SELinux/IB tests to the
selinux-testsuite project?

* https://github.com/SELinuxProject/selinux-testsuite

-- 
paul moore
www.paul-moore.com

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

* Re: [PATCH v3 0/9] SELinux support for Infiniband RDMA
  2016-08-29 21:40 ` [PATCH v3 0/9] SELinux support for Infiniband RDMA Paul Moore
@ 2016-08-29 21:48   ` Daniel Jurgens
  2016-08-30  0:00     ` Paul Moore
  0 siblings, 1 reply; 79+ messages in thread
From: Daniel Jurgens @ 2016-08-29 21:48 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 8/29/2016 4:40 PM, Paul Moore wrote:
> On Fri, Jul 29, 2016 at 9:53 AM, Dan Jurgens <danielj@mellanox.com> wrote:
>> From: Daniel Jurgens <danielj@mellanox.com>
> ...
>
>> 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
> Hi Daniel,
>
> My apologies for such a long delay in responding to this latest
> patchset; conferences, travel, and vacation have made for a very busy
> August.  After you posted the v2 patchset we had an off-list
> discussion regarding testing the SELinux/IB integration; unfortunately
> we realized that IB hardware would be needed to test this (no IB
> loopback device), but we agreed that having tests would be beneficial.
>
> Have you done any work yet towards adding SELinux/IB tests to the
> selinux-testsuite project?
>
> * https://github.com/SELinuxProject/selinux-testsuite
>
Hi Paul, I've not started doing that yet.  I've been waiting for feedback of any kind from the RDMA list.  I thought the test updates would be more appropriate around the time I'm submitting the changes to the user space utilities to allow labeling the new types.


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

* Re: [PATCH v3 0/9] SELinux support for Infiniband RDMA
  2016-08-29 21:48   ` Daniel Jurgens
@ 2016-08-30  0:00     ` Paul Moore
  2016-08-30  7:46       ` Leon Romanovsky
  0 siblings, 1 reply; 79+ messages in thread
From: Paul Moore @ 2016-08-30  0:00 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 Mon, Aug 29, 2016 at 5:48 PM, Daniel Jurgens <danielj@mellanox.com> wrote:
> On 8/29/2016 4:40 PM, Paul Moore wrote:
>> On Fri, Jul 29, 2016 at 9:53 AM, Dan Jurgens <danielj@mellanox.com> wrote:
>>> From: Daniel Jurgens <danielj@mellanox.com>
>> ...
>>
>>> 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
>> Hi Daniel,
>>
>> My apologies for such a long delay in responding to this latest
>> patchset; conferences, travel, and vacation have made for a very busy
>> August.  After you posted the v2 patchset we had an off-list
>> discussion regarding testing the SELinux/IB integration; unfortunately
>> we realized that IB hardware would be needed to test this (no IB
>> loopback device), but we agreed that having tests would be beneficial.
>>
>> Have you done any work yet towards adding SELinux/IB tests to the
>> selinux-testsuite project?
>>
>> * https://github.com/SELinuxProject/selinux-testsuite
>
> Hi Paul, I've not started doing that yet.  I've been waiting for feedback of any kind from the RDMA list.  I thought the test updates would be more appropriate around the time I'm submitting the changes to the user space utilities to allow labeling the new types.

Okay, no problem.  I just want the tests in place and functional when
we merge the kernel code.

-- 
paul moore
www.paul-moore.com

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

* Re: [PATCH v3 0/9] SELinux support for Infiniband RDMA
  2016-08-30  0:00     ` Paul Moore
@ 2016-08-30  7:46       ` Leon Romanovsky
  2016-08-30 13:53         ` Paul Moore
       [not found]         ` <20160830074607.GN594-2ukJVAZIZ/Y@public.gmane.org>
  0 siblings, 2 replies; 79+ messages in thread
From: Leon Romanovsky @ 2016-08-30  7:46 UTC (permalink / raw)
  To: Paul Moore
  Cc: Daniel Jurgens, chrisw, Stephen Smalley, Eric Paris, dledford,
	sean.hefty, hal.rosenstock, selinux, linux-security-module,
	linux-rdma, Yevgeny Petrilin

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

On Mon, Aug 29, 2016 at 08:00:32PM -0400, Paul Moore wrote:
> On Mon, Aug 29, 2016 at 5:48 PM, Daniel Jurgens <danielj@mellanox.com> wrote:
> > On 8/29/2016 4:40 PM, Paul Moore wrote:
> >> On Fri, Jul 29, 2016 at 9:53 AM, Dan Jurgens <danielj@mellanox.com> wrote:
> >>> From: Daniel Jurgens <danielj@mellanox.com>
> >> ...
> >>
> >>> 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
> >> Hi Daniel,
> >>
> >> My apologies for such a long delay in responding to this latest
> >> patchset; conferences, travel, and vacation have made for a very busy
> >> August.  After you posted the v2 patchset we had an off-list
> >> discussion regarding testing the SELinux/IB integration; unfortunately
> >> we realized that IB hardware would be needed to test this (no IB
> >> loopback device), but we agreed that having tests would be beneficial.
> >>
> >> Have you done any work yet towards adding SELinux/IB tests to the
> >> selinux-testsuite project?
> >>
> >> * https://github.com/SELinuxProject/selinux-testsuite
> >
> > Hi Paul, I've not started doing that yet.  I've been waiting for feedback of any kind from the RDMA list.  I thought the test updates would be more appropriate around the time I'm submitting the changes to the user space utilities to allow labeling the new types.
>
> Okay, no problem.  I just want the tests in place and functional when
> we merge the kernel code.

Hi Paul,

IMHO, you can use Soft RoCE (RXE) [1] for it.

----
Soft RoCE (RXE) - The software RoCE driver

ib_rxe implements the RDMA transport and registers to the RDMA core
device as a kernel verbs provider. It also implements the packet IO
layer. On the other hand ib_rxe registers to the Linux netdev stack
as a udp encapsulating protocol, in that case RDMA, for sending and
receiving packets over any Ethernet device.  This yields a RDMA
transport over the UDP/Ethernet network layer forming a RoCEv2
compatible device.

The configuration procedure of the Soft RoCE drivers requires
binding to any existing Ethernet network device. This is done with
/sys interface.
----

[1]
https://git.kernel.org/cgit/linux/kernel/git/dledford/rdma.git/tree/drivers/infiniband/sw/rxe

>
> --
> 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@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

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

* Re: [PATCH v3 0/9] SELinux support for Infiniband RDMA
  2016-08-30  7:46       ` Leon Romanovsky
@ 2016-08-30 13:53         ` Paul Moore
  2016-08-30 14:06             ` Daniel Jurgens
       [not found]         ` <20160830074607.GN594-2ukJVAZIZ/Y@public.gmane.org>
  1 sibling, 1 reply; 79+ messages in thread
From: Paul Moore @ 2016-08-30 13:53 UTC (permalink / raw)
  To: Leon Romanovsky, Daniel Jurgens
  Cc: chrisw, Stephen Smalley, Eric Paris, dledford, sean.hefty,
	hal.rosenstock, selinux, linux-security-module, linux-rdma,
	Yevgeny Petrilin

On Tue, Aug 30, 2016 at 3:46 AM, Leon Romanovsky <leon@kernel.org> wrote:
> On Mon, Aug 29, 2016 at 08:00:32PM -0400, Paul Moore wrote:
>> On Mon, Aug 29, 2016 at 5:48 PM, Daniel Jurgens <danielj@mellanox.com> wrote:
>> > On 8/29/2016 4:40 PM, Paul Moore wrote:
>> >> On Fri, Jul 29, 2016 at 9:53 AM, Dan Jurgens <danielj@mellanox.com> wrote:
>> >>> From: Daniel Jurgens <danielj@mellanox.com>
>> >> ...
>> >>
>> >>> 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
>> >> Hi Daniel,
>> >>
>> >> My apologies for such a long delay in responding to this latest
>> >> patchset; conferences, travel, and vacation have made for a very busy
>> >> August.  After you posted the v2 patchset we had an off-list
>> >> discussion regarding testing the SELinux/IB integration; unfortunately
>> >> we realized that IB hardware would be needed to test this (no IB
>> >> loopback device), but we agreed that having tests would be beneficial.
>> >>
>> >> Have you done any work yet towards adding SELinux/IB tests to the
>> >> selinux-testsuite project?
>> >>
>> >> * https://github.com/SELinuxProject/selinux-testsuite
>> >
>> > Hi Paul, I've not started doing that yet.  I've been waiting for feedback of any kind from the RDMA list.  I thought the test updates would be more appropriate around the time I'm submitting the changes to the user space utilities to allow labeling the new types.
>>
>> Okay, no problem.  I just want the tests in place and functional when
>> we merge the kernel code.
>
> Hi Paul,
>
> IMHO, you can use Soft RoCE (RXE) [1] for it.
>
> ----
> Soft RoCE (RXE) - The software RoCE driver
>
> ib_rxe implements the RDMA transport and registers to the RDMA core
> device as a kernel verbs provider. It also implements the packet IO
> layer. On the other hand ib_rxe registers to the Linux netdev stack
> as a udp encapsulating protocol, in that case RDMA, for sending and
> receiving packets over any Ethernet device.  This yields a RDMA
> transport over the UDP/Ethernet network layer forming a RoCEv2
> compatible device.
>
> The configuration procedure of the Soft RoCE drivers requires
> binding to any existing Ethernet network device. This is done with
> /sys interface.
> ----
>
> [1]
> https://git.kernel.org/cgit/linux/kernel/git/dledford/rdma.git/tree/drivers/infiniband/sw/rxe

Hi Leon,

It looks like v4.8 will have all the necessary pieces for this, yes?
Is there any documentation on this other than the git log?  Keep in
mind I'm looking at this from the SELinux side, I'm very Infiniband
ignorant at the moment; although Daniel has been very patient in
walking me through some of the basics.

Daniel, does this look like something we might be able to use?

-- 
paul moore
www.paul-moore.com

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

* Re: [PATCH v3 0/9] SELinux support for Infiniband RDMA
  2016-08-30 13:53         ` Paul Moore
@ 2016-08-30 14:06             ` Daniel Jurgens
  0 siblings, 0 replies; 79+ messages in thread
From: Daniel Jurgens @ 2016-08-30 14:06 UTC (permalink / raw)
  To: Paul Moore, Leon Romanovsky
  Cc: linux-rdma-u79uwXL29TY76Z2rM5mHXA,
	linux-security-module-u79uwXL29TY76Z2rM5mHXA,
	chrisw-69jw2NvuJkxg9hUCZPvPmw, dledford-H+wXaHxf7aLQT0dZR+AlfA,
	selinux-+05T5uksL2qpZYMLLGbcSA,
	sean.hefty-ral2JQCrhuEAvxtiuMwx3w, Stephen Smalley,
	hal.rosenstock-Re5JQEeQqe8AvxtiuMwx3w

On 8/30/2016 8:53 AM, Paul Moore wrote:
> On Tue, Aug 30, 2016 at 3:46 AM, Leon Romanovsky <leon-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> wrote:
>> On Mon, Aug 29, 2016 at 08:00:32PM -0400, Paul Moore wrote:
>>> On Mon, Aug 29, 2016 at 5:48 PM, Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org> wrote:
>>>> On 8/29/2016 4:40 PM, Paul Moore wrote:
>>>>> On Fri, Jul 29, 2016 at 9:53 AM, Dan Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org> wrote:
>>>>>> From: Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
>>>>> ...
>>>>>
>>>>>> 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
>>>>> Hi Daniel,
>>>>>
>>>>> My apologies for such a long delay in responding to this latest
>>>>> patchset; conferences, travel, and vacation have made for a very busy
>>>>> August.  After you posted the v2 patchset we had an off-list
>>>>> discussion regarding testing the SELinux/IB integration; unfortunately
>>>>> we realized that IB hardware would be needed to test this (no IB
>>>>> loopback device), but we agreed that having tests would be beneficial.
>>>>>
>>>>> Have you done any work yet towards adding SELinux/IB tests to the
>>>>> selinux-testsuite project?
>>>>>
>>>>> * https://github.com/SELinuxProject/selinux-testsuite
>>>> Hi Paul, I've not started doing that yet.  I've been waiting for feedback of any kind from the RDMA list.  I thought the test updates would be more appropriate around the time I'm submitting the changes to the user space utilities to allow labeling the new types.
>>> Okay, no problem.  I just want the tests in place and functional when
>>> we merge the kernel code.
>> Hi Paul,
>>
>> IMHO, you can use Soft RoCE (RXE) [1] for it.
>>
>> ----
>> Soft RoCE (RXE) - The software RoCE driver
>>
>> ib_rxe implements the RDMA transport and registers to the RDMA core
>> device as a kernel verbs provider. It also implements the packet IO
>> layer. On the other hand ib_rxe registers to the Linux netdev stack
>> as a udp encapsulating protocol, in that case RDMA, for sending and
>> receiving packets over any Ethernet device.  This yields a RDMA
>> transport over the UDP/Ethernet network layer forming a RoCEv2
>> compatible device.
>>
>> The configuration procedure of the Soft RoCE drivers requires
>> binding to any existing Ethernet network device. This is done with
>> /sys interface.
>> ----
>>
>> [1]
>> https://git.kernel.org/cgit/linux/kernel/git/dledford/rdma.git/tree/drivers/infiniband/sw/rxe
> Hi Leon,
>
> It looks like v4.8 will have all the necessary pieces for this, yes?
> Is there any documentation on this other than the git log?  Keep in
> mind I'm looking at this from the SELinux side, I'm very Infiniband
> ignorant at the moment; although Daniel has been very patient in
> walking me through some of the basics.
>
> Daniel, does this look like something we might be able to use?
>
I don't this will be useful, RoCE doesn't have partitions/PKeys because it uses Ethernet as the transport instead of Infiniband. 


_______________________________________________
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] 79+ messages in thread

* Re: [PATCH v3 0/9] SELinux support for Infiniband RDMA
@ 2016-08-30 14:06             ` Daniel Jurgens
  0 siblings, 0 replies; 79+ messages in thread
From: Daniel Jurgens @ 2016-08-30 14:06 UTC (permalink / raw)
  To: Paul Moore, Leon Romanovsky
  Cc: chrisw, Stephen Smalley, Eric Paris, dledford, sean.hefty,
	hal.rosenstock, selinux, linux-security-module, linux-rdma,
	Yevgeny Petrilin

On 8/30/2016 8:53 AM, Paul Moore wrote:
> On Tue, Aug 30, 2016 at 3:46 AM, Leon Romanovsky <leon@kernel.org> wrote:
>> On Mon, Aug 29, 2016 at 08:00:32PM -0400, Paul Moore wrote:
>>> On Mon, Aug 29, 2016 at 5:48 PM, Daniel Jurgens <danielj@mellanox.com> wrote:
>>>> On 8/29/2016 4:40 PM, Paul Moore wrote:
>>>>> On Fri, Jul 29, 2016 at 9:53 AM, Dan Jurgens <danielj@mellanox.com> wrote:
>>>>>> From: Daniel Jurgens <danielj@mellanox.com>
>>>>> ...
>>>>>
>>>>>> 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
>>>>> Hi Daniel,
>>>>>
>>>>> My apologies for such a long delay in responding to this latest
>>>>> patchset; conferences, travel, and vacation have made for a very busy
>>>>> August.  After you posted the v2 patchset we had an off-list
>>>>> discussion regarding testing the SELinux/IB integration; unfortunately
>>>>> we realized that IB hardware would be needed to test this (no IB
>>>>> loopback device), but we agreed that having tests would be beneficial.
>>>>>
>>>>> Have you done any work yet towards adding SELinux/IB tests to the
>>>>> selinux-testsuite project?
>>>>>
>>>>> * https://github.com/SELinuxProject/selinux-testsuite
>>>> Hi Paul, I've not started doing that yet.  I've been waiting for feedback of any kind from the RDMA list.  I thought the test updates would be more appropriate around the time I'm submitting the changes to the user space utilities to allow labeling the new types.
>>> Okay, no problem.  I just want the tests in place and functional when
>>> we merge the kernel code.
>> Hi Paul,
>>
>> IMHO, you can use Soft RoCE (RXE) [1] for it.
>>
>> ----
>> Soft RoCE (RXE) - The software RoCE driver
>>
>> ib_rxe implements the RDMA transport and registers to the RDMA core
>> device as a kernel verbs provider. It also implements the packet IO
>> layer. On the other hand ib_rxe registers to the Linux netdev stack
>> as a udp encapsulating protocol, in that case RDMA, for sending and
>> receiving packets over any Ethernet device.  This yields a RDMA
>> transport over the UDP/Ethernet network layer forming a RoCEv2
>> compatible device.
>>
>> The configuration procedure of the Soft RoCE drivers requires
>> binding to any existing Ethernet network device. This is done with
>> /sys interface.
>> ----
>>
>> [1]
>> https://git.kernel.org/cgit/linux/kernel/git/dledford/rdma.git/tree/drivers/infiniband/sw/rxe
> Hi Leon,
>
> It looks like v4.8 will have all the necessary pieces for this, yes?
> Is there any documentation on this other than the git log?  Keep in
> mind I'm looking at this from the SELinux side, I'm very Infiniband
> ignorant at the moment; although Daniel has been very patient in
> walking me through some of the basics.
>
> Daniel, does this look like something we might be able to use?
>
I don't this will be useful, RoCE doesn't have partitions/PKeys because it uses Ethernet as the transport instead of Infiniband. 

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

* Re: [PATCH v3 0/9] SELinux support for Infiniband RDMA
  2016-08-30 14:06             ` Daniel Jurgens
@ 2016-08-30 15:01                 ` Leon Romanovsky
  -1 siblings, 0 replies; 79+ messages in thread
From: Leon Romanovsky @ 2016-08-30 15:01 UTC (permalink / raw)
  To: Daniel Jurgens
  Cc: Paul Moore, 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, Yevgeny Petrilin

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

On Tue, Aug 30, 2016 at 02:06:53PM +0000, Daniel Jurgens wrote:
> On 8/30/2016 8:53 AM, Paul Moore wrote:
> > On Tue, Aug 30, 2016 at 3:46 AM, Leon Romanovsky <leon-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> wrote:
> >> On Mon, Aug 29, 2016 at 08:00:32PM -0400, Paul Moore wrote:
> >>> On Mon, Aug 29, 2016 at 5:48 PM, Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org> wrote:
> >>>> On 8/29/2016 4:40 PM, Paul Moore wrote:
> >>>>> On Fri, Jul 29, 2016 at 9:53 AM, Dan Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org> wrote:
> >>>>>> From: Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
> >>>>> ...
> >>>>>
> >>>>>> 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
> >>>>> Hi Daniel,
> >>>>>
> >>>>> My apologies for such a long delay in responding to this latest
> >>>>> patchset; conferences, travel, and vacation have made for a very busy
> >>>>> August.  After you posted the v2 patchset we had an off-list
> >>>>> discussion regarding testing the SELinux/IB integration; unfortunately
> >>>>> we realized that IB hardware would be needed to test this (no IB
> >>>>> loopback device), but we agreed that having tests would be beneficial.
> >>>>>
> >>>>> Have you done any work yet towards adding SELinux/IB tests to the
> >>>>> selinux-testsuite project?
> >>>>>
> >>>>> * https://github.com/SELinuxProject/selinux-testsuite
> >>>> Hi Paul, I've not started doing that yet.  I've been waiting for feedback of any kind from the RDMA list.  I thought the test updates would be more appropriate around the time I'm submitting the changes to the user space utilities to allow labeling the new types.
> >>> Okay, no problem.  I just want the tests in place and functional when
> >>> we merge the kernel code.
> >> Hi Paul,
> >>
> >> IMHO, you can use Soft RoCE (RXE) [1] for it.
> >>
> >> ----
> >> Soft RoCE (RXE) - The software RoCE driver
> >>
> >> ib_rxe implements the RDMA transport and registers to the RDMA core
> >> device as a kernel verbs provider. It also implements the packet IO
> >> layer. On the other hand ib_rxe registers to the Linux netdev stack
> >> as a udp encapsulating protocol, in that case RDMA, for sending and
> >> receiving packets over any Ethernet device.  This yields a RDMA
> >> transport over the UDP/Ethernet network layer forming a RoCEv2
> >> compatible device.
> >>
> >> The configuration procedure of the Soft RoCE drivers requires
> >> binding to any existing Ethernet network device. This is done with
> >> /sys interface.
> >> ----
> >>
> >> [1]
> >> https://git.kernel.org/cgit/linux/kernel/git/dledford/rdma.git/tree/drivers/infiniband/sw/rxe
> > Hi Leon,
> >
> > It looks like v4.8 will have all the necessary pieces for this, yes?
> > Is there any documentation on this other than the git log?  Keep in
> > mind I'm looking at this from the SELinux side, I'm very Infiniband
> > ignorant at the moment; although Daniel has been very patient in
> > walking me through some of the basics.
> >
> > Daniel, does this look like something we might be able to use?
> >
> I don't this will be useful, RoCE doesn't have partitions/PKeys because it uses Ethernet as the transport instead of Infiniband.
>

Yeah, sorry for the noise.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

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

* Re: [PATCH v3 0/9] SELinux support for Infiniband RDMA
@ 2016-08-30 15:01                 ` Leon Romanovsky
  0 siblings, 0 replies; 79+ messages in thread
From: Leon Romanovsky @ 2016-08-30 15:01 UTC (permalink / raw)
  To: Daniel Jurgens
  Cc: Paul Moore, chrisw, Stephen Smalley, Eric Paris, dledford,
	sean.hefty, hal.rosenstock, selinux, linux-security-module,
	linux-rdma, Yevgeny Petrilin

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

On Tue, Aug 30, 2016 at 02:06:53PM +0000, Daniel Jurgens wrote:
> On 8/30/2016 8:53 AM, Paul Moore wrote:
> > On Tue, Aug 30, 2016 at 3:46 AM, Leon Romanovsky <leon@kernel.org> wrote:
> >> On Mon, Aug 29, 2016 at 08:00:32PM -0400, Paul Moore wrote:
> >>> On Mon, Aug 29, 2016 at 5:48 PM, Daniel Jurgens <danielj@mellanox.com> wrote:
> >>>> On 8/29/2016 4:40 PM, Paul Moore wrote:
> >>>>> On Fri, Jul 29, 2016 at 9:53 AM, Dan Jurgens <danielj@mellanox.com> wrote:
> >>>>>> From: Daniel Jurgens <danielj@mellanox.com>
> >>>>> ...
> >>>>>
> >>>>>> 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
> >>>>> Hi Daniel,
> >>>>>
> >>>>> My apologies for such a long delay in responding to this latest
> >>>>> patchset; conferences, travel, and vacation have made for a very busy
> >>>>> August.  After you posted the v2 patchset we had an off-list
> >>>>> discussion regarding testing the SELinux/IB integration; unfortunately
> >>>>> we realized that IB hardware would be needed to test this (no IB
> >>>>> loopback device), but we agreed that having tests would be beneficial.
> >>>>>
> >>>>> Have you done any work yet towards adding SELinux/IB tests to the
> >>>>> selinux-testsuite project?
> >>>>>
> >>>>> * https://github.com/SELinuxProject/selinux-testsuite
> >>>> Hi Paul, I've not started doing that yet.  I've been waiting for feedback of any kind from the RDMA list.  I thought the test updates would be more appropriate around the time I'm submitting the changes to the user space utilities to allow labeling the new types.
> >>> Okay, no problem.  I just want the tests in place and functional when
> >>> we merge the kernel code.
> >> Hi Paul,
> >>
> >> IMHO, you can use Soft RoCE (RXE) [1] for it.
> >>
> >> ----
> >> Soft RoCE (RXE) - The software RoCE driver
> >>
> >> ib_rxe implements the RDMA transport and registers to the RDMA core
> >> device as a kernel verbs provider. It also implements the packet IO
> >> layer. On the other hand ib_rxe registers to the Linux netdev stack
> >> as a udp encapsulating protocol, in that case RDMA, for sending and
> >> receiving packets over any Ethernet device.  This yields a RDMA
> >> transport over the UDP/Ethernet network layer forming a RoCEv2
> >> compatible device.
> >>
> >> The configuration procedure of the Soft RoCE drivers requires
> >> binding to any existing Ethernet network device. This is done with
> >> /sys interface.
> >> ----
> >>
> >> [1]
> >> https://git.kernel.org/cgit/linux/kernel/git/dledford/rdma.git/tree/drivers/infiniband/sw/rxe
> > Hi Leon,
> >
> > It looks like v4.8 will have all the necessary pieces for this, yes?
> > Is there any documentation on this other than the git log?  Keep in
> > mind I'm looking at this from the SELinux side, I'm very Infiniband
> > ignorant at the moment; although Daniel has been very patient in
> > walking me through some of the basics.
> >
> > Daniel, does this look like something we might be able to use?
> >
> I don't this will be useful, RoCE doesn't have partitions/PKeys because it uses Ethernet as the transport instead of Infiniband.
>

Yeah, sorry for the noise.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

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

* Re: [PATCH v3 0/9] SELinux support for Infiniband RDMA
  2016-08-30  7:46       ` Leon Romanovsky
@ 2016-08-30 15:02             ` Or Gerlitz
       [not found]         ` <20160830074607.GN594-2ukJVAZIZ/Y@public.gmane.org>
  1 sibling, 0 replies; 79+ messages in thread
From: Or Gerlitz @ 2016-08-30 15:02 UTC (permalink / raw)
  To: Leon Romanovsky, Daniel Jurgens
  Cc: Paul Moore, 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, Yevgeny Petrilin

On Tue, Aug 30, 2016 at 10:46 AM, Leon Romanovsky <leon-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> wrote:
> On Mon, Aug 29, 2016 at 08:00:32PM -0400, Paul Moore wrote:
>> On Mon, Aug 29, 2016 at 5:48 PM, Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org> wrote:
>> > On 8/29/2016 4:40 PM, Paul Moore wrote:
>> >> On Fri, Jul 29, 2016 at 9:53 AM, Dan Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org> wrote:
>> >>> From: Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
>> >> ...
>> >>
>> >>> 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
>> >> Hi Daniel,
>> >>
>> >> My apologies for such a long delay in responding to this latest
>> >> patchset; conferences, travel, and vacation have made for a very busy
>> >> August.  After you posted the v2 patchset we had an off-list
>> >> discussion regarding testing the SELinux/IB integration; unfortunately
>> >> we realized that IB hardware would be needed to test this (no IB
>> >> loopback device), but we agreed that having tests would be beneficial.
>> >>
>> >> Have you done any work yet towards adding SELinux/IB tests to the
>> >> selinux-testsuite project?
>> >>
>> >> * https://github.com/SELinuxProject/selinux-testsuite
>> >
>> > Hi Paul, I've not started doing that yet.  I've been waiting for feedback of any kind from the RDMA list.  I thought the test updates would be more appropriate around the time I'm submitting the changes to the user space utilities to allow labeling the new types.

>> Okay, no problem.  I just want the tests in place and functional when
>> we merge the kernel code.

> Hi Paul,
> IMHO, you can use Soft RoCE (RXE) [1] for it.

If I got it right, little if not nothing of this patch set is
applicable to RoCE ports, this is about IB ports, Daniel, can you
comment?

Or.
--
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] 79+ messages in thread

* Re: [PATCH v3 0/9] SELinux support for Infiniband RDMA
@ 2016-08-30 15:02             ` Or Gerlitz
  0 siblings, 0 replies; 79+ messages in thread
From: Or Gerlitz @ 2016-08-30 15:02 UTC (permalink / raw)
  To: Leon Romanovsky, Daniel Jurgens
  Cc: Paul Moore, chrisw, Stephen Smalley, Eric Paris, dledford,
	sean.hefty, hal.rosenstock, selinux, linux-security-module,
	linux-rdma, Yevgeny Petrilin

On Tue, Aug 30, 2016 at 10:46 AM, Leon Romanovsky <leon@kernel.org> wrote:
> On Mon, Aug 29, 2016 at 08:00:32PM -0400, Paul Moore wrote:
>> On Mon, Aug 29, 2016 at 5:48 PM, Daniel Jurgens <danielj@mellanox.com> wrote:
>> > On 8/29/2016 4:40 PM, Paul Moore wrote:
>> >> On Fri, Jul 29, 2016 at 9:53 AM, Dan Jurgens <danielj@mellanox.com> wrote:
>> >>> From: Daniel Jurgens <danielj@mellanox.com>
>> >> ...
>> >>
>> >>> 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
>> >> Hi Daniel,
>> >>
>> >> My apologies for such a long delay in responding to this latest
>> >> patchset; conferences, travel, and vacation have made for a very busy
>> >> August.  After you posted the v2 patchset we had an off-list
>> >> discussion regarding testing the SELinux/IB integration; unfortunately
>> >> we realized that IB hardware would be needed to test this (no IB
>> >> loopback device), but we agreed that having tests would be beneficial.
>> >>
>> >> Have you done any work yet towards adding SELinux/IB tests to the
>> >> selinux-testsuite project?
>> >>
>> >> * https://github.com/SELinuxProject/selinux-testsuite
>> >
>> > Hi Paul, I've not started doing that yet.  I've been waiting for feedback of any kind from the RDMA list.  I thought the test updates would be more appropriate around the time I'm submitting the changes to the user space utilities to allow labeling the new types.

>> Okay, no problem.  I just want the tests in place and functional when
>> we merge the kernel code.

> Hi Paul,
> IMHO, you can use Soft RoCE (RXE) [1] for it.

If I got it right, little if not nothing of this patch set is
applicable to RoCE ports, this is about IB ports, Daniel, can you
comment?

Or.

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

* Re: [PATCH v3 0/9] SELinux support for Infiniband RDMA
  2016-08-30 14:06             ` Daniel Jurgens
  (?)
  (?)
@ 2016-08-30 18:46             ` Jason Gunthorpe
  2016-08-30 18:52                 ` Daniel Jurgens
  -1 siblings, 1 reply; 79+ messages in thread
From: Jason Gunthorpe @ 2016-08-30 18:46 UTC (permalink / raw)
  To: Daniel Jurgens
  Cc: Paul Moore, Leon Romanovsky, chrisw, Stephen Smalley, Eric Paris,
	dledford, sean.hefty, hal.rosenstock, selinux,
	linux-security-module, linux-rdma, Yevgeny Petrilin

On Tue, Aug 30, 2016 at 02:06:53PM +0000, Daniel Jurgens wrote:

> I don't this will be useful, RoCE doesn't have partitions/PKeys
> because it uses Ethernet as the transport instead of Infiniband.

The vlan stuff in roce should be just as restricted as the pkey is in
IB....

Jason

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

* Re: [PATCH v3 0/9] SELinux support for Infiniband RDMA
  2016-08-30 18:46             ` Jason Gunthorpe
@ 2016-08-30 18:52                 ` Daniel Jurgens
  0 siblings, 0 replies; 79+ messages in thread
From: Daniel Jurgens @ 2016-08-30 18:52 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: Leon Romanovsky, linux-rdma-u79uwXL29TY76Z2rM5mHXA,
	linux-security-module-u79uwXL29TY76Z2rM5mHXA,
	chrisw-69jw2NvuJkxg9hUCZPvPmw, dledford-H+wXaHxf7aLQT0dZR+AlfA,
	selinux-+05T5uksL2qpZYMLLGbcSA,
	sean.hefty-ral2JQCrhuEAvxtiuMwx3w, Stephen Smalley,
	hal.rosenstock-Re5JQEeQqe8AvxtiuMwx3w

On 8/30/2016 1:46 PM, Jason Gunthorpe wrote:
> On Tue, Aug 30, 2016 at 02:06:53PM +0000, Daniel Jurgens wrote:
>
>> I don't this will be useful, RoCE doesn't have partitions/PKeys
>> because it uses Ethernet as the transport instead of Infiniband.
> The vlan stuff in roce should be just as restricted as the pkey is in
> IB....
>
> Jason
>
This patch set introduces a mechanism for controlling access to Infiniband partitions.  If someone is interested in writing SELinux tests regarding RoCE and VLANs then RXE may very well be useful for them.  It just doesn't apply here.


_______________________________________________
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] 79+ messages in thread

* Re: [PATCH v3 0/9] SELinux support for Infiniband RDMA
@ 2016-08-30 18:52                 ` Daniel Jurgens
  0 siblings, 0 replies; 79+ messages in thread
From: Daniel Jurgens @ 2016-08-30 18:52 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: Paul Moore, Leon Romanovsky, chrisw, Stephen Smalley, Eric Paris,
	dledford, sean.hefty, hal.rosenstock, selinux,
	linux-security-module, linux-rdma, Yevgeny Petrilin

On 8/30/2016 1:46 PM, Jason Gunthorpe wrote:
> On Tue, Aug 30, 2016 at 02:06:53PM +0000, Daniel Jurgens wrote:
>
>> I don't this will be useful, RoCE doesn't have partitions/PKeys
>> because it uses Ethernet as the transport instead of Infiniband.
> The vlan stuff in roce should be just as restricted as the pkey is in
> IB....
>
> Jason
>
This patch set introduces a mechanism for controlling access to Infiniband partitions.  If someone is interested in writing SELinux tests regarding RoCE and VLANs then RXE may very well be useful for them.  It just doesn't apply here.

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

* Re: [PATCH v3 0/9] SELinux support for Infiniband RDMA
  2016-08-30 18:52                 ` Daniel Jurgens
  (?)
@ 2016-08-30 18:55                 ` Jason Gunthorpe
  2016-08-30 19:10                     ` Daniel Jurgens
  -1 siblings, 1 reply; 79+ messages in thread
From: Jason Gunthorpe @ 2016-08-30 18:55 UTC (permalink / raw)
  To: Daniel Jurgens
  Cc: Paul Moore, Leon Romanovsky, chrisw, Stephen Smalley, Eric Paris,
	dledford, sean.hefty, hal.rosenstock, selinux,
	linux-security-module, linux-rdma, Yevgeny Petrilin

On Tue, Aug 30, 2016 at 06:52:28PM +0000, Daniel Jurgens wrote:
> On 8/30/2016 1:46 PM, Jason Gunthorpe wrote:
> > On Tue, Aug 30, 2016 at 02:06:53PM +0000, Daniel Jurgens wrote:
> >
> >> I don't this will be useful, RoCE doesn't have partitions/PKeys
> >> because it uses Ethernet as the transport instead of Infiniband.
> > The vlan stuff in roce should be just as restricted as the pkey is in
> > IB....

> This patch set introduces a mechanism for controlling access to
> Infiniband partitions.  If someone is interested in writing SELinux
> tests regarding RoCE and VLANs then RXE may very well be useful for
> them.  It just doesn't apply here.

Are subsystems usually SELinux enabled in such a piecemeal way?

Are you sure the 'partition' SELinux label should not be more general
to cover more of the similar RDMA cases?

Jason

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

* Re: [PATCH v3 0/9] SELinux support for Infiniband RDMA
  2016-08-30 18:55                 ` Jason Gunthorpe
@ 2016-08-30 19:10                     ` Daniel Jurgens
  0 siblings, 0 replies; 79+ messages in thread
From: Daniel Jurgens @ 2016-08-30 19:10 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: Leon Romanovsky, linux-rdma-u79uwXL29TY76Z2rM5mHXA,
	linux-security-module-u79uwXL29TY76Z2rM5mHXA,
	chrisw-69jw2NvuJkxg9hUCZPvPmw, dledford-H+wXaHxf7aLQT0dZR+AlfA,
	selinux-+05T5uksL2qpZYMLLGbcSA,
	sean.hefty-ral2JQCrhuEAvxtiuMwx3w, Stephen Smalley,
	hal.rosenstock-Re5JQEeQqe8AvxtiuMwx3w

On 8/30/2016 1:56 PM, Jason Gunthorpe wrote:
>
> Are subsystems usually SELinux enabled in such a piecemeal way?
>
> Are you sure the 'partition' SELinux label should not be more general
> to cover more of the similar RDMA cases?
>
> Jason
>
In order to label something you have to be able to describe something unique about an instance of it, like a Subnet Prefix/PKey value pair.  What other thing could we label more generally to control access to a partition/VLAN?


_______________________________________________
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] 79+ messages in thread

* Re: [PATCH v3 0/9] SELinux support for Infiniband RDMA
@ 2016-08-30 19:10                     ` Daniel Jurgens
  0 siblings, 0 replies; 79+ messages in thread
From: Daniel Jurgens @ 2016-08-30 19:10 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: Paul Moore, Leon Romanovsky, chrisw, Stephen Smalley, Eric Paris,
	dledford, sean.hefty, hal.rosenstock, selinux,
	linux-security-module, linux-rdma, Yevgeny Petrilin

On 8/30/2016 1:56 PM, Jason Gunthorpe wrote:
>
> Are subsystems usually SELinux enabled in such a piecemeal way?
>
> Are you sure the 'partition' SELinux label should not be more general
> to cover more of the similar RDMA cases?
>
> Jason
>
In order to label something you have to be able to describe something unique about an instance of it, like a Subnet Prefix/PKey value pair.  What other thing could we label more generally to control access to a partition/VLAN?

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

* Re: [PATCH v3 3/9] selinux lsm IB/core: Implement LSM notification system
  2016-07-29 13:53     ` Dan Jurgens
  (?)
  (?)
@ 2016-09-01  1:35     ` Paul Moore
  -1 siblings, 0 replies; 79+ messages in thread
From: Paul Moore @ 2016-09-01  1:35 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 Fri, Jul 29, 2016 at 9:53 AM, Dan Jurgens <danielj@mellanox.com> 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
>
>  drivers/infiniband/core/device.c | 53 ++++++++++++++++++++++++++++++++++++++++
>  include/linux/security.h         |  8 ++++++
>  security/security.c              | 20 +++++++++++++++
>  security/selinux/hooks.c         |  5 ++--
>  security/selinux/selinuxfs.c     |  2 ++
>  5 files changed, 86 insertions(+), 2 deletions(-)

One small comment below, I also assume you've seen the test robot's
email regarding build problems on IA64?

> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index a86d537..7c22703 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -159,13 +159,14 @@ static int selinux_peerlbl_enabled(void)
>         return (selinux_policycap_alwaysnetwork || netlbl_enabled() || selinux_xfrm_enabled());
>  }
>
> -static int selinux_netcache_avc_callback(u32 event)
> +static int selinux_cache_avc_callback(u32 event)
>  {
>         if (event == AVC_CALLBACK_RESET) {
>                 sel_netif_flush();
>                 sel_netnode_flush();
>                 sel_netport_flush();
>                 synchronize_net();
> +               call_lsm_notifier(LSM_POLICY_CHANGE, NULL);
>         }
>         return 0;
>  }

We are getting down to the small details now ... I think I would
prefer if the "call_lsm_notifier(...)" call was done from its own AVC
callback instead of hanging off the existing netcache callback.

-- 
paul moore
www.paul-moore.com

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

* Re: [PATCH v3 5/9] selinux: Create policydb version for Infiniband support
  2016-07-29 13:53     ` Dan Jurgens
@ 2016-09-01  1:39         ` Paul Moore
  -1 siblings, 0 replies; 79+ messages in thread
From: Paul Moore @ 2016-09-01  1:39 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 Fri, Jul 29, 2016 at 9:53 AM, Dan Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org> 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>
>
> ---
> 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

Nit picky, but you still have some curly braces in ocontext_read()
that aren't strictly necessary.

> v3:
> - ib_port -> ib_endport. Paul Moore
>
>  security/selinux/include/security.h |   3 +-
>  security/selinux/ss/policydb.c      | 130 +++++++++++++++++++++++++++++++-----
>  security/selinux/ss/policydb.h      |  27 +++++---
>  3 files changed, 136 insertions(+), 24 deletions(-)

-- 
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] 79+ messages in thread

* Re: [PATCH v3 5/9] selinux: Create policydb version for Infiniband support
@ 2016-09-01  1:39         ` Paul Moore
  0 siblings, 0 replies; 79+ messages in thread
From: Paul Moore @ 2016-09-01  1:39 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 Fri, Jul 29, 2016 at 9:53 AM, Dan Jurgens <danielj@mellanox.com> 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>
>
> ---
> 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

Nit picky, but you still have some curly braces in ocontext_read()
that aren't strictly necessary.

> v3:
> - ib_port -> ib_endport. Paul Moore
>
>  security/selinux/include/security.h |   3 +-
>  security/selinux/ss/policydb.c      | 130 +++++++++++++++++++++++++++++++-----
>  security/selinux/ss/policydb.h      |  27 +++++---
>  3 files changed, 136 insertions(+), 24 deletions(-)

-- 
paul moore
www.paul-moore.com

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

* Re: [PATCH v3 0/9] SELinux support for Infiniband RDMA
  2016-08-30 19:10                     ` Daniel Jurgens
  (?)
@ 2016-09-01 16:34                     ` Jason Gunthorpe
       [not found]                       ` <20160901163418.GA6479-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
  -1 siblings, 1 reply; 79+ messages in thread
From: Jason Gunthorpe @ 2016-09-01 16:34 UTC (permalink / raw)
  To: Daniel Jurgens
  Cc: Paul Moore, Leon Romanovsky, chrisw, Stephen Smalley, Eric Paris,
	dledford, sean.hefty, hal.rosenstock, selinux,
	linux-security-module, linux-rdma, Yevgeny Petrilin

On Tue, Aug 30, 2016 at 07:10:12PM +0000, Daniel Jurgens wrote:
> On 8/30/2016 1:56 PM, Jason Gunthorpe wrote:
> >
> > Are subsystems usually SELinux enabled in such a piecemeal way?
> >
> > Are you sure the 'partition' SELinux label should not be more general
> > to cover more of the similar RDMA cases?

> In order to label something you have to be able to describe
> something unique about an instance of it, like a Subnet Prefix/PKey
> value pair.  What other thing could we label more generally to
> control access to a partition/VLAN?

IP prefix / vlan #? How does it work in net?

Shouldn't you at least have a plan for how this will expand to cover
the whole subsystem??

Jason

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

* Re: [PATCH v3 0/9] SELinux support for Infiniband RDMA
  2016-09-01 16:34                     ` Jason Gunthorpe
@ 2016-09-01 18:06                           ` Paul Moore
  0 siblings, 0 replies; 79+ messages in thread
From: Paul Moore @ 2016-09-01 18:06 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: chrisw-69jw2NvuJkxg9hUCZPvPmw, Leon Romanovsky,
	linux-rdma-u79uwXL29TY76Z2rM5mHXA,
	linux-security-module-u79uwXL29TY76Z2rM5mHXA,
	dledford-H+wXaHxf7aLQT0dZR+AlfA, selinux-+05T5uksL2qpZYMLLGbcSA,
	sean.hefty-ral2JQCrhuEAvxtiuMwx3w, Stephen Smalley,
	hal.rosenstock-Re5JQEeQqe8AvxtiuMwx3w

On Thu, Sep 1, 2016 at 12:34 PM, Jason Gunthorpe
<jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org> wrote:
> On Tue, Aug 30, 2016 at 07:10:12PM +0000, Daniel Jurgens wrote:
>> On 8/30/2016 1:56 PM, Jason Gunthorpe wrote:
>> >
>> > Are subsystems usually SELinux enabled in such a piecemeal way?
>> >
>> > Are you sure the 'partition' SELinux label should not be more general
>> > to cover more of the similar RDMA cases?
>
>> In order to label something you have to be able to describe
>> something unique about an instance of it, like a Subnet Prefix/PKey
>> value pair.  What other thing could we label more generally to
>> control access to a partition/VLAN?
>
> IP prefix / vlan #? How does it work in net?
>
> Shouldn't you at least have a plan for how this will expand to cover
> the whole subsystem??

Jason and/or Daniel, I think it would be helpful if you could explain
both the InifiniBand and IP based approaches for those of us who know
SELinux, but not necessarily the RDMA and InfiniBand portions of this
discussion.  Be verbose and explain it as if we were idiots (I get
called that enough, it must be true).

-- 
paul moore
www.paul-moore.com
_______________________________________________
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] 79+ messages in thread

* Re: [PATCH v3 0/9] SELinux support for Infiniband RDMA
@ 2016-09-01 18:06                           ` Paul Moore
  0 siblings, 0 replies; 79+ messages in thread
From: Paul Moore @ 2016-09-01 18:06 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: Daniel Jurgens, Leon Romanovsky, chrisw, Stephen Smalley,
	Eric Paris, dledford, sean.hefty, hal.rosenstock, selinux,
	linux-security-module, linux-rdma, Yevgeny Petrilin

On Thu, Sep 1, 2016 at 12:34 PM, Jason Gunthorpe
<jgunthorpe@obsidianresearch.com> wrote:
> On Tue, Aug 30, 2016 at 07:10:12PM +0000, Daniel Jurgens wrote:
>> On 8/30/2016 1:56 PM, Jason Gunthorpe wrote:
>> >
>> > Are subsystems usually SELinux enabled in such a piecemeal way?
>> >
>> > Are you sure the 'partition' SELinux label should not be more general
>> > to cover more of the similar RDMA cases?
>
>> In order to label something you have to be able to describe
>> something unique about an instance of it, like a Subnet Prefix/PKey
>> value pair.  What other thing could we label more generally to
>> control access to a partition/VLAN?
>
> IP prefix / vlan #? How does it work in net?
>
> Shouldn't you at least have a plan for how this will expand to cover
> the whole subsystem??

Jason and/or Daniel, I think it would be helpful if you could explain
both the InifiniBand and IP based approaches for those of us who know
SELinux, but not necessarily the RDMA and InfiniBand portions of this
discussion.  Be verbose and explain it as if we were idiots (I get
called that enough, it must be true).

-- 
paul moore
www.paul-moore.com

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

* Re: [PATCH v3 0/9] SELinux support for Infiniband RDMA
  2016-09-01 18:06                           ` Paul Moore
  (?)
@ 2016-09-06 20:02                           ` Jason Gunthorpe
  2016-09-06 20:35                               ` Daniel Jurgens
  2016-09-20 23:43                             ` Paul Moore
  -1 siblings, 2 replies; 79+ messages in thread
From: Jason Gunthorpe @ 2016-09-06 20:02 UTC (permalink / raw)
  To: Paul Moore
  Cc: Daniel Jurgens, Leon Romanovsky, chrisw, Stephen Smalley,
	Eric Paris, dledford, sean.hefty, hal.rosenstock, selinux,
	linux-security-module, linux-rdma, Yevgeny Petrilin

On Thu, Sep 01, 2016 at 02:06:46PM -0400, Paul Moore wrote:

> Jason and/or Daniel, I think it would be helpful if you could explain
> both the InifiniBand and IP based approaches for those of us who know
> SELinux, but not necessarily the RDMA and InfiniBand portions of this
> discussion.  Be verbose and explain it as if we were idiots (I get
> called that enough, it must be true).

Well, I'm not really familiar with SELinux, I know a little bit about
how labels are applied in the netstack, but not that much...

The RDMA subsystem supports 4 different networking standards, and they
each have their own objects..

Just focusing on the pkey/vlan ideas. Every packet placed on the
network has either a pkey or vlan label, the networking switches and
receivers use these labels to create strong access control.

The labels are not-global, they are isolated to a site, or even a
single network within a site.

ipoib also uses pkey&vlan in the same way netdev does (with these
patches it looks like a userspace can still access a pkey via ipoib
even if selinux is restricting access to it).

Daniel's patch also touched on the QP1 and QP0 concepts. Packets can
be labeled as being for QP0/1 and the recievers process them under the
assumption they were sent by something with privilege (eg like the low
port numbers in IP)

So, from my perspective, we shouldn't be talking about doing pkey
without also addressing vlan. It sounds like Daniel's concern is how to
identify the number space (eg he is using a GID prefix for IB, which
won't work on anything else, maybe rdma device handle is a better choice)

Jason

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

* Re: [PATCH v3 0/9] SELinux support for Infiniband RDMA
  2016-09-06 20:02                           ` Jason Gunthorpe
@ 2016-09-06 20:35                               ` Daniel Jurgens
  2016-09-20 23:43                             ` Paul Moore
  1 sibling, 0 replies; 79+ messages in thread
From: Daniel Jurgens @ 2016-09-06 20:35 UTC (permalink / raw)
  To: Jason Gunthorpe, Paul Moore
  Cc: Leon Romanovsky, linux-rdma-u79uwXL29TY76Z2rM5mHXA,
	linux-security-module-u79uwXL29TY76Z2rM5mHXA,
	chrisw-69jw2NvuJkxg9hUCZPvPmw, dledford-H+wXaHxf7aLQT0dZR+AlfA,
	selinux-+05T5uksL2qpZYMLLGbcSA,
	sean.hefty-ral2JQCrhuEAvxtiuMwx3w, Stephen Smalley,
	hal.rosenstock-Re5JQEeQqe8AvxtiuMwx3w

On 9/6/2016 3:02 PM, Jason Gunthorpe wrote:
> On Thu, Sep 01, 2016 at 02:06:46PM -0400, Paul Moore wrote:
>
>> Jason and/or Daniel, I think it would be helpful if you could explain
>> both the InifiniBand and IP based approaches for those of us who know
>> SELinux, but not necessarily the RDMA and InfiniBand portions of this
>> discussion.  Be verbose and explain it as if we were idiots (I get
>> called that enough, it must be true).
> Well, I'm not really familiar with SELinux, I know a little bit about
> how labels are applied in the netstack, but not that much...
>
> The RDMA subsystem supports 4 different networking standards, and they
> each have their own objects..
>
> Just focusing on the pkey/vlan ideas. Every packet placed on the
> network has either a pkey or vlan label, the networking switches and
> receivers use these labels to create strong access control.
>
> The labels are not-global, they are isolated to a site, or even a
> single network within a site.
>
> ipoib also uses pkey&vlan in the same way netdev does (with these
> patches it looks like a userspace can still access a pkey via ipoib
> even if selinux is restricting access to it).
>
> Daniel's patch also touched on the QP1 and QP0 concepts. Packets can
> be labeled as being for QP0/1 and the recievers process them under the
> assumption they were sent by something with privilege (eg like the low
> port numbers in IP)
>
> So, from my perspective, we shouldn't be talking about doing pkey
> without also addressing vlan. It sounds like Daniel's concern is how to
> identify the number space (eg he is using a GID prefix for IB, which
> won't work on anything else, maybe rdma device handle is a better choice)
>
> Jason
>
I think to control access to a VLAN for RoCE there would have to labels for GIDs, since that's how you select which VLAN to use.  It'd be very similar to how the pkey labels works, but it doesn't help with Infiniband, so I think the pkey labeling scheme is still required.  RDMA device handle labeling isn't granular enough for what I'm trying to accomplish.  We want users with different levels of permission to be able to use the same device, but restrict who they can communicate with by isolating them to separate partitions.


_______________________________________________
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] 79+ messages in thread

* Re: [PATCH v3 0/9] SELinux support for Infiniband RDMA
@ 2016-09-06 20:35                               ` Daniel Jurgens
  0 siblings, 0 replies; 79+ messages in thread
From: Daniel Jurgens @ 2016-09-06 20:35 UTC (permalink / raw)
  To: Jason Gunthorpe, Paul Moore
  Cc: Leon Romanovsky, chrisw, Stephen Smalley, Eric Paris, dledford,
	sean.hefty, hal.rosenstock, selinux, linux-security-module,
	linux-rdma, Yevgeny Petrilin

On 9/6/2016 3:02 PM, Jason Gunthorpe wrote:
> On Thu, Sep 01, 2016 at 02:06:46PM -0400, Paul Moore wrote:
>
>> Jason and/or Daniel, I think it would be helpful if you could explain
>> both the InifiniBand and IP based approaches for those of us who know
>> SELinux, but not necessarily the RDMA and InfiniBand portions of this
>> discussion.  Be verbose and explain it as if we were idiots (I get
>> called that enough, it must be true).
> Well, I'm not really familiar with SELinux, I know a little bit about
> how labels are applied in the netstack, but not that much...
>
> The RDMA subsystem supports 4 different networking standards, and they
> each have their own objects..
>
> Just focusing on the pkey/vlan ideas. Every packet placed on the
> network has either a pkey or vlan label, the networking switches and
> receivers use these labels to create strong access control.
>
> The labels are not-global, they are isolated to a site, or even a
> single network within a site.
>
> ipoib also uses pkey&vlan in the same way netdev does (with these
> patches it looks like a userspace can still access a pkey via ipoib
> even if selinux is restricting access to it).
>
> Daniel's patch also touched on the QP1 and QP0 concepts. Packets can
> be labeled as being for QP0/1 and the recievers process them under the
> assumption they were sent by something with privilege (eg like the low
> port numbers in IP)
>
> So, from my perspective, we shouldn't be talking about doing pkey
> without also addressing vlan. It sounds like Daniel's concern is how to
> identify the number space (eg he is using a GID prefix for IB, which
> won't work on anything else, maybe rdma device handle is a better choice)
>
> Jason
>
I think to control access to a VLAN for RoCE there would have to labels for GIDs, since that's how you select which VLAN to use.  It'd be very similar to how the pkey labels works, but it doesn't help with Infiniband, so I think the pkey labeling scheme is still required.  RDMA device handle labeling isn't granular enough for what I'm trying to accomplish.  We want users with different levels of permission to be able to use the same device, but restrict who they can communicate with by isolating them to separate partitions.

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

* Re: [PATCH v3 0/9] SELinux support for Infiniband RDMA
  2016-09-06 20:35                               ` Daniel Jurgens
  (?)
@ 2016-09-06 21:55                               ` Jason Gunthorpe
  2016-09-08  0:01                                 ` ira.weiny
  -1 siblings, 1 reply; 79+ messages in thread
From: Jason Gunthorpe @ 2016-09-06 21:55 UTC (permalink / raw)
  To: Daniel Jurgens
  Cc: Paul Moore, Leon Romanovsky, chrisw, Stephen Smalley, Eric Paris,
	dledford, sean.hefty, hal.rosenstock, selinux,
	linux-security-module, linux-rdma, Yevgeny Petrilin

On Tue, Sep 06, 2016 at 08:35:56PM +0000, Daniel Jurgens wrote:

> I think to control access to a VLAN for RoCE there would have to
> labels for GIDs, since that's how you select which VLAN to use.

Since people are talking about using GIDs for containers adding a GID
constraint for all technologies makes sense to me..

But rocev1 (at least mlx4) does not use vlan ids from the GID, the
vlan id is set directly in the id, so it still seems to need direct
containment. I also see vlan related stuff in the iwarp providers, so
they probably have a similar requirement.

> required.  RDMA device handle labeling isn't granular enough for
> what I'm trying to accomplish.  We want users with different levels
> of permission to be able to use the same device, but restrict who
> they can communicate with by isolating them to separate partitions.

Sure, but maybe you should use the (device handle:pkey/vlan_id) as your
labeling tuple not (Subnet Prefix, pkey)

Jason

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

* Re: [PATCH v3 0/9] SELinux support for Infiniband RDMA
  2016-09-06 21:55                               ` Jason Gunthorpe
@ 2016-09-08  0:01                                 ` ira.weiny
  2016-09-08 14:12                                     ` Daniel Jurgens
  0 siblings, 1 reply; 79+ messages in thread
From: ira.weiny @ 2016-09-08  0:01 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: Daniel Jurgens, Paul Moore, Leon Romanovsky, chrisw,
	Stephen Smalley, Eric Paris, dledford, sean.hefty,
	hal.rosenstock, selinux, linux-security-module, linux-rdma,
	Yevgeny Petrilin

On Tue, Sep 06, 2016 at 03:55:48PM -0600, Jason Gunthorpe wrote:
> On Tue, Sep 06, 2016 at 08:35:56PM +0000, Daniel Jurgens wrote:
> 
> > I think to control access to a VLAN for RoCE there would have to
> > labels for GIDs, since that's how you select which VLAN to use.
> 
> Since people are talking about using GIDs for containers adding a GID
> constraint for all technologies makes sense to me..
> 
> But rocev1 (at least mlx4) does not use vlan ids from the GID, the
> vlan id is set directly in the id, so it still seems to need direct
> containment. I also see vlan related stuff in the iwarp providers, so
> they probably have a similar requirement.
> 
> > required.  RDMA device handle labeling isn't granular enough for
> > what I'm trying to accomplish.  We want users with different levels
> > of permission to be able to use the same device, but restrict who
> > they can communicate with by isolating them to separate partitions.
> 
> Sure, but maybe you should use the (device handle:pkey/vlan_id) as your
> labeling tuple not (Subnet Prefix, pkey)

Would "device handle" here specify the port?

Ira

> 
> Jason
> --
> To unsubscribe from this list: send the line "unsubscribe linux-rdma" 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] 79+ messages in thread

* Re: [PATCH v3 0/9] SELinux support for Infiniband RDMA
  2016-09-08  0:01                                 ` ira.weiny
@ 2016-09-08 14:12                                     ` Daniel Jurgens
  0 siblings, 0 replies; 79+ messages in thread
From: Daniel Jurgens @ 2016-09-08 14:12 UTC (permalink / raw)
  To: ira.weiny, Jason Gunthorpe, Liran Liss
  Cc: Leon Romanovsky, linux-rdma-u79uwXL29TY76Z2rM5mHXA,
	linux-security-module-u79uwXL29TY76Z2rM5mHXA,
	chrisw-69jw2NvuJkxg9hUCZPvPmw, dledford-H+wXaHxf7aLQT0dZR+AlfA,
	selinux-+05T5uksL2qpZYMLLGbcSA,
	sean.hefty-ral2JQCrhuEAvxtiuMwx3w, Stephen Smalley,
	hal.rosenstock-Re5JQEeQqe8AvxtiuMwx3w

On 9/7/2016 7:01 PM, ira.weiny wrote:
> On Tue, Sep 06, 2016 at 03:55:48PM -0600, Jason Gunthorpe wrote:
>> On Tue, Sep 06, 2016 at 08:35:56PM +0000, Daniel Jurgens wrote:
>>
>>> I think to control access to a VLAN for RoCE there would have to
>>> labels for GIDs, since that's how you select which VLAN to use.
>> Since people are talking about using GIDs for containers adding a GID
>> constraint for all technologies makes sense to me..
>>
>> But rocev1 (at least mlx4) does not use vlan ids from the GID, the
>> vlan id is set directly in the id, so it still seems to need direct
>> containment. I also see vlan related stuff in the iwarp providers, so
>> they probably have a similar requirement.
>>
>>> required.  RDMA device handle labeling isn't granular enough for
>>> what I'm trying to accomplish.  We want users with different levels
>>> of permission to be able to use the same device, but restrict who
>>> they can communicate with by isolating them to separate partitions.
>> Sure, but maybe you should use the (device handle:pkey/vlan_id) as your
>> labeling tuple not (Subnet Prefix, pkey)
> Would "device handle" here specify the port?
>
> Ira

It would have to include the port, but idea of using a device name for this is pretty ugly.  <subnet_prefix,pkey> makes it very easy to write a policy that can be deployed widely.  <device,port,pkey/vlan> could require many different policies depending on the configuration of each machine.

I've added Liran Liss, he devised the approach that's implemented.  This would be a pretty big change, with worse usability so I'd like to get his feedback. 


_______________________________________________
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] 79+ messages in thread

* Re: [PATCH v3 0/9] SELinux support for Infiniband RDMA
@ 2016-09-08 14:12                                     ` Daniel Jurgens
  0 siblings, 0 replies; 79+ messages in thread
From: Daniel Jurgens @ 2016-09-08 14:12 UTC (permalink / raw)
  To: ira.weiny, Jason Gunthorpe, Liran Liss
  Cc: Paul Moore, Leon Romanovsky, chrisw, Stephen Smalley, Eric Paris,
	dledford, sean.hefty, hal.rosenstock, selinux,
	linux-security-module, linux-rdma, Yevgeny Petrilin

On 9/7/2016 7:01 PM, ira.weiny wrote:
> On Tue, Sep 06, 2016 at 03:55:48PM -0600, Jason Gunthorpe wrote:
>> On Tue, Sep 06, 2016 at 08:35:56PM +0000, Daniel Jurgens wrote:
>>
>>> I think to control access to a VLAN for RoCE there would have to
>>> labels for GIDs, since that's how you select which VLAN to use.
>> Since people are talking about using GIDs for containers adding a GID
>> constraint for all technologies makes sense to me..
>>
>> But rocev1 (at least mlx4) does not use vlan ids from the GID, the
>> vlan id is set directly in the id, so it still seems to need direct
>> containment. I also see vlan related stuff in the iwarp providers, so
>> they probably have a similar requirement.
>>
>>> required.  RDMA device handle labeling isn't granular enough for
>>> what I'm trying to accomplish.  We want users with different levels
>>> of permission to be able to use the same device, but restrict who
>>> they can communicate with by isolating them to separate partitions.
>> Sure, but maybe you should use the (device handle:pkey/vlan_id) as your
>> labeling tuple not (Subnet Prefix, pkey)
> Would "device handle" here specify the port?
>
> Ira

It would have to include the port, but idea of using a device name for this is pretty ugly.  <subnet_prefix,pkey> makes it very easy to write a policy that can be deployed widely.  <device,port,pkey/vlan> could require many different policies depending on the configuration of each machine.

I've added Liran Liss, he devised the approach that's implemented.  This would be a pretty big change, with worse usability so I'd like to get his feedback. 

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

* Re: [PATCH v3 0/9] SELinux support for Infiniband RDMA
  2016-09-08 14:12                                     ` Daniel Jurgens
  (?)
@ 2016-09-08 16:19                                     ` Jason Gunthorpe
  2016-09-08 16:44                                         ` Daniel Jurgens
       [not found]                                       ` <20160908161948.GA21614-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
  -1 siblings, 2 replies; 79+ messages in thread
From: Jason Gunthorpe @ 2016-09-08 16:19 UTC (permalink / raw)
  To: Daniel Jurgens
  Cc: ira.weiny, Liran Liss, Paul Moore, Leon Romanovsky, chrisw,
	Stephen Smalley, Eric Paris, dledford, sean.hefty,
	hal.rosenstock, selinux, linux-security-module, linux-rdma,
	Yevgeny Petrilin

On Thu, Sep 08, 2016 at 02:12:48PM +0000, Daniel Jurgens wrote:

> It would have to include the port, but idea of using a device name
> for this is pretty ugly.  <subnet_prefix,pkey> makes it very easy to
> write a policy that can be deployed widely.  <device,port,pkey/vlan>
> could require many different policies depending on the configuration
> of each machine.

What does net do? Should we have a way to unformly label the rdma ports?

How do you imagine these policies working anyhow? They cannot be
shipped from a distro. Are these going to be labeled on filesystem
objects? (how doe that work??) Or somehow injected when starting a
container?

If they are not written to disk I don't see the problem, the dynamic
injector will have to figure out what interface is what.

Jason

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

* Re: [PATCH v3 0/9] SELinux support for Infiniband RDMA
  2016-09-08 16:19                                     ` Jason Gunthorpe
@ 2016-09-08 16:44                                         ` Daniel Jurgens
       [not found]                                       ` <20160908161948.GA21614-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
  1 sibling, 0 replies; 79+ messages in thread
From: Daniel Jurgens @ 2016-09-08 16:44 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: Liran Liss, Leon Romanovsky, linux-rdma-u79uwXL29TY76Z2rM5mHXA,
	Stephen Smalley, linux-security-module-u79uwXL29TY76Z2rM5mHXA,
	chrisw-69jw2NvuJkxg9hUCZPvPmw, dledford-H+wXaHxf7aLQT0dZR+AlfA,
	selinux-+05T5uksL2qpZYMLLGbcSA,
	sean.hefty-ral2JQCrhuEAvxtiuMwx3w, ira.weiny,
	hal.rosenstock-Re5JQEeQqe8AvxtiuMwx3w

On 9/8/2016 11:20 AM, Jason Gunthorpe wrote:
> On Thu, Sep 08, 2016 at 02:12:48PM +0000, Daniel Jurgens wrote:
>
>> It would have to include the port, but idea of using a device name
>> for this is pretty ugly.  <subnet_prefix,pkey> makes it very easy to
>> write a policy that can be deployed widely.  <device,port,pkey/vlan>
>> could require many different policies depending on the configuration
>> of each machine.
> What does net do? Should we have a way to unformly label the rdma ports?
>
> How do you imagine these policies working anyhow? They cannot be
> shipped from a distro. Are these going to be labeled on filesystem
> objects? (how doe that work??) Or somehow injected when starting a
> container?
>
> If they are not written to disk I don't see the problem, the dynamic
> injector will have to figure out what interface is what.
>
> Jason
>
Net has variety of means of enforcement, one of which is controlling access to ports <tcp/udp,port number>, which is the most like what I'm doing here.  They also have other enforcement options that can't work for RDMA because it bypasses the kernel.

It will work like any other SELinux policy.  You label the things you want to control with a type and setup rules about which roles/types can interact with them and how.  I'm sure the default policy from distros will be to not restrict access.  Policy is loaded into the kernel, the disk and filesystem has nothing to do with this aside from it being where the policy is stored before being loaded.  What is this dynamic injector you are talking about?

Assume you have machines on one subnet (0xfe80::) one has a device called mlx5_0, the another mlx4_0 and you want to grant access to system administrators.

This hypothetical policy could be deployed on both:

    pkeycon 0xfe80:: 0xFFFF  gen_context(system_u:object_r:default_pkey_t);

    allow sysadm_t default_pkey_t access;

If we use device name you'd need to write separate policy for each node.

    pkeyvlancon mlx4_0 1 0xFFFF gen_context(system_u:object_r:default_pkey_t);

or

    pkeyvlancon mlx5_0 1 0xFFFF gen_context(system_u:object_r:default_pkey_t);




_______________________________________________
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] 79+ messages in thread

* Re: [PATCH v3 0/9] SELinux support for Infiniband RDMA
@ 2016-09-08 16:44                                         ` Daniel Jurgens
  0 siblings, 0 replies; 79+ messages in thread
From: Daniel Jurgens @ 2016-09-08 16:44 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: ira.weiny, Liran Liss, Paul Moore, Leon Romanovsky, chrisw,
	Stephen Smalley, Eric Paris, dledford, sean.hefty,
	hal.rosenstock, selinux, linux-security-module, linux-rdma,
	Yevgeny Petrilin

On 9/8/2016 11:20 AM, Jason Gunthorpe wrote:
> On Thu, Sep 08, 2016 at 02:12:48PM +0000, Daniel Jurgens wrote:
>
>> It would have to include the port, but idea of using a device name
>> for this is pretty ugly.  <subnet_prefix,pkey> makes it very easy to
>> write a policy that can be deployed widely.  <device,port,pkey/vlan>
>> could require many different policies depending on the configuration
>> of each machine.
> What does net do? Should we have a way to unformly label the rdma ports?
>
> How do you imagine these policies working anyhow? They cannot be
> shipped from a distro. Are these going to be labeled on filesystem
> objects? (how doe that work??) Or somehow injected when starting a
> container?
>
> If they are not written to disk I don't see the problem, the dynamic
> injector will have to figure out what interface is what.
>
> Jason
>
Net has variety of means of enforcement, one of which is controlling access to ports <tcp/udp,port number>, which is the most like what I'm doing here.  They also have other enforcement options that can't work for RDMA because it bypasses the kernel.

It will work like any other SELinux policy.  You label the things you want to control with a type and setup rules about which roles/types can interact with them and how.  I'm sure the default policy from distros will be to not restrict access.  Policy is loaded into the kernel, the disk and filesystem has nothing to do with this aside from it being where the policy is stored before being loaded.  What is this dynamic injector you are talking about?

Assume you have machines on one subnet (0xfe80::) one has a device called mlx5_0, the another mlx4_0 and you want to grant access to system administrators.

This hypothetical policy could be deployed on both:

    pkeycon 0xfe80:: 0xFFFF  gen_context(system_u:object_r:default_pkey_t);

    allow sysadm_t default_pkey_t access;

If we use device name you'd need to write separate policy for each node.

    pkeyvlancon mlx4_0 1 0xFFFF gen_context(system_u:object_r:default_pkey_t);

or

    pkeyvlancon mlx5_0 1 0xFFFF gen_context(system_u:object_r:default_pkey_t);

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

* RE: [PATCH v3 0/9] SELinux support for Infiniband RDMA
  2016-09-08 14:12                                     ` Daniel Jurgens
@ 2016-09-08 17:47                                         ` Liran Liss
  -1 siblings, 0 replies; 79+ messages in thread
From: Liran Liss @ 2016-09-08 17:47 UTC (permalink / raw)
  To: Daniel Jurgens, ira.weiny, Jason Gunthorpe
  Cc: Leon Romanovsky, linux-rdma-u79uwXL29TY76Z2rM5mHXA,
	linux-security-module-u79uwXL29TY76Z2rM5mHXA,
	chrisw-69jw2NvuJkxg9hUCZPvPmw, dledford-H+wXaHxf7aLQT0dZR+AlfA,
	selinux-+05T5uksL2qpZYMLLGbcSA,
	sean.hefty-ral2JQCrhuEAvxtiuMwx3w, Stephen Smalley,
	hal.rosenstock-Re5JQEeQqe8AvxtiuMwx3w

> From: Daniel Jurgens

> It would have to include the port, but idea of using a device name for this is
> pretty ugly.  <subnet_prefix,pkey> makes it very easy to write a policy that can
> be deployed widely.  <device,port,pkey/vlan> could require many different
> policies depending on the configuration of each machine.
> 
> I've added Liran Liss, he devised the approach that's implemented.  This would
> be a pretty big change, with worse usability so I'd like to get his feedback.

This patch-set enables partition-based isolation for Infiniband networks in a very intuitive manner, that's it.
IB partitions don't have anything to do with VLANs.
--Liran


_______________________________________________
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] 79+ messages in thread

* RE: [PATCH v3 0/9] SELinux support for Infiniband RDMA
@ 2016-09-08 17:47                                         ` Liran Liss
  0 siblings, 0 replies; 79+ messages in thread
From: Liran Liss @ 2016-09-08 17:47 UTC (permalink / raw)
  To: Daniel Jurgens, ira.weiny, Jason Gunthorpe
  Cc: Paul Moore, Leon Romanovsky, chrisw, Stephen Smalley, Eric Paris,
	dledford, sean.hefty, hal.rosenstock, selinux,
	linux-security-module, linux-rdma, Yevgeny Petrilin

> From: Daniel Jurgens

> It would have to include the port, but idea of using a device name for this is
> pretty ugly.  <subnet_prefix,pkey> makes it very easy to write a policy that can
> be deployed widely.  <device,port,pkey/vlan> could require many different
> policies depending on the configuration of each machine.
> 
> I've added Liran Liss, he devised the approach that's implemented.  This would
> be a pretty big change, with worse usability so I'd like to get his feedback.

This patch-set enables partition-based isolation for Infiniband networks in a very intuitive manner, that's it.
IB partitions don't have anything to do with VLANs.
--Liran

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

* Re: [PATCH v3 0/9] SELinux support for Infiniband RDMA
  2016-09-08 14:12                                     ` Daniel Jurgens
                                                       ` (2 preceding siblings ...)
  (?)
@ 2016-09-08 18:34                                     ` ira.weiny
  -1 siblings, 0 replies; 79+ messages in thread
From: ira.weiny @ 2016-09-08 18:34 UTC (permalink / raw)
  To: Daniel Jurgens
  Cc: Jason Gunthorpe, Liran Liss, Paul Moore, Leon Romanovsky, chrisw,
	Stephen Smalley, Eric Paris, dledford, sean.hefty,
	hal.rosenstock, selinux, linux-security-module, linux-rdma,
	Yevgeny Petrilin

On Thu, Sep 08, 2016 at 02:12:48PM +0000, Daniel Jurgens wrote:
> On 9/7/2016 7:01 PM, ira.weiny wrote:
> > On Tue, Sep 06, 2016 at 03:55:48PM -0600, Jason Gunthorpe wrote:
> >> On Tue, Sep 06, 2016 at 08:35:56PM +0000, Daniel Jurgens wrote:
> >>
> >>> I think to control access to a VLAN for RoCE there would have to
> >>> labels for GIDs, since that's how you select which VLAN to use.
> >> Since people are talking about using GIDs for containers adding a GID
> >> constraint for all technologies makes sense to me..
> >>
> >> But rocev1 (at least mlx4) does not use vlan ids from the GID, the
> >> vlan id is set directly in the id, so it still seems to need direct
> >> containment. I also see vlan related stuff in the iwarp providers, so
> >> they probably have a similar requirement.
> >>
> >>> required.  RDMA device handle labeling isn't granular enough for
> >>> what I'm trying to accomplish.  We want users with different levels
> >>> of permission to be able to use the same device, but restrict who
> >>> they can communicate with by isolating them to separate partitions.
> >> Sure, but maybe you should use the (device handle:pkey/vlan_id) as your
> >> labeling tuple not (Subnet Prefix, pkey)
> > Would "device handle" here specify the port?
> >
> > Ira
> 
> It would have to include the port, but idea of using a device name for this is pretty ugly.  <subnet_prefix,pkey> makes it very easy to write a policy that can be deployed widely.  <device,port,pkey/vlan> could require many different policies depending on the configuration of each machine.
> 

I agree that this seems weird.  Using the Subnet prefix seems much safer in an
IB/OPA environment.  That would be my vote.  Unfortunately I don't have enough
knowledge of the net stat to know how this would work with RoCE or iWarp.

> I've added Liran Liss, he devised the approach that's implemented.  This would be a pretty big change, with worse usability so I'd like to get his feedback. 
> 

Sounds good,
Ira


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

* Re: [PATCH v3 0/9] SELinux support for Infiniband RDMA
  2016-09-08 16:44                                         ` Daniel Jurgens
  (?)
@ 2016-09-08 18:36                                         ` Jason Gunthorpe
  2016-09-08 18:59                                             ` Daniel Jurgens
  -1 siblings, 1 reply; 79+ messages in thread
From: Jason Gunthorpe @ 2016-09-08 18:36 UTC (permalink / raw)
  To: Daniel Jurgens
  Cc: ira.weiny, Liran Liss, Paul Moore, Leon Romanovsky, chrisw,
	Stephen Smalley, Eric Paris, dledford, sean.hefty,
	hal.rosenstock, selinux, linux-security-module, linux-rdma,
	Yevgeny Petrilin

On Thu, Sep 08, 2016 at 04:44:36PM +0000, Daniel Jurgens wrote:

> Net has variety of means of enforcement, one of which is controlling
> access to ports <tcp/udp,port number>, which is the most like what
> I'm doing here.

No, the analog the tcp/udp,port number is <ib, service_id> 

> It will work like any other SELinux policy.  You label the things
> you want to control with a type and setup rules about which
> roles/types can interact with them and how.  I'm sure the default
> policy from distros will be to not restrict access.  Policy is
> loaded into the kernel, the disk and filesystem has nothing to do

Eh? I thought the main utility of selinux was using the labels written
to the filesystem to constrain access, eg I might label
/usr/bin/apache in a way that gets the <tcp,80> policy applied to it.

> with this aside from it being where the policy is stored before
> being loaded.  What is this dynamic injector you are talking about?

The container projects (eg docker) somehow setup selinux on the
fly for each container. I'm not sure how.

> Assume you have machines on one subnet (0xfe80::) one has a device
> called mlx5_0, the another mlx4_0 and you want to grant access to
> system administrators.

So do this in userspace? Why should the kernel do the translation?

Jason

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

* Re: [PATCH v3 0/9] SELinux support for Infiniband RDMA
  2016-09-08 17:47                                         ` Liran Liss
  (?)
@ 2016-09-08 18:37                                         ` Jason Gunthorpe
  2016-09-08 19:01                                             ` Daniel Jurgens
  -1 siblings, 1 reply; 79+ messages in thread
From: Jason Gunthorpe @ 2016-09-08 18:37 UTC (permalink / raw)
  To: Liran Liss
  Cc: Daniel Jurgens, ira.weiny, Paul Moore, Leon Romanovsky, chrisw,
	Stephen Smalley, Eric Paris, dledford, sean.hefty,
	hal.rosenstock, selinux, linux-security-module, linux-rdma,
	Yevgeny Petrilin

On Thu, Sep 08, 2016 at 05:47:46PM +0000, Liran Liss wrote:

> This patch-set enables partition-based isolation for Infiniband networks in a very intuitive manner, that's it.
> IB partitions don't have anything to do with VLANs.

You guys need to do a better job at supporting the whole subsystem
when you propose new uapi features.

Jason

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

* Re: [PATCH v3 0/9] SELinux support for Infiniband RDMA
  2016-09-08 18:36                                         ` Jason Gunthorpe
@ 2016-09-08 18:59                                             ` Daniel Jurgens
  0 siblings, 0 replies; 79+ messages in thread
From: Daniel Jurgens @ 2016-09-08 18:59 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: Liran Liss, Leon Romanovsky, linux-rdma-u79uwXL29TY76Z2rM5mHXA,
	Stephen Smalley, linux-security-module-u79uwXL29TY76Z2rM5mHXA,
	chrisw-69jw2NvuJkxg9hUCZPvPmw, dledford-H+wXaHxf7aLQT0dZR+AlfA,
	selinux-+05T5uksL2qpZYMLLGbcSA,
	sean.hefty-ral2JQCrhuEAvxtiuMwx3w, ira.weiny,
	hal.rosenstock-Re5JQEeQqe8AvxtiuMwx3w

On 9/8/2016 1:36 PM, Jason Gunthorpe wrote:
> On Thu, Sep 08, 2016 at 04:44:36PM +0000, Daniel Jurgens wrote:
>
>> Net has variety of means of enforcement, one of which is controlling
>> access to ports <tcp/udp,port number>, which is the most like what
>> I'm doing here.
> No, the analog the tcp/udp,port number is <ib, service_id> 
I should have been clearer here.  From the SELinux perspective this scheme is very similar to net ports.
>> It will work like any other SELinux policy.  You label the things
>> you want to control with a type and setup rules about which
>> roles/types can interact with them and how.  I'm sure the default
>> policy from distros will be to not restrict access.  Policy is
>> loaded into the kernel, the disk and filesystem has nothing to do
> Eh? I thought the main utility of selinux was using the labels written
> to the filesystem to constrain access, eg I might label
> /usr/bin/apache in a way that gets the <tcp,80> policy applied to it.
Filesystems can be labeled, but so can other things without a filesystem representation.
>> with this aside from it being where the policy is stored before
>> being loaded.  What is this dynamic injector you are talking about?
> The container projects (eg docker) somehow setup selinux on the
> fly for each container. I'm not sure how.
SELinux policy is modular and can be changed or updated while running, I'm not very familiar with docker so I'm not sure what they do regarding SELinux.  I'm also not sure it's relevant to the issues at hand.
>
>> Assume you have machines on one subnet (0xfe80::) one has a device
>> called mlx5_0, the another mlx4_0 and you want to grant access to
>> system administrators.
> So do this in userspace? Why should the kernel do the translation?
I'm still not clear on what translation you are talking about.  To look up a label for something the kernel uses the same attributes the policy writer used to create the label.  In this patch set when modify_qp is called there is a search of all the labels for pkeys for one that matches subnet prefix for the relevant port and the pkey number.


_______________________________________________
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] 79+ messages in thread

* Re: [PATCH v3 0/9] SELinux support for Infiniband RDMA
@ 2016-09-08 18:59                                             ` Daniel Jurgens
  0 siblings, 0 replies; 79+ messages in thread
From: Daniel Jurgens @ 2016-09-08 18:59 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: ira.weiny, Liran Liss, Paul Moore, Leon Romanovsky, chrisw,
	Stephen Smalley, Eric Paris, dledford, sean.hefty,
	hal.rosenstock, selinux, linux-security-module, linux-rdma,
	Yevgeny Petrilin

On 9/8/2016 1:36 PM, Jason Gunthorpe wrote:
> On Thu, Sep 08, 2016 at 04:44:36PM +0000, Daniel Jurgens wrote:
>
>> Net has variety of means of enforcement, one of which is controlling
>> access to ports <tcp/udp,port number>, which is the most like what
>> I'm doing here.
> No, the analog the tcp/udp,port number is <ib, service_id> 
I should have been clearer here.  From the SELinux perspective this scheme is very similar to net ports.
>> It will work like any other SELinux policy.  You label the things
>> you want to control with a type and setup rules about which
>> roles/types can interact with them and how.  I'm sure the default
>> policy from distros will be to not restrict access.  Policy is
>> loaded into the kernel, the disk and filesystem has nothing to do
> Eh? I thought the main utility of selinux was using the labels written
> to the filesystem to constrain access, eg I might label
> /usr/bin/apache in a way that gets the <tcp,80> policy applied to it.
Filesystems can be labeled, but so can other things without a filesystem representation.
>> with this aside from it being where the policy is stored before
>> being loaded.  What is this dynamic injector you are talking about?
> The container projects (eg docker) somehow setup selinux on the
> fly for each container. I'm not sure how.
SELinux policy is modular and can be changed or updated while running, I'm not very familiar with docker so I'm not sure what they do regarding SELinux.  I'm also not sure it's relevant to the issues at hand.
>
>> Assume you have machines on one subnet (0xfe80::) one has a device
>> called mlx5_0, the another mlx4_0 and you want to grant access to
>> system administrators.
> So do this in userspace? Why should the kernel do the translation?
I'm still not clear on what translation you are talking about.  To look up a label for something the kernel uses the same attributes the policy writer used to create the label.  In this patch set when modify_qp is called there is a search of all the labels for pkeys for one that matches subnet prefix for the relevant port and the pkey number.

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

* Re: [PATCH v3 0/9] SELinux support for Infiniband RDMA
  2016-09-08 18:37                                         ` Jason Gunthorpe
@ 2016-09-08 19:01                                             ` Daniel Jurgens
  0 siblings, 0 replies; 79+ messages in thread
From: Daniel Jurgens @ 2016-09-08 19:01 UTC (permalink / raw)
  To: Jason Gunthorpe, Liran Liss
  Cc: Leon Romanovsky, linux-rdma-u79uwXL29TY76Z2rM5mHXA, ira.weiny,
	linux-security-module-u79uwXL29TY76Z2rM5mHXA,
	chrisw-69jw2NvuJkxg9hUCZPvPmw, dledford-H+wXaHxf7aLQT0dZR+AlfA,
	selinux-+05T5uksL2qpZYMLLGbcSA,
	sean.hefty-ral2JQCrhuEAvxtiuMwx3w, Stephen Smalley,
	hal.rosenstock-Re5JQEeQqe8AvxtiuMwx3w

On 9/8/2016 1:38 PM, Jason Gunthorpe wrote:
> On Thu, Sep 08, 2016 at 05:47:46PM +0000, Liran Liss wrote:
>
>> This patch-set enables partition-based isolation for Infiniband networks in a very intuitive manner, that's it.
>> IB partitions don't have anything to do with VLANs.
> You guys need to do a better job at supporting the whole subsystem
> when you propose new uapi features.
>
> Jason
> --
> 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
>
The uapi of this subsystem isn't changed.


_______________________________________________
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] 79+ messages in thread

* Re: [PATCH v3 0/9] SELinux support for Infiniband RDMA
@ 2016-09-08 19:01                                             ` Daniel Jurgens
  0 siblings, 0 replies; 79+ messages in thread
From: Daniel Jurgens @ 2016-09-08 19:01 UTC (permalink / raw)
  To: Jason Gunthorpe, Liran Liss
  Cc: ira.weiny, Paul Moore, Leon Romanovsky, chrisw, Stephen Smalley,
	Eric Paris, dledford, sean.hefty, hal.rosenstock, selinux,
	linux-security-module, linux-rdma, Yevgeny Petrilin

On 9/8/2016 1:38 PM, Jason Gunthorpe wrote:
> On Thu, Sep 08, 2016 at 05:47:46PM +0000, Liran Liss wrote:
>
>> This patch-set enables partition-based isolation for Infiniband networks in a very intuitive manner, that's it.
>> IB partitions don't have anything to do with VLANs.
> You guys need to do a better job at supporting the whole subsystem
> when you propose new uapi features.
>
> Jason
> --
> 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
>
The uapi of this subsystem isn't changed.

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

* Re: [PATCH v3 0/9] SELinux support for Infiniband RDMA
  2016-09-08 16:19                                     ` Jason Gunthorpe
@ 2016-09-08 19:14                                           ` ira.weiny
       [not found]                                       ` <20160908161948.GA21614-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
  1 sibling, 0 replies; 79+ messages in thread
From: ira.weiny @ 2016-09-08 19:14 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: Daniel Jurgens, Liran Liss, Paul Moore, Leon Romanovsky,
	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, Yevgeny Petrilin

On Thu, Sep 08, 2016 at 10:19:48AM -0600, Jason Gunthorpe wrote:
> On Thu, Sep 08, 2016 at 02:12:48PM +0000, Daniel Jurgens wrote:
> 
> > It would have to include the port, but idea of using a device name
> > for this is pretty ugly.  <subnet_prefix,pkey> makes it very easy to
> > write a policy that can be deployed widely.  <device,port,pkey/vlan>
> > could require many different policies depending on the configuration
> > of each machine.
> 
> What does net do? Should we have a way to unformly label the rdma ports?

Uniformly label them on the local node or across a cluster?

I think Daniel has a point here.  Given a node with multiple device/ports using
the local device names is IMO wrong.

> 
> How do you imagine these policies working anyhow? They cannot be
> shipped from a distro. Are these going to be labeled on filesystem
> objects? (how doe that work??) Or somehow injected when starting a
> container?
> 
> If they are not written to disk I don't see the problem, the dynamic
> injector will have to figure out what interface is what.

Who is the "dynamic injector"?

Ira

> 
> Jason
--
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] 79+ messages in thread

* Re: [PATCH v3 0/9] SELinux support for Infiniband RDMA
@ 2016-09-08 19:14                                           ` ira.weiny
  0 siblings, 0 replies; 79+ messages in thread
From: ira.weiny @ 2016-09-08 19:14 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: Daniel Jurgens, Liran Liss, Paul Moore, Leon Romanovsky, chrisw,
	Stephen Smalley, Eric Paris, dledford, sean.hefty,
	hal.rosenstock, selinux, linux-security-module, linux-rdma,
	Yevgeny Petrilin

On Thu, Sep 08, 2016 at 10:19:48AM -0600, Jason Gunthorpe wrote:
> On Thu, Sep 08, 2016 at 02:12:48PM +0000, Daniel Jurgens wrote:
> 
> > It would have to include the port, but idea of using a device name
> > for this is pretty ugly.  <subnet_prefix,pkey> makes it very easy to
> > write a policy that can be deployed widely.  <device,port,pkey/vlan>
> > could require many different policies depending on the configuration
> > of each machine.
> 
> What does net do? Should we have a way to unformly label the rdma ports?

Uniformly label them on the local node or across a cluster?

I think Daniel has a point here.  Given a node with multiple device/ports using
the local device names is IMO wrong.

> 
> How do you imagine these policies working anyhow? They cannot be
> shipped from a distro. Are these going to be labeled on filesystem
> objects? (how doe that work??) Or somehow injected when starting a
> container?
> 
> If they are not written to disk I don't see the problem, the dynamic
> injector will have to figure out what interface is what.

Who is the "dynamic injector"?

Ira

> 
> Jason

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

* Re: [PATCH v3 0/9] SELinux support for Infiniband RDMA
  2016-09-08 18:59                                             ` Daniel Jurgens
  (?)
@ 2016-09-08 19:32                                             ` Jason Gunthorpe
  2016-09-21 16:16                                               ` ira.weiny
  -1 siblings, 1 reply; 79+ messages in thread
From: Jason Gunthorpe @ 2016-09-08 19:32 UTC (permalink / raw)
  To: Daniel Jurgens
  Cc: ira.weiny, Liran Liss, Paul Moore, Leon Romanovsky, chrisw,
	Stephen Smalley, Eric Paris, dledford, sean.hefty,
	hal.rosenstock, selinux, linux-security-module, linux-rdma,
	Yevgeny Petrilin

On Thu, Sep 08, 2016 at 06:59:13PM +0000, Daniel Jurgens wrote:

> >> Net has variety of means of enforcement, one of which is controlling
> >> access to ports <tcp/udp,port number>, which is the most like what
> >> I'm doing here.
> > No, the analog the tcp/udp,port number is <ib, service_id> 

> I should have been clearer here.  From the SELinux perspective this
> scheme is very similar to net ports.

It really isn't. net ports and service_ids are global things that do
not need machine-specific customizations while subnet prefix or device
name/port are both machine-local information.

> >> with this aside from it being where the policy is stored before
> >> being loaded.  What is this dynamic injector you are talking about?
> > The container projects (eg docker) somehow setup selinux on the
> > fly for each container. I'm not sure how.

> SELinux policy is modular and can be changed or updated while
> running, I'm not very familiar with docker so I'm not sure what they
> do regarding SELinux.  I'm also not sure it's relevant to the issues
> at hand.

docker and the like would seem to be the #1 user of this kind of
feature, it goes hand in hand with the ipoib namespace work that does
a similar (but less complete thing). This is a great way to create a
container and constrain it to a single pkey/vlan/ipoib device, which
would be the basic capability needed to sensibly rdma and containers
together.

This is why thinking about how to fully support the pkey/vlan concept
across all the rdma drivers seems so critical.

I'm surprised this isn't your use case. Again, I wish you'd think more
broadly before designing new uapis. selinux enabling the rdma
subsystem is a whole new uapi aspect for rdma that we have to live
with forever.

> >> called mlx5_0, the another mlx4_0 and you want to grant access to
> >> system administrators.
> > So do this in userspace? Why should the kernel do the translation?

> I'm still not clear on what translation you are talking about.

Converting the subnet prefix to a list of physical ports.

Jason

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

* Re: [PATCH v3 0/9] SELinux support for Infiniband RDMA
  2016-09-08 19:14                                           ` ira.weiny
  (?)
@ 2016-09-08 19:35                                           ` Jason Gunthorpe
  2016-09-15  1:52                                             ` ira.weiny
  -1 siblings, 1 reply; 79+ messages in thread
From: Jason Gunthorpe @ 2016-09-08 19:35 UTC (permalink / raw)
  To: ira.weiny
  Cc: Daniel Jurgens, Liran Liss, Paul Moore, Leon Romanovsky, chrisw,
	Stephen Smalley, Eric Paris, dledford, sean.hefty,
	hal.rosenstock, selinux, linux-security-module, linux-rdma,
	Yevgeny Petrilin

On Thu, Sep 08, 2016 at 03:14:57PM -0400, ira.weiny wrote:
> On Thu, Sep 08, 2016 at 10:19:48AM -0600, Jason Gunthorpe wrote:
> > On Thu, Sep 08, 2016 at 02:12:48PM +0000, Daniel Jurgens wrote:
> > 
> > > It would have to include the port, but idea of using a device name
> > > for this is pretty ugly.  <subnet_prefix,pkey> makes it very easy to
> > > write a policy that can be deployed widely.  <device,port,pkey/vlan>
> > > could require many different policies depending on the configuration
> > > of each machine.
> > 
> > What does net do? Should we have a way to unformly label the rdma ports?
> 
> Uniformly label them on the local node or across a cluster?

However we want. If the argument comes down to 'we stupidly choose to
call our devices mlx5_0', then lets allow the admin rename that to
'rdma0' and a cluster wide config file will apply uniformly. This
approach applies to all configuration related to rdma, not just
SELinux.

> > If they are not written to disk I don't see the problem, the dynamic
> > injector will have to figure out what interface is what.
> 
> Who is the "dynamic injector"?

Docker, for instance.

Jason

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

* Re: [PATCH v3 0/9] SELinux support for Infiniband RDMA
  2016-09-08 19:35                                           ` Jason Gunthorpe
@ 2016-09-15  1:52                                             ` ira.weiny
  0 siblings, 0 replies; 79+ messages in thread
From: ira.weiny @ 2016-09-15  1:52 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: Daniel Jurgens, Liran Liss, Paul Moore, Leon Romanovsky, chrisw,
	Stephen Smalley, Eric Paris, dledford, sean.hefty,
	hal.rosenstock, selinux, linux-security-module, linux-rdma,
	Yevgeny Petrilin

On Thu, Sep 08, 2016 at 01:35:12PM -0600, Jason Gunthorpe wrote:
> On Thu, Sep 08, 2016 at 03:14:57PM -0400, ira.weiny wrote:
> > On Thu, Sep 08, 2016 at 10:19:48AM -0600, Jason Gunthorpe wrote:
> > > On Thu, Sep 08, 2016 at 02:12:48PM +0000, Daniel Jurgens wrote:
> > > 
> > > > It would have to include the port, but idea of using a device name
> > > > for this is pretty ugly.  <subnet_prefix,pkey> makes it very easy to
> > > > write a policy that can be deployed widely.  <device,port,pkey/vlan>
> > > > could require many different policies depending on the configuration
> > > > of each machine.
> > > 
> > > What does net do? Should we have a way to unformly label the rdma ports?
> > 
> > Uniformly label them on the local node or across a cluster?
> 
> However we want. If the argument comes down to 'we stupidly choose to
> call our devices mlx5_0', then lets allow the admin rename that to
> 'rdma0' and a cluster wide config file will apply uniformly. This
> approach applies to all configuration related to rdma, not just
> SELinux.

I'm not sure I like the idea of trying to use "rdmaX".  It seems like this has
been a confusion point for things like drives and NICs in the past.  (Where the
order of device discovery is an issue.)

But I guess with more network types coming online we may have to have something
generic.

That said in the netdev world not all things are called eth0.  Some are called
wlanX, etc...

Does anyone know why do they have names based on network type?

So I could see where having a global "name" for a subnet would be nice...  But
isn't something like that called a domain name?  Does SELinux work in
conjunction with domain names in the netdev stack?

This may be a bit off topic but has anyone thought about adding GID specific
DNS record types?

I have experimented with just putting a GID in an IPv6 record and things I
tried work quite well.  Should we have a method to map a domain name to a
subnet prefix?

If the domain name mapped to a subnet prefix it would imply a set of port GIDs
on IB/OPA devices and if it mapped to an IPv4/v6 subnet it would be
iwarp/roce/usnic.

For this series and others the kernel could continue to use the correct
"subnet" information and user space could translate as appropriate?

Would this series work looking at a "subnet prefix" of an IPv6 address in RoCE?

Ira


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

* Re: [PATCH v3 0/9] SELinux support for Infiniband RDMA
  2016-09-06 20:02                           ` Jason Gunthorpe
  2016-09-06 20:35                               ` Daniel Jurgens
@ 2016-09-20 23:43                             ` Paul Moore
  2016-09-23 13:26                                 ` Daniel Jurgens
  2016-09-26 18:17                               ` Jason Gunthorpe
  1 sibling, 2 replies; 79+ messages in thread
From: Paul Moore @ 2016-09-20 23:43 UTC (permalink / raw)
  To: Jason Gunthorpe, Daniel Jurgens
  Cc: Leon Romanovsky, chrisw, Stephen Smalley, Eric Paris, dledford,
	sean.hefty, hal.rosenstock, selinux, linux-security-module,
	linux-rdma, Yevgeny Petrilin

On Tue, Sep 6, 2016 at 4:02 PM, Jason Gunthorpe
<jgunthorpe@obsidianresearch.com> wrote:
> On Thu, Sep 01, 2016 at 02:06:46PM -0400, Paul Moore wrote:
>
>> Jason and/or Daniel, I think it would be helpful if you could explain
>> both the InifiniBand and IP based approaches for those of us who know
>> SELinux, but not necessarily the RDMA and InfiniBand portions of this
>> discussion.  Be verbose and explain it as if we were idiots (I get
>> called that enough, it must be true).
>
> Well, I'm not really familiar with SELinux, I know a little bit about
> how labels are applied in the netstack, but not that much...
>
> The RDMA subsystem supports 4 different networking standards, and they
> each have their own objects..

All right, I'm done traveling for a bit and it seems like this
discussion has settled into a stalemate so let's try to pick things
back up and sort this out.

Starting we a better RDMA education for me.

So far the discussion has been around providing access controls at the
transport layer, are there any RDMA entities that are transport
agnostic that might be better suited for what we are trying to do?  Or
is it simply that the RDMA layer is tied so tightly to the underlying
transport that we can't separate the two and have to consider them as
one?

-- 
paul moore
www.paul-moore.com

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

* Re: [PATCH v3 0/9] SELinux support for Infiniband RDMA
  2016-09-08 19:32                                             ` Jason Gunthorpe
@ 2016-09-21 16:16                                               ` ira.weiny
       [not found]                                                 ` <20160921161626.GA27837-W4f6Xiosr+yv7QzWx2u06xL4W9x8LtSr@public.gmane.org>
  0 siblings, 1 reply; 79+ messages in thread
From: ira.weiny @ 2016-09-21 16:16 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: Daniel Jurgens, Liran Liss, Paul Moore, Leon Romanovsky, chrisw,
	Stephen Smalley, Eric Paris, dledford, sean.hefty,
	hal.rosenstock, selinux, linux-security-module, linux-rdma,
	Yevgeny Petrilin

On Thu, Sep 08, 2016 at 01:32:35PM -0600, Jason Gunthorpe wrote:
> On Thu, Sep 08, 2016 at 06:59:13PM +0000, Daniel Jurgens wrote:
> 
> > >> Net has variety of means of enforcement, one of which is controlling
> > >> access to ports <tcp/udp,port number>, which is the most like what
> > >> I'm doing here.
> > > No, the analog the tcp/udp,port number is <ib, service_id> 
> 
> > I should have been clearer here.  From the SELinux perspective this
> > scheme is very similar to net ports.
> 
> It really isn't. net ports and service_ids are global things that do
> not need machine-specific customizations while subnet prefix or device
> name/port are both machine-local information.

I agree that service_ids are more analogous to net ports.

However, subnet prefixes are _not_ machine-local.  They are controlled by the
Admin of the fabric by a central entity (the SM).  This is more helpful than in
ethernet where if you configure the wrong port with the wrong subnet things
just don't work.  In IB I can physically plug my network into any IB port I
want and the system is _told_ which "subnet" that port belongs to.  (OPA is the
same way.)

So for IB/OPA a subnet prefix is a really good way to ID which network (subnet)
you want to use.  Unfortunately, I'm not sure how to translate that to
iwarp/roce seamlessly except to have some concept of "domain" as I mentioned in
my other email.

Ira


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

* RE: [PATCH v3 0/9] SELinux support for Infiniband RDMA
  2016-09-21 16:16                                               ` ira.weiny
@ 2016-09-22 15:04                                                     ` Liran Liss
  0 siblings, 0 replies; 79+ messages in thread
From: Liran Liss @ 2016-09-22 15:04 UTC (permalink / raw)
  To: ira.weiny, Jason Gunthorpe
  Cc: chrisw-69jw2NvuJkxg9hUCZPvPmw, Leon Romanovsky,
	linux-rdma-u79uwXL29TY76Z2rM5mHXA,
	linux-security-module-u79uwXL29TY76Z2rM5mHXA,
	dledford-H+wXaHxf7aLQT0dZR+AlfA, selinux-+05T5uksL2qpZYMLLGbcSA,
	sean.hefty-ral2JQCrhuEAvxtiuMwx3w, Stephen Smalley,
	hal.rosenstock-Re5JQEeQqe8AvxtiuMwx3w

> From: ira.weiny [mailto:ira.weiny-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org]

> >
> > It really isn't. net ports and service_ids are global things that do
> > not need machine-specific customizations while subnet prefix or device
> > name/port are both machine-local information.
> 
> I agree that service_ids are more analogous to net ports.
> 
> However, subnet prefixes are _not_ machine-local.  They are controlled by the
> Admin of the fabric by a central entity (the SM).  This is more helpful than in
> ethernet where if you configure the wrong port with the wrong subnet things
> just don't work.  In IB I can physically plug my network into any IB port I want
> and the system is _told_ which "subnet" that port belongs to.  (OPA is the same
> way.)
> 
> So for IB/OPA a subnet prefix is a really good way to ID which network (subnet)
> you want to use.  Unfortunately, I'm not sure how to translate that to
> iwarp/roce seamlessly except to have some concept of "domain" as I mentioned
> in my other email.
> 

Exactly. The identity of both the "domain" (the subnet ID) and the "label" stem from a central entity - the SM.
It would be very natural to have IB/OPA subnet policies that are configured in all hosts and the SM. These policies are automatically enforced for any port connected to the subnet.

Not everything needs to be related to IP interfaces.
I can envision multiple jobs in the cluster, running on distinct partitions using distinct security tags, without configuring IP interfaces on these partitions.
Partition security is a useful and an effective measure that is applicable to IB/OPA networks. That's it.

Ethernet VLANs are a totally different thing --- SELinux *already* handles them for Ethernet interfaces.
There is nothing special from an admin's point of view regarding how SELinux applies to RDMA over Ethernet (RoCE/iWarp). RDMA is just another transport, and any Ethernet L2 policies should apply to it seamlessly.

--Liran


_______________________________________________
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] 79+ messages in thread

* RE: [PATCH v3 0/9] SELinux support for Infiniband RDMA
@ 2016-09-22 15:04                                                     ` Liran Liss
  0 siblings, 0 replies; 79+ messages in thread
From: Liran Liss @ 2016-09-22 15:04 UTC (permalink / raw)
  To: ira.weiny, Jason Gunthorpe
  Cc: Daniel Jurgens, Paul Moore, Leon Romanovsky, chrisw,
	Stephen Smalley, Eric Paris, dledford, sean.hefty,
	hal.rosenstock, selinux, linux-security-module, linux-rdma,
	Yevgeny Petrilin

> From: ira.weiny [mailto:ira.weiny@intel.com]

> >
> > It really isn't. net ports and service_ids are global things that do
> > not need machine-specific customizations while subnet prefix or device
> > name/port are both machine-local information.
> 
> I agree that service_ids are more analogous to net ports.
> 
> However, subnet prefixes are _not_ machine-local.  They are controlled by the
> Admin of the fabric by a central entity (the SM).  This is more helpful than in
> ethernet where if you configure the wrong port with the wrong subnet things
> just don't work.  In IB I can physically plug my network into any IB port I want
> and the system is _told_ which "subnet" that port belongs to.  (OPA is the same
> way.)
> 
> So for IB/OPA a subnet prefix is a really good way to ID which network (subnet)
> you want to use.  Unfortunately, I'm not sure how to translate that to
> iwarp/roce seamlessly except to have some concept of "domain" as I mentioned
> in my other email.
> 

Exactly. The identity of both the "domain" (the subnet ID) and the "label" stem from a central entity - the SM.
It would be very natural to have IB/OPA subnet policies that are configured in all hosts and the SM. These policies are automatically enforced for any port connected to the subnet.

Not everything needs to be related to IP interfaces.
I can envision multiple jobs in the cluster, running on distinct partitions using distinct security tags, without configuring IP interfaces on these partitions.
Partition security is a useful and an effective measure that is applicable to IB/OPA networks. That's it.

Ethernet VLANs are a totally different thing --- SELinux *already* handles them for Ethernet interfaces.
There is nothing special from an admin's point of view regarding how SELinux applies to RDMA over Ethernet (RoCE/iWarp). RDMA is just another transport, and any Ethernet L2 policies should apply to it seamlessly.

--Liran

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

* Re: [PATCH v3 0/9] SELinux support for Infiniband RDMA
  2016-09-20 23:43                             ` Paul Moore
@ 2016-09-23 13:26                                 ` Daniel Jurgens
  2016-09-26 18:17                               ` Jason Gunthorpe
  1 sibling, 0 replies; 79+ messages in thread
From: Daniel Jurgens @ 2016-09-23 13:26 UTC (permalink / raw)
  To: Paul Moore, Jason Gunthorpe
  Cc: Leon Romanovsky, linux-rdma-u79uwXL29TY76Z2rM5mHXA,
	linux-security-module-u79uwXL29TY76Z2rM5mHXA,
	chrisw-69jw2NvuJkxg9hUCZPvPmw, dledford-H+wXaHxf7aLQT0dZR+AlfA,
	selinux-+05T5uksL2qpZYMLLGbcSA,
	sean.hefty-ral2JQCrhuEAvxtiuMwx3w, Stephen Smalley,
	hal.rosenstock-Re5JQEeQqe8AvxtiuMwx3w

On 9/20/2016 6:43 PM, Paul Moore wrote:
> On Tue, Sep 6, 2016 at 4:02 PM, Jason Gunthorpe
> <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org> wrote:
>> On Thu, Sep 01, 2016 at 02:06:46PM -0400, Paul Moore wrote:
>>
>>> Jason and/or Daniel, I think it would be helpful if you could explain
>>> both the InifiniBand and IP based approaches for those of us who know
>>> SELinux, but not necessarily the RDMA and InfiniBand portions of this
>>> discussion.  Be verbose and explain it as if we were idiots (I get
>>> called that enough, it must be true).
>> Well, I'm not really familiar with SELinux, I know a little bit about
>> how labels are applied in the netstack, but not that much...
>>
>> The RDMA subsystem supports 4 different networking standards, and they
>> each have their own objects..
> All right, I'm done traveling for a bit and it seems like this
> discussion has settled into a stalemate so let's try to pick things
> back up and sort this out.
>
> Starting we a better RDMA education for me.
>
> So far the discussion has been around providing access controls at the
> transport layer, are there any RDMA entities that are transport
> agnostic that might be better suited for what we are trying to do?  Or
> is it simply that the RDMA layer is tied so tightly to the underlying
> transport that we can't separate the two and have to consider them as
> one?
Welcome back Paul.

I don't think there is a transport agnostic way to provide the kind of control I use in this patch set, which is very Infiniband specific.  RoCE uses VLANs and they are conceptually similar to subnet partitions, but the means of using them is completely different.  To use a different VLAN the user must select a GID for that VLAN.  One could provide a means to control RoCE access to VLANs by labeling GIDs and controlling them in a similar way to how I do PKeys.  That approach doesn't help with Infiniband partitions though, because the same GID can be used on multiple partitions.  It's also not very desirable from a policy writers perspective because it makes it so a bespoke policy is required per node.

Regardless of any other approaches one might like to use to provide access control for RDMA non-Infiniband transport I think controlling access to Infiniband PKeys is still a desirable feature and I don't see any other way to have that.


_______________________________________________
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] 79+ messages in thread

* Re: [PATCH v3 0/9] SELinux support for Infiniband RDMA
@ 2016-09-23 13:26                                 ` Daniel Jurgens
  0 siblings, 0 replies; 79+ messages in thread
From: Daniel Jurgens @ 2016-09-23 13:26 UTC (permalink / raw)
  To: Paul Moore, Jason Gunthorpe
  Cc: Leon Romanovsky, chrisw, Stephen Smalley, Eric Paris, dledford,
	sean.hefty, hal.rosenstock, selinux, linux-security-module,
	linux-rdma, Yevgeny Petrilin

On 9/20/2016 6:43 PM, Paul Moore wrote:
> On Tue, Sep 6, 2016 at 4:02 PM, Jason Gunthorpe
> <jgunthorpe@obsidianresearch.com> wrote:
>> On Thu, Sep 01, 2016 at 02:06:46PM -0400, Paul Moore wrote:
>>
>>> Jason and/or Daniel, I think it would be helpful if you could explain
>>> both the InifiniBand and IP based approaches for those of us who know
>>> SELinux, but not necessarily the RDMA and InfiniBand portions of this
>>> discussion.  Be verbose and explain it as if we were idiots (I get
>>> called that enough, it must be true).
>> Well, I'm not really familiar with SELinux, I know a little bit about
>> how labels are applied in the netstack, but not that much...
>>
>> The RDMA subsystem supports 4 different networking standards, and they
>> each have their own objects..
> All right, I'm done traveling for a bit and it seems like this
> discussion has settled into a stalemate so let's try to pick things
> back up and sort this out.
>
> Starting we a better RDMA education for me.
>
> So far the discussion has been around providing access controls at the
> transport layer, are there any RDMA entities that are transport
> agnostic that might be better suited for what we are trying to do?  Or
> is it simply that the RDMA layer is tied so tightly to the underlying
> transport that we can't separate the two and have to consider them as
> one?
Welcome back Paul.

I don't think there is a transport agnostic way to provide the kind of control I use in this patch set, which is very Infiniband specific.  RoCE uses VLANs and they are conceptually similar to subnet partitions, but the means of using them is completely different.  To use a different VLAN the user must select a GID for that VLAN.  One could provide a means to control RoCE access to VLANs by labeling GIDs and controlling them in a similar way to how I do PKeys.  That approach doesn't help with Infiniband partitions though, because the same GID can be used on multiple partitions.  It's also not very desirable from a policy writers perspective because it makes it so a bespoke policy is required per node.

Regardless of any other approaches one might like to use to provide access control for RDMA non-Infiniband transport I think controlling access to Infiniband PKeys is still a desirable feature and I don't see any other way to have that.

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

* Re: [PATCH v3 0/9] SELinux support for Infiniband RDMA
  2016-09-20 23:43                             ` Paul Moore
  2016-09-23 13:26                                 ` Daniel Jurgens
@ 2016-09-26 18:17                               ` Jason Gunthorpe
  1 sibling, 0 replies; 79+ messages in thread
From: Jason Gunthorpe @ 2016-09-26 18:17 UTC (permalink / raw)
  To: Paul Moore
  Cc: Daniel Jurgens, Leon Romanovsky, chrisw, Stephen Smalley,
	Eric Paris, dledford, sean.hefty, hal.rosenstock, selinux,
	linux-security-module, linux-rdma, Yevgeny Petrilin

On Tue, Sep 20, 2016 at 07:43:34PM -0400, Paul Moore wrote:

> So far the discussion has been around providing access controls at the
> transport layer, are there any RDMA entities that are transport
> agnostic that might be better suited for what we are trying to do?  Or
> is it simply that the RDMA layer is tied so tightly to the underlying
> transport that we can't separate the two and have to consider them as
> one?

The generic RDMA layer is called 'rdmacm' and it is the layer
Mellanox's already applied patches for RDMA namespace enablement
worked at.

Jason

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

* Re: [PATCH v3 0/9] SELinux support for Infiniband RDMA
  2016-09-23 13:26                                 ` Daniel Jurgens
@ 2016-09-29 22:16                                     ` Paul Moore
  -1 siblings, 0 replies; 79+ messages in thread
From: Paul Moore @ 2016-09-29 22:16 UTC (permalink / raw)
  To: Daniel Jurgens
  Cc: Jason Gunthorpe, Leon Romanovsky, 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, Yevgeny Petrilin

On Fri, Sep 23, 2016 at 9:26 AM, Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org> wrote:
> On 9/20/2016 6:43 PM, Paul Moore wrote:
>> On Tue, Sep 6, 2016 at 4:02 PM, Jason Gunthorpe
>> <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org> wrote:
>>> On Thu, Sep 01, 2016 at 02:06:46PM -0400, Paul Moore wrote:
>>>
>>>> Jason and/or Daniel, I think it would be helpful if you could explain
>>>> both the InifiniBand and IP based approaches for those of us who know
>>>> SELinux, but not necessarily the RDMA and InfiniBand portions of this
>>>> discussion.  Be verbose and explain it as if we were idiots (I get
>>>> called that enough, it must be true).
>>> Well, I'm not really familiar with SELinux, I know a little bit about
>>> how labels are applied in the netstack, but not that much...
>>>
>>> The RDMA subsystem supports 4 different networking standards, and they
>>> each have their own objects..
>> All right, I'm done traveling for a bit and it seems like this
>> discussion has settled into a stalemate so let's try to pick things
>> back up and sort this out.
>>
>> Starting we a better RDMA education for me.
>>
>> So far the discussion has been around providing access controls at the
>> transport layer, are there any RDMA entities that are transport
>> agnostic that might be better suited for what we are trying to do?  Or
>> is it simply that the RDMA layer is tied so tightly to the underlying
>> transport that we can't separate the two and have to consider them as
>> one?
>
> Welcome back Paul.
>
> I don't think there is a transport agnostic way to provide the kind of control I use in this patch set, which is very Infiniband specific.  RoCE uses VLANs and they are conceptually similar to subnet partitions, but the means of using them is completely different.  To use a different VLAN the user must select a GID for that VLAN.  One could provide a means to control RoCE access to VLANs by labeling GIDs and controlling them in a similar way to how I do PKeys.  That approach doesn't help with Infiniband partitions though, because the same GID can be used on multiple partitions.  It's also not very desirable from a policy writers perspective because it makes it so a bespoke policy is required per node.
>
> Regardless of any other approaches one might like to use to provide access control for RDMA non-Infiniband transport I think controlling access to Infiniband PKeys is still a desirable feature and I don't see any other way to have that.

Let me try to summarize and work through some of this stuff, please
correct me if any of this is wrong.

The queue pair (QP) concept lives in the RDMA layer and isn't tied to
any particular transport.  They appear to be somewhat analogous to
network sockets, although I'm guessing they can't be shared/passed
between process like a network socket, yes?

The IB partition is similar to a ethernet VLAN in that it providedes
enforced separation across the network; IB uses partition keys, VLANs
use tags/IDs.  IB partition keys are a 16 bit number, GIDs appear to
be a 16 byte number created from some combination of IP address, MAC
address, and VLAN ID.

In the case of RDMA over IB, we want to control QP access to
partitions/pkeys; in the case of RDMA over ethernet we want to control
QP access to VLANs/GIDs.

Is the above correct?

-- 
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] 79+ messages in thread

* Re: [PATCH v3 0/9] SELinux support for Infiniband RDMA
@ 2016-09-29 22:16                                     ` Paul Moore
  0 siblings, 0 replies; 79+ messages in thread
From: Paul Moore @ 2016-09-29 22:16 UTC (permalink / raw)
  To: Daniel Jurgens
  Cc: Jason Gunthorpe, Leon Romanovsky, chrisw, Stephen Smalley,
	Eric Paris, dledford, sean.hefty, hal.rosenstock, selinux,
	linux-security-module, linux-rdma, Yevgeny Petrilin

On Fri, Sep 23, 2016 at 9:26 AM, Daniel Jurgens <danielj@mellanox.com> wrote:
> On 9/20/2016 6:43 PM, Paul Moore wrote:
>> On Tue, Sep 6, 2016 at 4:02 PM, Jason Gunthorpe
>> <jgunthorpe@obsidianresearch.com> wrote:
>>> On Thu, Sep 01, 2016 at 02:06:46PM -0400, Paul Moore wrote:
>>>
>>>> Jason and/or Daniel, I think it would be helpful if you could explain
>>>> both the InifiniBand and IP based approaches for those of us who know
>>>> SELinux, but not necessarily the RDMA and InfiniBand portions of this
>>>> discussion.  Be verbose and explain it as if we were idiots (I get
>>>> called that enough, it must be true).
>>> Well, I'm not really familiar with SELinux, I know a little bit about
>>> how labels are applied in the netstack, but not that much...
>>>
>>> The RDMA subsystem supports 4 different networking standards, and they
>>> each have their own objects..
>> All right, I'm done traveling for a bit and it seems like this
>> discussion has settled into a stalemate so let's try to pick things
>> back up and sort this out.
>>
>> Starting we a better RDMA education for me.
>>
>> So far the discussion has been around providing access controls at the
>> transport layer, are there any RDMA entities that are transport
>> agnostic that might be better suited for what we are trying to do?  Or
>> is it simply that the RDMA layer is tied so tightly to the underlying
>> transport that we can't separate the two and have to consider them as
>> one?
>
> Welcome back Paul.
>
> I don't think there is a transport agnostic way to provide the kind of control I use in this patch set, which is very Infiniband specific.  RoCE uses VLANs and they are conceptually similar to subnet partitions, but the means of using them is completely different.  To use a different VLAN the user must select a GID for that VLAN.  One could provide a means to control RoCE access to VLANs by labeling GIDs and controlling them in a similar way to how I do PKeys.  That approach doesn't help with Infiniband partitions though, because the same GID can be used on multiple partitions.  It's also not very desirable from a policy writers perspective because it makes it so a bespoke policy is required per node.
>
> Regardless of any other approaches one might like to use to provide access control for RDMA non-Infiniband transport I think controlling access to Infiniband PKeys is still a desirable feature and I don't see any other way to have that.

Let me try to summarize and work through some of this stuff, please
correct me if any of this is wrong.

The queue pair (QP) concept lives in the RDMA layer and isn't tied to
any particular transport.  They appear to be somewhat analogous to
network sockets, although I'm guessing they can't be shared/passed
between process like a network socket, yes?

The IB partition is similar to a ethernet VLAN in that it providedes
enforced separation across the network; IB uses partition keys, VLANs
use tags/IDs.  IB partition keys are a 16 bit number, GIDs appear to
be a 16 byte number created from some combination of IP address, MAC
address, and VLAN ID.

In the case of RDMA over IB, we want to control QP access to
partitions/pkeys; in the case of RDMA over ethernet we want to control
QP access to VLANs/GIDs.

Is the above correct?

-- 
paul moore
www.paul-moore.com

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

* Re: [PATCH v3 0/9] SELinux support for Infiniband RDMA
  2016-09-29 22:16                                     ` Paul Moore
@ 2016-09-29 22:41                                         ` Jason Gunthorpe
  -1 siblings, 0 replies; 79+ messages in thread
From: Jason Gunthorpe @ 2016-09-29 22:41 UTC (permalink / raw)
  To: Paul Moore
  Cc: Daniel Jurgens, Leon Romanovsky, 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, Yevgeny Petrilin

On Thu, Sep 29, 2016 at 06:16:03PM -0400, Paul Moore wrote:
> The queue pair (QP) concept lives in the RDMA layer and isn't tied to
> any particular transport.  They appear to be somewhat analogous to
> network sockets, although I'm guessing they can't be shared/passed
> between process like a network socket, yes?

Yes

> The IB partition is similar to a ethernet VLAN in that it providedes
> enforced separation across the network; IB uses partition keys, VLANs
> use tags/IDs.  IB partition keys are a 16 bit number,

> GIDs appear to be a 16 byte number created from some combination of
> IP address, MAC address, and VLAN ID.

There are several gid formats

IB/OPA: 128 bit IPv6 address
RoCEv1: Sort of a link local IPv6 (?), vlan is specified directly
        by apps
RoCEv2: Some sort of label that also implies a vlan tag

We also have iwarp vs rocee where AFAIK iwarp should get the vlan tag
from the IP socket that is allocated against the eth interface.

> In the case of RDMA over IB, we want to control QP access to
> partitions/pkeys; in the case of RDMA over ethernet we want to control
> QP access to VLANs/GIDs.

Broadly, yes, and I don't know what restriction iwarp would
need. Probably restrict access based on the eth device, but that will
probably need additional selinux checking in the rdma core.

There are also UD QPs which are like UDP sockets, so every address
handle creation will need a security check too.

Jason
--
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] 79+ messages in thread

* Re: [PATCH v3 0/9] SELinux support for Infiniband RDMA
@ 2016-09-29 22:41                                         ` Jason Gunthorpe
  0 siblings, 0 replies; 79+ messages in thread
From: Jason Gunthorpe @ 2016-09-29 22:41 UTC (permalink / raw)
  To: Paul Moore
  Cc: Daniel Jurgens, Leon Romanovsky, chrisw, Stephen Smalley,
	Eric Paris, dledford, sean.hefty, hal.rosenstock, selinux,
	linux-security-module, linux-rdma, Yevgeny Petrilin

On Thu, Sep 29, 2016 at 06:16:03PM -0400, Paul Moore wrote:
> The queue pair (QP) concept lives in the RDMA layer and isn't tied to
> any particular transport.  They appear to be somewhat analogous to
> network sockets, although I'm guessing they can't be shared/passed
> between process like a network socket, yes?

Yes

> The IB partition is similar to a ethernet VLAN in that it providedes
> enforced separation across the network; IB uses partition keys, VLANs
> use tags/IDs.  IB partition keys are a 16 bit number,

> GIDs appear to be a 16 byte number created from some combination of
> IP address, MAC address, and VLAN ID.

There are several gid formats

IB/OPA: 128 bit IPv6 address
RoCEv1: Sort of a link local IPv6 (?), vlan is specified directly
        by apps
RoCEv2: Some sort of label that also implies a vlan tag

We also have iwarp vs rocee where AFAIK iwarp should get the vlan tag
from the IP socket that is allocated against the eth interface.

> In the case of RDMA over IB, we want to control QP access to
> partitions/pkeys; in the case of RDMA over ethernet we want to control
> QP access to VLANs/GIDs.

Broadly, yes, and I don't know what restriction iwarp would
need. Probably restrict access based on the eth device, but that will
probably need additional selinux checking in the rdma core.

There are also UD QPs which are like UDP sockets, so every address
handle creation will need a security check too.

Jason

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

* Re: [PATCH v3 0/9] SELinux support for Infiniband RDMA
  2016-09-29 22:41                                         ` Jason Gunthorpe
  (?)
@ 2016-09-30 19:59                                         ` Paul Moore
       [not found]                                           ` <CAHC9VhTBW9VsMHag41x1GWUbwPQeLngi8_iq9CPuQ=UMxDebkg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  -1 siblings, 1 reply; 79+ messages in thread
From: Paul Moore @ 2016-09-30 19:59 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: Daniel Jurgens, Leon Romanovsky, chrisw, Stephen Smalley,
	Eric Paris, dledford, sean.hefty, hal.rosenstock, selinux,
	linux-security-module, linux-rdma, Yevgeny Petrilin

On Thu, Sep 29, 2016 at 6:41 PM, Jason Gunthorpe
<jgunthorpe@obsidianresearch.com> wrote:
> On Thu, Sep 29, 2016 at 06:16:03PM -0400, Paul Moore wrote:
>> The queue pair (QP) concept lives in the RDMA layer and isn't tied to
>> any particular transport.  They appear to be somewhat analogous to
>> network sockets, although I'm guessing they can't be shared/passed
>> between process like a network socket, yes?
>
> Yes

Okay, that should make life easier.

>> The IB partition is similar to a ethernet VLAN in that it providedes
>> enforced separation across the network; IB uses partition keys, VLANs
>> use tags/IDs.  IB partition keys are a 16 bit number,
>
>> GIDs appear to be a 16 byte number created from some combination of
>> IP address, MAC address, and VLAN ID.
>
> There are several gid formats
>
> IB/OPA: 128 bit IPv6 address
> RoCEv1: Sort of a link local IPv6 (?), vlan is specified directly
>         by apps
> RoCEv2: Some sort of label that also implies a vlan tag

Thanks for the extra information, but at this point I don't think the
exact format is important; I'm just trying to get a basic
understanding of what we might need to do.

> We also have iwarp vs rocee where AFAIK iwarp should get the vlan tag
> from the IP socket that is allocated against the eth interface.

Sigh.

So we've got RDMA over IB (does this have an acronym?  my googling
isn't showing anything ...), RoCEv1 which appears to be RDMA over
Ethernet (although it looks like it might still use an IP header?),
RoCEv2 which appears to be RDMA over UDP, and iWARP which seems to be
RDMA over TCP/SCTP.  Are there any others?

We've already talked about the RDMA/IB's pkeys and RoCEv1's GID/VLANs,
but RoCEv2 and iWARP are a little more interesting as they ride on top
of a routable network transport.  Do RoCEv2 and iWARP use the kernel's
stack, or is that off-loaded?  Actually, now that I think of it,
RoCEv2 and iWARP are probably implemented as userspace libraries
aren't they?  The kernel probably doesn't know or care about these
protocols at all, or does it?

>> In the case of RDMA over IB, we want to control QP access to
>> partitions/pkeys; in the case of RDMA over ethernet we want to control
>> QP access to VLANs/GIDs.
>
> Broadly, yes, and I don't know what restriction iwarp would
> need. Probably restrict access based on the eth device, but that will
> probably need additional selinux checking in the rdma core.
>
> There are also UD QPs which are like UDP sockets, so every address
> handle creation will need a security check too.

-- 
paul moore
www.paul-moore.com

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

* Re: [PATCH v3 0/9] SELinux support for Infiniband RDMA
  2016-09-30 19:59                                         ` Paul Moore
@ 2016-09-30 20:46                                               ` Jason Gunthorpe
  0 siblings, 0 replies; 79+ messages in thread
From: Jason Gunthorpe @ 2016-09-30 20:46 UTC (permalink / raw)
  To: Paul Moore
  Cc: Daniel Jurgens, Leon Romanovsky, 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, Yevgeny Petrilin

On Fri, Sep 30, 2016 at 03:59:55PM -0400, Paul Moore wrote:
> > We also have iwarp vs rocee where AFAIK iwarp should get the vlan tag
> > from the IP socket that is allocated against the eth interface.
> 
> Sigh.
> 
> So we've got RDMA over IB (does this have an acronym?  my googling

We just call that IB

> isn't showing anything ...), RoCEv1 which appears to be RDMA over

Technically (IIRC) RoCEv1 is exactly the IB protocol with an ethernet
MAC header tacked in front. It even has a slot for a pkey value, but
no switches will inspect it.

> Ethernet (although it looks like it might still use an IP header?),

The 'IP' header is a IB GRH which is identical to a IPv6 header. We
call the IPv6 address in this header a GID.

> RoCEv2 which appears to be RDMA over UDP, and iWARP which seems to be
> RDMA over TCP/SCTP.  Are there any others?

RoCEv2 is the IB protocol with a UDP header added in.

iWARP is a unique protocol that runs RDMA inside TCP.

> We've already talked about the RDMA/IB's pkeys and RoCEv1's GID/VLANs,
> but RoCEv2 and iWARP are a little more interesting as they ride on top
> of a routable network transport.  Do RoCEv2 and iWARP use the kernel's
> stack, or is that off-loaded?

Gernally all off-loaded. There is one software implementation but it
is not used for anything serious. Well, maybe two IB drivers don't
offload this, I'm not sure.

> Actually, now that I think of it, RoCEv2 and iWARP are probably
> implemented as userspace libraries aren't they?

Nope, there is a userspace library component, but the kernel is
largely in charge. They are sort of distinct from the netstack, but
part of the RDMA stack. It is very confusing because netdev is
ideologically opposed (for good reason) to any form of offload, so
even though these devices use the same physical network port, and use
IP headers, they are not very well integrated.

Eg iwarp calls out to a userspace process which opens a socket to
reserve a port number and then feeds that back into the kernel to
setup IP headers which are safe to use. :\ The nic steals those
packets before the kernel ever sees them and processes them with an
internal 'CPU' and then feeds the QP infrastructure. (this is what is
ment by the term offload)

This also means that likely all the SE linux protections that apply to
ethernet are merrily voided by all this offload hardware and AFAIK
nobody has done any work to try and do something about that.

So Liran is right, when we talk about iWarp/RoCEv2 the SELinux stuff
should follow the ethernet stack.

However, every IB port typically has some number of child ipoib
netdevices as well, and those devices also specify a Pkey. This is
where the namespace patches source their pkey information from. I
don't know why a different approach is proposed for selinux. (Well,
aside from the fact the namespace patches were never completed and
basically don't work for strong isolation..)

.. and that is my basic concern, that selinux will get one patch
series and be left essentially incomplete like namespaces were.

Jason
--
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] 79+ messages in thread

* Re: [PATCH v3 0/9] SELinux support for Infiniband RDMA
@ 2016-09-30 20:46                                               ` Jason Gunthorpe
  0 siblings, 0 replies; 79+ messages in thread
From: Jason Gunthorpe @ 2016-09-30 20:46 UTC (permalink / raw)
  To: Paul Moore
  Cc: Daniel Jurgens, Leon Romanovsky, chrisw, Stephen Smalley,
	Eric Paris, dledford, sean.hefty, hal.rosenstock, selinux,
	linux-security-module, linux-rdma, Yevgeny Petrilin

On Fri, Sep 30, 2016 at 03:59:55PM -0400, Paul Moore wrote:
> > We also have iwarp vs rocee where AFAIK iwarp should get the vlan tag
> > from the IP socket that is allocated against the eth interface.
> 
> Sigh.
> 
> So we've got RDMA over IB (does this have an acronym?  my googling

We just call that IB

> isn't showing anything ...), RoCEv1 which appears to be RDMA over

Technically (IIRC) RoCEv1 is exactly the IB protocol with an ethernet
MAC header tacked in front. It even has a slot for a pkey value, but
no switches will inspect it.

> Ethernet (although it looks like it might still use an IP header?),

The 'IP' header is a IB GRH which is identical to a IPv6 header. We
call the IPv6 address in this header a GID.

> RoCEv2 which appears to be RDMA over UDP, and iWARP which seems to be
> RDMA over TCP/SCTP.  Are there any others?

RoCEv2 is the IB protocol with a UDP header added in.

iWARP is a unique protocol that runs RDMA inside TCP.

> We've already talked about the RDMA/IB's pkeys and RoCEv1's GID/VLANs,
> but RoCEv2 and iWARP are a little more interesting as they ride on top
> of a routable network transport.  Do RoCEv2 and iWARP use the kernel's
> stack, or is that off-loaded?

Gernally all off-loaded. There is one software implementation but it
is not used for anything serious. Well, maybe two IB drivers don't
offload this, I'm not sure.

> Actually, now that I think of it, RoCEv2 and iWARP are probably
> implemented as userspace libraries aren't they?

Nope, there is a userspace library component, but the kernel is
largely in charge. They are sort of distinct from the netstack, but
part of the RDMA stack. It is very confusing because netdev is
ideologically opposed (for good reason) to any form of offload, so
even though these devices use the same physical network port, and use
IP headers, they are not very well integrated.

Eg iwarp calls out to a userspace process which opens a socket to
reserve a port number and then feeds that back into the kernel to
setup IP headers which are safe to use. :\ The nic steals those
packets before the kernel ever sees them and processes them with an
internal 'CPU' and then feeds the QP infrastructure. (this is what is
ment by the term offload)

This also means that likely all the SE linux protections that apply to
ethernet are merrily voided by all this offload hardware and AFAIK
nobody has done any work to try and do something about that.

So Liran is right, when we talk about iWarp/RoCEv2 the SELinux stuff
should follow the ethernet stack.

However, every IB port typically has some number of child ipoib
netdevices as well, and those devices also specify a Pkey. This is
where the namespace patches source their pkey information from. I
don't know why a different approach is proposed for selinux. (Well,
aside from the fact the namespace patches were never completed and
basically don't work for strong isolation..)

.. and that is my basic concern, that selinux will get one patch
series and be left essentially incomplete like namespaces were.

Jason

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

end of thread, other threads:[~2016-09-30 20:46 UTC | newest]

Thread overview: 79+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-07-29 13:53 [PATCH v3 0/9] SELinux support for Infiniband RDMA Dan Jurgens
2016-07-29 13:53 ` Dan Jurgens
2016-07-29 13:53 ` [PATCH v3 1/9] IB/core: IB cache enhancements to support Infiniband security Dan Jurgens
     [not found] ` <1469800416-125043-1-git-send-email-danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
2016-07-29 13:53   ` [PATCH v3 2/9] IB/core: Enforce PKey security on QPs Dan Jurgens
2016-07-29 13:53     ` Dan Jurgens
2016-07-29 13:53   ` [PATCH v3 3/9] selinux lsm IB/core: Implement LSM notification system Dan Jurgens
2016-07-29 13:53     ` Dan Jurgens
     [not found]     ` <1469800416-125043-4-git-send-email-danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
2016-07-29 22:40       ` kbuild test robot
2016-07-29 22:40         ` kbuild test robot
2016-09-01  1:35     ` Paul Moore
2016-07-29 13:53   ` [PATCH v3 4/9] IB/core: Enforce security on management datagrams Dan Jurgens
2016-07-29 13:53     ` Dan Jurgens
2016-07-29 13:53   ` [PATCH v3 5/9] selinux: Create policydb version for Infiniband support Dan Jurgens
2016-07-29 13:53     ` Dan Jurgens
     [not found]     ` <1469800416-125043-6-git-send-email-danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
2016-09-01  1:39       ` Paul Moore
2016-09-01  1:39         ` Paul Moore
2016-07-29 13:53   ` [PATCH v3 9/9] selinux: Add a cache for quicker retreival of PKey SIDs Dan Jurgens
2016-07-29 13:53     ` Dan Jurgens
2016-07-29 13:53 ` [PATCH v3 6/9] selinux: Allocate and free infiniband security hooks Dan Jurgens
2016-07-29 13:53 ` [PATCH v3 7/9] selinux: Implement Infiniband PKey "Access" access vector Dan Jurgens
2016-07-29 13:53 ` [PATCH v3 8/9] selinux: Add IB Port SMP " Dan Jurgens
2016-08-29 21:40 ` [PATCH v3 0/9] SELinux support for Infiniband RDMA Paul Moore
2016-08-29 21:48   ` Daniel Jurgens
2016-08-30  0:00     ` Paul Moore
2016-08-30  7:46       ` Leon Romanovsky
2016-08-30 13:53         ` Paul Moore
2016-08-30 14:06           ` Daniel Jurgens
2016-08-30 14:06             ` Daniel Jurgens
     [not found]             ` <VI1PR0501MB242949202A1DA23E5C8E1E8AC4E00-o1MPJYiShEyB6Z+oivrBG8DSnupUy6xnnBOFsp37pqbUKgpGm//BTAC/G2K4zDHf@public.gmane.org>
2016-08-30 15:01               ` Leon Romanovsky
2016-08-30 15:01                 ` Leon Romanovsky
2016-08-30 18:46             ` Jason Gunthorpe
2016-08-30 18:52               ` Daniel Jurgens
2016-08-30 18:52                 ` Daniel Jurgens
2016-08-30 18:55                 ` Jason Gunthorpe
2016-08-30 19:10                   ` Daniel Jurgens
2016-08-30 19:10                     ` Daniel Jurgens
2016-09-01 16:34                     ` Jason Gunthorpe
     [not found]                       ` <20160901163418.GA6479-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
2016-09-01 18:06                         ` Paul Moore
2016-09-01 18:06                           ` Paul Moore
2016-09-06 20:02                           ` Jason Gunthorpe
2016-09-06 20:35                             ` Daniel Jurgens
2016-09-06 20:35                               ` Daniel Jurgens
2016-09-06 21:55                               ` Jason Gunthorpe
2016-09-08  0:01                                 ` ira.weiny
2016-09-08 14:12                                   ` Daniel Jurgens
2016-09-08 14:12                                     ` Daniel Jurgens
2016-09-08 16:19                                     ` Jason Gunthorpe
2016-09-08 16:44                                       ` Daniel Jurgens
2016-09-08 16:44                                         ` Daniel Jurgens
2016-09-08 18:36                                         ` Jason Gunthorpe
2016-09-08 18:59                                           ` Daniel Jurgens
2016-09-08 18:59                                             ` Daniel Jurgens
2016-09-08 19:32                                             ` Jason Gunthorpe
2016-09-21 16:16                                               ` ira.weiny
     [not found]                                                 ` <20160921161626.GA27837-W4f6Xiosr+yv7QzWx2u06xL4W9x8LtSr@public.gmane.org>
2016-09-22 15:04                                                   ` Liran Liss
2016-09-22 15:04                                                     ` Liran Liss
     [not found]                                       ` <20160908161948.GA21614-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
2016-09-08 19:14                                         ` ira.weiny
2016-09-08 19:14                                           ` ira.weiny
2016-09-08 19:35                                           ` Jason Gunthorpe
2016-09-15  1:52                                             ` ira.weiny
     [not found]                                     ` <DB6PR0501MB2422EA34EED4EE35EE7B1D28C4FB0-wTfl6qNNZ1ODMMyMbWtEF8DSnupUy6xnnBOFsp37pqbUKgpGm//BTAC/G2K4zDHf@public.gmane.org>
2016-09-08 17:47                                       ` Liran Liss
2016-09-08 17:47                                         ` Liran Liss
2016-09-08 18:37                                         ` Jason Gunthorpe
2016-09-08 19:01                                           ` Daniel Jurgens
2016-09-08 19:01                                             ` Daniel Jurgens
2016-09-08 18:34                                     ` ira.weiny
2016-09-20 23:43                             ` Paul Moore
2016-09-23 13:26                               ` Daniel Jurgens
2016-09-23 13:26                                 ` Daniel Jurgens
     [not found]                                 ` <VI1PR0501MB24299E036F1FCD335A2C2049C4C80-o1MPJYiShEyB6Z+oivrBG8DSnupUy6xnnBOFsp37pqbUKgpGm//BTAC/G2K4zDHf@public.gmane.org>
2016-09-29 22:16                                   ` Paul Moore
2016-09-29 22:16                                     ` Paul Moore
     [not found]                                     ` <CAHC9VhShCgxonV1rN-J7LyezamzZtKNZ1SR7ywnTB9Kgia_u1w-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2016-09-29 22:41                                       ` Jason Gunthorpe
2016-09-29 22:41                                         ` Jason Gunthorpe
2016-09-30 19:59                                         ` Paul Moore
     [not found]                                           ` <CAHC9VhTBW9VsMHag41x1GWUbwPQeLngi8_iq9CPuQ=UMxDebkg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2016-09-30 20:46                                             ` Jason Gunthorpe
2016-09-30 20:46                                               ` Jason Gunthorpe
2016-09-26 18:17                               ` Jason Gunthorpe
     [not found]         ` <20160830074607.GN594-2ukJVAZIZ/Y@public.gmane.org>
2016-08-30 15:02           ` Or Gerlitz
2016-08-30 15:02             ` Or Gerlitz

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.