All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/12] SELinux support for Infiniband RDMA
@ 2016-06-23 19:52 ` Dan Jurgens
  0 siblings, 0 replies; 128+ messages in thread
From: Dan Jurgens @ 2016-06-23 19:52 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>

This patch series was submitted previously as an RFC.  The 3rd version was
posted on 19 Apr 2016 with the subject "[RFC PATCH v3 NN/MM] SELinux support
for Infiniband RDMA".

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.

All Infiniband fabrics must have a subnet manager.  The subnet manager
provisions the partitions and configures the end nodes.  Each end port has a
PKey table containing all 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 SMIs.

A PKey label consists of a subnet prefix and a range of PKey values and is
similar to the labeling mechanism for netports.  Infiniband end 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 end port (ib_end_port) is labeled by name and port number. There
is a single access vector for ib_end_ports as well, called "smp".

Because RDMA allows for kernel bypass all enforcement must be done during
connection setup.  To communicate 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 two LSM hooks are provided, ib_core will
register and unregister a callback function at init and cleanup respectively.
SELinux will call the callback as appropriate if it has been registered.
When the callback is called ib_core will recheck the PKey access for all
existing QPs.

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
each 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 modify attempt.  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 hardware driver
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 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.

Daniel Jurgens (12):
  security: Add LSM hooks for Infiniband security
  selinux: Create policydb version for Infiniband support
  selinux: Implement Infiniband flush callback
  selinux: Allocate and free infiniband security hooks
  selinux: Implement Infiniband PKey "Access" access vector
  selinux: Add IB End Port SMP access vector
  selinux: Add a cache for quicker retreival of PKey SIDs
  IB/core: IB cache enhancements to support Infiniband security
  IB/core: Enforce PKey security on QPs
  IB/core: Enforce PKey security on management datagrams
  IB/core: Enforce Infiniband device SMI security
  IB/core: Implement the Infiniband flush callback.

 drivers/infiniband/core/Makefile                 |   3 +-
 drivers/infiniband/core/cache.c                  |  56 +-
 drivers/infiniband/core/core_priv.h              |  93 ++++
 drivers/infiniband/core/device.c                 |  59 +++
 drivers/infiniband/core/mad.c                    | 105 +++-
 drivers/infiniband/core/security.c               | 641 +++++++++++++++++++++++
 drivers/infiniband/core/uverbs_cmd.c             |  20 +-
 drivers/infiniband/core/verbs.c                  |  29 +-
 include/linux/lsm_audit.h                        |  37 +-
 include/linux/lsm_hooks.h                        |  71 +++
 include/linux/security.h                         |  63 +++
 include/rdma/ib_mad.h                            |   1 +
 include/rdma/ib_verbs.h                          |  49 ++
 security/Kconfig                                 |   9 +
 security/security.c                              |  83 +++
 security/selinux/Makefile                        |   2 +-
 security/selinux/hooks.c                         | 160 +++++-
 security/selinux/include/classmap.h              |   4 +
 security/selinux/include/initial_sid_to_string.h |   2 +
 security/selinux/include/objsec.h                |  11 +
 security/selinux/include/pkey.h                  |  31 ++
 security/selinux/include/security.h              |   7 +-
 security/selinux/pkey.c                          | 243 +++++++++
 security/selinux/ss/policydb.c                   | 129 ++++-
 security/selinux/ss/policydb.h                   |  27 +-
 security/selinux/ss/services.c                   |  84 +++
 26 files changed, 1963 insertions(+), 56 deletions(-)
 create mode 100644 drivers/infiniband/core/security.c
 create mode 100644 security/selinux/include/pkey.h
 create mode 100644 security/selinux/pkey.c

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

* [PATCH 00/12] SELinux support for Infiniband RDMA
@ 2016-06-23 19:52 ` Dan Jurgens
  0 siblings, 0 replies; 128+ messages in thread
From: Dan Jurgens @ 2016-06-23 19:52 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>

This patch series was submitted previously as an RFC.  The 3rd version was
posted on 19 Apr 2016 with the subject "[RFC PATCH v3 NN/MM] SELinux support
for Infiniband RDMA".

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.

All Infiniband fabrics must have a subnet manager.  The subnet manager
provisions the partitions and configures the end nodes.  Each end port has a
PKey table containing all 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 SMIs.

A PKey label consists of a subnet prefix and a range of PKey values and is
similar to the labeling mechanism for netports.  Infiniband end 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 end port (ib_end_port) is labeled by name and port number. There
is a single access vector for ib_end_ports as well, called "smp".

Because RDMA allows for kernel bypass all enforcement must be done during
connection setup.  To communicate 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 two LSM hooks are provided, ib_core will
register and unregister a callback function at init and cleanup respectively.
SELinux will call the callback as appropriate if it has been registered.
When the callback is called ib_core will recheck the PKey access for all
existing QPs.

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
each 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 modify attempt.  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 hardware driver
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 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.

Daniel Jurgens (12):
  security: Add LSM hooks for Infiniband security
  selinux: Create policydb version for Infiniband support
  selinux: Implement Infiniband flush callback
  selinux: Allocate and free infiniband security hooks
  selinux: Implement Infiniband PKey "Access" access vector
  selinux: Add IB End Port SMP access vector
  selinux: Add a cache for quicker retreival of PKey SIDs
  IB/core: IB cache enhancements to support Infiniband security
  IB/core: Enforce PKey security on QPs
  IB/core: Enforce PKey security on management datagrams
  IB/core: Enforce Infiniband device SMI security
  IB/core: Implement the Infiniband flush callback.

 drivers/infiniband/core/Makefile                 |   3 +-
 drivers/infiniband/core/cache.c                  |  56 +-
 drivers/infiniband/core/core_priv.h              |  93 ++++
 drivers/infiniband/core/device.c                 |  59 +++
 drivers/infiniband/core/mad.c                    | 105 +++-
 drivers/infiniband/core/security.c               | 641 +++++++++++++++++++++++
 drivers/infiniband/core/uverbs_cmd.c             |  20 +-
 drivers/infiniband/core/verbs.c                  |  29 +-
 include/linux/lsm_audit.h                        |  37 +-
 include/linux/lsm_hooks.h                        |  71 +++
 include/linux/security.h                         |  63 +++
 include/rdma/ib_mad.h                            |   1 +
 include/rdma/ib_verbs.h                          |  49 ++
 security/Kconfig                                 |   9 +
 security/security.c                              |  83 +++
 security/selinux/Makefile                        |   2 +-
 security/selinux/hooks.c                         | 160 +++++-
 security/selinux/include/classmap.h              |   4 +
 security/selinux/include/initial_sid_to_string.h |   2 +
 security/selinux/include/objsec.h                |  11 +
 security/selinux/include/pkey.h                  |  31 ++
 security/selinux/include/security.h              |   7 +-
 security/selinux/pkey.c                          | 243 +++++++++
 security/selinux/ss/policydb.c                   | 129 ++++-
 security/selinux/ss/policydb.h                   |  27 +-
 security/selinux/ss/services.c                   |  84 +++
 26 files changed, 1963 insertions(+), 56 deletions(-)
 create mode 100644 drivers/infiniband/core/security.c
 create mode 100644 security/selinux/include/pkey.h
 create mode 100644 security/selinux/pkey.c

-- 
1.8.3.1

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

* [PATCH 01/12] security: Add LSM hooks for Infiniband security
  2016-06-23 19:52 ` Dan Jurgens
  (?)
@ 2016-06-23 19:52 ` Dan Jurgens
       [not found]   ` <1466711578-64398-2-git-send-email-danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
  -1 siblings, 1 reply; 128+ messages in thread
From: Dan Jurgens @ 2016-06-23 19:52 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 nine new hooks
 1. Allocate security contexts for Infiniband QPs.
 2. Free security contexts for Infiniband QPs.
 3. Allocate security contexts for Infiniband MAD agents.
 4. Free security contexts for Infiniband MAD agents.
 5. Enforce QP access to Pkeys
 6. Enforce MAD agent access to Pkeys
 7. Enforce MAD agent access to Infiniband End Ports for sending Subnet
    Management Packets (SMP)
 8. A hook to register a callback to receive notifications of
    security policy or enforcement changes.  Restricting a QPs access to
    a pkey will be done during setup and not on a per packet basis
    access must be enforced again.
 9. A hook to unregister the callback.

Signed-off-by: Daniel Jurgens <danielj@mellanox.com>
Reviewed-by: Eli Cohen <eli@mellanox.com>
---
 include/linux/lsm_hooks.h | 71 ++++++++++++++++++++++++++++++++++++++++
 include/linux/security.h  | 63 +++++++++++++++++++++++++++++++++++
 include/rdma/ib_verbs.h   |  4 +++
 security/Kconfig          |  9 +++++
 security/security.c       | 83 +++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 230 insertions(+)

diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index 7ae3976..6b47c8d 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,50 @@
  *	associated with the TUN device's security structure.
  *	@security pointer to the TUN devices's security structure.
  *
+ * Security hooks for Infiniband
+ *
+ * @ib_qp_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.
+ *	@qp_sec pointer to the ib_qp_security structure.
+ * @ib_mad_agent_pkey_access:
+ *	Check permission to access a pkey when transmiting and receiving MADS.
+ *	@subnet_prefix the subnet prefix of the port being used.
+ *	@pkey the pkey to be accessed.
+ *	@mad_agent pointer to the ib_mad_agent structure.
+ * @ib_end_port_smp:
+ *	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.
+ *	@mad_agent pointer to the ib_mad_agent structure.
+ * @ib_qp_alloc_security:
+ *	Allocate and attach a security structure to the qp_sec->q_security
+ *	field. The q_security field is initialized to NULL when the structure
+ *	is allocated.  A separate QP security structure is used instead of the
+ *	QP structure because when a QP is destroyed the memory is freed by the
+ *	hardware driver.  That operation can fail so the security info must be
+ *	maintained until the destroy completes successfully.
+ *	@qp_sec contains the ib_qp_security structure to be modified.
+ *	Return 0 if operation was successful.
+ * @ib_mad_agent_alloc_security:
+ *	Allocate and attach a security structure to the mad_agent->m_security
+ *	field. The m_security field is initialized to NULL when the structure
+ *	is allocated.
+ *	@mad_agent contains the ib_mad_agent structure to be modified.
+ *	Return 0 if operation was successful.
+ * @ib_qp_free_security:
+ *	Deallocate and clear the qp_sec->q_security field.
+ *	@qp_sec contains the ib_qp_security structure to be modified.
+ * @ib_mad_agent_free_security:
+ *	Deallocate and clear the mad_agent->m_security field.
+ *	@mad_agent contains the ib_mad_agent structure to be modified.
+ * @register_ib_flush_callback:
+ *	Provide a way for security modules to notify ib_core of policy changes.
+ *	@callback function pointer to call when policy changes.
+ * @unregister_ib_flush_callback:
+ *	Unregister the callback function.
+ *
  * Security hooks for XFRM operations.
  *
  * @xfrm_policy_alloc_security:
@@ -1579,6 +1624,21 @@ union security_list_options {
 	int (*tun_dev_open)(void *security);
 #endif	/* CONFIG_SECURITY_NETWORK */
 
+#ifdef CONFIG_SECURITY_INFINIBAND
+	int (*ib_qp_pkey_access)(u64 subnet_prefix, u16 pkey,
+				 struct ib_qp_security *qp_sec);
+	int (*ib_mad_agent_pkey_access)(u64 subnet_prefix, u16 pkey,
+					struct ib_mad_agent *mad_agent);
+	int (*ib_end_port_smp)(const char *dev_name, u8 port,
+			       struct ib_mad_agent *mad_agent);
+	int (*ib_qp_alloc_security)(struct ib_qp_security *qp_sec);
+	int (*ib_mad_agent_alloc_security)(struct ib_mad_agent *mad_agent);
+	void (*ib_qp_free_security)(struct ib_qp_security *qp_sec);
+	void (*ib_mad_agent_free_security)(struct ib_mad_agent *mad_agent);
+	void (*register_ib_flush_callback)(void (*callback)(void));
+	void (*unregister_ib_flush_callback)(void);
+#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 +1866,17 @@ 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_qp_pkey_access;
+	struct list_head ib_mad_agent_pkey_access;
+	struct list_head ib_end_port_smp;
+	struct list_head ib_qp_alloc_security;
+	struct list_head ib_qp_free_security;
+	struct list_head ib_mad_agent_alloc_security;
+	struct list_head ib_mad_agent_free_security;
+	struct list_head register_ib_flush_callback;
+	struct list_head unregister_ib_flush_callback;
+#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..a75d3e6 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
@@ -55,6 +56,8 @@ struct msg_queue;
 struct xattr;
 struct xfrm_sec_ctx;
 struct mm_struct;
+struct ib_qp_security;
+struct ib_mad_agent;
 
 /* If capable should audit the security request */
 #define SECURITY_CAP_NOAUDIT 0
@@ -1370,6 +1373,66 @@ static inline int security_tun_dev_open(void *security)
 }
 #endif	/* CONFIG_SECURITY_NETWORK */
 
+#ifdef CONFIG_SECURITY_INFINIBAND
+int security_ib_qp_pkey_access(u64 subnet_prefix, u16 pkey,
+			       struct ib_qp_security *qp_sec);
+int security_ib_mad_agent_pkey_access(u64 subnet_prefix, u16 pkey,
+				      struct ib_mad_agent *mad_agent);
+int security_ib_end_port_smp(const char *name, u8 port,
+			     struct ib_mad_agent *mad_agent);
+int security_ib_qp_alloc_security(struct ib_qp_security *qp_sec);
+void security_ib_qp_free_security(struct ib_qp_security *qp_sec);
+int security_ib_mad_agent_alloc_security(struct ib_mad_agent *mad_agent);
+void security_ib_mad_agent_free_security(struct ib_mad_agent *mad_agent);
+void security_register_ib_flush_callback(void (*callback)(void));
+void security_unregister_ib_flush_callback(void);
+#else	/* CONFIG_SECURITY_INFINIBAND */
+static inline int security_ib_qp_pkey_access(u64 subnet_prefix, u16 pkey,
+					     struct ib_qp_security *qp_sec)
+{
+	return 0;
+}
+
+static inline int security_ib_mad_agent_pkey_access(u64 subnet_prefix,
+						    u16 pkey,
+						    struct ib_mad_agent *mad_agent)
+{
+	return 0;
+}
+
+static inline int security_ib_end_port_smp(const char *dev_name, u8 port,
+					   struct ib_mad_agent *mad_agent)
+{
+	return 0;
+}
+
+static inline int security_ib_qp_alloc_security(struct ib_qp_security *qp_sec)
+{
+	return 0;
+}
+
+static inline void security_ib_qp_free_security(struct ib_qp_security *qp_sec)
+{
+}
+
+static inline int security_ib_mad_agent_alloc_security(struct ib_mad_agent *mad_agent)
+{
+	return 0;
+}
+
+static inline void security_ib_mad_agent_free_security(struct ib_mad_agent *mad_agent)
+{
+}
+
+static inline void security_register_ib_flush_callback(void (*callback)(void))
+{
+}
+
+static inline void security_unregister_ib_flush_callback(void)
+{
+}
+#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 432bed5..3f6780b 100644
--- a/include/rdma/ib_verbs.h
+++ b/include/rdma/ib_verbs.h
@@ -1428,6 +1428,10 @@ struct ib_srq {
 	} ext;
 };
 
+struct ib_qp_security {
+	void *q_security;
+};
+
 struct ib_qp {
 	struct ib_device       *device;
 	struct ib_pd	       *pd;
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..d75a0e9 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,67 @@ EXPORT_SYMBOL(security_tun_dev_open);
 
 #endif	/* CONFIG_SECURITY_NETWORK */
 
+#ifdef CONFIG_SECURITY_INFINIBAND
+
+int security_ib_qp_pkey_access(u64 subnet_prefix, u16 pkey,
+			       struct ib_qp_security *qp_sec)
+{
+	return call_int_hook(ib_qp_pkey_access, 0, subnet_prefix, pkey, qp_sec);
+}
+EXPORT_SYMBOL(security_ib_qp_pkey_access);
+
+int security_ib_mad_agent_pkey_access(u64 subnet_prefix, u16 pkey,
+				      struct ib_mad_agent *mad_agent)
+{
+	return call_int_hook(ib_mad_agent_pkey_access, 0, subnet_prefix, pkey, mad_agent);
+}
+EXPORT_SYMBOL(security_ib_mad_agent_pkey_access);
+
+int security_ib_end_port_smp(const char *dev_name, u8 port,
+			     struct ib_mad_agent *mad_agent)
+{
+	return call_int_hook(ib_end_port_smp, 0, dev_name, port, mad_agent);
+}
+EXPORT_SYMBOL(security_ib_end_port_smp);
+
+int security_ib_qp_alloc_security(struct ib_qp_security *qp_sec)
+{
+	return call_int_hook(ib_qp_alloc_security, 0, qp_sec);
+}
+EXPORT_SYMBOL(security_ib_qp_alloc_security);
+
+void security_ib_qp_free_security(struct ib_qp_security *qp_sec)
+{
+	call_void_hook(ib_qp_free_security, qp_sec);
+}
+EXPORT_SYMBOL(security_ib_qp_free_security);
+
+int security_ib_mad_agent_alloc_security(struct ib_mad_agent *mad_agent)
+{
+	return call_int_hook(ib_mad_agent_alloc_security, 0, mad_agent);
+}
+EXPORT_SYMBOL(security_ib_mad_agent_alloc_security);
+
+void security_ib_mad_agent_free_security(struct ib_mad_agent *mad_agent)
+{
+	call_void_hook(ib_mad_agent_free_security, mad_agent);
+}
+EXPORT_SYMBOL(security_ib_mad_agent_free_security);
+
+void security_register_ib_flush_callback(void (*callback)(void))
+{
+	call_void_hook(register_ib_flush_callback, callback);
+}
+EXPORT_SYMBOL(security_register_ib_flush_callback);
+
+void security_unregister_ib_flush_callback(void)
+{
+	call_void_hook(unregister_ib_flush_callback);
+}
+EXPORT_SYMBOL(security_unregister_ib_flush_callback);
+
+#endif	/* CONFIG_SECURITY_INFINIBAND */
+
 #ifdef CONFIG_SECURITY_NETWORK_XFRM
 
 int security_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp,
@@ -1850,6 +1912,27 @@ 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_qp_pkey_access =
+		LIST_HEAD_INIT(security_hook_heads.ib_qp_pkey_access),
+	.ib_mad_agent_pkey_access =
+		LIST_HEAD_INIT(security_hook_heads.ib_mad_agent_pkey_access),
+	.ib_end_port_smp = LIST_HEAD_INIT(security_hook_heads.ib_end_port_smp),
+	.ib_qp_alloc_security =
+		LIST_HEAD_INIT(security_hook_heads.ib_qp_alloc_security),
+	.ib_qp_free_security =
+		LIST_HEAD_INIT(security_hook_heads.ib_qp_free_security),
+	.ib_mad_agent_alloc_security =
+		LIST_HEAD_INIT(security_hook_heads.ib_mad_agent_alloc_security),
+	.ib_mad_agent_free_security =
+		LIST_HEAD_INIT(security_hook_heads.ib_mad_agent_free_security),
+	.register_ib_flush_callback =
+		LIST_HEAD_INIT(security_hook_heads.register_ib_flush_callback),
+	.unregister_ib_flush_callback =
+		LIST_HEAD_INIT(security_hook_heads.unregister_ib_flush_callback),
+#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] 128+ messages in thread

* [PATCH 02/12] selinux: Create policydb version for Infiniband support
  2016-06-23 19:52 ` Dan Jurgens
  (?)
  (?)
@ 2016-06-23 19:52 ` Dan Jurgens
       [not found]   ` <1466711578-64398-3-git-send-email-danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
  -1 siblings, 1 reply; 128+ messages in thread
From: Dan Jurgens @ 2016-06-23 19:52 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 End 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>
---
 security/selinux/include/security.h |   3 +-
 security/selinux/ss/policydb.c      | 129 +++++++++++++++++++++++++++++++-----
 security/selinux/ss/policydb.h      |  27 +++++---
 3 files changed, 135 insertions(+), 24 deletions(-)

diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index 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..78b819c 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,58 @@ 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_END_PORT:
+				rc = next_entry(buf, fp, sizeof(u32) * 2);
+				if (rc)
+					goto out;
+				len = le32_to_cpu(buf[0]);
+
+				rc = str_read(&c->u.ib_end_port.dev_name, GFP_KERNEL,
+					      fp,
+					      len);
+				if (rc)
+					goto out;
+
+				c->u.ib_end_port.port = le32_to_cpu(buf[1]);
+
+				rc = context_read_and_validate(&c->context[0],
+							       p,
+							       fp);
+				if (rc)
+					goto out;
+				break;
 			}
 		}
 	}
@@ -3147,6 +3209,43 @@ static int ocontext_write(struct policydb *p, struct policydb_compat_info *info,
 				if (rc)
 					return rc;
 				break;
+			case OCON_PKEY: {
+				__be64 *sbn_pfx = (__be64 *)nodebuf;
+				*sbn_pfx = 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_END_PORT:
+				len = strlen(c->u.ib_end_port.dev_name);
+				buf[0] = cpu_to_le32(len);
+				buf[1] = cpu_to_le32(c->u.ib_end_port.port);
+				rc = put_entry(buf, sizeof(u32), 2, fp);
+				if (rc)
+					return rc;
+				rc = put_entry(c->u.ib_end_port.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..751bf604 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;
+		} ib_end_port;
 	} 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_END_PORT 8 /* Infiniband End ports */
+#define OCON_NUM	 9
 
 /* The policy database */
 struct policydb {
-- 
1.8.3.1


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

* [PATCH 03/12] selinux: Implement Infiniband flush callback
  2016-06-23 19:52 ` Dan Jurgens
@ 2016-06-23 19:52     ` Dan Jurgens
  -1 siblings, 0 replies; 128+ messages in thread
From: Dan Jurgens @ 2016-06-23 19:52 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>

Because access for infiniband is enforced in the setup phase of a
connection there must be a way to notify ib_core if the policy or
enforcement setting have changed.

Added register and unregister_ib_flush_callback hooks so infiniband can
setup notification of policy and enforment changes.  In the AVC reset
callback function call the ib_flush callback if it's registered. Also
renamed the callback function, the previous name was 'net' specific.

Signed-off-by: Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
Reviewed-by: Eli Cohen <eli-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
---
 security/selinux/hooks.c | 36 ++++++++++++++++++++++++++++++++++--
 1 file changed, 34 insertions(+), 2 deletions(-)

diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index a86d537..6a8841d 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -94,6 +94,9 @@
 #include "audit.h"
 #include "avc_ss.h"
 
+static void (*ib_flush_callback)(void);
+static DEFINE_MUTEX(ib_flush_mutex);
+
 /* SECMARK reference count */
 static atomic_t selinux_secmark_refcount = ATOMIC_INIT(0);
 
@@ -159,13 +162,17 @@ 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();
+		mutex_lock(&ib_flush_mutex);
+		if (ib_flush_callback)
+			ib_flush_callback();
+		mutex_unlock(&ib_flush_mutex);
 	}
 	return 0;
 }
@@ -5993,6 +6000,23 @@ static int selinux_key_getsecurity(struct key *key, char **_buffer)
 
 #endif
 
+#ifdef CONFIG_SECURITY_INFINIBAND
+static void selinux_register_ib_flush_callback(void (*callback)(void))
+{
+	mutex_lock(&ib_flush_mutex);
+	ib_flush_callback = callback;
+	mutex_unlock(&ib_flush_mutex);
+}
+
+static void selinux_unregister_ib_flush_callback(void)
+{
+	mutex_lock(&ib_flush_mutex);
+	ib_flush_callback = NULL;
+	mutex_unlock(&ib_flush_mutex);
+}
+
+#endif
+
 static struct security_hook_list selinux_hooks[] = {
 	LSM_HOOK_INIT(binder_set_context_mgr, selinux_binder_set_context_mgr),
 	LSM_HOOK_INIT(binder_transaction, selinux_binder_transaction),
@@ -6174,6 +6198,12 @@ 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(register_ib_flush_callback,
+		      selinux_register_ib_flush_callback),
+	LSM_HOOK_INIT(unregister_ib_flush_callback,
+		      selinux_unregister_ib_flush_callback),
+#endif
 
 #ifdef CONFIG_SECURITY_NETWORK_XFRM
 	LSM_HOOK_INIT(xfrm_policy_alloc_security, selinux_xfrm_policy_alloc),
@@ -6233,9 +6263,11 @@ static __init int selinux_init(void)
 					    0, SLAB_PANIC, NULL);
 	avc_init();
 
+	ib_flush_callback = NULL;
+
 	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)
-- 
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] 128+ messages in thread

* [PATCH 03/12] selinux: Implement Infiniband flush callback
@ 2016-06-23 19:52     ` Dan Jurgens
  0 siblings, 0 replies; 128+ messages in thread
From: Dan Jurgens @ 2016-06-23 19:52 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>

Because access for infiniband is enforced in the setup phase of a
connection there must be a way to notify ib_core if the policy or
enforcement setting have changed.

Added register and unregister_ib_flush_callback hooks so infiniband can
setup notification of policy and enforment changes.  In the AVC reset
callback function call the ib_flush callback if it's registered. Also
renamed the callback function, the previous name was 'net' specific.

Signed-off-by: Daniel Jurgens <danielj@mellanox.com>
Reviewed-by: Eli Cohen <eli@mellanox.com>
---
 security/selinux/hooks.c | 36 ++++++++++++++++++++++++++++++++++--
 1 file changed, 34 insertions(+), 2 deletions(-)

diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index a86d537..6a8841d 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -94,6 +94,9 @@
 #include "audit.h"
 #include "avc_ss.h"
 
+static void (*ib_flush_callback)(void);
+static DEFINE_MUTEX(ib_flush_mutex);
+
 /* SECMARK reference count */
 static atomic_t selinux_secmark_refcount = ATOMIC_INIT(0);
 
@@ -159,13 +162,17 @@ 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();
+		mutex_lock(&ib_flush_mutex);
+		if (ib_flush_callback)
+			ib_flush_callback();
+		mutex_unlock(&ib_flush_mutex);
 	}
 	return 0;
 }
@@ -5993,6 +6000,23 @@ static int selinux_key_getsecurity(struct key *key, char **_buffer)
 
 #endif
 
+#ifdef CONFIG_SECURITY_INFINIBAND
+static void selinux_register_ib_flush_callback(void (*callback)(void))
+{
+	mutex_lock(&ib_flush_mutex);
+	ib_flush_callback = callback;
+	mutex_unlock(&ib_flush_mutex);
+}
+
+static void selinux_unregister_ib_flush_callback(void)
+{
+	mutex_lock(&ib_flush_mutex);
+	ib_flush_callback = NULL;
+	mutex_unlock(&ib_flush_mutex);
+}
+
+#endif
+
 static struct security_hook_list selinux_hooks[] = {
 	LSM_HOOK_INIT(binder_set_context_mgr, selinux_binder_set_context_mgr),
 	LSM_HOOK_INIT(binder_transaction, selinux_binder_transaction),
@@ -6174,6 +6198,12 @@ 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(register_ib_flush_callback,
+		      selinux_register_ib_flush_callback),
+	LSM_HOOK_INIT(unregister_ib_flush_callback,
+		      selinux_unregister_ib_flush_callback),
+#endif
 
 #ifdef CONFIG_SECURITY_NETWORK_XFRM
 	LSM_HOOK_INIT(xfrm_policy_alloc_security, selinux_xfrm_policy_alloc),
@@ -6233,9 +6263,11 @@ static __init int selinux_init(void)
 					    0, SLAB_PANIC, NULL);
 	avc_init();
 
+	ib_flush_callback = NULL;
+
 	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)
-- 
1.8.3.1

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

* [PATCH 04/12] selinux: Allocate and free infiniband security hooks
  2016-06-23 19:52 ` Dan Jurgens
@ 2016-06-23 19:52     ` Dan Jurgens
  -1 siblings, 0 replies; 128+ messages in thread
From: Dan Jurgens @ 2016-06-23 19:52 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>

Implement and attach hooks to allocate and free Infiniband QP and MAD
agent security structures.

Signed-off-by: Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
Reviewed-by: Eli Cohen <eli-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
---
 include/rdma/ib_mad.h             |  1 +
 include/rdma/ib_verbs.h           |  1 +
 security/selinux/hooks.c          | 53 +++++++++++++++++++++++++++++++++++++++
 security/selinux/include/objsec.h |  5 ++++
 4 files changed, 60 insertions(+)

diff --git a/include/rdma/ib_mad.h b/include/rdma/ib_mad.h
index c8a773f..a1ed025 100644
--- a/include/rdma/ib_mad.h
+++ b/include/rdma/ib_mad.h
@@ -537,6 +537,7 @@ struct ib_mad_agent {
 	u32			flags;
 	u8			port_num;
 	u8			rmpp_version;
+	void			*m_security;
 };
 
 /**
diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
index 3f6780b..e522acb 100644
--- a/include/rdma/ib_verbs.h
+++ b/include/rdma/ib_verbs.h
@@ -1454,6 +1454,7 @@ struct ib_qp {
 	void		       *qp_context;
 	u32			qp_num;
 	enum ib_qp_type		qp_type;
+	struct ib_qp_security  *qp_sec;
 };
 
 struct ib_mr {
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 6a8841d..4f13ea4 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -17,6 +17,7 @@
  *	Paul Moore <paul-r2n+y4ga6xFZroRs9YW3xA@public.gmane.org>
  *  Copyright (C) 2007 Hitachi Software Engineering Co., Ltd.
  *		       Yuichi Nakamura <ynakam-FkO1umbPgv4fag7Bw7Dlfw@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 version 2,
@@ -83,6 +84,8 @@
 #include <linux/export.h>
 #include <linux/msg.h>
 #include <linux/shm.h>
+#include <rdma/ib_verbs.h>
+#include <rdma/ib_mad.h>
 
 #include "avc.h"
 #include "objsec.h"
@@ -6015,6 +6018,47 @@ static void selinux_unregister_ib_flush_callback(void)
 	mutex_unlock(&ib_flush_mutex);
 }
 
+static int selinux_ib_qp_alloc_security(struct ib_qp_security *qp_sec)
+{
+	struct ib_security_struct *sec;
+
+	sec = kzalloc(sizeof(*sec), GFP_ATOMIC);
+	if (!sec)
+		return -ENOMEM;
+	sec->sid = current_sid();
+
+	qp_sec->q_security = sec;
+	return 0;
+}
+
+static void selinux_ib_qp_free_security(struct ib_qp_security *qp_sec)
+{
+	struct ib_security_struct *sec = qp_sec->q_security;
+
+	qp_sec->q_security = NULL;
+	kfree(sec);
+}
+
+static int selinux_ib_mad_agent_alloc_security(struct ib_mad_agent *mad_agent)
+{
+	struct ib_security_struct *sec;
+
+	sec = kzalloc(sizeof(*sec), GFP_ATOMIC);
+	if (!sec)
+		return -ENOMEM;
+	sec->sid = current_sid();
+
+	mad_agent->m_security = sec;
+	return 0;
+}
+
+static void selinux_ib_mad_agent_free_security(struct ib_mad_agent *mad_agent)
+{
+	struct ib_security_struct *sec = mad_agent->m_security;
+
+	mad_agent->m_security = NULL;
+	kfree(sec);
+}
 #endif
 
 static struct security_hook_list selinux_hooks[] = {
@@ -6198,11 +6242,20 @@ 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(register_ib_flush_callback,
 		      selinux_register_ib_flush_callback),
 	LSM_HOOK_INIT(unregister_ib_flush_callback,
 		      selinux_unregister_ib_flush_callback),
+	LSM_HOOK_INIT(ib_qp_alloc_security,
+		      selinux_ib_qp_alloc_security),
+	LSM_HOOK_INIT(ib_qp_free_security,
+		      selinux_ib_qp_free_security),
+	LSM_HOOK_INIT(ib_mad_agent_alloc_security,
+		      selinux_ib_mad_agent_alloc_security),
+	LSM_HOOK_INIT(ib_mad_agent_free_security,
+		      selinux_ib_mad_agent_free_security),
 #endif
 
 #ifdef CONFIG_SECURITY_NETWORK_XFRM
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-H+wXaHxf7aLQT0dZR+AlfA@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 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

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

* [PATCH 04/12] selinux: Allocate and free infiniband security hooks
@ 2016-06-23 19:52     ` Dan Jurgens
  0 siblings, 0 replies; 128+ messages in thread
From: Dan Jurgens @ 2016-06-23 19:52 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 QP and MAD
agent security structures.

Signed-off-by: Daniel Jurgens <danielj@mellanox.com>
Reviewed-by: Eli Cohen <eli@mellanox.com>
---
 include/rdma/ib_mad.h             |  1 +
 include/rdma/ib_verbs.h           |  1 +
 security/selinux/hooks.c          | 53 +++++++++++++++++++++++++++++++++++++++
 security/selinux/include/objsec.h |  5 ++++
 4 files changed, 60 insertions(+)

diff --git a/include/rdma/ib_mad.h b/include/rdma/ib_mad.h
index c8a773f..a1ed025 100644
--- a/include/rdma/ib_mad.h
+++ b/include/rdma/ib_mad.h
@@ -537,6 +537,7 @@ struct ib_mad_agent {
 	u32			flags;
 	u8			port_num;
 	u8			rmpp_version;
+	void			*m_security;
 };
 
 /**
diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
index 3f6780b..e522acb 100644
--- a/include/rdma/ib_verbs.h
+++ b/include/rdma/ib_verbs.h
@@ -1454,6 +1454,7 @@ struct ib_qp {
 	void		       *qp_context;
 	u32			qp_num;
 	enum ib_qp_type		qp_type;
+	struct ib_qp_security  *qp_sec;
 };
 
 struct ib_mr {
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 6a8841d..4f13ea4 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,
@@ -83,6 +84,8 @@
 #include <linux/export.h>
 #include <linux/msg.h>
 #include <linux/shm.h>
+#include <rdma/ib_verbs.h>
+#include <rdma/ib_mad.h>
 
 #include "avc.h"
 #include "objsec.h"
@@ -6015,6 +6018,47 @@ static void selinux_unregister_ib_flush_callback(void)
 	mutex_unlock(&ib_flush_mutex);
 }
 
+static int selinux_ib_qp_alloc_security(struct ib_qp_security *qp_sec)
+{
+	struct ib_security_struct *sec;
+
+	sec = kzalloc(sizeof(*sec), GFP_ATOMIC);
+	if (!sec)
+		return -ENOMEM;
+	sec->sid = current_sid();
+
+	qp_sec->q_security = sec;
+	return 0;
+}
+
+static void selinux_ib_qp_free_security(struct ib_qp_security *qp_sec)
+{
+	struct ib_security_struct *sec = qp_sec->q_security;
+
+	qp_sec->q_security = NULL;
+	kfree(sec);
+}
+
+static int selinux_ib_mad_agent_alloc_security(struct ib_mad_agent *mad_agent)
+{
+	struct ib_security_struct *sec;
+
+	sec = kzalloc(sizeof(*sec), GFP_ATOMIC);
+	if (!sec)
+		return -ENOMEM;
+	sec->sid = current_sid();
+
+	mad_agent->m_security = sec;
+	return 0;
+}
+
+static void selinux_ib_mad_agent_free_security(struct ib_mad_agent *mad_agent)
+{
+	struct ib_security_struct *sec = mad_agent->m_security;
+
+	mad_agent->m_security = NULL;
+	kfree(sec);
+}
 #endif
 
 static struct security_hook_list selinux_hooks[] = {
@@ -6198,11 +6242,20 @@ 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(register_ib_flush_callback,
 		      selinux_register_ib_flush_callback),
 	LSM_HOOK_INIT(unregister_ib_flush_callback,
 		      selinux_unregister_ib_flush_callback),
+	LSM_HOOK_INIT(ib_qp_alloc_security,
+		      selinux_ib_qp_alloc_security),
+	LSM_HOOK_INIT(ib_qp_free_security,
+		      selinux_ib_qp_free_security),
+	LSM_HOOK_INIT(ib_mad_agent_alloc_security,
+		      selinux_ib_mad_agent_alloc_security),
+	LSM_HOOK_INIT(ib_mad_agent_free_security,
+		      selinux_ib_mad_agent_free_security),
 #endif
 
 #ifdef CONFIG_SECURITY_NETWORK_XFRM
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] 128+ messages in thread

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

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

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

Signed-off-by: Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
Reviewed-by: Eli Cohen <eli-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
---
 include/linux/lsm_audit.h                        |  7 ++++
 security/selinux/hooks.c                         | 41 ++++++++++++++++++++++++
 security/selinux/include/classmap.h              |  2 ++
 security/selinux/include/initial_sid_to_string.h |  1 +
 security/selinux/include/security.h              |  2 ++
 security/selinux/ss/services.c                   | 41 ++++++++++++++++++++++++
 6 files changed, 94 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/selinux/hooks.c b/security/selinux/hooks.c
index 4f13ea4..5a40b10 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -6018,6 +6018,44 @@ static void selinux_unregister_ib_flush_callback(void)
 	mutex_unlock(&ib_flush_mutex);
 }
 
+static int selinux_pkey_access(u64 subnet_prefix, u16 pkey_val, void *security)
+{
+	struct common_audit_data ad;
+	int err;
+	u32 sid = 0;
+	struct ib_security_struct *sec = security;
+	struct lsm_pkey_audit pkey;
+
+	err = security_pkey_sid(subnet_prefix, pkey_val, &sid);
+
+	if (err)
+		goto out;
+
+	ad.type = LSM_AUDIT_DATA_PKEY;
+	pkey.subnet_prefix = subnet_prefix;
+	pkey.pkey = pkey_val;
+	ad.u.pkey = &pkey;
+	err = avc_has_perm(sec->sid, sid,
+			   SECCLASS_INFINIBAND_PKEY,
+			   INFINIBAND_PKEY__ACCESS, &ad);
+out:
+	return err;
+}
+
+static int selinux_ib_qp_pkey_access(u64 subnet_prefix, u16 pkey_val,
+				     struct ib_qp_security *qp_sec)
+{
+	return selinux_pkey_access(subnet_prefix, pkey_val,
+				   qp_sec->q_security);
+}
+
+static int selinux_ib_mad_agent_pkey_access(u64 subnet_prefix, u16 pkey_val,
+					    struct ib_mad_agent *mad_agent)
+{
+	return selinux_pkey_access(subnet_prefix, pkey_val,
+					mad_agent->m_security);
+}
+
 static int selinux_ib_qp_alloc_security(struct ib_qp_security *qp_sec)
 {
 	struct ib_security_struct *sec;
@@ -6248,6 +6286,9 @@ static struct security_hook_list selinux_hooks[] = {
 		      selinux_register_ib_flush_callback),
 	LSM_HOOK_INIT(unregister_ib_flush_callback,
 		      selinux_unregister_ib_flush_callback),
+	LSM_HOOK_INIT(ib_qp_pkey_access, selinux_ib_qp_pkey_access),
+	LSM_HOOK_INIT(ib_mad_agent_pkey_access,
+		      selinux_ib_mad_agent_pkey_access),
 	LSM_HOOK_INIT(ib_qp_alloc_security,
 		      selinux_ib_qp_alloc_security),
 	LSM_HOOK_INIT(ib_qp_free_security,
diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h
index 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/initial_sid_to_string.h b/security/selinux/include/initial_sid_to_string.h
index a59b64e..8f2eefc 100644
--- a/security/selinux/include/initial_sid_to_string.h
+++ b/security/selinux/include/initial_sid_to_string.h
@@ -29,5 +29,6 @@ static const char *initial_sid_to_string[] =
     "policy",
     "scmp_packet",
     "devnull",
+    "pkey",
 };
 
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..49701a5 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_PKEY;
+	}
+
+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

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

* [PATCH 05/12] selinux: Implement Infiniband PKey "Access" access vector
@ 2016-06-23 19:52     ` Dan Jurgens
  0 siblings, 0 replies; 128+ messages in thread
From: Dan Jurgens @ 2016-06-23 19:52 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 qp_pkey_access
and mad_agent_pkey_access hooks 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>
Reviewed-by: Eli Cohen <eli@mellanox.com>
---
 include/linux/lsm_audit.h                        |  7 ++++
 security/selinux/hooks.c                         | 41 ++++++++++++++++++++++++
 security/selinux/include/classmap.h              |  2 ++
 security/selinux/include/initial_sid_to_string.h |  1 +
 security/selinux/include/security.h              |  2 ++
 security/selinux/ss/services.c                   | 41 ++++++++++++++++++++++++
 6 files changed, 94 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/selinux/hooks.c b/security/selinux/hooks.c
index 4f13ea4..5a40b10 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -6018,6 +6018,44 @@ static void selinux_unregister_ib_flush_callback(void)
 	mutex_unlock(&ib_flush_mutex);
 }
 
+static int selinux_pkey_access(u64 subnet_prefix, u16 pkey_val, void *security)
+{
+	struct common_audit_data ad;
+	int err;
+	u32 sid = 0;
+	struct ib_security_struct *sec = security;
+	struct lsm_pkey_audit pkey;
+
+	err = security_pkey_sid(subnet_prefix, pkey_val, &sid);
+
+	if (err)
+		goto out;
+
+	ad.type = LSM_AUDIT_DATA_PKEY;
+	pkey.subnet_prefix = subnet_prefix;
+	pkey.pkey = pkey_val;
+	ad.u.pkey = &pkey;
+	err = avc_has_perm(sec->sid, sid,
+			   SECCLASS_INFINIBAND_PKEY,
+			   INFINIBAND_PKEY__ACCESS, &ad);
+out:
+	return err;
+}
+
+static int selinux_ib_qp_pkey_access(u64 subnet_prefix, u16 pkey_val,
+				     struct ib_qp_security *qp_sec)
+{
+	return selinux_pkey_access(subnet_prefix, pkey_val,
+				   qp_sec->q_security);
+}
+
+static int selinux_ib_mad_agent_pkey_access(u64 subnet_prefix, u16 pkey_val,
+					    struct ib_mad_agent *mad_agent)
+{
+	return selinux_pkey_access(subnet_prefix, pkey_val,
+					mad_agent->m_security);
+}
+
 static int selinux_ib_qp_alloc_security(struct ib_qp_security *qp_sec)
 {
 	struct ib_security_struct *sec;
@@ -6248,6 +6286,9 @@ static struct security_hook_list selinux_hooks[] = {
 		      selinux_register_ib_flush_callback),
 	LSM_HOOK_INIT(unregister_ib_flush_callback,
 		      selinux_unregister_ib_flush_callback),
+	LSM_HOOK_INIT(ib_qp_pkey_access, selinux_ib_qp_pkey_access),
+	LSM_HOOK_INIT(ib_mad_agent_pkey_access,
+		      selinux_ib_mad_agent_pkey_access),
 	LSM_HOOK_INIT(ib_qp_alloc_security,
 		      selinux_ib_qp_alloc_security),
 	LSM_HOOK_INIT(ib_qp_free_security,
diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h
index 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/initial_sid_to_string.h b/security/selinux/include/initial_sid_to_string.h
index a59b64e..8f2eefc 100644
--- a/security/selinux/include/initial_sid_to_string.h
+++ b/security/selinux/include/initial_sid_to_string.h
@@ -29,5 +29,6 @@ static const char *initial_sid_to_string[] =
     "policy",
     "scmp_packet",
     "devnull",
+    "pkey",
 };
 
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..49701a5 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_PKEY;
+	}
+
+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] 128+ messages in thread

* [PATCH 06/12] selinux: Add IB End Port SMP access vector
  2016-06-23 19:52 ` Dan Jurgens
@ 2016-06-23 19:52     ` Dan Jurgens
  -1 siblings, 0 replies; 128+ messages in thread
From: Dan Jurgens @ 2016-06-23 19:52 UTC (permalink / raw)
  To: chrisw-69jw2NvuJkxg9hUCZPvPmw, paul-r2n+y4ga6xFZroRs9YW3xA,
	sds-+05T5uksL2qpZYMLLGbcSA, eparis-FjpueFixGhCM4zKIHC2jIg,
	dledford-H+wXaHxf7aLQT0dZR+AlfA,
	sean.hefty-ral2JQCrhuEAvxtiuMwx3w,
	hal.rosenstock-Re5JQEeQqe8AvxtiuMwx3w
  Cc: selinux-+05T5uksL2qpZYMLLGbcSA,
	linux-security-module-u79uwXL29TY76Z2rM5mHXA,
	linux-rdma-u79uwXL29TY76Z2rM5mHXA,
	yevgenyp-VPRAkNaXOzVWk0Htik3J/w, Daniel Jurgens

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

Add a type for Infiniband end ports and an access vector for subnet
management packets. Implement the ib_end_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
end port, which walks the IB_END_PORT ocontexts to find an entry for the
given name and port.

Signed-off-by: Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
Reviewed-by: Eli Cohen <eli-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
---
 include/linux/lsm_audit.h                        | 32 +++++++++++-------
 security/selinux/hooks.c                         | 27 +++++++++++++++
 security/selinux/include/classmap.h              |  2 ++
 security/selinux/include/initial_sid_to_string.h |  1 +
 security/selinux/include/security.h              |  2 ++
 security/selinux/ss/services.c                   | 43 ++++++++++++++++++++++++
 6 files changed, 95 insertions(+), 12 deletions(-)

diff --git a/include/linux/lsm_audit.h b/include/linux/lsm_audit.h
index 8ff7eae..acf6de7 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_end_port_audit {
+	char	dev_name[IB_DEVICE_NAME_MAX];
+	u8	port;
+};
+
 /* Auxiliary data to use in generating the audit record. */
 struct common_audit_data {
 	char type;
-#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_END_PORT	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_end_port_audit *ib_end_port;
 	} u;
 	/* this union contains LSM specific data */
 	union {
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 5a40b10..fc44542 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -6056,6 +6056,32 @@ static int selinux_ib_mad_agent_pkey_access(u64 subnet_prefix, u16 pkey_val,
 					mad_agent->m_security);
 }
 
+static int selinux_ib_end_port_smp(const char *dev_name, u8 port,
+				   struct ib_mad_agent *mad_agent)
+{
+	struct common_audit_data ad;
+	int err;
+	u32 sid = 0;
+	struct ib_security_struct *sec = mad_agent->m_security;
+	struct lsm_ib_end_port_audit ib_end_port;
+
+	err = security_ib_end_port_sid(dev_name, port, &sid);
+
+	if (err)
+		goto out;
+
+	ad.type = LSM_AUDIT_DATA_IB_END_PORT;
+	strncpy(ib_end_port.dev_name, dev_name, sizeof(ib_end_port.dev_name));
+	ib_end_port.port = port;
+	ad.u.ib_end_port = &ib_end_port;
+	err = avc_has_perm(sec->sid, sid,
+			   SECCLASS_INFINIBAND_END_PORT,
+			   INFINIBAND_END_PORT__SMP, &ad);
+
+out:
+	return err;
+}
+
 static int selinux_ib_qp_alloc_security(struct ib_qp_security *qp_sec)
 {
 	struct ib_security_struct *sec;
@@ -6289,6 +6315,7 @@ static struct security_hook_list selinux_hooks[] = {
 	LSM_HOOK_INIT(ib_qp_pkey_access, selinux_ib_qp_pkey_access),
 	LSM_HOOK_INIT(ib_mad_agent_pkey_access,
 		      selinux_ib_mad_agent_pkey_access),
+	LSM_HOOK_INIT(ib_end_port_smp, selinux_ib_end_port_smp),
 	LSM_HOOK_INIT(ib_qp_alloc_security,
 		      selinux_ib_qp_alloc_security),
 	LSM_HOOK_INIT(ib_qp_free_security,
diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h
index d42dd4d..21972c8 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_end_port",
+	  { "smp", NULL } },
 	{ NULL }
   };
diff --git a/security/selinux/include/initial_sid_to_string.h b/security/selinux/include/initial_sid_to_string.h
index 8f2eefc..ba47169 100644
--- a/security/selinux/include/initial_sid_to_string.h
+++ b/security/selinux/include/initial_sid_to_string.h
@@ -30,5 +30,6 @@ static const char *initial_sid_to_string[] =
     "scmp_packet",
     "devnull",
     "pkey",
+    "ib_end_port",
 };
 
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index 8f1a66e..f5d9d4e 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_end_port_sid(const char *dev_name, u8 port, u32 *out_sid);
+
 int security_netif_sid(char *name, u32 *if_sid);
 
 int security_node_sid(u16 domain, void *addr, u32 addrlen,
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index 49701a5..9afabee 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -53,6 +53,7 @@
 #include <linux/flex_array.h>
 #include <linux/vmalloc.h>
 #include <net/netlabel.h>
+#include <rdma/ib_verbs.h>
 
 #include "flask.h"
 #include "avc.h"
@@ -2270,6 +2271,48 @@ out:
 }
 
 /**
+ * security_ib_end_port_sid - Obtain the SID for a subnet management interface.
+ * @dev_name: device name
+ * @port: port number
+ * @out_sid: security identifier
+ */
+int security_ib_end_port_sid(const char *dev_name, u8 port, u32 *out_sid)
+{
+	struct ocontext *c;
+	int rc = 0;
+
+	read_lock(&policy_rwlock);
+
+	c = policydb.ocontexts[OCON_IB_END_PORT];
+	while (c) {
+		if (c->u.ib_end_port.port == port &&
+		    !strncmp(c->u.ib_end_port.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_IB_END_PORT;
+	}
+
+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

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

* [PATCH 06/12] selinux: Add IB End Port SMP access vector
@ 2016-06-23 19:52     ` Dan Jurgens
  0 siblings, 0 replies; 128+ messages in thread
From: Dan Jurgens @ 2016-06-23 19:52 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 end ports and an access vector for subnet
management packets. Implement the ib_end_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
end port, which walks the IB_END_PORT ocontexts to find an entry for the
given name and port.

Signed-off-by: Daniel Jurgens <danielj@mellanox.com>
Reviewed-by: Eli Cohen <eli@mellanox.com>
---
 include/linux/lsm_audit.h                        | 32 +++++++++++-------
 security/selinux/hooks.c                         | 27 +++++++++++++++
 security/selinux/include/classmap.h              |  2 ++
 security/selinux/include/initial_sid_to_string.h |  1 +
 security/selinux/include/security.h              |  2 ++
 security/selinux/ss/services.c                   | 43 ++++++++++++++++++++++++
 6 files changed, 95 insertions(+), 12 deletions(-)

diff --git a/include/linux/lsm_audit.h b/include/linux/lsm_audit.h
index 8ff7eae..acf6de7 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_end_port_audit {
+	char	dev_name[IB_DEVICE_NAME_MAX];
+	u8	port;
+};
+
 /* Auxiliary data to use in generating the audit record. */
 struct common_audit_data {
 	char type;
-#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_END_PORT	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_end_port_audit *ib_end_port;
 	} u;
 	/* this union contains LSM specific data */
 	union {
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 5a40b10..fc44542 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -6056,6 +6056,32 @@ static int selinux_ib_mad_agent_pkey_access(u64 subnet_prefix, u16 pkey_val,
 					mad_agent->m_security);
 }
 
+static int selinux_ib_end_port_smp(const char *dev_name, u8 port,
+				   struct ib_mad_agent *mad_agent)
+{
+	struct common_audit_data ad;
+	int err;
+	u32 sid = 0;
+	struct ib_security_struct *sec = mad_agent->m_security;
+	struct lsm_ib_end_port_audit ib_end_port;
+
+	err = security_ib_end_port_sid(dev_name, port, &sid);
+
+	if (err)
+		goto out;
+
+	ad.type = LSM_AUDIT_DATA_IB_END_PORT;
+	strncpy(ib_end_port.dev_name, dev_name, sizeof(ib_end_port.dev_name));
+	ib_end_port.port = port;
+	ad.u.ib_end_port = &ib_end_port;
+	err = avc_has_perm(sec->sid, sid,
+			   SECCLASS_INFINIBAND_END_PORT,
+			   INFINIBAND_END_PORT__SMP, &ad);
+
+out:
+	return err;
+}
+
 static int selinux_ib_qp_alloc_security(struct ib_qp_security *qp_sec)
 {
 	struct ib_security_struct *sec;
@@ -6289,6 +6315,7 @@ static struct security_hook_list selinux_hooks[] = {
 	LSM_HOOK_INIT(ib_qp_pkey_access, selinux_ib_qp_pkey_access),
 	LSM_HOOK_INIT(ib_mad_agent_pkey_access,
 		      selinux_ib_mad_agent_pkey_access),
+	LSM_HOOK_INIT(ib_end_port_smp, selinux_ib_end_port_smp),
 	LSM_HOOK_INIT(ib_qp_alloc_security,
 		      selinux_ib_qp_alloc_security),
 	LSM_HOOK_INIT(ib_qp_free_security,
diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h
index d42dd4d..21972c8 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_end_port",
+	  { "smp", NULL } },
 	{ NULL }
   };
diff --git a/security/selinux/include/initial_sid_to_string.h b/security/selinux/include/initial_sid_to_string.h
index 8f2eefc..ba47169 100644
--- a/security/selinux/include/initial_sid_to_string.h
+++ b/security/selinux/include/initial_sid_to_string.h
@@ -30,5 +30,6 @@ static const char *initial_sid_to_string[] =
     "scmp_packet",
     "devnull",
     "pkey",
+    "ib_end_port",
 };
 
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index 8f1a66e..f5d9d4e 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_end_port_sid(const char *dev_name, u8 port, u32 *out_sid);
+
 int security_netif_sid(char *name, u32 *if_sid);
 
 int security_node_sid(u16 domain, void *addr, u32 addrlen,
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index 49701a5..9afabee 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -53,6 +53,7 @@
 #include <linux/flex_array.h>
 #include <linux/vmalloc.h>
 #include <net/netlabel.h>
+#include <rdma/ib_verbs.h>
 
 #include "flask.h"
 #include "avc.h"
@@ -2270,6 +2271,48 @@ out:
 }
 
 /**
+ * security_ib_end_port_sid - Obtain the SID for a subnet management interface.
+ * @dev_name: device name
+ * @port: port number
+ * @out_sid: security identifier
+ */
+int security_ib_end_port_sid(const char *dev_name, u8 port, u32 *out_sid)
+{
+	struct ocontext *c;
+	int rc = 0;
+
+	read_lock(&policy_rwlock);
+
+	c = policydb.ocontexts[OCON_IB_END_PORT];
+	while (c) {
+		if (c->u.ib_end_port.port == port &&
+		    !strncmp(c->u.ib_end_port.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_IB_END_PORT;
+	}
+
+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] 128+ messages in thread

* [PATCH 07/12] selinux: Add a cache for quicker retreival of PKey SIDs
  2016-06-23 19:52 ` Dan Jurgens
@ 2016-06-23 19:52     ` Dan Jurgens
  -1 siblings, 0 replies; 128+ messages in thread
From: Dan Jurgens @ 2016-06-23 19:52 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>
Reviewed-by: Eli Cohen <eli-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
---
 security/selinux/Makefile         |   2 +-
 security/selinux/hooks.c          |   5 +-
 security/selinux/include/objsec.h |   6 +
 security/selinux/include/pkey.h   |  31 +++++
 security/selinux/pkey.c           | 243 ++++++++++++++++++++++++++++++++++++++
 5 files changed, 285 insertions(+), 2 deletions(-)
 create mode 100644 security/selinux/include/pkey.h
 create mode 100644 security/selinux/pkey.c

diff --git a/security/selinux/Makefile b/security/selinux/Makefile
index 3411c33..a698df4 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 pkey.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 fc44542..5c8cebb 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -92,6 +92,7 @@
 #include "netif.h"
 #include "netnode.h"
 #include "netport.h"
+#include "pkey.h"
 #include "xfrm.h"
 #include "netlabel.h"
 #include "audit.h"
@@ -172,6 +173,8 @@ static int selinux_cache_avc_callback(u32 event)
 		sel_netnode_flush();
 		sel_netport_flush();
 		synchronize_net();
+
+		sel_pkey_flush();
 		mutex_lock(&ib_flush_mutex);
 		if (ib_flush_callback)
 			ib_flush_callback();
@@ -6026,7 +6029,7 @@ static int selinux_pkey_access(u64 subnet_prefix, u16 pkey_val, void *security)
 	struct ib_security_struct *sec = security;
 	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)
 		goto out;
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_ */
diff --git a/security/selinux/include/pkey.h b/security/selinux/include/pkey.h
new file mode 100644
index 0000000..58a7a3b
--- /dev/null
+++ b/security/selinux/include/pkey.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_H
+#define _SELINUX_IB_H
+
+void sel_pkey_flush(void);
+
+int sel_pkey_sid(u64 subnet_prefix, u16 pkey, u32 *sid);
+
+#endif
diff --git a/security/selinux/pkey.c b/security/selinux/pkey.c
new file mode 100644
index 0000000..565474d
--- /dev/null
+++ b/security/selinux/pkey.c
@@ -0,0 +1,243 @@
+/*
+ * 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 "pkey.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;
+
+	spin_lock_bh(&sel_pkey_lock);
+	pkey = sel_pkey_find(subnet_prefix, pkey_num);
+	if (pkey) {
+		*sid = pkey->psec.sid;
+		spin_unlock_bh(&sel_pkey_lock);
+		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_bh(&sel_pkey_lock);
+	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;
+
+	spin_lock_bh(&sel_pkey_lock);
+	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_bh(&sel_pkey_lock);
+}
+
+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);
-- 
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] 128+ messages in thread

* [PATCH 07/12] selinux: Add a cache for quicker retreival of PKey SIDs
@ 2016-06-23 19:52     ` Dan Jurgens
  0 siblings, 0 replies; 128+ messages in thread
From: Dan Jurgens @ 2016-06-23 19:52 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>
Reviewed-by: Eli Cohen <eli@mellanox.com>
---
 security/selinux/Makefile         |   2 +-
 security/selinux/hooks.c          |   5 +-
 security/selinux/include/objsec.h |   6 +
 security/selinux/include/pkey.h   |  31 +++++
 security/selinux/pkey.c           | 243 ++++++++++++++++++++++++++++++++++++++
 5 files changed, 285 insertions(+), 2 deletions(-)
 create mode 100644 security/selinux/include/pkey.h
 create mode 100644 security/selinux/pkey.c

diff --git a/security/selinux/Makefile b/security/selinux/Makefile
index 3411c33..a698df4 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 pkey.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 fc44542..5c8cebb 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -92,6 +92,7 @@
 #include "netif.h"
 #include "netnode.h"
 #include "netport.h"
+#include "pkey.h"
 #include "xfrm.h"
 #include "netlabel.h"
 #include "audit.h"
@@ -172,6 +173,8 @@ static int selinux_cache_avc_callback(u32 event)
 		sel_netnode_flush();
 		sel_netport_flush();
 		synchronize_net();
+
+		sel_pkey_flush();
 		mutex_lock(&ib_flush_mutex);
 		if (ib_flush_callback)
 			ib_flush_callback();
@@ -6026,7 +6029,7 @@ static int selinux_pkey_access(u64 subnet_prefix, u16 pkey_val, void *security)
 	struct ib_security_struct *sec = security;
 	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)
 		goto out;
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_ */
diff --git a/security/selinux/include/pkey.h b/security/selinux/include/pkey.h
new file mode 100644
index 0000000..58a7a3b
--- /dev/null
+++ b/security/selinux/include/pkey.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_H
+#define _SELINUX_IB_H
+
+void sel_pkey_flush(void);
+
+int sel_pkey_sid(u64 subnet_prefix, u16 pkey, u32 *sid);
+
+#endif
diff --git a/security/selinux/pkey.c b/security/selinux/pkey.c
new file mode 100644
index 0000000..565474d
--- /dev/null
+++ b/security/selinux/pkey.c
@@ -0,0 +1,243 @@
+/*
+ * 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 "pkey.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;
+
+	spin_lock_bh(&sel_pkey_lock);
+	pkey = sel_pkey_find(subnet_prefix, pkey_num);
+	if (pkey) {
+		*sid = pkey->psec.sid;
+		spin_unlock_bh(&sel_pkey_lock);
+		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_bh(&sel_pkey_lock);
+	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;
+
+	spin_lock_bh(&sel_pkey_lock);
+	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_bh(&sel_pkey_lock);
+}
+
+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);
-- 
1.8.3.1

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

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

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

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

Also removed an unneded pr_warn about memory allocation failure.

Signed-off-by: Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
Reviewed-by: Eli Cohen <eli-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
Reviewed-by: Leon Romanovsky <leonro-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
---
 drivers/infiniband/core/cache.c     | 35 +++++++++++++++++++++++++++++++++--
 drivers/infiniband/core/core_priv.h |  3 +++
 include/rdma/ib_verbs.h             |  1 +
 3 files changed, 37 insertions(+), 2 deletions(-)

diff --git a/drivers/infiniband/core/cache.c b/drivers/infiniband/core/cache.c
index c2e257d..4894e21 100644
--- a/drivers/infiniband/core/cache.c
+++ b/drivers/infiniband/core/cache.c
@@ -926,6 +926,25 @@ 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 = port_num - rdma_start_port(device);
+
+	if (port_num < rdma_start_port(device) ||
+	    port_num > rdma_end_port(device))
+		return -EINVAL;
+
+	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,
@@ -1102,6 +1121,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);
@@ -1160,9 +1181,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;
 	}
 
@@ -1205,6 +1235,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 e522acb..c00b6b1 100644
--- a/include/rdma/ib_verbs.h
+++ b/include/rdma/ib_verbs.h
@@ -1637,6 +1637,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

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

* [PATCH 08/12] IB/core: IB cache enhancements to support Infiniband security
@ 2016-06-23 19:52     ` Dan Jurgens
  0 siblings, 0 replies; 128+ messages in thread
From: Dan Jurgens @ 2016-06-23 19:52 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>
---
 drivers/infiniband/core/cache.c     | 35 +++++++++++++++++++++++++++++++++--
 drivers/infiniband/core/core_priv.h |  3 +++
 include/rdma/ib_verbs.h             |  1 +
 3 files changed, 37 insertions(+), 2 deletions(-)

diff --git a/drivers/infiniband/core/cache.c b/drivers/infiniband/core/cache.c
index c2e257d..4894e21 100644
--- a/drivers/infiniband/core/cache.c
+++ b/drivers/infiniband/core/cache.c
@@ -926,6 +926,25 @@ 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 = port_num - rdma_start_port(device);
+
+	if (port_num < rdma_start_port(device) ||
+	    port_num > rdma_end_port(device))
+		return -EINVAL;
+
+	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,
@@ -1102,6 +1121,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);
@@ -1160,9 +1181,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;
 	}
 
@@ -1205,6 +1235,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 e522acb..c00b6b1 100644
--- a/include/rdma/ib_verbs.h
+++ b/include/rdma/ib_verbs.h
@@ -1637,6 +1637,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] 128+ messages in thread

* [PATCH 09/12] IB/core: Enforce PKey security on QPs
  2016-06-23 19:52 ` Dan Jurgens
@ 2016-06-23 19:52     ` Dan Jurgens
  -1 siblings, 0 replies; 128+ messages in thread
From: Dan Jurgens @ 2016-06-23 19:52 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 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>
Reviewed-by: Leon Romanovsky <leonro-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
---
 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      |  29 +-
 include/rdma/ib_verbs.h              |  45 ++-
 8 files changed, 835 insertions(+), 10 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 4894e21..dde09e9 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;
@@ -1037,7 +1038,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;
@@ -1125,6 +1127,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);
@@ -1141,7 +1148,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);
 }
 
@@ -1162,6 +1171,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);
 		}
 	}
@@ -1202,7 +1217,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 5516fb0..63deb5c 100644
--- a/drivers/infiniband/core/device.c
+++ b/drivers/infiniband/core/device.c
@@ -311,6 +311,30 @@ static int read_port_immutable(struct ib_device *device)
 	return 0;
 }
 
+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
@@ -348,6 +372,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");
@@ -418,6 +448,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..71a72e7
--- /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 *sec)
+{
+	struct ib_qp_security *shared_qp_sec;
+	int ret = 0;
+
+	ret = security_ib_qp_pkey_access(subnet_prefix, pkey, sec);
+	if (ret)
+		return ret;
+
+	if (sec->qp == sec->qp->real_qp) {
+		list_for_each_entry(shared_qp_sec,
+				    &sec->shared_qp_list,
+				    shared_qp_list) {
+			ret = security_ib_qp_pkey_access(subnet_prefix,
+							 pkey,
+							 shared_qp_sec);
+			if (ret)
+				break;
+		}
+	}
+	return ret;
+}
+
+/* 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_qp_free_security(sec);
+	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_qp_alloc_security(qp->qp_sec);
+	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 1a8babb..c16110c 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"
@@ -1858,6 +1858,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;
@@ -2340,10 +2344,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 1d7d4cf..b812806 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;
@@ -767,6 +776,10 @@ 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)
+		goto destroy_qp;
+
 	qp->device     = device;
 	qp->real_qp    = qp;
 	qp->uobject    = NULL;
@@ -811,6 +824,10 @@ struct ib_qp *ib_create_qp(struct ib_pd *pd,
 	}
 
 	return qp;
+
+destroy_qp:
+	ib_destroy_qp(qp);
+	return ERR_PTR(ret);
 }
 EXPORT_SYMBOL(ib_create_qp);
 
@@ -1211,7 +1228,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);
 
@@ -1240,6 +1257,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;
@@ -1279,6 +1297,7 @@ int ib_destroy_qp(struct ib_qp *qp)
 	struct ib_pd *pd;
 	struct ib_cq *scq, *rcq;
 	struct ib_srq *srq;
+	struct ib_qp_security *sec;
 	int ret;
 
 	WARN_ON_ONCE(qp->mrs_used > 0);
@@ -1293,6 +1312,9 @@ int ib_destroy_qp(struct ib_qp *qp)
 	scq  = qp->send_cq;
 	rcq  = qp->recv_cq;
 	srq  = qp->srq;
+	sec  = qp->qp_sec;
+	if (sec)
+		ib_destroy_qp_security_begin(sec);
 
 	if (!qp->uobject)
 		rdma_rw_cleanup_mrs(qp);
@@ -1307,6 +1329,11 @@ int ib_destroy_qp(struct ib_qp *qp)
 			atomic_dec(&rcq->usecnt);
 		if (srq)
 			atomic_dec(&srq->usecnt);
+		if (sec)
+			ib_destroy_qp_security_end(sec);
+	} else {
+		if (sec)
+			ib_destroy_qp_security_abort(sec);
 	}
 
 	return ret;
diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
index c00b6b1..0daa867 100644
--- a/include/rdma/ib_verbs.h
+++ b/include/rdma/ib_verbs.h
@@ -1428,8 +1428,43 @@ struct ib_srq {
 	} ext;
 };
 
+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 {
-	void *q_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                   *q_security;
+	bool			destroying;
+	atomic_t		error_list_count;
+	struct completion	error_complete;
+	int			error_comps_pending;
 };
 
 struct ib_qp {
@@ -1688,6 +1723,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;
 
@@ -1710,6 +1751,8 @@ struct ib_device {
 
 	int			      num_comp_vectors;
 
+	struct ib_port_pkey_list     *port_pkey_list;
+
 	struct iw_cm_verbs	     *iwcm;
 
 	/**
-- 
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] 128+ messages in thread

* [PATCH 09/12] IB/core: Enforce PKey security on QPs
@ 2016-06-23 19:52     ` Dan Jurgens
  0 siblings, 0 replies; 128+ messages in thread
From: Dan Jurgens @ 2016-06-23 19:52 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 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>
Reviewed-by: Leon Romanovsky <leonro@mellanox.com>
---
 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      |  29 +-
 include/rdma/ib_verbs.h              |  45 ++-
 8 files changed, 835 insertions(+), 10 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 4894e21..dde09e9 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;
@@ -1037,7 +1038,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;
@@ -1125,6 +1127,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);
@@ -1141,7 +1148,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);
 }
 
@@ -1162,6 +1171,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);
 		}
 	}
@@ -1202,7 +1217,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 5516fb0..63deb5c 100644
--- a/drivers/infiniband/core/device.c
+++ b/drivers/infiniband/core/device.c
@@ -311,6 +311,30 @@ static int read_port_immutable(struct ib_device *device)
 	return 0;
 }
 
+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
@@ -348,6 +372,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");
@@ -418,6 +448,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..71a72e7
--- /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 *sec)
+{
+	struct ib_qp_security *shared_qp_sec;
+	int ret = 0;
+
+	ret = security_ib_qp_pkey_access(subnet_prefix, pkey, sec);
+	if (ret)
+		return ret;
+
+	if (sec->qp == sec->qp->real_qp) {
+		list_for_each_entry(shared_qp_sec,
+				    &sec->shared_qp_list,
+				    shared_qp_list) {
+			ret = security_ib_qp_pkey_access(subnet_prefix,
+							 pkey,
+							 shared_qp_sec);
+			if (ret)
+				break;
+		}
+	}
+	return ret;
+}
+
+/* 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_qp_free_security(sec);
+	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_qp_alloc_security(qp->qp_sec);
+	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 1a8babb..c16110c 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"
@@ -1858,6 +1858,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;
@@ -2340,10 +2344,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 1d7d4cf..b812806 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;
@@ -767,6 +776,10 @@ 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)
+		goto destroy_qp;
+
 	qp->device     = device;
 	qp->real_qp    = qp;
 	qp->uobject    = NULL;
@@ -811,6 +824,10 @@ struct ib_qp *ib_create_qp(struct ib_pd *pd,
 	}
 
 	return qp;
+
+destroy_qp:
+	ib_destroy_qp(qp);
+	return ERR_PTR(ret);
 }
 EXPORT_SYMBOL(ib_create_qp);
 
@@ -1211,7 +1228,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);
 
@@ -1240,6 +1257,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;
@@ -1279,6 +1297,7 @@ int ib_destroy_qp(struct ib_qp *qp)
 	struct ib_pd *pd;
 	struct ib_cq *scq, *rcq;
 	struct ib_srq *srq;
+	struct ib_qp_security *sec;
 	int ret;
 
 	WARN_ON_ONCE(qp->mrs_used > 0);
@@ -1293,6 +1312,9 @@ int ib_destroy_qp(struct ib_qp *qp)
 	scq  = qp->send_cq;
 	rcq  = qp->recv_cq;
 	srq  = qp->srq;
+	sec  = qp->qp_sec;
+	if (sec)
+		ib_destroy_qp_security_begin(sec);
 
 	if (!qp->uobject)
 		rdma_rw_cleanup_mrs(qp);
@@ -1307,6 +1329,11 @@ int ib_destroy_qp(struct ib_qp *qp)
 			atomic_dec(&rcq->usecnt);
 		if (srq)
 			atomic_dec(&srq->usecnt);
+		if (sec)
+			ib_destroy_qp_security_end(sec);
+	} else {
+		if (sec)
+			ib_destroy_qp_security_abort(sec);
 	}
 
 	return ret;
diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
index c00b6b1..0daa867 100644
--- a/include/rdma/ib_verbs.h
+++ b/include/rdma/ib_verbs.h
@@ -1428,8 +1428,43 @@ struct ib_srq {
 	} ext;
 };
 
+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 {
-	void *q_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                   *q_security;
+	bool			destroying;
+	atomic_t		error_list_count;
+	struct completion	error_complete;
+	int			error_comps_pending;
 };
 
 struct ib_qp {
@@ -1688,6 +1723,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;
 
@@ -1710,6 +1751,8 @@ struct ib_device {
 
 	int			      num_comp_vectors;
 
+	struct ib_port_pkey_list     *port_pkey_list;
+
 	struct iw_cm_verbs	     *iwcm;
 
 	/**
-- 
1.8.3.1

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

* [PATCH 10/12] IB/core: Enforce PKey security on management datagrams
  2016-06-23 19:52 ` Dan Jurgens
                   ` (2 preceding siblings ...)
  (?)
@ 2016-06-23 19:52 ` Dan Jurgens
  -1 siblings, 0 replies; 128+ messages in thread
From: Dan Jurgens @ 2016-06-23 19:52 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.

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

Signed-off-by: Daniel Jurgens <danielj@mellanox.com>
Reviewed-by: Eli Cohen <eli@mellanox.com>
Reviewed-by: Leon Romanovsky <leonro@mellanox.com>
---
 drivers/infiniband/core/core_priv.h | 13 ++++++++
 drivers/infiniband/core/mad.c       | 63 ++++++++++++++++++++++++++++++++-----
 drivers/infiniband/core/security.c  | 24 ++++++++++++++
 3 files changed, 93 insertions(+), 7 deletions(-)

diff --git a/drivers/infiniband/core/core_priv.h b/drivers/infiniband/core/core_priv.h
index 68e3de0..8ab8d58 100644
--- a/drivers/infiniband/core/core_priv.h
+++ b/drivers/infiniband/core/core_priv.h
@@ -166,6 +166,11 @@ int ib_get_cached_subnet_prefix(struct ib_device *device,
 				u64              *sn_pfx);
 
 #ifdef CONFIG_SECURITY_INFINIBAND
+int ib_security_ma_pkey_access(struct ib_device *dev,
+			       u8 port_num,
+			       u16 pkey_index,
+			       struct ib_mad_agent *mad_agent);
+
 void ib_security_destroy_port_pkey_list(struct ib_device *device);
 
 void ib_security_cache_change(struct ib_device *device,
@@ -184,6 +189,14 @@ 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 int ib_security_ma_pkey_access(struct ib_device *dev,
+					     u8 port_num,
+					     u16 pkey_index,
+					     struct ib_mad_agent *mad_agent)
+{
+	return 0;
+}
+
 static inline void ib_security_destroy_port_pkey_list(struct ib_device *device)
 {
 }
diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c
index 82fb511..975b472 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"
@@ -337,11 +339,17 @@ struct ib_mad_agent *ib_register_mad_agent(struct ib_device *device,
 		goto error1;
 	}
 
+	ret2 = security_ib_mad_agent_alloc_security(&mad_agent_priv->agent);
+	if (ret2) {
+		ret = ERR_PTR(ret2);
+		goto error3;
+	}
+
 	if (mad_reg_req) {
 		reg_req = kmemdup(mad_reg_req, sizeof *reg_req, GFP_KERNEL);
 		if (!reg_req) {
 			ret = ERR_PTR(-ENOMEM);
-			goto error3;
+			goto error4;
 		}
 	}
 
@@ -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;
 		}
 	}
 
@@ -417,9 +425,11 @@ struct ib_mad_agent *ib_register_mad_agent(struct ib_device *device,
 
 	return &mad_agent_priv->agent;
 
-error4:
+error5:
 	spin_unlock_irqrestore(&port_priv->reg_lock, flags);
 	kfree(reg_req);
+error4:
+	security_ib_mad_agent_free_security(&mad_agent_priv->agent);
 error3:
 	kfree(mad_agent_priv);
 error1:
@@ -489,6 +499,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) ||
@@ -513,6 +524,13 @@ struct ib_mad_agent *ib_register_mad_snoop(struct ib_device *device,
 		goto error1;
 	}
 
+	err = security_ib_mad_agent_alloc_security(&mad_snoop_priv->agent);
+
+	if (err) {
+		ret = ERR_PTR(err);
+		goto error2;
+	}
+
 	/* Now, fill in the various structures */
 	mad_snoop_priv->qp_info = &port_priv->qp_info[qpn];
 	mad_snoop_priv->agent.device = device;
@@ -523,17 +541,19 @@ 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);
+
 	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:
+	security_ib_mad_agent_free_security(&mad_snoop_priv->agent);
 error2:
 	kfree(mad_snoop_priv);
 error1:
@@ -579,6 +599,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);
 
+	security_ib_mad_agent_free_security(&mad_agent_priv->agent);
+
 	kfree(mad_agent_priv->reg_req);
 	kfree(mad_agent_priv);
 }
@@ -597,6 +619,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);
 
+	security_ib_mad_agent_free_security(&mad_snoop_priv->agent);
+
 	kfree(mad_snoop_priv);
 }
 
@@ -1216,6 +1240,7 @@ int ib_post_send_mad(struct ib_mad_send_buf *send_buf,
 	struct ib_mad_send_wr_private *mad_send_wr;
 	unsigned long flags;
 	int ret = -EINVAL;
+	u16 pkey_index;
 
 	/* Walk list of send WRs and post each on send list */
 	for (; send_buf; send_buf = next_send_buf) {
@@ -1224,6 +1249,15 @@ int ib_post_send_mad(struct ib_mad_send_buf *send_buf,
 					   struct ib_mad_send_wr_private,
 					   send_buf);
 		mad_agent_priv = mad_send_wr->mad_agent_priv;
+		pkey_index = mad_send_wr->send_wr.pkey_index;
+
+		ret = ib_security_ma_pkey_access(mad_agent_priv->agent.device,
+						 mad_agent_priv->agent.port_num,
+						 pkey_index,
+						 &mad_agent_priv->agent);
+
+		if (ret)
+			goto error;
 
 		if (!send_buf->mad_agent->send_handler ||
 		    (send_buf->timeout_ms &&
@@ -1958,6 +1992,15 @@ 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_security_ma_pkey_access(mad_agent_priv->agent.device,
+					 mad_agent_priv->agent.port_num,
+					 mad_recv_wc->wc->pkey_index,
+					 &mad_agent_priv->agent);
+
+	if (ret)
+		goto security_error;
 
 	INIT_LIST_HEAD(&mad_recv_wc->rmpp_list);
 	list_add(&mad_recv_wc->recv_buf.list, &mad_recv_wc->rmpp_list);
@@ -2015,6 +2058,12 @@ static void ib_mad_complete_recv(struct ib_mad_agent_private *mad_agent_priv,
 						   mad_recv_wc);
 		deref_mad_agent(mad_agent_priv);
 	}
+
+	return;
+
+security_error:
+	ib_free_recv_mad(mad_recv_wc);
+	deref_mad_agent(mad_agent_priv);
 }
 
 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 71a72e7..f88b328 100644
--- a/drivers/infiniband/core/security.c
+++ b/drivers/infiniband/core/security.c
@@ -614,4 +614,28 @@ int ib_security_modify_qp(struct ib_qp *qp,
 }
 EXPORT_SYMBOL(ib_security_modify_qp);
 
+int ib_security_ma_pkey_access(struct ib_device *dev,
+			       u8 port_num,
+			       u16 pkey_index,
+			       struct ib_mad_agent *mad_agent)
+{
+	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_mad_agent_pkey_access(subnet_prefix,
+						 pkey,
+						 mad_agent);
+}
+EXPORT_SYMBOL(ib_security_ma_pkey_access);
+
 #endif /* CONFIG_SECURITY_INFINIBAND */
-- 
1.8.3.1


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

* [PATCH 11/12] IB/core: Enforce Infiniband device SMI security
  2016-06-23 19:52 ` Dan Jurgens
@ 2016-06-23 19:52     ` Dan Jurgens
  -1 siblings, 0 replies; 128+ messages in thread
From: Dan Jurgens @ 2016-06-23 19:52 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>

During MAD and snoop agent registration for SMI QPs check that the
calling process has permission to access the SMI.

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>
Reviewed-by: Eli Cohen <eli-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
Reviewed-by: Leon Romanovsky <leonro-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
---
 drivers/infiniband/core/mad.c | 44 ++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 43 insertions(+), 1 deletion(-)

diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c
index 975b472..684dcac 100644
--- a/drivers/infiniband/core/mad.c
+++ b/drivers/infiniband/core/mad.c
@@ -345,6 +345,16 @@ struct ib_mad_agent *ib_register_mad_agent(struct ib_device *device,
 		goto error3;
 	}
 
+	if (qp_type == IB_QPT_SMI) {
+		ret2 = security_ib_end_port_smp(device->name,
+						port_num,
+						&mad_agent_priv->agent);
+		if (ret2) {
+			ret = ERR_PTR(ret2);
+			goto error4;
+		}
+	}
+
 	if (mad_reg_req) {
 		reg_req = kmemdup(mad_reg_req, sizeof *reg_req, GFP_KERNEL);
 		if (!reg_req) {
@@ -531,6 +541,17 @@ struct ib_mad_agent *ib_register_mad_snoop(struct ib_device *device,
 		goto error2;
 	}
 
+	if (qp_type == IB_QPT_SMI) {
+		err = security_ib_end_port_smp(device->name,
+					       port_num,
+					       &mad_snoop_priv->agent);
+
+		if (err) {
+			ret = ERR_PTR(err);
+			goto error3;
+		}
+	}
+
 	/* Now, fill in the various structures */
 	mad_snoop_priv->qp_info = &port_priv->qp_info[qpn];
 	mad_snoop_priv->agent.device = device;
@@ -1244,6 +1265,7 @@ 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) {
+		int err = 0;
 
 		mad_send_wr = container_of(send_buf,
 					   struct ib_mad_send_wr_private,
@@ -1251,6 +1273,17 @@ int ib_post_send_mad(struct ib_mad_send_buf *send_buf,
 		mad_agent_priv = mad_send_wr->mad_agent_priv;
 		pkey_index = mad_send_wr->send_wr.pkey_index;
 
+		if (mad_agent_priv->agent.qp->qp_type == IB_QPT_SMI)
+			err = security_ib_end_port_smp(
+					mad_agent_priv->agent.device->name,
+					mad_agent_priv->agent.port_num,
+					&mad_agent_priv->agent);
+
+		if (err) {
+			ret = err;
+			goto error;
+		}
+
 		ret = ib_security_ma_pkey_access(mad_agent_priv->agent.device,
 						 mad_agent_priv->agent.port_num,
 						 pkey_index,
@@ -1992,7 +2025,16 @@ 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;
+	int ret = 0;
+
+	if (mad_agent_priv->agent.qp->qp_type == IB_QPT_SMI)
+		ret = security_ib_end_port_smp(
+					mad_agent_priv->agent.device->name,
+					mad_agent_priv->agent.port_num,
+					&mad_agent_priv->agent);
+
+	if (ret)
+		goto security_error;
 
 	ret = ib_security_ma_pkey_access(mad_agent_priv->agent.device,
 					 mad_agent_priv->agent.port_num,
-- 
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] 128+ messages in thread

* [PATCH 11/12] IB/core: Enforce Infiniband device SMI security
@ 2016-06-23 19:52     ` Dan Jurgens
  0 siblings, 0 replies; 128+ messages in thread
From: Dan Jurgens @ 2016-06-23 19:52 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>

During MAD and snoop agent registration for SMI QPs check that the
calling process has permission to access the SMI.

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>
Reviewed-by: Eli Cohen <eli@mellanox.com>
Reviewed-by: Leon Romanovsky <leonro@mellanox.com>
---
 drivers/infiniband/core/mad.c | 44 ++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 43 insertions(+), 1 deletion(-)

diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c
index 975b472..684dcac 100644
--- a/drivers/infiniband/core/mad.c
+++ b/drivers/infiniband/core/mad.c
@@ -345,6 +345,16 @@ struct ib_mad_agent *ib_register_mad_agent(struct ib_device *device,
 		goto error3;
 	}
 
+	if (qp_type == IB_QPT_SMI) {
+		ret2 = security_ib_end_port_smp(device->name,
+						port_num,
+						&mad_agent_priv->agent);
+		if (ret2) {
+			ret = ERR_PTR(ret2);
+			goto error4;
+		}
+	}
+
 	if (mad_reg_req) {
 		reg_req = kmemdup(mad_reg_req, sizeof *reg_req, GFP_KERNEL);
 		if (!reg_req) {
@@ -531,6 +541,17 @@ struct ib_mad_agent *ib_register_mad_snoop(struct ib_device *device,
 		goto error2;
 	}
 
+	if (qp_type == IB_QPT_SMI) {
+		err = security_ib_end_port_smp(device->name,
+					       port_num,
+					       &mad_snoop_priv->agent);
+
+		if (err) {
+			ret = ERR_PTR(err);
+			goto error3;
+		}
+	}
+
 	/* Now, fill in the various structures */
 	mad_snoop_priv->qp_info = &port_priv->qp_info[qpn];
 	mad_snoop_priv->agent.device = device;
@@ -1244,6 +1265,7 @@ 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) {
+		int err = 0;
 
 		mad_send_wr = container_of(send_buf,
 					   struct ib_mad_send_wr_private,
@@ -1251,6 +1273,17 @@ int ib_post_send_mad(struct ib_mad_send_buf *send_buf,
 		mad_agent_priv = mad_send_wr->mad_agent_priv;
 		pkey_index = mad_send_wr->send_wr.pkey_index;
 
+		if (mad_agent_priv->agent.qp->qp_type == IB_QPT_SMI)
+			err = security_ib_end_port_smp(
+					mad_agent_priv->agent.device->name,
+					mad_agent_priv->agent.port_num,
+					&mad_agent_priv->agent);
+
+		if (err) {
+			ret = err;
+			goto error;
+		}
+
 		ret = ib_security_ma_pkey_access(mad_agent_priv->agent.device,
 						 mad_agent_priv->agent.port_num,
 						 pkey_index,
@@ -1992,7 +2025,16 @@ 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;
+	int ret = 0;
+
+	if (mad_agent_priv->agent.qp->qp_type == IB_QPT_SMI)
+		ret = security_ib_end_port_smp(
+					mad_agent_priv->agent.device->name,
+					mad_agent_priv->agent.port_num,
+					&mad_agent_priv->agent);
+
+	if (ret)
+		goto security_error;
 
 	ret = ib_security_ma_pkey_access(mad_agent_priv->agent.device,
 					 mad_agent_priv->agent.port_num,
-- 
1.8.3.1

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

* [PATCH 12/12] IB/core: Implement the Infiniband flush callback
  2016-06-23 19:52 ` Dan Jurgens
@ 2016-06-23 19:52     ` Dan Jurgens
  -1 siblings, 0 replies; 128+ messages in thread
From: Dan Jurgens @ 2016-06-23 19:52 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>

Register the callback at init and unregister it at cleanup.

When called walk the device list and call ib_security_cache_change for
each port on each device.

Signed-off-by: Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
Reviewed-by: Eli Cohen <eli-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
Reviewed-by: Leon Romanovsky <leonro-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
---
 drivers/infiniband/core/device.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c
index 63deb5c..5060a7f 100644
--- a/drivers/infiniband/core/device.c
+++ b/drivers/infiniband/core/device.c
@@ -335,6 +335,29 @@ static int setup_port_pkey_list(struct ib_device *device)
 	return 0;
 }
 
+static void ib_security_flush(void)
+{
+	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);
+}
+
 /**
  * ib_register_device - Register an IB device with IB core
  * @device:Device to register
@@ -1062,6 +1085,8 @@ static int __init ib_core_init(void)
 		goto err_sa;
 	}
 
+	security_register_ib_flush_callback(&ib_security_flush);
+
 	ib_cache_setup();
 
 	return 0;
@@ -1085,6 +1110,7 @@ err:
 
 static void __exit ib_core_cleanup(void)
 {
+	security_unregister_ib_flush_callback();
 	ib_cache_cleanup();
 	ib_remove_ibnl_clients();
 	ib_sa_cleanup();
-- 
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] 128+ messages in thread

* [PATCH 12/12] IB/core: Implement the Infiniband flush callback
@ 2016-06-23 19:52     ` Dan Jurgens
  0 siblings, 0 replies; 128+ messages in thread
From: Dan Jurgens @ 2016-06-23 19:52 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>

Register the callback at init and unregister it at cleanup.

When called walk the device list and call ib_security_cache_change for
each port on each device.

Signed-off-by: Daniel Jurgens <danielj@mellanox.com>
Reviewed-by: Eli Cohen <eli@mellanox.com>
Reviewed-by: Leon Romanovsky <leonro@mellanox.com>
---
 drivers/infiniband/core/device.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c
index 63deb5c..5060a7f 100644
--- a/drivers/infiniband/core/device.c
+++ b/drivers/infiniband/core/device.c
@@ -335,6 +335,29 @@ static int setup_port_pkey_list(struct ib_device *device)
 	return 0;
 }
 
+static void ib_security_flush(void)
+{
+	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);
+}
+
 /**
  * ib_register_device - Register an IB device with IB core
  * @device:Device to register
@@ -1062,6 +1085,8 @@ static int __init ib_core_init(void)
 		goto err_sa;
 	}
 
+	security_register_ib_flush_callback(&ib_security_flush);
+
 	ib_cache_setup();
 
 	return 0;
@@ -1085,6 +1110,7 @@ err:
 
 static void __exit ib_core_cleanup(void)
 {
+	security_unregister_ib_flush_callback();
 	ib_cache_cleanup();
 	ib_remove_ibnl_clients();
 	ib_sa_cleanup();
-- 
1.8.3.1

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

* Re: [PATCH 07/12] selinux: Add a cache for quicker retreival of PKey SIDs
  2016-06-23 19:52     ` Dan Jurgens
@ 2016-06-23 21:59         ` kbuild test robot
  -1 siblings, 0 replies; 128+ messages in thread
From: kbuild test robot @ 2016-06-23 21:59 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

Hi,

[auto build test WARNING on rdma/master]
[also build test WARNING on v4.7-rc4]
[cannot apply to pcmoore-selinux/next next-20160623]
[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/20160624-035944
base:   https://git.kernel.org/pub/scm/linux/kernel/git/dledford/rdma master
reproduce:
        # apt-get install sparse
        make ARCH=x86_64 allmodconfig
        make C=1 CF=-D__CHECK_ENDIAN__


sparse warnings: (new ones prefixed by >>)

   include/linux/compiler.h:232:8: sparse: attribute 'no_sanitize_address': unknown attribute
>> security/selinux/pkey.c:116:24: sparse: incompatible types in comparison expression (different address spaces)

vim +116 security/selinux/pkey.c

   100	 * Description:
   101	 * Add a new pkey record to the hash table.
   102	 *
   103	 */
   104	static void sel_pkey_insert(struct sel_pkey *pkey)
   105	{
   106		unsigned int idx;
   107	
   108		/* we need to impose a limit on the growth of the hash table so check
   109		 * this bucket to make sure it is within the specified bounds
   110		 */
   111		idx = sel_pkey_hashfn(pkey->psec.pkey);
   112		list_add_rcu(&pkey->list, &sel_pkey_hash[idx].list);
   113		if (sel_pkey_hash[idx].size == SEL_PKEY_HASH_BKT_LIMIT) {
   114			struct sel_pkey *tail;
   115	
 > 116			tail = list_entry(
   117				rcu_dereference_protected(
   118					sel_pkey_hash[idx].list.prev,
   119					lockdep_is_held(&sel_pkey_lock)),
   120				struct sel_pkey, list);
   121			list_del_rcu(&tail->list);
   122			kfree_rcu(tail, rcu);
   123		} else {
   124			sel_pkey_hash[idx].size++;

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
--
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] 128+ messages in thread

* Re: [PATCH 07/12] selinux: Add a cache for quicker retreival of PKey SIDs
@ 2016-06-23 21:59         ` kbuild test robot
  0 siblings, 0 replies; 128+ messages in thread
From: kbuild test robot @ 2016-06-23 21:59 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

Hi,

[auto build test WARNING on rdma/master]
[also build test WARNING on v4.7-rc4]
[cannot apply to pcmoore-selinux/next next-20160623]
[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/20160624-035944
base:   https://git.kernel.org/pub/scm/linux/kernel/git/dledford/rdma master
reproduce:
        # apt-get install sparse
        make ARCH=x86_64 allmodconfig
        make C=1 CF=-D__CHECK_ENDIAN__


sparse warnings: (new ones prefixed by >>)

   include/linux/compiler.h:232:8: sparse: attribute 'no_sanitize_address': unknown attribute
>> security/selinux/pkey.c:116:24: sparse: incompatible types in comparison expression (different address spaces)

vim +116 security/selinux/pkey.c

   100	 * Description:
   101	 * Add a new pkey record to the hash table.
   102	 *
   103	 */
   104	static void sel_pkey_insert(struct sel_pkey *pkey)
   105	{
   106		unsigned int idx;
   107	
   108		/* we need to impose a limit on the growth of the hash table so check
   109		 * this bucket to make sure it is within the specified bounds
   110		 */
   111		idx = sel_pkey_hashfn(pkey->psec.pkey);
   112		list_add_rcu(&pkey->list, &sel_pkey_hash[idx].list);
   113		if (sel_pkey_hash[idx].size == SEL_PKEY_HASH_BKT_LIMIT) {
   114			struct sel_pkey *tail;
   115	
 > 116			tail = list_entry(
   117				rcu_dereference_protected(
   118					sel_pkey_hash[idx].list.prev,
   119					lockdep_is_held(&sel_pkey_lock)),
   120				struct sel_pkey, list);
   121			list_del_rcu(&tail->list);
   122			kfree_rcu(tail, rcu);
   123		} else {
   124			sel_pkey_hash[idx].size++;

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

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

* Re: [PATCH 00/12] SELinux support for Infiniband RDMA
  2016-06-23 19:52 ` Dan Jurgens
                   ` (4 preceding siblings ...)
  (?)
@ 2016-06-29 17:33 ` Paul Moore
  2016-06-29 19:09     ` Daniel Jurgens
  -1 siblings, 1 reply; 128+ messages in thread
From: Paul Moore @ 2016-06-29 17:33 UTC (permalink / raw)
  To: Dan Jurgens, Stephen Smalley
  Cc: chrisw, Eric Paris, dledford, sean.hefty, hal.rosenstock,
	selinux, linux-security-module, linux-rdma, yevgenyp

On Thu, Jun 23, 2016 at 3:52 PM, Dan Jurgens <danielj@mellanox.com> wrote:
> From: Daniel Jurgens <danielj@mellanox.com>
>
> This patch series was submitted previously as an RFC.  The 3rd version was
> posted on 19 Apr 2016 with the subject "[RFC PATCH v3 NN/MM] SELinux support
> for Infiniband RDMA".

Hi Dan,

Thanks for sticking with this patchset, I'm working through it right
now and I have a question on the overall design (below).

> Because RDMA allows for kernel bypass all enforcement must be done during
> connection setup.  To communicate 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 two LSM hooks are provided, ib_core will
> register and unregister a callback function at init and cleanup respectively.
> SELinux will call the callback as appropriate if it has been registered.
> When the callback is called ib_core will recheck the PKey access for all
> existing QPs.

...

> 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
> each 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 modify attempt.  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 hardware driver
> 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 restored.
> If the destroy succeeds the security info can be cleaned up and freed.

Perhaps I'll end up answering this for myself as I work my way through
the patches, but hopefully you are handling the case where a destroy
operation fails and the QP needs to be revalidated?

I'm also wondering if QP revalidation on a security policy change is
worth the trouble; we've historically not been able to provide any
revoke guarantees so I'm not sure if it is worth a lot of added
complexity to gain this functionality just for Infiniband.  That said,
it would be *nice* to have revalidation/revocation working, even if
only for IB.  It may be that we need similar code to handle the
various corner cases, so we may be stuck with the complexity anyway, I
just thought it was worth bringing up as a topic of discussion.

-- 
paul moore
www.paul-moore.com

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

* Re: [PATCH 00/12] SELinux support for Infiniband RDMA
  2016-06-29 17:33 ` Paul Moore
@ 2016-06-29 19:09     ` Daniel Jurgens
  0 siblings, 0 replies; 128+ messages in thread
From: Daniel Jurgens @ 2016-06-29 19:09 UTC (permalink / raw)
  To: Paul Moore, Stephen Smalley
  Cc: chrisw-69jw2NvuJkxg9hUCZPvPmw, Eric Paris,
	dledford-H+wXaHxf7aLQT0dZR+AlfA,
	sean.hefty-ral2JQCrhuEAvxtiuMwx3w,
	hal.rosenstock-Re5JQEeQqe8AvxtiuMwx3w,
	selinux-+05T5uksL2qpZYMLLGbcSA,
	linux-security-module-u79uwXL29TY76Z2rM5mHXA,
	linux-rdma-u79uwXL29TY76Z2rM5mHXA, Yevgeny Petrilin

On 6/29/2016 12:33 PM, Paul Moore wrote:
> On Thu, Jun 23, 2016 at 3:52 PM, Dan Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org> wrote:
>> When destroying a QP the ib_qp structure is freed by the hardware driver
>> 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 restored.
>> If the destroy succeeds the security info can be cleaned up and freed.
> Perhaps I'll end up answering this for myself as I work my way through
> the patches, but hopefully you are handling the case where a destroy
> operation fails and the QP needs to be revalidated?

Yes, if the destroy fails the security is checked again.  You can see
this in security.c
ib_destroy_qp_security_abort which is added in "[PATCH 09/12] IB/core:
Enforce PKey
security on QPs"

> I'm also wondering if QP revalidation on a security policy change is
> worth the trouble; we've historically not been able to provide any
> revoke guarantees so I'm not sure if it is worth a lot of added
> complexity to gain this functionality just for Infiniband.  That said,
> it would be *nice* to have revalidation/revocation working, even if
> only for IB.  It may be that we need similar code to handle the
> various corner cases, so we may be stuck with the complexity anyway, I
> just thought it was worth bringing up as a topic of discussion.

QP re-validation on policy change comes cheap because it's possible for the
PKey table to change.  So a mechanism to recheck all the QPs is needed
regardless.  I'd be fine with getting rid of it if you think that's
best.  In a
production environment SELinux will always be enforcing so it's probably not
really needed.  During my testing it left a funny taste in my mouth when
I had
QPs that shouldn't be allowed continue to exist after setenforce 1.  On
the other
hand I'm not in love with the callback registration for policy change
notification
one off for Infiniband.  In on of the RFCs I used an LSM hook that
ib/core would
implement.  I think Casey commented on that, so I changed it to what you see
now.

Thank you for reviewing this.
--
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] 128+ messages in thread

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

On 6/29/2016 12:33 PM, Paul Moore wrote:
> On Thu, Jun 23, 2016 at 3:52 PM, Dan Jurgens <danielj@mellanox.com> wrote:
>> When destroying a QP the ib_qp structure is freed by the hardware driver
>> 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 restored.
>> If the destroy succeeds the security info can be cleaned up and freed.
> Perhaps I'll end up answering this for myself as I work my way through
> the patches, but hopefully you are handling the case where a destroy
> operation fails and the QP needs to be revalidated?

Yes, if the destroy fails the security is checked again.  You can see
this in security.c
ib_destroy_qp_security_abort which is added in "[PATCH 09/12] IB/core:
Enforce PKey
security on QPs"

> I'm also wondering if QP revalidation on a security policy change is
> worth the trouble; we've historically not been able to provide any
> revoke guarantees so I'm not sure if it is worth a lot of added
> complexity to gain this functionality just for Infiniband.  That said,
> it would be *nice* to have revalidation/revocation working, even if
> only for IB.  It may be that we need similar code to handle the
> various corner cases, so we may be stuck with the complexity anyway, I
> just thought it was worth bringing up as a topic of discussion.

QP re-validation on policy change comes cheap because it's possible for the
PKey table to change.  So a mechanism to recheck all the QPs is needed
regardless.  I'd be fine with getting rid of it if you think that's
best.  In a
production environment SELinux will always be enforcing so it's probably not
really needed.  During my testing it left a funny taste in my mouth when
I had
QPs that shouldn't be allowed continue to exist after setenforce 1.  On
the other
hand I'm not in love with the callback registration for policy change
notification
one off for Infiniband.  In on of the RFCs I used an LSM hook that
ib/core would
implement.  I think Casey commented on that, so I changed it to what you see
now.

Thank you for reviewing this.

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

* Re: [PATCH 00/12] SELinux support for Infiniband RDMA
  2016-06-23 19:52 ` Dan Jurgens
@ 2016-06-30 14:43     ` Yuval Shaia
  -1 siblings, 0 replies; 128+ messages in thread
From: Yuval Shaia @ 2016-06-30 14:43 UTC (permalink / raw)
  To: Dan Jurgens
  Cc: 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

Few extremely minor cosmetic suggestions to commit message.

On Thu, Jun 23, 2016 at 10:52:46PM +0300, Dan Jurgens wrote:
> From: Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
> 
> This patch series was submitted previously as an RFC.  The 3rd version was

Extra space before " The"

> posted on 19 Apr 2016 with the subject "[RFC PATCH v3 NN/MM] SELinux support
> for Infiniband RDMA".
> 
> 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

Extra space before " By"

> subfabrics administrators can limit access to bandwidth and isolate users on

Suggesting "," after "subfabrics"

> 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

Extra space before " A partition"

> 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

Extra space before " The partition"

> number identifying the partition.  By controlling access to PKeys users can be

1. Extra space before " By"
2. Suggesting "," after "PKeys"

> isolated on the fabric.
> 
> All Infiniband fabrics must have a subnet manager.  The subnet manager

1. s/All/Every
2. Extra space before " The subnet"

> provisions the partitions and configures the end nodes.  Each end port has a

Extra space before " Each end"

> PKey table containing all the partitions it can access.  In order to enforce

Extra space before " In order"

> access to partitions the subnet management interface (SMI) must also be

Suggesting "," after "partitions"

> 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 SMIs.
> 
> A PKey label consists of a subnet prefix and a range of PKey values and is
> similar to the labeling mechanism for netports.  Infiniband end port can

Extra space before " Infiniband"

> reside on a different subnet, labeling the PKey values for specific subnet

s/reside/resides

> prefixes provides the user maximum flexibility. There is a single access
> vector for PKeys, called "access".

Suggesting to remove ","

> 
> An Infiniband end port (ib_end_port) is labeled by name and port number. There
> is a single access vector for ib_end_ports as well, called "smp".

Suggesting to remove ","

> 
> Because RDMA allows for kernel bypass all enforcement must be done during

1. Suggesting to remove "for"
2. Suggesting "," after "bypass"

> connection setup.  To communicate over RDMA requires a send and receive queue

1. Extra space before " To communicate"
2. Suggesting s/"The communication"/"To communicate"
3. s/queue/queues

> called a queue pair (QP).  During the creation of a QP it is initialized

Extra space before " During"

> before it can be used to send or receive data.  During initialization the user

Extra space before " During"

> 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 two LSM hooks are provided, ib_core will

1. Extra space before " To"
2. Suggesting "," after "this"

> register and unregister a callback function at init and cleanup respectively.
> SELinux will call the callback as appropriate if it has been registered.
> When the callback is called ib_core will recheck the PKey access for all
> existing QPs.
> 
> 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
> each port, pkey index, and alternate path for every IB device.  This makes

1. s/each/which (unless i wrongly understood it)
2. Extra space before " This"

> operations that used to be atomic transactional.
> 
> When modifying a QP ib_core must associate it with the PKey index, port,

Suggesting "," after "QP"

> and alternate path specified.  If the QP was already associated with different

Extra space before " If"

> settings the QP is added to the new list prior to the modify attempt.  If

1. Suggesting "," after "settings"
2. Suggesting s/"modify attempt"/modification
3. Extra space before " If"

> the modify succeeds then the old listing is removed.  If the modify fails

1. s/modify/modification/g
2. Extra space before " If"

> the new listing is removed and the old listing remains unchanged.
> 
> When destroying a QP the ib_qp structure is freed by the hardware driver

What is "hardware driver"?

> if the destroy is successful.  This requires storing security related

1. s/destroy/destruction
2. Extra space before " This"

> information in a separate structure. When a destroy request is in process

Suggesting either s/destroy/'destroy' or s/destroy/destruction

> 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

Suggesting "," after "table"

> doesn't have permission for the new setting.  If the destroy fails security

1. Extra space before " If"
2. Suggesting either s/destroy/'destroy' or s/destroy/destruction
3. Suggesting "," after "fails"

> for that QP must be enforced again, and its status in the list restored. 

1. Remove "," before "and"
2. s/restored/"is restored"

> If the destroy succeeds the security info can be cleaned up and freed.

1. Suggesting either s/destroy/'destroy' or s/destroy/destruction
2. Suggesting "," after "the"

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

1. Extra space before " If"
2. Suggesting "," before "the"

> safe locking order is qp security structure mutex first, followed by any list

1. Suggesting ":" after "is"
2. s/qp/QP

> locks needed, which are sorted first by port followed by pkey index.
> 
> Daniel Jurgens (12):
>   security: Add LSM hooks for Infiniband security
>   selinux: Create policydb version for Infiniband support
>   selinux: Implement Infiniband flush callback
>   selinux: Allocate and free infiniband security hooks
>   selinux: Implement Infiniband PKey "Access" access vector
>   selinux: Add IB End Port SMP access vector
>   selinux: Add a cache for quicker retreival of PKey SIDs
>   IB/core: IB cache enhancements to support Infiniband security
>   IB/core: Enforce PKey security on QPs
>   IB/core: Enforce PKey security on management datagrams
>   IB/core: Enforce Infiniband device SMI security
>   IB/core: Implement the Infiniband flush callback.
> 
>  drivers/infiniband/core/Makefile                 |   3 +-
>  drivers/infiniband/core/cache.c                  |  56 +-
>  drivers/infiniband/core/core_priv.h              |  93 ++++
>  drivers/infiniband/core/device.c                 |  59 +++
>  drivers/infiniband/core/mad.c                    | 105 +++-
>  drivers/infiniband/core/security.c               | 641 +++++++++++++++++++++++
>  drivers/infiniband/core/uverbs_cmd.c             |  20 +-
>  drivers/infiniband/core/verbs.c                  |  29 +-
>  include/linux/lsm_audit.h                        |  37 +-
>  include/linux/lsm_hooks.h                        |  71 +++
>  include/linux/security.h                         |  63 +++
>  include/rdma/ib_mad.h                            |   1 +
>  include/rdma/ib_verbs.h                          |  49 ++
>  security/Kconfig                                 |   9 +
>  security/security.c                              |  83 +++
>  security/selinux/Makefile                        |   2 +-
>  security/selinux/hooks.c                         | 160 +++++-
>  security/selinux/include/classmap.h              |   4 +
>  security/selinux/include/initial_sid_to_string.h |   2 +
>  security/selinux/include/objsec.h                |  11 +
>  security/selinux/include/pkey.h                  |  31 ++
>  security/selinux/include/security.h              |   7 +-
>  security/selinux/pkey.c                          | 243 +++++++++
>  security/selinux/ss/policydb.c                   | 129 ++++-
>  security/selinux/ss/policydb.h                   |  27 +-
>  security/selinux/ss/services.c                   |  84 +++
>  26 files changed, 1963 insertions(+), 56 deletions(-)
>  create mode 100644 drivers/infiniband/core/security.c
>  create mode 100644 security/selinux/include/pkey.h
>  create mode 100644 security/selinux/pkey.c
> 
> -- 
> 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
--
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] 128+ messages in thread

* Re: [PATCH 00/12] SELinux support for Infiniband RDMA
@ 2016-06-30 14:43     ` Yuval Shaia
  0 siblings, 0 replies; 128+ messages in thread
From: Yuval Shaia @ 2016-06-30 14:43 UTC (permalink / raw)
  To: Dan Jurgens
  Cc: chrisw, paul, sds, eparis, dledford, sean.hefty, hal.rosenstock,
	selinux, linux-security-module, linux-rdma, yevgenyp

Few extremely minor cosmetic suggestions to commit message.

On Thu, Jun 23, 2016 at 10:52:46PM +0300, Dan Jurgens wrote:
> From: Daniel Jurgens <danielj@mellanox.com>
> 
> This patch series was submitted previously as an RFC.  The 3rd version was

Extra space before " The"

> posted on 19 Apr 2016 with the subject "[RFC PATCH v3 NN/MM] SELinux support
> for Infiniband RDMA".
> 
> 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

Extra space before " By"

> subfabrics administrators can limit access to bandwidth and isolate users on

Suggesting "," after "subfabrics"

> 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

Extra space before " A partition"

> 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

Extra space before " The partition"

> number identifying the partition.  By controlling access to PKeys users can be

1. Extra space before " By"
2. Suggesting "," after "PKeys"

> isolated on the fabric.
> 
> All Infiniband fabrics must have a subnet manager.  The subnet manager

1. s/All/Every
2. Extra space before " The subnet"

> provisions the partitions and configures the end nodes.  Each end port has a

Extra space before " Each end"

> PKey table containing all the partitions it can access.  In order to enforce

Extra space before " In order"

> access to partitions the subnet management interface (SMI) must also be

Suggesting "," after "partitions"

> 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 SMIs.
> 
> A PKey label consists of a subnet prefix and a range of PKey values and is
> similar to the labeling mechanism for netports.  Infiniband end port can

Extra space before " Infiniband"

> reside on a different subnet, labeling the PKey values for specific subnet

s/reside/resides

> prefixes provides the user maximum flexibility. There is a single access
> vector for PKeys, called "access".

Suggesting to remove ","

> 
> An Infiniband end port (ib_end_port) is labeled by name and port number. There
> is a single access vector for ib_end_ports as well, called "smp".

Suggesting to remove ","

> 
> Because RDMA allows for kernel bypass all enforcement must be done during

1. Suggesting to remove "for"
2. Suggesting "," after "bypass"

> connection setup.  To communicate over RDMA requires a send and receive queue

1. Extra space before " To communicate"
2. Suggesting s/"The communication"/"To communicate"
3. s/queue/queues

> called a queue pair (QP).  During the creation of a QP it is initialized

Extra space before " During"

> before it can be used to send or receive data.  During initialization the user

Extra space before " During"

> 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 two LSM hooks are provided, ib_core will

1. Extra space before " To"
2. Suggesting "," after "this"

> register and unregister a callback function at init and cleanup respectively.
> SELinux will call the callback as appropriate if it has been registered.
> When the callback is called ib_core will recheck the PKey access for all
> existing QPs.
> 
> 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
> each port, pkey index, and alternate path for every IB device.  This makes

1. s/each/which (unless i wrongly understood it)
2. Extra space before " This"

> operations that used to be atomic transactional.
> 
> When modifying a QP ib_core must associate it with the PKey index, port,

Suggesting "," after "QP"

> and alternate path specified.  If the QP was already associated with different

Extra space before " If"

> settings the QP is added to the new list prior to the modify attempt.  If

1. Suggesting "," after "settings"
2. Suggesting s/"modify attempt"/modification
3. Extra space before " If"

> the modify succeeds then the old listing is removed.  If the modify fails

1. s/modify/modification/g
2. Extra space before " If"

> the new listing is removed and the old listing remains unchanged.
> 
> When destroying a QP the ib_qp structure is freed by the hardware driver

What is "hardware driver"?

> if the destroy is successful.  This requires storing security related

1. s/destroy/destruction
2. Extra space before " This"

> information in a separate structure. When a destroy request is in process

Suggesting either s/destroy/'destroy' or s/destroy/destruction

> 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

Suggesting "," after "table"

> doesn't have permission for the new setting.  If the destroy fails security

1. Extra space before " If"
2. Suggesting either s/destroy/'destroy' or s/destroy/destruction
3. Suggesting "," after "fails"

> for that QP must be enforced again, and its status in the list restored. 

1. Remove "," before "and"
2. s/restored/"is restored"

> If the destroy succeeds the security info can be cleaned up and freed.

1. Suggesting either s/destroy/'destroy' or s/destroy/destruction
2. Suggesting "," after "the"

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

1. Extra space before " If"
2. Suggesting "," before "the"

> safe locking order is qp security structure mutex first, followed by any list

1. Suggesting ":" after "is"
2. s/qp/QP

> locks needed, which are sorted first by port followed by pkey index.
> 
> Daniel Jurgens (12):
>   security: Add LSM hooks for Infiniband security
>   selinux: Create policydb version for Infiniband support
>   selinux: Implement Infiniband flush callback
>   selinux: Allocate and free infiniband security hooks
>   selinux: Implement Infiniband PKey "Access" access vector
>   selinux: Add IB End Port SMP access vector
>   selinux: Add a cache for quicker retreival of PKey SIDs
>   IB/core: IB cache enhancements to support Infiniband security
>   IB/core: Enforce PKey security on QPs
>   IB/core: Enforce PKey security on management datagrams
>   IB/core: Enforce Infiniband device SMI security
>   IB/core: Implement the Infiniband flush callback.
> 
>  drivers/infiniband/core/Makefile                 |   3 +-
>  drivers/infiniband/core/cache.c                  |  56 +-
>  drivers/infiniband/core/core_priv.h              |  93 ++++
>  drivers/infiniband/core/device.c                 |  59 +++
>  drivers/infiniband/core/mad.c                    | 105 +++-
>  drivers/infiniband/core/security.c               | 641 +++++++++++++++++++++++
>  drivers/infiniband/core/uverbs_cmd.c             |  20 +-
>  drivers/infiniband/core/verbs.c                  |  29 +-
>  include/linux/lsm_audit.h                        |  37 +-
>  include/linux/lsm_hooks.h                        |  71 +++
>  include/linux/security.h                         |  63 +++
>  include/rdma/ib_mad.h                            |   1 +
>  include/rdma/ib_verbs.h                          |  49 ++
>  security/Kconfig                                 |   9 +
>  security/security.c                              |  83 +++
>  security/selinux/Makefile                        |   2 +-
>  security/selinux/hooks.c                         | 160 +++++-
>  security/selinux/include/classmap.h              |   4 +
>  security/selinux/include/initial_sid_to_string.h |   2 +
>  security/selinux/include/objsec.h                |  11 +
>  security/selinux/include/pkey.h                  |  31 ++
>  security/selinux/include/security.h              |   7 +-
>  security/selinux/pkey.c                          | 243 +++++++++
>  security/selinux/ss/policydb.c                   | 129 ++++-
>  security/selinux/ss/policydb.h                   |  27 +-
>  security/selinux/ss/services.c                   |  84 +++
>  26 files changed, 1963 insertions(+), 56 deletions(-)
>  create mode 100644 drivers/infiniband/core/security.c
>  create mode 100644 security/selinux/include/pkey.h
>  create mode 100644 security/selinux/pkey.c
> 
> -- 
> 1.8.3.1
> 
> --
> 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] 128+ messages in thread

* Re: [PATCH 00/12] SELinux support for Infiniband RDMA
  2016-06-30 14:43     ` Yuval Shaia
@ 2016-06-30 14:47       ` Daniel Jurgens
  -1 siblings, 0 replies; 128+ messages in thread
From: Daniel Jurgens @ 2016-06-30 14:47 UTC (permalink / raw)
  To: Yuval Shaia
  Cc: 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, Yevgeny Petrilin

On 6/30/2016 9:43 AM, Yuval Shaia wrote:
> Few extremely minor cosmetic suggestions to commit message.
>
Thanks Yuval, I'll address these in the eventual v2 series.
--
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] 128+ messages in thread

* Re: [PATCH 00/12] SELinux support for Infiniband RDMA
@ 2016-06-30 14:47       ` Daniel Jurgens
  0 siblings, 0 replies; 128+ messages in thread
From: Daniel Jurgens @ 2016-06-30 14:47 UTC (permalink / raw)
  To: Yuval Shaia
  Cc: chrisw, paul, sds, eparis, dledford, sean.hefty, hal.rosenstock,
	selinux, linux-security-module, linux-rdma, Yevgeny Petrilin

On 6/30/2016 9:43 AM, Yuval Shaia wrote:
> Few extremely minor cosmetic suggestions to commit message.
>
Thanks Yuval, I'll address these in the eventual v2 series.

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

* Re: [PATCH 01/12] security: Add LSM hooks for Infiniband security
  2016-06-23 19:52 ` [PATCH 01/12] security: Add LSM hooks for Infiniband security Dan Jurgens
@ 2016-06-30 14:57       ` Yuval Shaia
  0 siblings, 0 replies; 128+ messages in thread
From: Yuval Shaia @ 2016-06-30 14:57 UTC (permalink / raw)
  To: Dan Jurgens
  Cc: 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

On Thu, Jun 23, 2016 at 10:52:47PM +0300, Dan Jurgens wrote:
> From: Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
> 
> Add nine new hooks
>  1. Allocate security contexts for Infiniband QPs.
>  2. Free security contexts for Infiniband QPs.
>  3. Allocate security contexts for Infiniband MAD agents.
>  4. Free security contexts for Infiniband MAD agents.
>  5. Enforce QP access to Pkeys
>  6. Enforce MAD agent access to Pkeys
>  7. Enforce MAD agent access to Infiniband End Ports for sending Subnet
>     Management Packets (SMP)
>  8. A hook to register a callback to receive notifications of
>     security policy or enforcement changes.  Restricting a QPs access to
>     a pkey will be done during setup and not on a per packet basis
>     access must be enforced again.
>  9. A hook to unregister the callback.
> 
> Signed-off-by: Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
> Reviewed-by: Eli Cohen <eli-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
> ---
>  include/linux/lsm_hooks.h | 71 ++++++++++++++++++++++++++++++++++++++++
>  include/linux/security.h  | 63 +++++++++++++++++++++++++++++++++++
>  include/rdma/ib_verbs.h   |  4 +++
>  security/Kconfig          |  9 +++++
>  security/security.c       | 83 +++++++++++++++++++++++++++++++++++++++++++++++
>  5 files changed, 230 insertions(+)
> 
> diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
> index 7ae3976..6b47c8d 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,50 @@
>   *	associated with the TUN device's security structure.
>   *	@security pointer to the TUN devices's security structure.
>   *
> + * Security hooks for Infiniband
> + *
> + * @ib_qp_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.
> + *	@qp_sec pointer to the ib_qp_security structure.
> + * @ib_mad_agent_pkey_access:
> + *	Check permission to access a pkey when transmiting and receiving MADS.
> + *	@subnet_prefix the subnet prefix of the port being used.
> + *	@pkey the pkey to be accessed.
> + *	@mad_agent pointer to the ib_mad_agent structure.
> + * @ib_end_port_smp:
> + *	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.
> + *	@mad_agent pointer to the ib_mad_agent structure.
> + * @ib_qp_alloc_security:
> + *	Allocate and attach a security structure to the qp_sec->q_security
> + *	field. The q_security field is initialized to NULL when the structure
> + *	is allocated.  A separate QP security structure is used instead of the
> + *	QP structure because when a QP is destroyed the memory is freed by the
> + *	hardware driver.  That operation can fail so the security info must be
> + *	maintained until the destroy completes successfully.
> + *	@qp_sec contains the ib_qp_security structure to be modified.
> + *	Return 0 if operation was successful.
> + * @ib_mad_agent_alloc_security:
> + *	Allocate and attach a security structure to the mad_agent->m_security
> + *	field. The m_security field is initialized to NULL when the structure
> + *	is allocated.
> + *	@mad_agent contains the ib_mad_agent structure to be modified.
> + *	Return 0 if operation was successful.
> + * @ib_qp_free_security:
> + *	Deallocate and clear the qp_sec->q_security field.
> + *	@qp_sec contains the ib_qp_security structure to be modified.
> + * @ib_mad_agent_free_security:
> + *	Deallocate and clear the mad_agent->m_security field.
> + *	@mad_agent contains the ib_mad_agent structure to be modified.
> + * @register_ib_flush_callback:
> + *	Provide a way for security modules to notify ib_core of policy changes.
> + *	@callback function pointer to call when policy changes.
> + * @unregister_ib_flush_callback:
> + *	Unregister the callback function.
> + *
>   * Security hooks for XFRM operations.
>   *
>   * @xfrm_policy_alloc_security:
> @@ -1579,6 +1624,21 @@ union security_list_options {
>  	int (*tun_dev_open)(void *security);
>  #endif	/* CONFIG_SECURITY_NETWORK */
>  
> +#ifdef CONFIG_SECURITY_INFINIBAND
> +	int (*ib_qp_pkey_access)(u64 subnet_prefix, u16 pkey,
> +				 struct ib_qp_security *qp_sec);
> +	int (*ib_mad_agent_pkey_access)(u64 subnet_prefix, u16 pkey,
> +					struct ib_mad_agent *mad_agent);
> +	int (*ib_end_port_smp)(const char *dev_name, u8 port,
> +			       struct ib_mad_agent *mad_agent);
> +	int (*ib_qp_alloc_security)(struct ib_qp_security *qp_sec);
> +	int (*ib_mad_agent_alloc_security)(struct ib_mad_agent *mad_agent);
> +	void (*ib_qp_free_security)(struct ib_qp_security *qp_sec);
> +	void (*ib_mad_agent_free_security)(struct ib_mad_agent *mad_agent);
> +	void (*register_ib_flush_callback)(void (*callback)(void));
> +	void (*unregister_ib_flush_callback)(void);
> +#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 +1866,17 @@ 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_qp_pkey_access;
> +	struct list_head ib_mad_agent_pkey_access;
> +	struct list_head ib_end_port_smp;
> +	struct list_head ib_qp_alloc_security;
> +	struct list_head ib_qp_free_security;
> +	struct list_head ib_mad_agent_alloc_security;
> +	struct list_head ib_mad_agent_free_security;
> +	struct list_head register_ib_flush_callback;
> +	struct list_head unregister_ib_flush_callback;
> +#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..a75d3e6 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
> @@ -55,6 +56,8 @@ struct msg_queue;
>  struct xattr;
>  struct xfrm_sec_ctx;
>  struct mm_struct;
> +struct ib_qp_security;
> +struct ib_mad_agent;
>  
>  /* If capable should audit the security request */
>  #define SECURITY_CAP_NOAUDIT 0
> @@ -1370,6 +1373,66 @@ static inline int security_tun_dev_open(void *security)
>  }
>  #endif	/* CONFIG_SECURITY_NETWORK */
>  
> +#ifdef CONFIG_SECURITY_INFINIBAND
> +int security_ib_qp_pkey_access(u64 subnet_prefix, u16 pkey,
> +			       struct ib_qp_security *qp_sec);
> +int security_ib_mad_agent_pkey_access(u64 subnet_prefix, u16 pkey,
> +				      struct ib_mad_agent *mad_agent);
> +int security_ib_end_port_smp(const char *name, u8 port,
> +			     struct ib_mad_agent *mad_agent);
> +int security_ib_qp_alloc_security(struct ib_qp_security *qp_sec);
> +void security_ib_qp_free_security(struct ib_qp_security *qp_sec);
> +int security_ib_mad_agent_alloc_security(struct ib_mad_agent *mad_agent);
> +void security_ib_mad_agent_free_security(struct ib_mad_agent *mad_agent);
> +void security_register_ib_flush_callback(void (*callback)(void));
> +void security_unregister_ib_flush_callback(void);
> +#else	/* CONFIG_SECURITY_INFINIBAND */
> +static inline int security_ib_qp_pkey_access(u64 subnet_prefix, u16 pkey,
> +					     struct ib_qp_security *qp_sec)
> +{
> +	return 0;
> +}
> +
> +static inline int security_ib_mad_agent_pkey_access(u64 subnet_prefix,
> +						    u16 pkey,
> +						    struct ib_mad_agent *mad_agent)
> +{
> +	return 0;
> +}
> +
> +static inline int security_ib_end_port_smp(const char *dev_name, u8 port,
> +					   struct ib_mad_agent *mad_agent)
> +{
> +	return 0;
> +}
> +
> +static inline int security_ib_qp_alloc_security(struct ib_qp_security *qp_sec)
> +{
> +	return 0;
> +}
> +
> +static inline void security_ib_qp_free_security(struct ib_qp_security *qp_sec)
> +{
> +}
> +
> +static inline int security_ib_mad_agent_alloc_security(struct ib_mad_agent *mad_agent)

More than 80 characters

> +{
> +	return 0;
> +}
> +
> +static inline void security_ib_mad_agent_free_security(struct ib_mad_agent *mad_agent)

More than 80 characters

> +{
> +}
> +
> +static inline void security_register_ib_flush_callback(void (*callback)(void))
> +{
> +}
> +
> +static inline void security_unregister_ib_flush_callback(void)
> +{
> +}
> +#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 432bed5..3f6780b 100644
> --- a/include/rdma/ib_verbs.h
> +++ b/include/rdma/ib_verbs.h
> @@ -1428,6 +1428,10 @@ struct ib_srq {
>  	} ext;
>  };
>  
> +struct ib_qp_security {
> +	void *q_security;
> +};
> +
>  struct ib_qp {
>  	struct ib_device       *device;
>  	struct ib_pd	       *pd;
> 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..d75a0e9 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,67 @@ EXPORT_SYMBOL(security_tun_dev_open);
>  
>  #endif	/* CONFIG_SECURITY_NETWORK */
>  
> +#ifdef CONFIG_SECURITY_INFINIBAND
> +
> +int security_ib_qp_pkey_access(u64 subnet_prefix, u16 pkey,
> +			       struct ib_qp_security *qp_sec)
> +{
> +	return call_int_hook(ib_qp_pkey_access, 0, subnet_prefix, pkey, qp_sec);
> +}
> +EXPORT_SYMBOL(security_ib_qp_pkey_access);
> +
> +int security_ib_mad_agent_pkey_access(u64 subnet_prefix, u16 pkey,
> +				      struct ib_mad_agent *mad_agent)
> +{
> +	return call_int_hook(ib_mad_agent_pkey_access, 0, subnet_prefix, pkey, mad_agent);

More than 80 characters

> +}
> +EXPORT_SYMBOL(security_ib_mad_agent_pkey_access);
> +
> +int security_ib_end_port_smp(const char *dev_name, u8 port,
> +			     struct ib_mad_agent *mad_agent)
> +{
> +	return call_int_hook(ib_end_port_smp, 0, dev_name, port, mad_agent);
> +}
> +EXPORT_SYMBOL(security_ib_end_port_smp);
> +
> +int security_ib_qp_alloc_security(struct ib_qp_security *qp_sec)
> +{
> +	return call_int_hook(ib_qp_alloc_security, 0, qp_sec);
> +}
> +EXPORT_SYMBOL(security_ib_qp_alloc_security);
> +
> +void security_ib_qp_free_security(struct ib_qp_security *qp_sec)
> +{
> +	call_void_hook(ib_qp_free_security, qp_sec);
> +}
> +EXPORT_SYMBOL(security_ib_qp_free_security);
> +
> +int security_ib_mad_agent_alloc_security(struct ib_mad_agent *mad_agent)
> +{
> +	return call_int_hook(ib_mad_agent_alloc_security, 0, mad_agent);
> +}
> +EXPORT_SYMBOL(security_ib_mad_agent_alloc_security);
> +
> +void security_ib_mad_agent_free_security(struct ib_mad_agent *mad_agent)
> +{
> +	call_void_hook(ib_mad_agent_free_security, mad_agent);
> +}
> +EXPORT_SYMBOL(security_ib_mad_agent_free_security);
> +
> +void security_register_ib_flush_callback(void (*callback)(void))
> +{
> +	call_void_hook(register_ib_flush_callback, callback);
> +}
> +EXPORT_SYMBOL(security_register_ib_flush_callback);
> +
> +void security_unregister_ib_flush_callback(void)
> +{
> +	call_void_hook(unregister_ib_flush_callback);
> +}
> +EXPORT_SYMBOL(security_unregister_ib_flush_callback);
> +
> +#endif	/* CONFIG_SECURITY_INFINIBAND */
> +
>  #ifdef CONFIG_SECURITY_NETWORK_XFRM
>  
>  int security_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp,
> @@ -1850,6 +1912,27 @@ 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_qp_pkey_access =
> +		LIST_HEAD_INIT(security_hook_heads.ib_qp_pkey_access),
> +	.ib_mad_agent_pkey_access =
> +		LIST_HEAD_INIT(security_hook_heads.ib_mad_agent_pkey_access),
> +	.ib_end_port_smp = LIST_HEAD_INIT(security_hook_heads.ib_end_port_smp),
> +	.ib_qp_alloc_security =
> +		LIST_HEAD_INIT(security_hook_heads.ib_qp_alloc_security),
> +	.ib_qp_free_security =
> +		LIST_HEAD_INIT(security_hook_heads.ib_qp_free_security),
> +	.ib_mad_agent_alloc_security =
> +		LIST_HEAD_INIT(security_hook_heads.ib_mad_agent_alloc_security),
> +	.ib_mad_agent_free_security =
> +		LIST_HEAD_INIT(security_hook_heads.ib_mad_agent_free_security),
> +	.register_ib_flush_callback =
> +		LIST_HEAD_INIT(security_hook_heads.register_ib_flush_callback),
> +	.unregister_ib_flush_callback =
> +		LIST_HEAD_INIT(security_hook_heads.unregister_ib_flush_callback),
> +#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
--
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] 128+ messages in thread

* Re: [PATCH 01/12] security: Add LSM hooks for Infiniband security
@ 2016-06-30 14:57       ` Yuval Shaia
  0 siblings, 0 replies; 128+ messages in thread
From: Yuval Shaia @ 2016-06-30 14:57 UTC (permalink / raw)
  To: Dan Jurgens
  Cc: chrisw, paul, sds, eparis, dledford, sean.hefty, hal.rosenstock,
	selinux, linux-security-module, linux-rdma, yevgenyp

On Thu, Jun 23, 2016 at 10:52:47PM +0300, Dan Jurgens wrote:
> From: Daniel Jurgens <danielj@mellanox.com>
> 
> Add nine new hooks
>  1. Allocate security contexts for Infiniband QPs.
>  2. Free security contexts for Infiniband QPs.
>  3. Allocate security contexts for Infiniband MAD agents.
>  4. Free security contexts for Infiniband MAD agents.
>  5. Enforce QP access to Pkeys
>  6. Enforce MAD agent access to Pkeys
>  7. Enforce MAD agent access to Infiniband End Ports for sending Subnet
>     Management Packets (SMP)
>  8. A hook to register a callback to receive notifications of
>     security policy or enforcement changes.  Restricting a QPs access to
>     a pkey will be done during setup and not on a per packet basis
>     access must be enforced again.
>  9. A hook to unregister the callback.
> 
> Signed-off-by: Daniel Jurgens <danielj@mellanox.com>
> Reviewed-by: Eli Cohen <eli@mellanox.com>
> ---
>  include/linux/lsm_hooks.h | 71 ++++++++++++++++++++++++++++++++++++++++
>  include/linux/security.h  | 63 +++++++++++++++++++++++++++++++++++
>  include/rdma/ib_verbs.h   |  4 +++
>  security/Kconfig          |  9 +++++
>  security/security.c       | 83 +++++++++++++++++++++++++++++++++++++++++++++++
>  5 files changed, 230 insertions(+)
> 
> diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
> index 7ae3976..6b47c8d 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,50 @@
>   *	associated with the TUN device's security structure.
>   *	@security pointer to the TUN devices's security structure.
>   *
> + * Security hooks for Infiniband
> + *
> + * @ib_qp_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.
> + *	@qp_sec pointer to the ib_qp_security structure.
> + * @ib_mad_agent_pkey_access:
> + *	Check permission to access a pkey when transmiting and receiving MADS.
> + *	@subnet_prefix the subnet prefix of the port being used.
> + *	@pkey the pkey to be accessed.
> + *	@mad_agent pointer to the ib_mad_agent structure.
> + * @ib_end_port_smp:
> + *	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.
> + *	@mad_agent pointer to the ib_mad_agent structure.
> + * @ib_qp_alloc_security:
> + *	Allocate and attach a security structure to the qp_sec->q_security
> + *	field. The q_security field is initialized to NULL when the structure
> + *	is allocated.  A separate QP security structure is used instead of the
> + *	QP structure because when a QP is destroyed the memory is freed by the
> + *	hardware driver.  That operation can fail so the security info must be
> + *	maintained until the destroy completes successfully.
> + *	@qp_sec contains the ib_qp_security structure to be modified.
> + *	Return 0 if operation was successful.
> + * @ib_mad_agent_alloc_security:
> + *	Allocate and attach a security structure to the mad_agent->m_security
> + *	field. The m_security field is initialized to NULL when the structure
> + *	is allocated.
> + *	@mad_agent contains the ib_mad_agent structure to be modified.
> + *	Return 0 if operation was successful.
> + * @ib_qp_free_security:
> + *	Deallocate and clear the qp_sec->q_security field.
> + *	@qp_sec contains the ib_qp_security structure to be modified.
> + * @ib_mad_agent_free_security:
> + *	Deallocate and clear the mad_agent->m_security field.
> + *	@mad_agent contains the ib_mad_agent structure to be modified.
> + * @register_ib_flush_callback:
> + *	Provide a way for security modules to notify ib_core of policy changes.
> + *	@callback function pointer to call when policy changes.
> + * @unregister_ib_flush_callback:
> + *	Unregister the callback function.
> + *
>   * Security hooks for XFRM operations.
>   *
>   * @xfrm_policy_alloc_security:
> @@ -1579,6 +1624,21 @@ union security_list_options {
>  	int (*tun_dev_open)(void *security);
>  #endif	/* CONFIG_SECURITY_NETWORK */
>  
> +#ifdef CONFIG_SECURITY_INFINIBAND
> +	int (*ib_qp_pkey_access)(u64 subnet_prefix, u16 pkey,
> +				 struct ib_qp_security *qp_sec);
> +	int (*ib_mad_agent_pkey_access)(u64 subnet_prefix, u16 pkey,
> +					struct ib_mad_agent *mad_agent);
> +	int (*ib_end_port_smp)(const char *dev_name, u8 port,
> +			       struct ib_mad_agent *mad_agent);
> +	int (*ib_qp_alloc_security)(struct ib_qp_security *qp_sec);
> +	int (*ib_mad_agent_alloc_security)(struct ib_mad_agent *mad_agent);
> +	void (*ib_qp_free_security)(struct ib_qp_security *qp_sec);
> +	void (*ib_mad_agent_free_security)(struct ib_mad_agent *mad_agent);
> +	void (*register_ib_flush_callback)(void (*callback)(void));
> +	void (*unregister_ib_flush_callback)(void);
> +#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 +1866,17 @@ 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_qp_pkey_access;
> +	struct list_head ib_mad_agent_pkey_access;
> +	struct list_head ib_end_port_smp;
> +	struct list_head ib_qp_alloc_security;
> +	struct list_head ib_qp_free_security;
> +	struct list_head ib_mad_agent_alloc_security;
> +	struct list_head ib_mad_agent_free_security;
> +	struct list_head register_ib_flush_callback;
> +	struct list_head unregister_ib_flush_callback;
> +#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..a75d3e6 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
> @@ -55,6 +56,8 @@ struct msg_queue;
>  struct xattr;
>  struct xfrm_sec_ctx;
>  struct mm_struct;
> +struct ib_qp_security;
> +struct ib_mad_agent;
>  
>  /* If capable should audit the security request */
>  #define SECURITY_CAP_NOAUDIT 0
> @@ -1370,6 +1373,66 @@ static inline int security_tun_dev_open(void *security)
>  }
>  #endif	/* CONFIG_SECURITY_NETWORK */
>  
> +#ifdef CONFIG_SECURITY_INFINIBAND
> +int security_ib_qp_pkey_access(u64 subnet_prefix, u16 pkey,
> +			       struct ib_qp_security *qp_sec);
> +int security_ib_mad_agent_pkey_access(u64 subnet_prefix, u16 pkey,
> +				      struct ib_mad_agent *mad_agent);
> +int security_ib_end_port_smp(const char *name, u8 port,
> +			     struct ib_mad_agent *mad_agent);
> +int security_ib_qp_alloc_security(struct ib_qp_security *qp_sec);
> +void security_ib_qp_free_security(struct ib_qp_security *qp_sec);
> +int security_ib_mad_agent_alloc_security(struct ib_mad_agent *mad_agent);
> +void security_ib_mad_agent_free_security(struct ib_mad_agent *mad_agent);
> +void security_register_ib_flush_callback(void (*callback)(void));
> +void security_unregister_ib_flush_callback(void);
> +#else	/* CONFIG_SECURITY_INFINIBAND */
> +static inline int security_ib_qp_pkey_access(u64 subnet_prefix, u16 pkey,
> +					     struct ib_qp_security *qp_sec)
> +{
> +	return 0;
> +}
> +
> +static inline int security_ib_mad_agent_pkey_access(u64 subnet_prefix,
> +						    u16 pkey,
> +						    struct ib_mad_agent *mad_agent)
> +{
> +	return 0;
> +}
> +
> +static inline int security_ib_end_port_smp(const char *dev_name, u8 port,
> +					   struct ib_mad_agent *mad_agent)
> +{
> +	return 0;
> +}
> +
> +static inline int security_ib_qp_alloc_security(struct ib_qp_security *qp_sec)
> +{
> +	return 0;
> +}
> +
> +static inline void security_ib_qp_free_security(struct ib_qp_security *qp_sec)
> +{
> +}
> +
> +static inline int security_ib_mad_agent_alloc_security(struct ib_mad_agent *mad_agent)

More than 80 characters

> +{
> +	return 0;
> +}
> +
> +static inline void security_ib_mad_agent_free_security(struct ib_mad_agent *mad_agent)

More than 80 characters

> +{
> +}
> +
> +static inline void security_register_ib_flush_callback(void (*callback)(void))
> +{
> +}
> +
> +static inline void security_unregister_ib_flush_callback(void)
> +{
> +}
> +#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 432bed5..3f6780b 100644
> --- a/include/rdma/ib_verbs.h
> +++ b/include/rdma/ib_verbs.h
> @@ -1428,6 +1428,10 @@ struct ib_srq {
>  	} ext;
>  };
>  
> +struct ib_qp_security {
> +	void *q_security;
> +};
> +
>  struct ib_qp {
>  	struct ib_device       *device;
>  	struct ib_pd	       *pd;
> 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..d75a0e9 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,67 @@ EXPORT_SYMBOL(security_tun_dev_open);
>  
>  #endif	/* CONFIG_SECURITY_NETWORK */
>  
> +#ifdef CONFIG_SECURITY_INFINIBAND
> +
> +int security_ib_qp_pkey_access(u64 subnet_prefix, u16 pkey,
> +			       struct ib_qp_security *qp_sec)
> +{
> +	return call_int_hook(ib_qp_pkey_access, 0, subnet_prefix, pkey, qp_sec);
> +}
> +EXPORT_SYMBOL(security_ib_qp_pkey_access);
> +
> +int security_ib_mad_agent_pkey_access(u64 subnet_prefix, u16 pkey,
> +				      struct ib_mad_agent *mad_agent)
> +{
> +	return call_int_hook(ib_mad_agent_pkey_access, 0, subnet_prefix, pkey, mad_agent);

More than 80 characters

> +}
> +EXPORT_SYMBOL(security_ib_mad_agent_pkey_access);
> +
> +int security_ib_end_port_smp(const char *dev_name, u8 port,
> +			     struct ib_mad_agent *mad_agent)
> +{
> +	return call_int_hook(ib_end_port_smp, 0, dev_name, port, mad_agent);
> +}
> +EXPORT_SYMBOL(security_ib_end_port_smp);
> +
> +int security_ib_qp_alloc_security(struct ib_qp_security *qp_sec)
> +{
> +	return call_int_hook(ib_qp_alloc_security, 0, qp_sec);
> +}
> +EXPORT_SYMBOL(security_ib_qp_alloc_security);
> +
> +void security_ib_qp_free_security(struct ib_qp_security *qp_sec)
> +{
> +	call_void_hook(ib_qp_free_security, qp_sec);
> +}
> +EXPORT_SYMBOL(security_ib_qp_free_security);
> +
> +int security_ib_mad_agent_alloc_security(struct ib_mad_agent *mad_agent)
> +{
> +	return call_int_hook(ib_mad_agent_alloc_security, 0, mad_agent);
> +}
> +EXPORT_SYMBOL(security_ib_mad_agent_alloc_security);
> +
> +void security_ib_mad_agent_free_security(struct ib_mad_agent *mad_agent)
> +{
> +	call_void_hook(ib_mad_agent_free_security, mad_agent);
> +}
> +EXPORT_SYMBOL(security_ib_mad_agent_free_security);
> +
> +void security_register_ib_flush_callback(void (*callback)(void))
> +{
> +	call_void_hook(register_ib_flush_callback, callback);
> +}
> +EXPORT_SYMBOL(security_register_ib_flush_callback);
> +
> +void security_unregister_ib_flush_callback(void)
> +{
> +	call_void_hook(unregister_ib_flush_callback);
> +}
> +EXPORT_SYMBOL(security_unregister_ib_flush_callback);
> +
> +#endif	/* CONFIG_SECURITY_INFINIBAND */
> +
>  #ifdef CONFIG_SECURITY_NETWORK_XFRM
>  
>  int security_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp,
> @@ -1850,6 +1912,27 @@ 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_qp_pkey_access =
> +		LIST_HEAD_INIT(security_hook_heads.ib_qp_pkey_access),
> +	.ib_mad_agent_pkey_access =
> +		LIST_HEAD_INIT(security_hook_heads.ib_mad_agent_pkey_access),
> +	.ib_end_port_smp = LIST_HEAD_INIT(security_hook_heads.ib_end_port_smp),
> +	.ib_qp_alloc_security =
> +		LIST_HEAD_INIT(security_hook_heads.ib_qp_alloc_security),
> +	.ib_qp_free_security =
> +		LIST_HEAD_INIT(security_hook_heads.ib_qp_free_security),
> +	.ib_mad_agent_alloc_security =
> +		LIST_HEAD_INIT(security_hook_heads.ib_mad_agent_alloc_security),
> +	.ib_mad_agent_free_security =
> +		LIST_HEAD_INIT(security_hook_heads.ib_mad_agent_free_security),
> +	.register_ib_flush_callback =
> +		LIST_HEAD_INIT(security_hook_heads.register_ib_flush_callback),
> +	.unregister_ib_flush_callback =
> +		LIST_HEAD_INIT(security_hook_heads.unregister_ib_flush_callback),
> +#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@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH 02/12] selinux: Create policydb version for Infiniband support
  2016-06-23 19:52 ` [PATCH 02/12] selinux: Create policydb version for Infiniband support Dan Jurgens
@ 2016-06-30 15:01       ` Yuval Shaia
  0 siblings, 0 replies; 128+ messages in thread
From: Yuval Shaia @ 2016-06-30 15:01 UTC (permalink / raw)
  To: Dan Jurgens
  Cc: 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

On Thu, Jun 23, 2016 at 10:52:48PM +0300, Dan Jurgens wrote:
> From: Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
> 
> Support for Infiniband requires the addition of two new object contexts,
> one for infiniband PKeys and another IB End Ports.  Added handlers to read

Extra space before " Added"

> 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>
> ---
>  security/selinux/include/security.h |   3 +-
>  security/selinux/ss/policydb.c      | 129 +++++++++++++++++++++++++++++++-----
>  security/selinux/ss/policydb.h      |  27 +++++---
>  3 files changed, 135 insertions(+), 24 deletions(-)
> 
> diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
> index 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..78b819c 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,58 @@ 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));

More than 80 characters

> +				/* 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_END_PORT:
> +				rc = next_entry(buf, fp, sizeof(u32) * 2);
> +				if (rc)
> +					goto out;
> +				len = le32_to_cpu(buf[0]);
> +
> +				rc = str_read(&c->u.ib_end_port.dev_name, GFP_KERNEL,

More than 80 characters?

> +					      fp,
> +					      len);
> +				if (rc)
> +					goto out;
> +
> +				c->u.ib_end_port.port = le32_to_cpu(buf[1]);
> +
> +				rc = context_read_and_validate(&c->context[0],
> +							       p,
> +							       fp);
> +				if (rc)
> +					goto out;
> +				break;
>  			}
>  		}
>  	}
> @@ -3147,6 +3209,43 @@ static int ocontext_write(struct policydb *p, struct policydb_compat_info *info,

More than 80 characters

>  				if (rc)
>  					return rc;
>  				break;
> +			case OCON_PKEY: {

Is "{" needed?

> +				__be64 *sbn_pfx = (__be64 *)nodebuf;
> +				*sbn_pfx = 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_END_PORT:
> +				len = strlen(c->u.ib_end_port.dev_name);
> +				buf[0] = cpu_to_le32(len);
> +				buf[1] = cpu_to_le32(c->u.ib_end_port.port);
> +				rc = put_entry(buf, sizeof(u32), 2, fp);
> +				if (rc)
> +					return rc;
> +				rc = put_entry(c->u.ib_end_port.dev_name, 1, len, fp);

More than 80 characters?

> +				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..751bf604 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;
> +		} ib_end_port;
>  	} 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_END_PORT 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
--
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] 128+ messages in thread

* Re: [PATCH 02/12] selinux: Create policydb version for Infiniband support
@ 2016-06-30 15:01       ` Yuval Shaia
  0 siblings, 0 replies; 128+ messages in thread
From: Yuval Shaia @ 2016-06-30 15:01 UTC (permalink / raw)
  To: Dan Jurgens
  Cc: chrisw, paul, sds, eparis, dledford, sean.hefty, hal.rosenstock,
	selinux, linux-security-module, linux-rdma, yevgenyp

On Thu, Jun 23, 2016 at 10:52:48PM +0300, Dan Jurgens wrote:
> From: Daniel Jurgens <danielj@mellanox.com>
> 
> Support for Infiniband requires the addition of two new object contexts,
> one for infiniband PKeys and another IB End Ports.  Added handlers to read

Extra space before " Added"

> 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>
> ---
>  security/selinux/include/security.h |   3 +-
>  security/selinux/ss/policydb.c      | 129 +++++++++++++++++++++++++++++++-----
>  security/selinux/ss/policydb.h      |  27 +++++---
>  3 files changed, 135 insertions(+), 24 deletions(-)
> 
> diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
> index 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..78b819c 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,58 @@ 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));

More than 80 characters

> +				/* 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_END_PORT:
> +				rc = next_entry(buf, fp, sizeof(u32) * 2);
> +				if (rc)
> +					goto out;
> +				len = le32_to_cpu(buf[0]);
> +
> +				rc = str_read(&c->u.ib_end_port.dev_name, GFP_KERNEL,

More than 80 characters?

> +					      fp,
> +					      len);
> +				if (rc)
> +					goto out;
> +
> +				c->u.ib_end_port.port = le32_to_cpu(buf[1]);
> +
> +				rc = context_read_and_validate(&c->context[0],
> +							       p,
> +							       fp);
> +				if (rc)
> +					goto out;
> +				break;
>  			}
>  		}
>  	}
> @@ -3147,6 +3209,43 @@ static int ocontext_write(struct policydb *p, struct policydb_compat_info *info,

More than 80 characters

>  				if (rc)
>  					return rc;
>  				break;
> +			case OCON_PKEY: {

Is "{" needed?

> +				__be64 *sbn_pfx = (__be64 *)nodebuf;
> +				*sbn_pfx = 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_END_PORT:
> +				len = strlen(c->u.ib_end_port.dev_name);
> +				buf[0] = cpu_to_le32(len);
> +				buf[1] = cpu_to_le32(c->u.ib_end_port.port);
> +				rc = put_entry(buf, sizeof(u32), 2, fp);
> +				if (rc)
> +					return rc;
> +				rc = put_entry(c->u.ib_end_port.dev_name, 1, len, fp);

More than 80 characters?

> +				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..751bf604 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;
> +		} ib_end_port;
>  	} 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_END_PORT 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@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH 03/12] selinux: Implement Infiniband flush callback
  2016-06-23 19:52     ` Dan Jurgens
@ 2016-06-30 15:10         ` Yuval Shaia
  -1 siblings, 0 replies; 128+ messages in thread
From: Yuval Shaia @ 2016-06-30 15:10 UTC (permalink / raw)
  To: Dan Jurgens
  Cc: 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

On Thu, Jun 23, 2016 at 10:52:49PM +0300, Dan Jurgens wrote:
> From: Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
> 
> Because access for infiniband is enforced in the setup phase of a
> connection there must be a way to notify ib_core if the policy or
> enforcement setting have changed.
> 
> Added register and unregister_ib_flush_callback hooks so infiniband can
> setup notification of policy and enforment changes.  In the AVC reset

Extra space before " In"

> callback function call the ib_flush callback if it's registered. Also
> renamed the callback function, the previous name was 'net' specific.
> 
> Signed-off-by: Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
> Reviewed-by: Eli Cohen <eli-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
> ---
>  security/selinux/hooks.c | 36 ++++++++++++++++++++++++++++++++++--
>  1 file changed, 34 insertions(+), 2 deletions(-)
> 
> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index a86d537..6a8841d 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -94,6 +94,9 @@
>  #include "audit.h"
>  #include "avc_ss.h"
>  
> +static void (*ib_flush_callback)(void);

Do we really want to have such ib_ prefix in security/ directory?

> +static DEFINE_MUTEX(ib_flush_mutex);
> +
>  /* SECMARK reference count */
>  static atomic_t selinux_secmark_refcount = ATOMIC_INIT(0);
>  
> @@ -159,13 +162,17 @@ 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();
> +		mutex_lock(&ib_flush_mutex);

Suggesting to have the lock inside the callback (unless you accept my
suggestion below)

> +		if (ib_flush_callback)
> +			ib_flush_callback();

How about some generic mechanism (such as a list) in case more
modules/drivers would like to register callbacks?
( assuming this is no longer RFC :) )

> +		mutex_unlock(&ib_flush_mutex);
>  	}
>  	return 0;
>  }
> @@ -5993,6 +6000,23 @@ static int selinux_key_getsecurity(struct key *key, char **_buffer)
>  
>  #endif
>  
> +#ifdef CONFIG_SECURITY_INFINIBAND
> +static void selinux_register_ib_flush_callback(void (*callback)(void))
> +{
> +	mutex_lock(&ib_flush_mutex);
> +	ib_flush_callback = callback;
> +	mutex_unlock(&ib_flush_mutex);
> +}
> +
> +static void selinux_unregister_ib_flush_callback(void)
> +{
> +	mutex_lock(&ib_flush_mutex);
> +	ib_flush_callback = NULL;
> +	mutex_unlock(&ib_flush_mutex);
> +}
> +
> +#endif
> +
>  static struct security_hook_list selinux_hooks[] = {
>  	LSM_HOOK_INIT(binder_set_context_mgr, selinux_binder_set_context_mgr),
>  	LSM_HOOK_INIT(binder_transaction, selinux_binder_transaction),
> @@ -6174,6 +6198,12 @@ 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(register_ib_flush_callback,
> +		      selinux_register_ib_flush_callback),
> +	LSM_HOOK_INIT(unregister_ib_flush_callback,
> +		      selinux_unregister_ib_flush_callback),
> +#endif
>  
>  #ifdef CONFIG_SECURITY_NETWORK_XFRM
>  	LSM_HOOK_INIT(xfrm_policy_alloc_security, selinux_xfrm_policy_alloc),
> @@ -6233,9 +6263,11 @@ static __init int selinux_init(void)
>  					    0, SLAB_PANIC, NULL);
>  	avc_init();
>  
> +	ib_flush_callback = NULL;
> +
>  	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)
> -- 
> 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
--
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] 128+ messages in thread

* Re: [PATCH 03/12] selinux: Implement Infiniband flush callback
@ 2016-06-30 15:10         ` Yuval Shaia
  0 siblings, 0 replies; 128+ messages in thread
From: Yuval Shaia @ 2016-06-30 15:10 UTC (permalink / raw)
  To: Dan Jurgens
  Cc: chrisw, paul, sds, eparis, dledford, sean.hefty, hal.rosenstock,
	selinux, linux-security-module, linux-rdma, yevgenyp

On Thu, Jun 23, 2016 at 10:52:49PM +0300, Dan Jurgens wrote:
> From: Daniel Jurgens <danielj@mellanox.com>
> 
> Because access for infiniband is enforced in the setup phase of a
> connection there must be a way to notify ib_core if the policy or
> enforcement setting have changed.
> 
> Added register and unregister_ib_flush_callback hooks so infiniband can
> setup notification of policy and enforment changes.  In the AVC reset

Extra space before " In"

> callback function call the ib_flush callback if it's registered. Also
> renamed the callback function, the previous name was 'net' specific.
> 
> Signed-off-by: Daniel Jurgens <danielj@mellanox.com>
> Reviewed-by: Eli Cohen <eli@mellanox.com>
> ---
>  security/selinux/hooks.c | 36 ++++++++++++++++++++++++++++++++++--
>  1 file changed, 34 insertions(+), 2 deletions(-)
> 
> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index a86d537..6a8841d 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -94,6 +94,9 @@
>  #include "audit.h"
>  #include "avc_ss.h"
>  
> +static void (*ib_flush_callback)(void);

Do we really want to have such ib_ prefix in security/ directory?

> +static DEFINE_MUTEX(ib_flush_mutex);
> +
>  /* SECMARK reference count */
>  static atomic_t selinux_secmark_refcount = ATOMIC_INIT(0);
>  
> @@ -159,13 +162,17 @@ 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();
> +		mutex_lock(&ib_flush_mutex);

Suggesting to have the lock inside the callback (unless you accept my
suggestion below)

> +		if (ib_flush_callback)
> +			ib_flush_callback();

How about some generic mechanism (such as a list) in case more
modules/drivers would like to register callbacks?
( assuming this is no longer RFC :) )

> +		mutex_unlock(&ib_flush_mutex);
>  	}
>  	return 0;
>  }
> @@ -5993,6 +6000,23 @@ static int selinux_key_getsecurity(struct key *key, char **_buffer)
>  
>  #endif
>  
> +#ifdef CONFIG_SECURITY_INFINIBAND
> +static void selinux_register_ib_flush_callback(void (*callback)(void))
> +{
> +	mutex_lock(&ib_flush_mutex);
> +	ib_flush_callback = callback;
> +	mutex_unlock(&ib_flush_mutex);
> +}
> +
> +static void selinux_unregister_ib_flush_callback(void)
> +{
> +	mutex_lock(&ib_flush_mutex);
> +	ib_flush_callback = NULL;
> +	mutex_unlock(&ib_flush_mutex);
> +}
> +
> +#endif
> +
>  static struct security_hook_list selinux_hooks[] = {
>  	LSM_HOOK_INIT(binder_set_context_mgr, selinux_binder_set_context_mgr),
>  	LSM_HOOK_INIT(binder_transaction, selinux_binder_transaction),
> @@ -6174,6 +6198,12 @@ 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(register_ib_flush_callback,
> +		      selinux_register_ib_flush_callback),
> +	LSM_HOOK_INIT(unregister_ib_flush_callback,
> +		      selinux_unregister_ib_flush_callback),
> +#endif
>  
>  #ifdef CONFIG_SECURITY_NETWORK_XFRM
>  	LSM_HOOK_INIT(xfrm_policy_alloc_security, selinux_xfrm_policy_alloc),
> @@ -6233,9 +6263,11 @@ static __init int selinux_init(void)
>  					    0, SLAB_PANIC, NULL);
>  	avc_init();
>  
> +	ib_flush_callback = NULL;
> +
>  	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)
> -- 
> 1.8.3.1
> 
> --
> 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] 128+ messages in thread

* Re: [PATCH 04/12] selinux: Allocate and free infiniband security hooks
  2016-06-23 19:52     ` Dan Jurgens
@ 2016-06-30 15:15         ` Yuval Shaia
  -1 siblings, 0 replies; 128+ messages in thread
From: Yuval Shaia @ 2016-06-30 15:15 UTC (permalink / raw)
  To: Dan Jurgens
  Cc: 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

On Thu, Jun 23, 2016 at 10:52:50PM +0300, Dan Jurgens wrote:
> From: Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
> 
> Implement and attach hooks to allocate and free Infiniband QP and MAD
> agent security structures.
> 
> Signed-off-by: Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
> Reviewed-by: Eli Cohen <eli-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
> ---
>  include/rdma/ib_mad.h             |  1 +
>  include/rdma/ib_verbs.h           |  1 +
>  security/selinux/hooks.c          | 53 +++++++++++++++++++++++++++++++++++++++
>  security/selinux/include/objsec.h |  5 ++++
>  4 files changed, 60 insertions(+)
> 
> diff --git a/include/rdma/ib_mad.h b/include/rdma/ib_mad.h
> index c8a773f..a1ed025 100644
> --- a/include/rdma/ib_mad.h
> +++ b/include/rdma/ib_mad.h
> @@ -537,6 +537,7 @@ struct ib_mad_agent {
>  	u32			flags;
>  	u8			port_num;
>  	u8			rmpp_version;
> +	void			*m_security;
>  };
>  
>  /**
> diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
> index 3f6780b..e522acb 100644
> --- a/include/rdma/ib_verbs.h
> +++ b/include/rdma/ib_verbs.h
> @@ -1454,6 +1454,7 @@ struct ib_qp {
>  	void		       *qp_context;
>  	u32			qp_num;
>  	enum ib_qp_type		qp_type;
> +	struct ib_qp_security  *qp_sec;
>  };
>  
>  struct ib_mr {
> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index 6a8841d..4f13ea4 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -17,6 +17,7 @@
>   *	Paul Moore <paul-r2n+y4ga6xFZroRs9YW3xA@public.gmane.org>
>   *  Copyright (C) 2007 Hitachi Software Engineering Co., Ltd.
>   *		       Yuichi Nakamura <ynakam-FkO1umbPgv4fag7Bw7Dlfw@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 version 2,
> @@ -83,6 +84,8 @@
>  #include <linux/export.h>
>  #include <linux/msg.h>
>  #include <linux/shm.h>
> +#include <rdma/ib_verbs.h>
> +#include <rdma/ib_mad.h>
>  
>  #include "avc.h"
>  #include "objsec.h"
> @@ -6015,6 +6018,47 @@ static void selinux_unregister_ib_flush_callback(void)
>  	mutex_unlock(&ib_flush_mutex);
>  }
>  
> +static int selinux_ib_qp_alloc_security(struct ib_qp_security *qp_sec)
> +{
> +	struct ib_security_struct *sec;
> +
> +	sec = kzalloc(sizeof(*sec), GFP_ATOMIC);

Kindly reminder to make sure GFP_ATOMIC is needed.

> +	if (!sec)
> +		return -ENOMEM;
> +	sec->sid = current_sid();
> +
> +	qp_sec->q_security = sec;
> +	return 0;
> +}
> +
> +static void selinux_ib_qp_free_security(struct ib_qp_security *qp_sec)
> +{
> +	struct ib_security_struct *sec = qp_sec->q_security;
> +
> +	qp_sec->q_security = NULL;
> +	kfree(sec);
> +}
> +
> +static int selinux_ib_mad_agent_alloc_security(struct ib_mad_agent *mad_agent)
> +{
> +	struct ib_security_struct *sec;
> +
> +	sec = kzalloc(sizeof(*sec), GFP_ATOMIC);
> +	if (!sec)
> +		return -ENOMEM;
> +	sec->sid = current_sid();
> +
> +	mad_agent->m_security = sec;
> +	return 0;
> +}
> +
> +static void selinux_ib_mad_agent_free_security(struct ib_mad_agent *mad_agent)
> +{
> +	struct ib_security_struct *sec = mad_agent->m_security;
> +
> +	mad_agent->m_security = NULL;
> +	kfree(sec);
> +}
>  #endif
>  
>  static struct security_hook_list selinux_hooks[] = {
> @@ -6198,11 +6242,20 @@ 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(register_ib_flush_callback,
>  		      selinux_register_ib_flush_callback),
>  	LSM_HOOK_INIT(unregister_ib_flush_callback,
>  		      selinux_unregister_ib_flush_callback),
> +	LSM_HOOK_INIT(ib_qp_alloc_security,
> +		      selinux_ib_qp_alloc_security),
> +	LSM_HOOK_INIT(ib_qp_free_security,
> +		      selinux_ib_qp_free_security),
> +	LSM_HOOK_INIT(ib_mad_agent_alloc_security,
> +		      selinux_ib_mad_agent_alloc_security),
> +	LSM_HOOK_INIT(ib_mad_agent_free_security,
> +		      selinux_ib_mad_agent_free_security),
>  #endif
>  
>  #ifdef CONFIG_SECURITY_NETWORK_XFRM
> 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-H+wXaHxf7aLQT0dZR+AlfA@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 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
> 
> --
> 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
--
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] 128+ messages in thread

* Re: [PATCH 04/12] selinux: Allocate and free infiniband security hooks
@ 2016-06-30 15:15         ` Yuval Shaia
  0 siblings, 0 replies; 128+ messages in thread
From: Yuval Shaia @ 2016-06-30 15:15 UTC (permalink / raw)
  To: Dan Jurgens
  Cc: chrisw, paul, sds, eparis, dledford, sean.hefty, hal.rosenstock,
	selinux, linux-security-module, linux-rdma, yevgenyp

On Thu, Jun 23, 2016 at 10:52:50PM +0300, Dan Jurgens wrote:
> From: Daniel Jurgens <danielj@mellanox.com>
> 
> Implement and attach hooks to allocate and free Infiniband QP and MAD
> agent security structures.
> 
> Signed-off-by: Daniel Jurgens <danielj@mellanox.com>
> Reviewed-by: Eli Cohen <eli@mellanox.com>
> ---
>  include/rdma/ib_mad.h             |  1 +
>  include/rdma/ib_verbs.h           |  1 +
>  security/selinux/hooks.c          | 53 +++++++++++++++++++++++++++++++++++++++
>  security/selinux/include/objsec.h |  5 ++++
>  4 files changed, 60 insertions(+)
> 
> diff --git a/include/rdma/ib_mad.h b/include/rdma/ib_mad.h
> index c8a773f..a1ed025 100644
> --- a/include/rdma/ib_mad.h
> +++ b/include/rdma/ib_mad.h
> @@ -537,6 +537,7 @@ struct ib_mad_agent {
>  	u32			flags;
>  	u8			port_num;
>  	u8			rmpp_version;
> +	void			*m_security;
>  };
>  
>  /**
> diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
> index 3f6780b..e522acb 100644
> --- a/include/rdma/ib_verbs.h
> +++ b/include/rdma/ib_verbs.h
> @@ -1454,6 +1454,7 @@ struct ib_qp {
>  	void		       *qp_context;
>  	u32			qp_num;
>  	enum ib_qp_type		qp_type;
> +	struct ib_qp_security  *qp_sec;
>  };
>  
>  struct ib_mr {
> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index 6a8841d..4f13ea4 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,
> @@ -83,6 +84,8 @@
>  #include <linux/export.h>
>  #include <linux/msg.h>
>  #include <linux/shm.h>
> +#include <rdma/ib_verbs.h>
> +#include <rdma/ib_mad.h>
>  
>  #include "avc.h"
>  #include "objsec.h"
> @@ -6015,6 +6018,47 @@ static void selinux_unregister_ib_flush_callback(void)
>  	mutex_unlock(&ib_flush_mutex);
>  }
>  
> +static int selinux_ib_qp_alloc_security(struct ib_qp_security *qp_sec)
> +{
> +	struct ib_security_struct *sec;
> +
> +	sec = kzalloc(sizeof(*sec), GFP_ATOMIC);

Kindly reminder to make sure GFP_ATOMIC is needed.

> +	if (!sec)
> +		return -ENOMEM;
> +	sec->sid = current_sid();
> +
> +	qp_sec->q_security = sec;
> +	return 0;
> +}
> +
> +static void selinux_ib_qp_free_security(struct ib_qp_security *qp_sec)
> +{
> +	struct ib_security_struct *sec = qp_sec->q_security;
> +
> +	qp_sec->q_security = NULL;
> +	kfree(sec);
> +}
> +
> +static int selinux_ib_mad_agent_alloc_security(struct ib_mad_agent *mad_agent)
> +{
> +	struct ib_security_struct *sec;
> +
> +	sec = kzalloc(sizeof(*sec), GFP_ATOMIC);
> +	if (!sec)
> +		return -ENOMEM;
> +	sec->sid = current_sid();
> +
> +	mad_agent->m_security = sec;
> +	return 0;
> +}
> +
> +static void selinux_ib_mad_agent_free_security(struct ib_mad_agent *mad_agent)
> +{
> +	struct ib_security_struct *sec = mad_agent->m_security;
> +
> +	mad_agent->m_security = NULL;
> +	kfree(sec);
> +}
>  #endif
>  
>  static struct security_hook_list selinux_hooks[] = {
> @@ -6198,11 +6242,20 @@ 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(register_ib_flush_callback,
>  		      selinux_register_ib_flush_callback),
>  	LSM_HOOK_INIT(unregister_ib_flush_callback,
>  		      selinux_unregister_ib_flush_callback),
> +	LSM_HOOK_INIT(ib_qp_alloc_security,
> +		      selinux_ib_qp_alloc_security),
> +	LSM_HOOK_INIT(ib_qp_free_security,
> +		      selinux_ib_qp_free_security),
> +	LSM_HOOK_INIT(ib_mad_agent_alloc_security,
> +		      selinux_ib_mad_agent_alloc_security),
> +	LSM_HOOK_INIT(ib_mad_agent_free_security,
> +		      selinux_ib_mad_agent_free_security),
>  #endif
>  
>  #ifdef CONFIG_SECURITY_NETWORK_XFRM
> 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
> 
> --
> 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] 128+ messages in thread

* Re: [PATCH 00/12] SELinux support for Infiniband RDMA
       [not found]     ` <DB6PR0501MB22611E2BA664DD033571AEDEC4230-wTfl6qNNZ1NK98U9gK7MJ8DSnupUy6xnnBOFsp37pqbUKgpGm//BTAC/G2K4zDHf@public.gmane.org>
@ 2016-06-30 15:18       ` Paul Moore
  0 siblings, 0 replies; 128+ messages in thread
From: Paul Moore @ 2016-06-30 15:18 UTC (permalink / raw)
  To: Daniel Jurgens
  Cc: Stephen Smalley, chrisw-69jw2NvuJkxg9hUCZPvPmw, Eric Paris,
	dledford-H+wXaHxf7aLQT0dZR+AlfA,
	sean.hefty-ral2JQCrhuEAvxtiuMwx3w,
	hal.rosenstock-Re5JQEeQqe8AvxtiuMwx3w,
	selinux-+05T5uksL2qpZYMLLGbcSA,
	linux-security-module-u79uwXL29TY76Z2rM5mHXA,
	linux-rdma-u79uwXL29TY76Z2rM5mHXA, Yevgeny Petrilin

On Wed, Jun 29, 2016 at 3:09 PM, Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org> wrote:
> On 6/29/2016 12:33 PM, Paul Moore wrote:
>> I'm also wondering if QP revalidation on a security policy change is
>> worth the trouble; we've historically not been able to provide any
>> revoke guarantees so I'm not sure if it is worth a lot of added
>> complexity to gain this functionality just for Infiniband.  That said,
>> it would be *nice* to have revalidation/revocation working, even if
>> only for IB.  It may be that we need similar code to handle the
>> various corner cases, so we may be stuck with the complexity anyway, I
>> just thought it was worth bringing up as a topic of discussion.
>
> QP re-validation on policy change comes cheap because it's possible for the
> PKey table to change.  So a mechanism to recheck all the QPs is needed
> regardless.

Okay, if we need the mechanism anyway, let's keep it.  Revalidation is
nice as long as we can make it work without too much pain, and based
on my first pass through the patches it didn't look as bad as I feared
it might.

> During my testing it left a funny taste in my mouth when I had QPs that shouldn't be allowed continue to exist after setenforce 1.

Yeah, the general inability to revoke access is pretty annoying, but
in practice I don't believe it is very common as I don't believe
people change their security policy very frequently, especially in
production.

> On the other hand I'm not in love with the callback registration for policy
> change notification one off for Infiniband.  In on of the RFCs I used an
> LSM hook that ib/core would implement.  I think Casey commented on that,
> so I changed it to what you see now.

I can't say I'm in love with it either, but sometimes things are just
awkward.  I suspect I'll probably have some comments on the
notification mechanism too, but I'm not comfortable enough with your
patches yet to make any quality comments.

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

* Re: [PATCH 05/12] selinux: Implement Infiniband PKey "Access" access vector
  2016-06-23 19:52     ` Dan Jurgens
@ 2016-06-30 15:23         ` Yuval Shaia
  -1 siblings, 0 replies; 128+ messages in thread
From: Yuval Shaia @ 2016-06-30 15:23 UTC (permalink / raw)
  To: Dan Jurgens
  Cc: 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

On Thu, Jun 23, 2016 at 10:52:51PM +0300, Dan Jurgens wrote:
> From: Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
> 
> Add a type and access vector for PKeys. Implement the qp_pkey_access
> and mad_agent_pkey_access hooks to check that the caller has
> permission to access the PKey on the given subnet prefix.  Add an

Extra space before " Add"

> interface to get the PKey SID. Walk the PKey ocontexts to find an entry
> for the given subnet prefix and pkey.
> 
> Signed-off-by: Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
> Reviewed-by: Eli Cohen <eli-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
> ---
>  include/linux/lsm_audit.h                        |  7 ++++
>  security/selinux/hooks.c                         | 41 ++++++++++++++++++++++++
>  security/selinux/include/classmap.h              |  2 ++
>  security/selinux/include/initial_sid_to_string.h |  1 +
>  security/selinux/include/security.h              |  2 ++
>  security/selinux/ss/services.c                   | 41 ++++++++++++++++++++++++
>  6 files changed, 94 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/selinux/hooks.c b/security/selinux/hooks.c
> index 4f13ea4..5a40b10 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -6018,6 +6018,44 @@ static void selinux_unregister_ib_flush_callback(void)
>  	mutex_unlock(&ib_flush_mutex);
>  }
>  
> +static int selinux_pkey_access(u64 subnet_prefix, u16 pkey_val, void *security)
> +{
> +	struct common_audit_data ad;
> +	int err;
> +	u32 sid = 0;
> +	struct ib_security_struct *sec = security;
> +	struct lsm_pkey_audit pkey;
> +
> +	err = security_pkey_sid(subnet_prefix, pkey_val, &sid);
> +
> +	if (err)
> +		goto out;
> +
> +	ad.type = LSM_AUDIT_DATA_PKEY;
> +	pkey.subnet_prefix = subnet_prefix;
> +	pkey.pkey = pkey_val;
> +	ad.u.pkey = &pkey;
> +	err = avc_has_perm(sec->sid, sid,
> +			   SECCLASS_INFINIBAND_PKEY,
> +			   INFINIBAND_PKEY__ACCESS, &ad);
> +out:
> +	return err;
> +}
> +
> +static int selinux_ib_qp_pkey_access(u64 subnet_prefix, u16 pkey_val,
> +				     struct ib_qp_security *qp_sec)
> +{
> +	return selinux_pkey_access(subnet_prefix, pkey_val,
> +				   qp_sec->q_security);
> +}
> +
> +static int selinux_ib_mad_agent_pkey_access(u64 subnet_prefix, u16 pkey_val,
> +					    struct ib_mad_agent *mad_agent)
> +{
> +	return selinux_pkey_access(subnet_prefix, pkey_val,
> +					mad_agent->m_security);
> +}
> +
>  static int selinux_ib_qp_alloc_security(struct ib_qp_security *qp_sec)
>  {
>  	struct ib_security_struct *sec;
> @@ -6248,6 +6286,9 @@ static struct security_hook_list selinux_hooks[] = {
>  		      selinux_register_ib_flush_callback),
>  	LSM_HOOK_INIT(unregister_ib_flush_callback,
>  		      selinux_unregister_ib_flush_callback),
> +	LSM_HOOK_INIT(ib_qp_pkey_access, selinux_ib_qp_pkey_access),
> +	LSM_HOOK_INIT(ib_mad_agent_pkey_access,
> +		      selinux_ib_mad_agent_pkey_access),
>  	LSM_HOOK_INIT(ib_qp_alloc_security,
>  		      selinux_ib_qp_alloc_security),
>  	LSM_HOOK_INIT(ib_qp_free_security,
> diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h
> index 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/initial_sid_to_string.h b/security/selinux/include/initial_sid_to_string.h
> index a59b64e..8f2eefc 100644
> --- a/security/selinux/include/initial_sid_to_string.h
> +++ b/security/selinux/include/initial_sid_to_string.h
> @@ -29,5 +29,6 @@ static const char *initial_sid_to_string[] =
>      "policy",
>      "scmp_packet",
>      "devnull",
> +    "pkey",
>  };
>  
> 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..49701a5 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_PKEY;
> +	}

Curly brackets are not needed

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

* Re: [PATCH 05/12] selinux: Implement Infiniband PKey "Access" access vector
@ 2016-06-30 15:23         ` Yuval Shaia
  0 siblings, 0 replies; 128+ messages in thread
From: Yuval Shaia @ 2016-06-30 15:23 UTC (permalink / raw)
  To: Dan Jurgens
  Cc: chrisw, paul, sds, eparis, dledford, sean.hefty, hal.rosenstock,
	selinux, linux-security-module, linux-rdma, yevgenyp

On Thu, Jun 23, 2016 at 10:52:51PM +0300, Dan Jurgens wrote:
> From: Daniel Jurgens <danielj@mellanox.com>
> 
> Add a type and access vector for PKeys. Implement the qp_pkey_access
> and mad_agent_pkey_access hooks to check that the caller has
> permission to access the PKey on the given subnet prefix.  Add an

Extra space before " Add"

> 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>
> Reviewed-by: Eli Cohen <eli@mellanox.com>
> ---
>  include/linux/lsm_audit.h                        |  7 ++++
>  security/selinux/hooks.c                         | 41 ++++++++++++++++++++++++
>  security/selinux/include/classmap.h              |  2 ++
>  security/selinux/include/initial_sid_to_string.h |  1 +
>  security/selinux/include/security.h              |  2 ++
>  security/selinux/ss/services.c                   | 41 ++++++++++++++++++++++++
>  6 files changed, 94 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/selinux/hooks.c b/security/selinux/hooks.c
> index 4f13ea4..5a40b10 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -6018,6 +6018,44 @@ static void selinux_unregister_ib_flush_callback(void)
>  	mutex_unlock(&ib_flush_mutex);
>  }
>  
> +static int selinux_pkey_access(u64 subnet_prefix, u16 pkey_val, void *security)
> +{
> +	struct common_audit_data ad;
> +	int err;
> +	u32 sid = 0;
> +	struct ib_security_struct *sec = security;
> +	struct lsm_pkey_audit pkey;
> +
> +	err = security_pkey_sid(subnet_prefix, pkey_val, &sid);
> +
> +	if (err)
> +		goto out;
> +
> +	ad.type = LSM_AUDIT_DATA_PKEY;
> +	pkey.subnet_prefix = subnet_prefix;
> +	pkey.pkey = pkey_val;
> +	ad.u.pkey = &pkey;
> +	err = avc_has_perm(sec->sid, sid,
> +			   SECCLASS_INFINIBAND_PKEY,
> +			   INFINIBAND_PKEY__ACCESS, &ad);
> +out:
> +	return err;
> +}
> +
> +static int selinux_ib_qp_pkey_access(u64 subnet_prefix, u16 pkey_val,
> +				     struct ib_qp_security *qp_sec)
> +{
> +	return selinux_pkey_access(subnet_prefix, pkey_val,
> +				   qp_sec->q_security);
> +}
> +
> +static int selinux_ib_mad_agent_pkey_access(u64 subnet_prefix, u16 pkey_val,
> +					    struct ib_mad_agent *mad_agent)
> +{
> +	return selinux_pkey_access(subnet_prefix, pkey_val,
> +					mad_agent->m_security);
> +}
> +
>  static int selinux_ib_qp_alloc_security(struct ib_qp_security *qp_sec)
>  {
>  	struct ib_security_struct *sec;
> @@ -6248,6 +6286,9 @@ static struct security_hook_list selinux_hooks[] = {
>  		      selinux_register_ib_flush_callback),
>  	LSM_HOOK_INIT(unregister_ib_flush_callback,
>  		      selinux_unregister_ib_flush_callback),
> +	LSM_HOOK_INIT(ib_qp_pkey_access, selinux_ib_qp_pkey_access),
> +	LSM_HOOK_INIT(ib_mad_agent_pkey_access,
> +		      selinux_ib_mad_agent_pkey_access),
>  	LSM_HOOK_INIT(ib_qp_alloc_security,
>  		      selinux_ib_qp_alloc_security),
>  	LSM_HOOK_INIT(ib_qp_free_security,
> diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h
> index 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/initial_sid_to_string.h b/security/selinux/include/initial_sid_to_string.h
> index a59b64e..8f2eefc 100644
> --- a/security/selinux/include/initial_sid_to_string.h
> +++ b/security/selinux/include/initial_sid_to_string.h
> @@ -29,5 +29,6 @@ static const char *initial_sid_to_string[] =
>      "policy",
>      "scmp_packet",
>      "devnull",
> +    "pkey",
>  };
>  
> 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..49701a5 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_PKEY;
> +	}

Curly brackets are not needed

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

* Re: [PATCH 06/12] selinux: Add IB End Port SMP access vector
  2016-06-23 19:52     ` Dan Jurgens
  (?)
@ 2016-06-30 15:31     ` Yuval Shaia
  -1 siblings, 0 replies; 128+ messages in thread
From: Yuval Shaia @ 2016-06-30 15:31 UTC (permalink / raw)
  To: Dan Jurgens
  Cc: chrisw, paul, sds, eparis, dledford, sean.hefty, hal.rosenstock,
	selinux, linux-security-module, linux-rdma, yevgenyp

On Thu, Jun 23, 2016 at 10:52:52PM +0300, Dan Jurgens wrote:
> From: Daniel Jurgens <danielj@mellanox.com>
> 
> Add a type for Infiniband end ports and an access vector for subnet
> management packets. Implement the ib_end_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

Extra space before " Add"

> end port, which walks the IB_END_PORT ocontexts to find an entry for the
> given name and port.
> 
> Signed-off-by: Daniel Jurgens <danielj@mellanox.com>
> Reviewed-by: Eli Cohen <eli@mellanox.com>
> ---
>  include/linux/lsm_audit.h                        | 32 +++++++++++-------
>  security/selinux/hooks.c                         | 27 +++++++++++++++
>  security/selinux/include/classmap.h              |  2 ++
>  security/selinux/include/initial_sid_to_string.h |  1 +
>  security/selinux/include/security.h              |  2 ++
>  security/selinux/ss/services.c                   | 43 ++++++++++++++++++++++++
>  6 files changed, 95 insertions(+), 12 deletions(-)
> 
> diff --git a/include/linux/lsm_audit.h b/include/linux/lsm_audit.h
> index 8ff7eae..acf6de7 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_end_port_audit {
> +	char	dev_name[IB_DEVICE_NAME_MAX];
> +	u8	port;
> +};
> +
>  /* Auxiliary data to use in generating the audit record. */
>  struct common_audit_data {
>  	char type;
> -#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_END_PORT	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_end_port_audit *ib_end_port;
>  	} u;
>  	/* this union contains LSM specific data */
>  	union {
> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index 5a40b10..fc44542 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -6056,6 +6056,32 @@ static int selinux_ib_mad_agent_pkey_access(u64 subnet_prefix, u16 pkey_val,
>  					mad_agent->m_security);
>  }
>  
> +static int selinux_ib_end_port_smp(const char *dev_name, u8 port,
> +				   struct ib_mad_agent *mad_agent)
> +{
> +	struct common_audit_data ad;
> +	int err;
> +	u32 sid = 0;
> +	struct ib_security_struct *sec = mad_agent->m_security;
> +	struct lsm_ib_end_port_audit ib_end_port;
> +
> +	err = security_ib_end_port_sid(dev_name, port, &sid);
> +
> +	if (err)
> +		goto out;
> +
> +	ad.type = LSM_AUDIT_DATA_IB_END_PORT;
> +	strncpy(ib_end_port.dev_name, dev_name, sizeof(ib_end_port.dev_name));
> +	ib_end_port.port = port;
> +	ad.u.ib_end_port = &ib_end_port;
> +	err = avc_has_perm(sec->sid, sid,
> +			   SECCLASS_INFINIBAND_END_PORT,
> +			   INFINIBAND_END_PORT__SMP, &ad);
> +
> +out:
> +	return err;
> +}
> +
>  static int selinux_ib_qp_alloc_security(struct ib_qp_security *qp_sec)
>  {
>  	struct ib_security_struct *sec;
> @@ -6289,6 +6315,7 @@ static struct security_hook_list selinux_hooks[] = {
>  	LSM_HOOK_INIT(ib_qp_pkey_access, selinux_ib_qp_pkey_access),
>  	LSM_HOOK_INIT(ib_mad_agent_pkey_access,
>  		      selinux_ib_mad_agent_pkey_access),
> +	LSM_HOOK_INIT(ib_end_port_smp, selinux_ib_end_port_smp),
>  	LSM_HOOK_INIT(ib_qp_alloc_security,
>  		      selinux_ib_qp_alloc_security),
>  	LSM_HOOK_INIT(ib_qp_free_security,
> diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h
> index d42dd4d..21972c8 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_end_port",
> +	  { "smp", NULL } },
>  	{ NULL }
>    };
> diff --git a/security/selinux/include/initial_sid_to_string.h b/security/selinux/include/initial_sid_to_string.h
> index 8f2eefc..ba47169 100644
> --- a/security/selinux/include/initial_sid_to_string.h
> +++ b/security/selinux/include/initial_sid_to_string.h
> @@ -30,5 +30,6 @@ static const char *initial_sid_to_string[] =
>      "scmp_packet",
>      "devnull",
>      "pkey",
> +    "ib_end_port",
>  };
>  
> diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
> index 8f1a66e..f5d9d4e 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_end_port_sid(const char *dev_name, u8 port, u32 *out_sid);
> +
>  int security_netif_sid(char *name, u32 *if_sid);
>  
>  int security_node_sid(u16 domain, void *addr, u32 addrlen,
> diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
> index 49701a5..9afabee 100644
> --- a/security/selinux/ss/services.c
> +++ b/security/selinux/ss/services.c
> @@ -53,6 +53,7 @@
>  #include <linux/flex_array.h>
>  #include <linux/vmalloc.h>
>  #include <net/netlabel.h>
> +#include <rdma/ib_verbs.h>
>  
>  #include "flask.h"
>  #include "avc.h"
> @@ -2270,6 +2271,48 @@ out:
>  }
>  
>  /**
> + * security_ib_end_port_sid - Obtain the SID for a subnet management interface.
> + * @dev_name: device name
> + * @port: port number
> + * @out_sid: security identifier
> + */
> +int security_ib_end_port_sid(const char *dev_name, u8 port, u32 *out_sid)
> +{
> +	struct ocontext *c;
> +	int rc = 0;
> +
> +	read_lock(&policy_rwlock);
> +
> +	c = policydb.ocontexts[OCON_IB_END_PORT];
> +	while (c) {
> +		if (c->u.ib_end_port.port == port &&
> +		    !strncmp(c->u.ib_end_port.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_IB_END_PORT;
> +	}

Curly braces are not allowed here

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

* Re: [PATCH 05/12] selinux: Implement Infiniband PKey "Access" access vector
  2016-06-30 15:23         ` Yuval Shaia
@ 2016-06-30 15:35           ` Daniel Jurgens
  -1 siblings, 0 replies; 128+ messages in thread
From: Daniel Jurgens @ 2016-06-30 15:35 UTC (permalink / raw)
  To: Yuval Shaia
  Cc: linux-rdma-u79uwXL29TY76Z2rM5mHXA,
	linux-security-module-u79uwXL29TY76Z2rM5mHXA,
	chrisw-69jw2NvuJkxg9hUCZPvPmw, dledford-H+wXaHxf7aLQT0dZR+AlfA,
	selinux-+05T5uksL2qpZYMLLGbcSA,
	sean.hefty-ral2JQCrhuEAvxtiuMwx3w, sds-+05T5uksL2qpZYMLLGbcSA,
	hal.rosenstock-Re5JQEeQqe8AvxtiuMwx3w

On 6/30/2016 10:24 AM, Yuval Shaia wrote:
> On Thu, Jun 23, 2016 at 10:52:51PM +0300, Dan Jurgens wrote:
>> +	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_PKEY;
>> +	}
> Curly brackets are not needed
>
According to the coding style guide if either branch requires brackets both should use them:

This does not apply if only one branch of a conditional statement is a single
statement; in the latter case use braces in both branches:

	if (condition) {
		do_this();
		do_that();
	} else {
		otherwise();
	}



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

* Re: [PATCH 05/12] selinux: Implement Infiniband PKey "Access" access vector
@ 2016-06-30 15:35           ` Daniel Jurgens
  0 siblings, 0 replies; 128+ messages in thread
From: Daniel Jurgens @ 2016-06-30 15:35 UTC (permalink / raw)
  To: Yuval Shaia
  Cc: chrisw, paul, sds, eparis, dledford, sean.hefty, hal.rosenstock,
	selinux, linux-security-module, linux-rdma, Yevgeny Petrilin

On 6/30/2016 10:24 AM, Yuval Shaia wrote:
> On Thu, Jun 23, 2016 at 10:52:51PM +0300, Dan Jurgens wrote:
>> +	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_PKEY;
>> +	}
> Curly brackets are not needed
>
According to the coding style guide if either branch requires brackets both should use them:

This does not apply if only one branch of a conditional statement is a single
statement; in the latter case use braces in both branches:

	if (condition) {
		do_this();
		do_that();
	} else {
		otherwise();
	}

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

* Re: [PATCH 07/12] selinux: Add a cache for quicker retreival of PKey SIDs
  2016-06-23 19:52     ` Dan Jurgens
@ 2016-06-30 15:41         ` Yuval Shaia
  -1 siblings, 0 replies; 128+ messages in thread
From: Yuval Shaia @ 2016-06-30 15:41 UTC (permalink / raw)
  To: Dan Jurgens
  Cc: 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

On Thu, Jun 23, 2016 at 10:52:53PM +0300, Dan Jurgens wrote:
> 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.

Extra space before " To"

> 
> 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>
> Reviewed-by: Eli Cohen <eli-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
> ---
>  security/selinux/Makefile         |   2 +-
>  security/selinux/hooks.c          |   5 +-
>  security/selinux/include/objsec.h |   6 +
>  security/selinux/include/pkey.h   |  31 +++++
>  security/selinux/pkey.c           | 243 ++++++++++++++++++++++++++++++++++++++
>  5 files changed, 285 insertions(+), 2 deletions(-)
>  create mode 100644 security/selinux/include/pkey.h
>  create mode 100644 security/selinux/pkey.c
> 
> diff --git a/security/selinux/Makefile b/security/selinux/Makefile
> index 3411c33..a698df4 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 pkey.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 fc44542..5c8cebb 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -92,6 +92,7 @@
>  #include "netif.h"
>  #include "netnode.h"
>  #include "netport.h"
> +#include "pkey.h"
>  #include "xfrm.h"
>  #include "netlabel.h"
>  #include "audit.h"
> @@ -172,6 +173,8 @@ static int selinux_cache_avc_callback(u32 event)
>  		sel_netnode_flush();
>  		sel_netport_flush();
>  		synchronize_net();
> +
> +		sel_pkey_flush();
>  		mutex_lock(&ib_flush_mutex);
>  		if (ib_flush_callback)
>  			ib_flush_callback();
> @@ -6026,7 +6029,7 @@ static int selinux_pkey_access(u64 subnet_prefix, u16 pkey_val, void *security)
>  	struct ib_security_struct *sec = security;
>  	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)
>  		goto out;
> 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_ */
> diff --git a/security/selinux/include/pkey.h b/security/selinux/include/pkey.h
> new file mode 100644
> index 0000000..58a7a3b
> --- /dev/null
> +++ b/security/selinux/include/pkey.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_H
> +#define _SELINUX_IB_H
> +
> +void sel_pkey_flush(void);
> +
> +int sel_pkey_sid(u64 subnet_prefix, u16 pkey, u32 *sid);
> +
> +#endif
> diff --git a/security/selinux/pkey.c b/security/selinux/pkey.c
> new file mode 100644
> index 0000000..565474d
> --- /dev/null
> +++ b/security/selinux/pkey.c
> @@ -0,0 +1,243 @@
> +/*
> + * 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 "pkey.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;
> +		}

'}' should be below "list_for_each_entry_rcu" to avoid reading mistakes.

> +
> +	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++;
> +	}

Curly braces are not allowed here.

> +}
> +
> +/**
> + * 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;
> +
> +	spin_lock_bh(&sel_pkey_lock);
> +	pkey = sel_pkey_find(subnet_prefix, pkey_num);
> +	if (pkey) {
> +		*sid = pkey->psec.sid;
> +		spin_unlock_bh(&sel_pkey_lock);
> +		return 0;
> +	}
> +
> +	ret = security_pkey_sid(subnet_prefix, pkey_num, sid);
> +	if (ret != 0)
> +		goto out;
> +
> +	new = kzalloc(sizeof(*new), GFP_ATOMIC);

Kindly reminder to make sure GFP_ATOMIC is needed.

> +	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_bh(&sel_pkey_lock);
> +	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;
> +
> +	spin_lock_bh(&sel_pkey_lock);
> +	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_bh(&sel_pkey_lock);
> +}
> +
> +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);
> -- 
> 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
--
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] 128+ messages in thread

* Re: [PATCH 07/12] selinux: Add a cache for quicker retreival of PKey SIDs
@ 2016-06-30 15:41         ` Yuval Shaia
  0 siblings, 0 replies; 128+ messages in thread
From: Yuval Shaia @ 2016-06-30 15:41 UTC (permalink / raw)
  To: Dan Jurgens
  Cc: chrisw, paul, sds, eparis, dledford, sean.hefty, hal.rosenstock,
	selinux, linux-security-module, linux-rdma, yevgenyp

On Thu, Jun 23, 2016 at 10:52:53PM +0300, Dan Jurgens wrote:
> 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.

Extra space before " To"

> 
> 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>
> Reviewed-by: Eli Cohen <eli@mellanox.com>
> ---
>  security/selinux/Makefile         |   2 +-
>  security/selinux/hooks.c          |   5 +-
>  security/selinux/include/objsec.h |   6 +
>  security/selinux/include/pkey.h   |  31 +++++
>  security/selinux/pkey.c           | 243 ++++++++++++++++++++++++++++++++++++++
>  5 files changed, 285 insertions(+), 2 deletions(-)
>  create mode 100644 security/selinux/include/pkey.h
>  create mode 100644 security/selinux/pkey.c
> 
> diff --git a/security/selinux/Makefile b/security/selinux/Makefile
> index 3411c33..a698df4 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 pkey.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 fc44542..5c8cebb 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -92,6 +92,7 @@
>  #include "netif.h"
>  #include "netnode.h"
>  #include "netport.h"
> +#include "pkey.h"
>  #include "xfrm.h"
>  #include "netlabel.h"
>  #include "audit.h"
> @@ -172,6 +173,8 @@ static int selinux_cache_avc_callback(u32 event)
>  		sel_netnode_flush();
>  		sel_netport_flush();
>  		synchronize_net();
> +
> +		sel_pkey_flush();
>  		mutex_lock(&ib_flush_mutex);
>  		if (ib_flush_callback)
>  			ib_flush_callback();
> @@ -6026,7 +6029,7 @@ static int selinux_pkey_access(u64 subnet_prefix, u16 pkey_val, void *security)
>  	struct ib_security_struct *sec = security;
>  	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)
>  		goto out;
> 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_ */
> diff --git a/security/selinux/include/pkey.h b/security/selinux/include/pkey.h
> new file mode 100644
> index 0000000..58a7a3b
> --- /dev/null
> +++ b/security/selinux/include/pkey.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_H
> +#define _SELINUX_IB_H
> +
> +void sel_pkey_flush(void);
> +
> +int sel_pkey_sid(u64 subnet_prefix, u16 pkey, u32 *sid);
> +
> +#endif
> diff --git a/security/selinux/pkey.c b/security/selinux/pkey.c
> new file mode 100644
> index 0000000..565474d
> --- /dev/null
> +++ b/security/selinux/pkey.c
> @@ -0,0 +1,243 @@
> +/*
> + * 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 "pkey.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;
> +		}

'}' should be below "list_for_each_entry_rcu" to avoid reading mistakes.

> +
> +	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++;
> +	}

Curly braces are not allowed here.

> +}
> +
> +/**
> + * 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;
> +
> +	spin_lock_bh(&sel_pkey_lock);
> +	pkey = sel_pkey_find(subnet_prefix, pkey_num);
> +	if (pkey) {
> +		*sid = pkey->psec.sid;
> +		spin_unlock_bh(&sel_pkey_lock);
> +		return 0;
> +	}
> +
> +	ret = security_pkey_sid(subnet_prefix, pkey_num, sid);
> +	if (ret != 0)
> +		goto out;
> +
> +	new = kzalloc(sizeof(*new), GFP_ATOMIC);

Kindly reminder to make sure GFP_ATOMIC is needed.

> +	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_bh(&sel_pkey_lock);
> +	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;
> +
> +	spin_lock_bh(&sel_pkey_lock);
> +	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_bh(&sel_pkey_lock);
> +}
> +
> +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);
> -- 
> 1.8.3.1
> 
> --
> 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] 128+ messages in thread

* Re: [PATCH 03/12] selinux: Implement Infiniband flush callback
  2016-06-30 15:10         ` Yuval Shaia
@ 2016-06-30 15:44           ` Daniel Jurgens
  -1 siblings, 0 replies; 128+ messages in thread
From: Daniel Jurgens @ 2016-06-30 15:44 UTC (permalink / raw)
  To: Yuval Shaia
  Cc: linux-rdma-u79uwXL29TY76Z2rM5mHXA,
	linux-security-module-u79uwXL29TY76Z2rM5mHXA,
	chrisw-69jw2NvuJkxg9hUCZPvPmw, dledford-H+wXaHxf7aLQT0dZR+AlfA,
	selinux-+05T5uksL2qpZYMLLGbcSA,
	sean.hefty-ral2JQCrhuEAvxtiuMwx3w, sds-+05T5uksL2qpZYMLLGbcSA,
	hal.rosenstock-Re5JQEeQqe8AvxtiuMwx3w

On 6/30/2016 10:10 AM, Yuval Shaia wrote:
> On Thu, Jun 23, 2016 at 10:52:49PM +0300, Dan Jurgens wrote:
>
>> +static void (*ib_flush_callback)(void);
> Do we really want to have such ib_ prefix in security/ directory?
>
>> +		if (ib_flush_callback)
>> +			ib_flush_callback();
> How about some generic mechanism (such as a list) in case more
> modules/drivers would like to register callbacks?
> ( assuming this is no longer RFC :) )
>
Paul Moore and I were having a higher level discussion about this in the 00/12 thread.  I think your suggestion makes sense, perhaps Paul will weigh in when he reaches this patch.

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

* Re: [PATCH 03/12] selinux: Implement Infiniband flush callback
@ 2016-06-30 15:44           ` Daniel Jurgens
  0 siblings, 0 replies; 128+ messages in thread
From: Daniel Jurgens @ 2016-06-30 15:44 UTC (permalink / raw)
  To: Yuval Shaia
  Cc: chrisw, paul, sds, eparis, dledford, sean.hefty, hal.rosenstock,
	selinux, linux-security-module, linux-rdma, Yevgeny Petrilin

On 6/30/2016 10:10 AM, Yuval Shaia wrote:
> On Thu, Jun 23, 2016 at 10:52:49PM +0300, Dan Jurgens wrote:
>
>> +static void (*ib_flush_callback)(void);
> Do we really want to have such ib_ prefix in security/ directory?
>
>> +		if (ib_flush_callback)
>> +			ib_flush_callback();
> How about some generic mechanism (such as a list) in case more
> modules/drivers would like to register callbacks?
> ( assuming this is no longer RFC :) )
>
Paul Moore and I were having a higher level discussion about this in the 00/12 thread.  I think your suggestion makes sense, perhaps Paul will weigh in when he reaches this patch.

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

* Re: [PATCH 08/12] IB/core: IB cache enhancements to support Infiniband security
  2016-06-23 19:52     ` Dan Jurgens
@ 2016-06-30 15:47         ` Yuval Shaia
  -1 siblings, 0 replies; 128+ messages in thread
From: Yuval Shaia @ 2016-06-30 15:47 UTC (permalink / raw)
  To: Dan Jurgens
  Cc: 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

On Thu, Jun 23, 2016 at 10:52:54PM +0300, Dan Jurgens wrote:
> From: Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
> 
> Cache the subnet prefix and add a function to access it. Enforcing
> security requires frequent queries of the subnet prefix and the pkeys in
> the pkey table.
> 
> Also removed an unneded pr_warn about memory allocation failure.
> 
> Signed-off-by: Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
> Reviewed-by: Eli Cohen <eli-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
> Reviewed-by: Leon Romanovsky <leonro-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
> ---
>  drivers/infiniband/core/cache.c     | 35 +++++++++++++++++++++++++++++++++--
>  drivers/infiniband/core/core_priv.h |  3 +++
>  include/rdma/ib_verbs.h             |  1 +
>  3 files changed, 37 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/infiniband/core/cache.c b/drivers/infiniband/core/cache.c
> index c2e257d..4894e21 100644
> --- a/drivers/infiniband/core/cache.c
> +++ b/drivers/infiniband/core/cache.c
> @@ -926,6 +926,25 @@ 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 = port_num - rdma_start_port(device);

Suggesting to initialize p after the validation.

> +
> +	if (port_num < rdma_start_port(device) ||
> +	    port_num > rdma_end_port(device))
> +		return -EINVAL;
> +
> +	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,
> @@ -1102,6 +1121,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);
> @@ -1160,9 +1181,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),

More than 80 characters.

> +						    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;
>  	}
>  
> @@ -1205,6 +1235,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 e522acb..c00b6b1 100644
> --- a/include/rdma/ib_verbs.h
> +++ b/include/rdma/ib_verbs.h
> @@ -1637,6 +1637,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
> 
> --
> 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
--
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] 128+ messages in thread

* Re: [PATCH 08/12] IB/core: IB cache enhancements to support Infiniband security
@ 2016-06-30 15:47         ` Yuval Shaia
  0 siblings, 0 replies; 128+ messages in thread
From: Yuval Shaia @ 2016-06-30 15:47 UTC (permalink / raw)
  To: Dan Jurgens
  Cc: chrisw, paul, sds, eparis, dledford, sean.hefty, hal.rosenstock,
	selinux, linux-security-module, linux-rdma, yevgenyp

On Thu, Jun 23, 2016 at 10:52:54PM +0300, Dan Jurgens wrote:
> 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>
> ---
>  drivers/infiniband/core/cache.c     | 35 +++++++++++++++++++++++++++++++++--
>  drivers/infiniband/core/core_priv.h |  3 +++
>  include/rdma/ib_verbs.h             |  1 +
>  3 files changed, 37 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/infiniband/core/cache.c b/drivers/infiniband/core/cache.c
> index c2e257d..4894e21 100644
> --- a/drivers/infiniband/core/cache.c
> +++ b/drivers/infiniband/core/cache.c
> @@ -926,6 +926,25 @@ 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 = port_num - rdma_start_port(device);

Suggesting to initialize p after the validation.

> +
> +	if (port_num < rdma_start_port(device) ||
> +	    port_num > rdma_end_port(device))
> +		return -EINVAL;
> +
> +	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,
> @@ -1102,6 +1121,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);
> @@ -1160,9 +1181,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),

More than 80 characters.

> +						    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;
>  	}
>  
> @@ -1205,6 +1235,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 e522acb..c00b6b1 100644
> --- a/include/rdma/ib_verbs.h
> +++ b/include/rdma/ib_verbs.h
> @@ -1637,6 +1637,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
> 
> --
> 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] 128+ messages in thread

* Re: [PATCH 03/12] selinux: Implement Infiniband flush callback
  2016-06-30 15:44           ` Daniel Jurgens
@ 2016-06-30 19:52               ` Paul Moore
  -1 siblings, 0 replies; 128+ messages in thread
From: Paul Moore @ 2016-06-30 19:52 UTC (permalink / raw)
  To: Daniel Jurgens, Yuval Shaia
  Cc: linux-rdma-u79uwXL29TY76Z2rM5mHXA,
	linux-security-module-u79uwXL29TY76Z2rM5mHXA,
	chrisw-69jw2NvuJkxg9hUCZPvPmw, dledford-H+wXaHxf7aLQT0dZR+AlfA,
	selinux-+05T5uksL2qpZYMLLGbcSA,
	sean.hefty-ral2JQCrhuEAvxtiuMwx3w, sds-+05T5uksL2qpZYMLLGbcSA,
	hal.rosenstock-Re5JQEeQqe8AvxtiuMwx3w

On Thu, Jun 30, 2016 at 11:44 AM, Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org> wrote:
> On 6/30/2016 10:10 AM, Yuval Shaia wrote:
>> On Thu, Jun 23, 2016 at 10:52:49PM +0300, Dan Jurgens wrote:
>>
>>> +static void (*ib_flush_callback)(void);
>> Do we really want to have such ib_ prefix in security/ directory?
>>
>>> +            if (ib_flush_callback)
>>> +                    ib_flush_callback();
>> How about some generic mechanism (such as a list) in case more
>> modules/drivers would like to register callbacks?
>> ( assuming this is no longer RFC :) )
>>
> Paul Moore and I were having a higher level discussion about this in the 00/12 thread.  I think your suggestion makes sense, perhaps Paul will weigh in when he reaches this patch.

I'm still working on understanding IB, but my current thinking is very
similar to Yuval's suggestions.  There is a risk of creating a general
purpose mechanism to solve a specific, isolated problem, but adding a
LSM notification mechanism does seem like a reasonable thing to do.

My current thinking is to have the LSM framework itself, e.g.
security/security.c, maintain a list of callbacks (BTW, please make it
a RCU protected list) with other non-LSM subsystems registering
callbacks, and specific LSMs making notification calls into the LSM
framework itself which would handle iterating through the registered
callbacks.  Since we're going down the general purpose solution route,
I might add an event field and a void pointer to the callback, for
example:

  void lsm_notifier_callback(unsigned int event, void *ptr);

... I would expect at first we would only have a POLICY_CHANGE event
(ptr set to NULL), but we may want/need to add other events in the
future.

Make sense?

-- 
paul moore
security @ redhat
--
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] 128+ messages in thread

* Re: [PATCH 03/12] selinux: Implement Infiniband flush callback
@ 2016-06-30 19:52               ` Paul Moore
  0 siblings, 0 replies; 128+ messages in thread
From: Paul Moore @ 2016-06-30 19:52 UTC (permalink / raw)
  To: Daniel Jurgens, Yuval Shaia
  Cc: linux-rdma, linux-security-module, chrisw, dledford, selinux,
	sean.hefty, sds, hal.rosenstock

On Thu, Jun 30, 2016 at 11:44 AM, Daniel Jurgens <danielj@mellanox.com> wrote:
> On 6/30/2016 10:10 AM, Yuval Shaia wrote:
>> On Thu, Jun 23, 2016 at 10:52:49PM +0300, Dan Jurgens wrote:
>>
>>> +static void (*ib_flush_callback)(void);
>> Do we really want to have such ib_ prefix in security/ directory?
>>
>>> +            if (ib_flush_callback)
>>> +                    ib_flush_callback();
>> How about some generic mechanism (such as a list) in case more
>> modules/drivers would like to register callbacks?
>> ( assuming this is no longer RFC :) )
>>
> Paul Moore and I were having a higher level discussion about this in the 00/12 thread.  I think your suggestion makes sense, perhaps Paul will weigh in when he reaches this patch.

I'm still working on understanding IB, but my current thinking is very
similar to Yuval's suggestions.  There is a risk of creating a general
purpose mechanism to solve a specific, isolated problem, but adding a
LSM notification mechanism does seem like a reasonable thing to do.

My current thinking is to have the LSM framework itself, e.g.
security/security.c, maintain a list of callbacks (BTW, please make it
a RCU protected list) with other non-LSM subsystems registering
callbacks, and specific LSMs making notification calls into the LSM
framework itself which would handle iterating through the registered
callbacks.  Since we're going down the general purpose solution route,
I might add an event field and a void pointer to the callback, for
example:

  void lsm_notifier_callback(unsigned int event, void *ptr);

... I would expect at first we would only have a POLICY_CHANGE event
(ptr set to NULL), but we may want/need to add other events in the
future.

Make sense?

-- 
paul moore
security @ redhat

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

* Re: [PATCH 03/12] selinux: Implement Infiniband flush callback
  2016-06-30 19:52               ` Paul Moore
@ 2016-06-30 20:16                   ` Casey Schaufler
  -1 siblings, 0 replies; 128+ messages in thread
From: Casey Schaufler @ 2016-06-30 20:16 UTC (permalink / raw)
  To: Paul Moore, Daniel Jurgens, Yuval Shaia
  Cc: linux-rdma-u79uwXL29TY76Z2rM5mHXA,
	dledford-H+wXaHxf7aLQT0dZR+AlfA, chrisw-69jw2NvuJkxg9hUCZPvPmw,
	linux-security-module-u79uwXL29TY76Z2rM5mHXA,
	selinux-+05T5uksL2qpZYMLLGbcSA,
	sean.hefty-ral2JQCrhuEAvxtiuMwx3w, sds-+05T5uksL2qpZYMLLGbcSA,
	hal.rosenstock-Re5JQEeQqe8AvxtiuMwx3w

On 6/30/2016 12:52 PM, Paul Moore wrote:
> On Thu, Jun 30, 2016 at 11:44 AM, Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org> wrote:
>> On 6/30/2016 10:10 AM, Yuval Shaia wrote:
>>> On Thu, Jun 23, 2016 at 10:52:49PM +0300, Dan Jurgens wrote:
>>>
>>>> +static void (*ib_flush_callback)(void);
>>> Do we really want to have such ib_ prefix in security/ directory?
>>>
>>>> +            if (ib_flush_callback)
>>>> +                    ib_flush_callback();
>>> How about some generic mechanism (such as a list) in case more
>>> modules/drivers would like to register callbacks?
>>> ( assuming this is no longer RFC :) )
>>>
>> Paul Moore and I were having a higher level discussion about this in the 00/12 thread.  I think your suggestion makes sense, perhaps Paul will weigh in when he reaches this patch.
> I'm still working on understanding IB, but my current thinking is very
> similar to Yuval's suggestions.  There is a risk of creating a general
> purpose mechanism to solve a specific, isolated problem, but adding a
> LSM notification mechanism does seem like a reasonable thing to do.
>
> My current thinking is to have the LSM framework itself, e.g.
> security/security.c, maintain a list of callbacks (BTW, please make it
> a RCU protected list) with other non-LSM subsystems registering
> callbacks, and specific LSMs making notification calls into the LSM
> framework itself which would handle iterating through the registered
> callbacks.  Since we're going down the general purpose solution route,
> I might add an event field and a void pointer to the callback, for
> example:
>
>   void lsm_notifier_callback(unsigned int event, void *ptr);
>
> ... I would expect at first we would only have a POLICY_CHANGE event
> (ptr set to NULL), but we may want/need to add other events in the
> future.
>
> Make sense?

Hmm. Do you think that we'd want to rewhack the audit code
so that it used this new, general mechanism for its callbacks?

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

* Re: [PATCH 03/12] selinux: Implement Infiniband flush callback
@ 2016-06-30 20:16                   ` Casey Schaufler
  0 siblings, 0 replies; 128+ messages in thread
From: Casey Schaufler @ 2016-06-30 20:16 UTC (permalink / raw)
  To: Paul Moore, Daniel Jurgens, Yuval Shaia
  Cc: linux-rdma, linux-security-module, chrisw, dledford, selinux,
	sean.hefty, sds, hal.rosenstock

On 6/30/2016 12:52 PM, Paul Moore wrote:
> On Thu, Jun 30, 2016 at 11:44 AM, Daniel Jurgens <danielj@mellanox.com> wrote:
>> On 6/30/2016 10:10 AM, Yuval Shaia wrote:
>>> On Thu, Jun 23, 2016 at 10:52:49PM +0300, Dan Jurgens wrote:
>>>
>>>> +static void (*ib_flush_callback)(void);
>>> Do we really want to have such ib_ prefix in security/ directory?
>>>
>>>> +            if (ib_flush_callback)
>>>> +                    ib_flush_callback();
>>> How about some generic mechanism (such as a list) in case more
>>> modules/drivers would like to register callbacks?
>>> ( assuming this is no longer RFC :) )
>>>
>> Paul Moore and I were having a higher level discussion about this in the 00/12 thread.  I think your suggestion makes sense, perhaps Paul will weigh in when he reaches this patch.
> I'm still working on understanding IB, but my current thinking is very
> similar to Yuval's suggestions.  There is a risk of creating a general
> purpose mechanism to solve a specific, isolated problem, but adding a
> LSM notification mechanism does seem like a reasonable thing to do.
>
> My current thinking is to have the LSM framework itself, e.g.
> security/security.c, maintain a list of callbacks (BTW, please make it
> a RCU protected list) with other non-LSM subsystems registering
> callbacks, and specific LSMs making notification calls into the LSM
> framework itself which would handle iterating through the registered
> callbacks.  Since we're going down the general purpose solution route,
> I might add an event field and a void pointer to the callback, for
> example:
>
>   void lsm_notifier_callback(unsigned int event, void *ptr);
>
> ... I would expect at first we would only have a POLICY_CHANGE event
> (ptr set to NULL), but we may want/need to add other events in the
> future.
>
> Make sense?

Hmm. Do you think that we'd want to rewhack the audit code
so that it used this new, general mechanism for its callbacks?

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

* Re: [PATCH 02/12] selinux: Create policydb version for Infiniband support
  2016-06-23 19:52 ` [PATCH 02/12] selinux: Create policydb version for Infiniband support Dan Jurgens
@ 2016-06-30 20:17       ` Paul Moore
  0 siblings, 0 replies; 128+ messages in thread
From: Paul Moore @ 2016-06-30 20:17 UTC (permalink / raw)
  To: Dan Jurgens
  Cc: linux-rdma-u79uwXL29TY76Z2rM5mHXA,
	linux-security-module-u79uwXL29TY76Z2rM5mHXA,
	chrisw-69jw2NvuJkxg9hUCZPvPmw, dledford-H+wXaHxf7aLQT0dZR+AlfA,
	selinux-+05T5uksL2qpZYMLLGbcSA,
	sean.hefty-ral2JQCrhuEAvxtiuMwx3w, sds-+05T5uksL2qpZYMLLGbcSA,
	hal.rosenstock-Re5JQEeQqe8AvxtiuMwx3w

On Thu, Jun 23, 2016 at 3:52 PM, 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 End 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>
> ---
>  security/selinux/include/security.h |   3 +-
>  security/selinux/ss/policydb.c      | 129 +++++++++++++++++++++++++++++++-----
>  security/selinux/ss/policydb.h      |  27 +++++---
>  3 files changed, 135 insertions(+), 24 deletions(-)

...

> diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
> index 992a315..78b819c 100644
> --- a/security/selinux/ss/policydb.c
> +++ b/security/selinux/ss/policydb.c
> @@ -2219,6 +2229,58 @@ 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.
> +                                */

Any particular reason why you reusing an IPv6 address format here?
Why not use a u64 for the prefix and u16/u32 fields for the partition
keys?

> +                               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_END_PORT:

This is a little bit of bikeshedding, but is there such thing as an IB
"port" that isn't an *end* "port"?  Could we simply use OCON_IB_PORT?

> +                               rc = next_entry(buf, fp, sizeof(u32) * 2);
> +                               if (rc)
> +                                       goto out;
> +                               len = le32_to_cpu(buf[0]);
> +
> +                               rc = str_read(&c->u.ib_end_port.dev_name, GFP_KERNEL,
> +                                             fp,
> +                                             len);
> +                               if (rc)
> +                                       goto out;
> +
> +                               c->u.ib_end_port.port = le32_to_cpu(buf[1]);

No range checking on the port value like you do on the partition keys above?

> +                               rc = context_read_and_validate(&c->context[0],
> +                                                              p,
> +                                                              fp);
> +                               if (rc)
> +                                       goto out;
> +                               break;
>                         }
>                 }
>         }

-- 
paul moore
security @ redhat
_______________________________________________
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] 128+ messages in thread

* Re: [PATCH 02/12] selinux: Create policydb version for Infiniband support
@ 2016-06-30 20:17       ` Paul Moore
  0 siblings, 0 replies; 128+ messages in thread
From: Paul Moore @ 2016-06-30 20:17 UTC (permalink / raw)
  To: Dan Jurgens
  Cc: chrisw, paul, sds, eparis, dledford, sean.hefty, hal.rosenstock,
	selinux, linux-security-module, linux-rdma, yevgenyp

On Thu, Jun 23, 2016 at 3:52 PM, 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 End 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>
> ---
>  security/selinux/include/security.h |   3 +-
>  security/selinux/ss/policydb.c      | 129 +++++++++++++++++++++++++++++++-----
>  security/selinux/ss/policydb.h      |  27 +++++---
>  3 files changed, 135 insertions(+), 24 deletions(-)

...

> diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
> index 992a315..78b819c 100644
> --- a/security/selinux/ss/policydb.c
> +++ b/security/selinux/ss/policydb.c
> @@ -2219,6 +2229,58 @@ 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.
> +                                */

Any particular reason why you reusing an IPv6 address format here?
Why not use a u64 for the prefix and u16/u32 fields for the partition
keys?

> +                               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_END_PORT:

This is a little bit of bikeshedding, but is there such thing as an IB
"port" that isn't an *end* "port"?  Could we simply use OCON_IB_PORT?

> +                               rc = next_entry(buf, fp, sizeof(u32) * 2);
> +                               if (rc)
> +                                       goto out;
> +                               len = le32_to_cpu(buf[0]);
> +
> +                               rc = str_read(&c->u.ib_end_port.dev_name, GFP_KERNEL,
> +                                             fp,
> +                                             len);
> +                               if (rc)
> +                                       goto out;
> +
> +                               c->u.ib_end_port.port = le32_to_cpu(buf[1]);

No range checking on the port value like you do on the partition keys above?

> +                               rc = context_read_and_validate(&c->context[0],
> +                                                              p,
> +                                                              fp);
> +                               if (rc)
> +                                       goto out;
> +                               break;
>                         }
>                 }
>         }

-- 
paul moore
security @ redhat

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

* Re: [PATCH 03/12] selinux: Implement Infiniband flush callback
  2016-06-30 20:16                   ` Casey Schaufler
@ 2016-06-30 20:24                       ` Paul Moore
  -1 siblings, 0 replies; 128+ messages in thread
From: Paul Moore @ 2016-06-30 20:24 UTC (permalink / raw)
  To: Casey Schaufler
  Cc: Daniel Jurgens, Yuval Shaia, linux-rdma-u79uwXL29TY76Z2rM5mHXA,
	linux-security-module-u79uwXL29TY76Z2rM5mHXA,
	chrisw-69jw2NvuJkxg9hUCZPvPmw, dledford-H+wXaHxf7aLQT0dZR+AlfA,
	selinux-+05T5uksL2qpZYMLLGbcSA,
	sean.hefty-ral2JQCrhuEAvxtiuMwx3w, sds-+05T5uksL2qpZYMLLGbcSA,
	hal.rosenstock-Re5JQEeQqe8AvxtiuMwx3w

On Thu, Jun 30, 2016 at 4:16 PM, Casey Schaufler <casey-iSGtlc1asvQWG2LlvL+J4A@public.gmane.org> wrote:
> On 6/30/2016 12:52 PM, Paul Moore wrote:
>> On Thu, Jun 30, 2016 at 11:44 AM, Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org> wrote:
>>> On 6/30/2016 10:10 AM, Yuval Shaia wrote:
>>>> On Thu, Jun 23, 2016 at 10:52:49PM +0300, Dan Jurgens wrote:
>>>>
>>>>> +static void (*ib_flush_callback)(void);
>>>> Do we really want to have such ib_ prefix in security/ directory?
>>>>
>>>>> +            if (ib_flush_callback)
>>>>> +                    ib_flush_callback();
>>>> How about some generic mechanism (such as a list) in case more
>>>> modules/drivers would like to register callbacks?
>>>> ( assuming this is no longer RFC :) )
>>>>
>>> Paul Moore and I were having a higher level discussion about this in the 00/12 thread.  I think your suggestion makes sense, perhaps Paul will weigh in when he reaches this patch.
>> I'm still working on understanding IB, but my current thinking is very
>> similar to Yuval's suggestions.  There is a risk of creating a general
>> purpose mechanism to solve a specific, isolated problem, but adding a
>> LSM notification mechanism does seem like a reasonable thing to do.
>>
>> My current thinking is to have the LSM framework itself, e.g.
>> security/security.c, maintain a list of callbacks (BTW, please make it
>> a RCU protected list) with other non-LSM subsystems registering
>> callbacks, and specific LSMs making notification calls into the LSM
>> framework itself which would handle iterating through the registered
>> callbacks.  Since we're going down the general purpose solution route,
>> I might add an event field and a void pointer to the callback, for
>> example:
>>
>>   void lsm_notifier_callback(unsigned int event, void *ptr);
>>
>> ... I would expect at first we would only have a POLICY_CHANGE event
>> (ptr set to NULL), but we may want/need to add other events in the
>> future.
>>
>> Make sense?
>
> Hmm. Do you think that we'd want to rewhack the audit code
> so that it used this new, general mechanism for its callbacks?

You aren't talking about the callbacks in common_lsm_audit() are you?
I think that's a completely different beast from a LSM notifier
callback.  I'm not opposed to changes to common_lsm_audit(), but I
think that's a different topic and a different thread.

-- 
paul moore
security @ redhat
--
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] 128+ messages in thread

* Re: [PATCH 03/12] selinux: Implement Infiniband flush callback
@ 2016-06-30 20:24                       ` Paul Moore
  0 siblings, 0 replies; 128+ messages in thread
From: Paul Moore @ 2016-06-30 20:24 UTC (permalink / raw)
  To: Casey Schaufler
  Cc: Daniel Jurgens, Yuval Shaia, linux-rdma, linux-security-module,
	chrisw, dledford, selinux, sean.hefty, sds, hal.rosenstock

On Thu, Jun 30, 2016 at 4:16 PM, Casey Schaufler <casey@schaufler-ca.com> wrote:
> On 6/30/2016 12:52 PM, Paul Moore wrote:
>> On Thu, Jun 30, 2016 at 11:44 AM, Daniel Jurgens <danielj@mellanox.com> wrote:
>>> On 6/30/2016 10:10 AM, Yuval Shaia wrote:
>>>> On Thu, Jun 23, 2016 at 10:52:49PM +0300, Dan Jurgens wrote:
>>>>
>>>>> +static void (*ib_flush_callback)(void);
>>>> Do we really want to have such ib_ prefix in security/ directory?
>>>>
>>>>> +            if (ib_flush_callback)
>>>>> +                    ib_flush_callback();
>>>> How about some generic mechanism (such as a list) in case more
>>>> modules/drivers would like to register callbacks?
>>>> ( assuming this is no longer RFC :) )
>>>>
>>> Paul Moore and I were having a higher level discussion about this in the 00/12 thread.  I think your suggestion makes sense, perhaps Paul will weigh in when he reaches this patch.
>> I'm still working on understanding IB, but my current thinking is very
>> similar to Yuval's suggestions.  There is a risk of creating a general
>> purpose mechanism to solve a specific, isolated problem, but adding a
>> LSM notification mechanism does seem like a reasonable thing to do.
>>
>> My current thinking is to have the LSM framework itself, e.g.
>> security/security.c, maintain a list of callbacks (BTW, please make it
>> a RCU protected list) with other non-LSM subsystems registering
>> callbacks, and specific LSMs making notification calls into the LSM
>> framework itself which would handle iterating through the registered
>> callbacks.  Since we're going down the general purpose solution route,
>> I might add an event field and a void pointer to the callback, for
>> example:
>>
>>   void lsm_notifier_callback(unsigned int event, void *ptr);
>>
>> ... I would expect at first we would only have a POLICY_CHANGE event
>> (ptr set to NULL), but we may want/need to add other events in the
>> future.
>>
>> Make sense?
>
> Hmm. Do you think that we'd want to rewhack the audit code
> so that it used this new, general mechanism for its callbacks?

You aren't talking about the callbacks in common_lsm_audit() are you?
I think that's a completely different beast from a LSM notifier
callback.  I'm not opposed to changes to common_lsm_audit(), but I
think that's a different topic and a different thread.

-- 
paul moore
security @ redhat

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

* Re: [PATCH 01/12] security: Add LSM hooks for Infiniband security
  2016-06-23 19:52 ` [PATCH 01/12] security: Add LSM hooks for Infiniband security Dan Jurgens
@ 2016-06-30 20:27       ` Paul Moore
  0 siblings, 0 replies; 128+ messages in thread
From: Paul Moore @ 2016-06-30 20:27 UTC (permalink / raw)
  To: Dan Jurgens
  Cc: 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

On Thu, Jun 23, 2016 at 3:52 PM, Dan Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org> wrote:
> From: Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
>
> Add nine new hooks
>  1. Allocate security contexts for Infiniband QPs.
>  2. Free security contexts for Infiniband QPs.
>  3. Allocate security contexts for Infiniband MAD agents.
>  4. Free security contexts for Infiniband MAD agents.
>  5. Enforce QP access to Pkeys
>  6. Enforce MAD agent access to Pkeys
>  7. Enforce MAD agent access to Infiniband End Ports for sending Subnet
>     Management Packets (SMP)
>  8. A hook to register a callback to receive notifications of
>     security policy or enforcement changes.  Restricting a QPs access to
>     a pkey will be done during setup and not on a per packet basis
>     access must be enforced again.
>  9. A hook to unregister the callback.
>
> Signed-off-by: Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
> Reviewed-by: Eli Cohen <eli-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
> ---
>  include/linux/lsm_hooks.h | 71 ++++++++++++++++++++++++++++++++++++++++
>  include/linux/security.h  | 63 +++++++++++++++++++++++++++++++++++
>  include/rdma/ib_verbs.h   |  4 +++
>  security/Kconfig          |  9 +++++
>  security/security.c       | 83 +++++++++++++++++++++++++++++++++++++++++++++++
>  5 files changed, 230 insertions(+)

I'd recommend putting the IB hook calls into this patch as well, it
helps make the hooks a bit more concrete as you can see where, and how
they are called.

> diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
> index 7ae3976..6b47c8d 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,50 @@
>   *     associated with the TUN device's security structure.
>   *     @security pointer to the TUN devices's security structure.
>   *
> + * Security hooks for Infiniband
> + *
> + * @ib_qp_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.
> + *     @qp_sec pointer to the ib_qp_security structure.
> + * @ib_mad_agent_pkey_access:
> + *     Check permission to access a pkey when transmiting and receiving MADS.
> + *     @subnet_prefix the subnet prefix of the port being used.
> + *     @pkey the pkey to be accessed.
> + *     @mad_agent pointer to the ib_mad_agent structure.
> + * @ib_end_port_smp:
> + *     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.
> + *     @mad_agent pointer to the ib_mad_agent structure.
> + * @ib_qp_alloc_security:
> + *     Allocate and attach a security structure to the qp_sec->q_security
> + *     field. The q_security field is initialized to NULL when the structure
> + *     is allocated.  A separate QP security structure is used instead of the
> + *     QP structure because when a QP is destroyed the memory is freed by the
> + *     hardware driver.  That operation can fail so the security info must be
> + *     maintained until the destroy completes successfully.
> + *     @qp_sec contains the ib_qp_security structure to be modified.
> + *     Return 0 if operation was successful.
> + * @ib_mad_agent_alloc_security:
> + *     Allocate and attach a security structure to the mad_agent->m_security
> + *     field. The m_security field is initialized to NULL when the structure
> + *     is allocated.
> + *     @mad_agent contains the ib_mad_agent structure to be modified.
> + *     Return 0 if operation was successful.
> + * @ib_qp_free_security:
> + *     Deallocate and clear the qp_sec->q_security field.
> + *     @qp_sec contains the ib_qp_security structure to be modified.
> + * @ib_mad_agent_free_security:
> + *     Deallocate and clear the mad_agent->m_security field.
> + *     @mad_agent contains the ib_mad_agent structure to be modified.
> + * @register_ib_flush_callback:
> + *     Provide a way for security modules to notify ib_core of policy changes.
> + *     @callback function pointer to call when policy changes.
> + * @unregister_ib_flush_callback:
> + *     Unregister the callback function.
> + *
>   * Security hooks for XFRM operations.
>   *
>   * @xfrm_policy_alloc_security:

-- 
paul moore
security @ redhat
--
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] 128+ messages in thread

* Re: [PATCH 01/12] security: Add LSM hooks for Infiniband security
@ 2016-06-30 20:27       ` Paul Moore
  0 siblings, 0 replies; 128+ messages in thread
From: Paul Moore @ 2016-06-30 20:27 UTC (permalink / raw)
  To: Dan Jurgens
  Cc: chrisw, paul, sds, eparis, dledford, sean.hefty, hal.rosenstock,
	selinux, linux-security-module, linux-rdma, yevgenyp

On Thu, Jun 23, 2016 at 3:52 PM, Dan Jurgens <danielj@mellanox.com> wrote:
> From: Daniel Jurgens <danielj@mellanox.com>
>
> Add nine new hooks
>  1. Allocate security contexts for Infiniband QPs.
>  2. Free security contexts for Infiniband QPs.
>  3. Allocate security contexts for Infiniband MAD agents.
>  4. Free security contexts for Infiniband MAD agents.
>  5. Enforce QP access to Pkeys
>  6. Enforce MAD agent access to Pkeys
>  7. Enforce MAD agent access to Infiniband End Ports for sending Subnet
>     Management Packets (SMP)
>  8. A hook to register a callback to receive notifications of
>     security policy or enforcement changes.  Restricting a QPs access to
>     a pkey will be done during setup and not on a per packet basis
>     access must be enforced again.
>  9. A hook to unregister the callback.
>
> Signed-off-by: Daniel Jurgens <danielj@mellanox.com>
> Reviewed-by: Eli Cohen <eli@mellanox.com>
> ---
>  include/linux/lsm_hooks.h | 71 ++++++++++++++++++++++++++++++++++++++++
>  include/linux/security.h  | 63 +++++++++++++++++++++++++++++++++++
>  include/rdma/ib_verbs.h   |  4 +++
>  security/Kconfig          |  9 +++++
>  security/security.c       | 83 +++++++++++++++++++++++++++++++++++++++++++++++
>  5 files changed, 230 insertions(+)

I'd recommend putting the IB hook calls into this patch as well, it
helps make the hooks a bit more concrete as you can see where, and how
they are called.

> diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
> index 7ae3976..6b47c8d 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,50 @@
>   *     associated with the TUN device's security structure.
>   *     @security pointer to the TUN devices's security structure.
>   *
> + * Security hooks for Infiniband
> + *
> + * @ib_qp_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.
> + *     @qp_sec pointer to the ib_qp_security structure.
> + * @ib_mad_agent_pkey_access:
> + *     Check permission to access a pkey when transmiting and receiving MADS.
> + *     @subnet_prefix the subnet prefix of the port being used.
> + *     @pkey the pkey to be accessed.
> + *     @mad_agent pointer to the ib_mad_agent structure.
> + * @ib_end_port_smp:
> + *     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.
> + *     @mad_agent pointer to the ib_mad_agent structure.
> + * @ib_qp_alloc_security:
> + *     Allocate and attach a security structure to the qp_sec->q_security
> + *     field. The q_security field is initialized to NULL when the structure
> + *     is allocated.  A separate QP security structure is used instead of the
> + *     QP structure because when a QP is destroyed the memory is freed by the
> + *     hardware driver.  That operation can fail so the security info must be
> + *     maintained until the destroy completes successfully.
> + *     @qp_sec contains the ib_qp_security structure to be modified.
> + *     Return 0 if operation was successful.
> + * @ib_mad_agent_alloc_security:
> + *     Allocate and attach a security structure to the mad_agent->m_security
> + *     field. The m_security field is initialized to NULL when the structure
> + *     is allocated.
> + *     @mad_agent contains the ib_mad_agent structure to be modified.
> + *     Return 0 if operation was successful.
> + * @ib_qp_free_security:
> + *     Deallocate and clear the qp_sec->q_security field.
> + *     @qp_sec contains the ib_qp_security structure to be modified.
> + * @ib_mad_agent_free_security:
> + *     Deallocate and clear the mad_agent->m_security field.
> + *     @mad_agent contains the ib_mad_agent structure to be modified.
> + * @register_ib_flush_callback:
> + *     Provide a way for security modules to notify ib_core of policy changes.
> + *     @callback function pointer to call when policy changes.
> + * @unregister_ib_flush_callback:
> + *     Unregister the callback function.
> + *
>   * Security hooks for XFRM operations.
>   *
>   * @xfrm_policy_alloc_security:

-- 
paul moore
security @ redhat

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

* Re: [PATCH 01/12] security: Add LSM hooks for Infiniband security
  2016-06-23 19:52 ` [PATCH 01/12] security: Add LSM hooks for Infiniband security Dan Jurgens
@ 2016-06-30 20:33       ` Paul Moore
  0 siblings, 0 replies; 128+ messages in thread
From: Paul Moore @ 2016-06-30 20:33 UTC (permalink / raw)
  To: Dan Jurgens
  Cc: linux-rdma-u79uwXL29TY76Z2rM5mHXA,
	linux-security-module-u79uwXL29TY76Z2rM5mHXA,
	chrisw-69jw2NvuJkxg9hUCZPvPmw, dledford-H+wXaHxf7aLQT0dZR+AlfA,
	selinux-+05T5uksL2qpZYMLLGbcSA,
	sean.hefty-ral2JQCrhuEAvxtiuMwx3w, sds-+05T5uksL2qpZYMLLGbcSA,
	hal.rosenstock-Re5JQEeQqe8AvxtiuMwx3w

On Thu, Jun 23, 2016 at 3:52 PM, Dan Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org> wrote:
> From: Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
>
> Add nine new hooks
>  1. Allocate security contexts for Infiniband QPs.
>  2. Free security contexts for Infiniband QPs.
>  3. Allocate security contexts for Infiniband MAD agents.
>  4. Free security contexts for Infiniband MAD agents.
>  5. Enforce QP access to Pkeys
>  6. Enforce MAD agent access to Pkeys
>  7. Enforce MAD agent access to Infiniband End Ports for sending Subnet
>     Management Packets (SMP)
>  8. A hook to register a callback to receive notifications of
>     security policy or enforcement changes.  Restricting a QPs access to
>     a pkey will be done during setup and not on a per packet basis
>     access must be enforced again.
>  9. A hook to unregister the callback.
>
> Signed-off-by: Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
> Reviewed-by: Eli Cohen <eli-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
> ---
>  include/linux/lsm_hooks.h | 71 ++++++++++++++++++++++++++++++++++++++++
>  include/linux/security.h  | 63 +++++++++++++++++++++++++++++++++++
>  include/rdma/ib_verbs.h   |  4 +++
>  security/Kconfig          |  9 +++++
>  security/security.c       | 83 +++++++++++++++++++++++++++++++++++++++++++++++
>  5 files changed, 230 insertions(+)

...

> diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
> index 432bed5..3f6780b 100644
> --- a/include/rdma/ib_verbs.h
> +++ b/include/rdma/ib_verbs.h
> @@ -1428,6 +1428,10 @@ struct ib_srq {
>         } ext;
>  };
>
> +struct ib_qp_security {
> +       void *q_security;
> +};

Sorry, I missed this earlier and didn't realize it until I was going
through 4/12 ... why both with ib_qp_security?  Why not just use a
straight void pointer?

-- 
paul moore
security @ redhat
_______________________________________________
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] 128+ messages in thread

* Re: [PATCH 01/12] security: Add LSM hooks for Infiniband security
@ 2016-06-30 20:33       ` Paul Moore
  0 siblings, 0 replies; 128+ messages in thread
From: Paul Moore @ 2016-06-30 20:33 UTC (permalink / raw)
  To: Dan Jurgens
  Cc: chrisw, paul, sds, eparis, dledford, sean.hefty, hal.rosenstock,
	selinux, linux-security-module, linux-rdma, yevgenyp

On Thu, Jun 23, 2016 at 3:52 PM, Dan Jurgens <danielj@mellanox.com> wrote:
> From: Daniel Jurgens <danielj@mellanox.com>
>
> Add nine new hooks
>  1. Allocate security contexts for Infiniband QPs.
>  2. Free security contexts for Infiniband QPs.
>  3. Allocate security contexts for Infiniband MAD agents.
>  4. Free security contexts for Infiniband MAD agents.
>  5. Enforce QP access to Pkeys
>  6. Enforce MAD agent access to Pkeys
>  7. Enforce MAD agent access to Infiniband End Ports for sending Subnet
>     Management Packets (SMP)
>  8. A hook to register a callback to receive notifications of
>     security policy or enforcement changes.  Restricting a QPs access to
>     a pkey will be done during setup and not on a per packet basis
>     access must be enforced again.
>  9. A hook to unregister the callback.
>
> Signed-off-by: Daniel Jurgens <danielj@mellanox.com>
> Reviewed-by: Eli Cohen <eli@mellanox.com>
> ---
>  include/linux/lsm_hooks.h | 71 ++++++++++++++++++++++++++++++++++++++++
>  include/linux/security.h  | 63 +++++++++++++++++++++++++++++++++++
>  include/rdma/ib_verbs.h   |  4 +++
>  security/Kconfig          |  9 +++++
>  security/security.c       | 83 +++++++++++++++++++++++++++++++++++++++++++++++
>  5 files changed, 230 insertions(+)

...

> diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
> index 432bed5..3f6780b 100644
> --- a/include/rdma/ib_verbs.h
> +++ b/include/rdma/ib_verbs.h
> @@ -1428,6 +1428,10 @@ struct ib_srq {
>         } ext;
>  };
>
> +struct ib_qp_security {
> +       void *q_security;
> +};

Sorry, I missed this earlier and didn't realize it until I was going
through 4/12 ... why both with ib_qp_security?  Why not just use a
straight void pointer?

-- 
paul moore
security @ redhat

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

* Re: [PATCH 03/12] selinux: Implement Infiniband flush callback
  2016-06-30 19:52               ` Paul Moore
@ 2016-06-30 20:39                 ` Daniel Jurgens
  -1 siblings, 0 replies; 128+ messages in thread
From: Daniel Jurgens @ 2016-06-30 20:39 UTC (permalink / raw)
  To: Paul Moore, Yuval Shaia
  Cc: linux-rdma-u79uwXL29TY76Z2rM5mHXA,
	linux-security-module-u79uwXL29TY76Z2rM5mHXA,
	chrisw-69jw2NvuJkxg9hUCZPvPmw, dledford-H+wXaHxf7aLQT0dZR+AlfA,
	selinux-+05T5uksL2qpZYMLLGbcSA,
	sean.hefty-ral2JQCrhuEAvxtiuMwx3w, sds-+05T5uksL2qpZYMLLGbcSA,
	hal.rosenstock-Re5JQEeQqe8AvxtiuMwx3w

On 6/30/2016 2:52 PM, Paul Moore wrote:
> I'm still working on understanding IB, but my current thinking is very
> similar to Yuval's suggestions.  There is a risk of creating a general
> purpose mechanism to solve a specific, isolated problem, but adding a
> LSM notification mechanism does seem like a reasonable thing to do.
>
> My current thinking is to have the LSM framework itself, e.g.
> security/security.c, maintain a list of callbacks (BTW, please make it
> a RCU protected list) with other non-LSM subsystems registering
> callbacks, and specific LSMs making notification calls into the LSM
> framework itself which would handle iterating through the registered
> callbacks.  Since we're going down the general purpose solution route,
> I might add an event field and a void pointer to the callback, for
> example:
>
>   void lsm_notifier_callback(unsigned int event, void *ptr);
>
> ... I would expect at first we would only have a POLICY_CHANGE event
> (ptr set to NULL), but we may want/need to add other events in the
> future.
>
> Make sense?

Yes, I think so.  I'll make this change.

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

* Re: [PATCH 03/12] selinux: Implement Infiniband flush callback
@ 2016-06-30 20:39                 ` Daniel Jurgens
  0 siblings, 0 replies; 128+ messages in thread
From: Daniel Jurgens @ 2016-06-30 20:39 UTC (permalink / raw)
  To: Paul Moore, Yuval Shaia
  Cc: linux-rdma, linux-security-module, chrisw, dledford, selinux,
	sean.hefty, sds, hal.rosenstock

On 6/30/2016 2:52 PM, Paul Moore wrote:
> I'm still working on understanding IB, but my current thinking is very
> similar to Yuval's suggestions.  There is a risk of creating a general
> purpose mechanism to solve a specific, isolated problem, but adding a
> LSM notification mechanism does seem like a reasonable thing to do.
>
> My current thinking is to have the LSM framework itself, e.g.
> security/security.c, maintain a list of callbacks (BTW, please make it
> a RCU protected list) with other non-LSM subsystems registering
> callbacks, and specific LSMs making notification calls into the LSM
> framework itself which would handle iterating through the registered
> callbacks.  Since we're going down the general purpose solution route,
> I might add an event field and a void pointer to the callback, for
> example:
>
>   void lsm_notifier_callback(unsigned int event, void *ptr);
>
> ... I would expect at first we would only have a POLICY_CHANGE event
> (ptr set to NULL), but we may want/need to add other events in the
> future.
>
> Make sense?

Yes, I think so.  I'll make this change.

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

* Re: [PATCH 04/12] selinux: Allocate and free infiniband security hooks
  2016-06-23 19:52     ` Dan Jurgens
@ 2016-06-30 20:42         ` Paul Moore
  -1 siblings, 0 replies; 128+ messages in thread
From: Paul Moore @ 2016-06-30 20:42 UTC (permalink / raw)
  To: Dan Jurgens
  Cc: 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

On Thu, Jun 23, 2016 at 3:52 PM, Dan Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org> wrote:
> From: Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
>
> Implement and attach hooks to allocate and free Infiniband QP and MAD
> agent security structures.
>
> Signed-off-by: Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
> Reviewed-by: Eli Cohen <eli-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
> ---
>  include/rdma/ib_mad.h             |  1 +
>  include/rdma/ib_verbs.h           |  1 +
>  security/selinux/hooks.c          | 53 +++++++++++++++++++++++++++++++++++++++
>  security/selinux/include/objsec.h |  5 ++++
>  4 files changed, 60 insertions(+)
>
> diff --git a/include/rdma/ib_mad.h b/include/rdma/ib_mad.h
> index c8a773f..a1ed025 100644
> --- a/include/rdma/ib_mad.h
> +++ b/include/rdma/ib_mad.h
> @@ -537,6 +537,7 @@ struct ib_mad_agent {
>         u32                     flags;
>         u8                      port_num;
>         u8                      rmpp_version;
> +       void                    *m_security;

General convention is to just call the LSM blobs "security" unless
there is already a field with that name.

>  };
>
>  /**
> diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
> index 3f6780b..e522acb 100644
> --- a/include/rdma/ib_verbs.h
> +++ b/include/rdma/ib_verbs.h
> @@ -1454,6 +1454,7 @@ struct ib_qp {
>         void                   *qp_context;
>         u32                     qp_num;
>         enum ib_qp_type         qp_type;
> +       struct ib_qp_security  *qp_sec;

See my earlier question/comment about just using a void pointer here.

>  };
>
>  struct ib_mr {
> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index 6a8841d..4f13ea4 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -17,6 +17,7 @@
>   *     Paul Moore <paul-r2n+y4ga6xFZroRs9YW3xA@public.gmane.org>
>   *  Copyright (C) 2007 Hitachi Software Engineering Co., Ltd.
>   *                    Yuichi Nakamura <ynakam-FkO1umbPgv4fag7Bw7Dlfw@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 version 2,
> @@ -83,6 +84,8 @@
>  #include <linux/export.h>
>  #include <linux/msg.h>
>  #include <linux/shm.h>
> +#include <rdma/ib_verbs.h>
> +#include <rdma/ib_mad.h>
>
>  #include "avc.h"
>  #include "objsec.h"
> @@ -6015,6 +6018,47 @@ static void selinux_unregister_ib_flush_callback(void)
>         mutex_unlock(&ib_flush_mutex);
>  }
>
> +static int selinux_ib_qp_alloc_security(struct ib_qp_security *qp_sec)
> +{
> +       struct ib_security_struct *sec;
> +
> +       sec = kzalloc(sizeof(*sec), GFP_ATOMIC);
> +       if (!sec)
> +               return -ENOMEM;
> +       sec->sid = current_sid();
> +
> +       qp_sec->q_security = sec;
> +       return 0;
> +}

If you get rid of the ip_qp_security struct, you can just return the
blob instead of an int (NULL on error).  Same with the MAD allocator
below.

Also, and this may be more important for the MAD allocator below (I'm
still pretty IB-ignorant), can you forsee the need/desire to have the
QP/MAD label different from the process which creates them?  How often
will other SELinux domains need to interact with these objects?

> +static void selinux_ib_qp_free_security(struct ib_qp_security *qp_sec)
> +{
> +       struct ib_security_struct *sec = qp_sec->q_security;
> +
> +       qp_sec->q_security = NULL;
> +       kfree(sec);
> +}
> +
> +static int selinux_ib_mad_agent_alloc_security(struct ib_mad_agent *mad_agent)
> +{
> +       struct ib_security_struct *sec;
> +
> +       sec = kzalloc(sizeof(*sec), GFP_ATOMIC);
> +       if (!sec)
> +               return -ENOMEM;
> +       sec->sid = current_sid();
> +
> +       mad_agent->m_security = sec;
> +       return 0;
> +}
> +
> +static void selinux_ib_mad_agent_free_security(struct ib_mad_agent *mad_agent)
> +{
> +       struct ib_security_struct *sec = mad_agent->m_security;
> +
> +       mad_agent->m_security = NULL;
> +       kfree(sec);
> +}
>  #endif

-- 
paul moore
security @ redhat
--
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] 128+ messages in thread

* Re: [PATCH 04/12] selinux: Allocate and free infiniband security hooks
@ 2016-06-30 20:42         ` Paul Moore
  0 siblings, 0 replies; 128+ messages in thread
From: Paul Moore @ 2016-06-30 20:42 UTC (permalink / raw)
  To: Dan Jurgens
  Cc: chrisw, paul, sds, eparis, dledford, sean.hefty, hal.rosenstock,
	selinux, linux-security-module, linux-rdma, yevgenyp

On Thu, Jun 23, 2016 at 3:52 PM, Dan Jurgens <danielj@mellanox.com> wrote:
> From: Daniel Jurgens <danielj@mellanox.com>
>
> Implement and attach hooks to allocate and free Infiniband QP and MAD
> agent security structures.
>
> Signed-off-by: Daniel Jurgens <danielj@mellanox.com>
> Reviewed-by: Eli Cohen <eli@mellanox.com>
> ---
>  include/rdma/ib_mad.h             |  1 +
>  include/rdma/ib_verbs.h           |  1 +
>  security/selinux/hooks.c          | 53 +++++++++++++++++++++++++++++++++++++++
>  security/selinux/include/objsec.h |  5 ++++
>  4 files changed, 60 insertions(+)
>
> diff --git a/include/rdma/ib_mad.h b/include/rdma/ib_mad.h
> index c8a773f..a1ed025 100644
> --- a/include/rdma/ib_mad.h
> +++ b/include/rdma/ib_mad.h
> @@ -537,6 +537,7 @@ struct ib_mad_agent {
>         u32                     flags;
>         u8                      port_num;
>         u8                      rmpp_version;
> +       void                    *m_security;

General convention is to just call the LSM blobs "security" unless
there is already a field with that name.

>  };
>
>  /**
> diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
> index 3f6780b..e522acb 100644
> --- a/include/rdma/ib_verbs.h
> +++ b/include/rdma/ib_verbs.h
> @@ -1454,6 +1454,7 @@ struct ib_qp {
>         void                   *qp_context;
>         u32                     qp_num;
>         enum ib_qp_type         qp_type;
> +       struct ib_qp_security  *qp_sec;

See my earlier question/comment about just using a void pointer here.

>  };
>
>  struct ib_mr {
> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index 6a8841d..4f13ea4 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,
> @@ -83,6 +84,8 @@
>  #include <linux/export.h>
>  #include <linux/msg.h>
>  #include <linux/shm.h>
> +#include <rdma/ib_verbs.h>
> +#include <rdma/ib_mad.h>
>
>  #include "avc.h"
>  #include "objsec.h"
> @@ -6015,6 +6018,47 @@ static void selinux_unregister_ib_flush_callback(void)
>         mutex_unlock(&ib_flush_mutex);
>  }
>
> +static int selinux_ib_qp_alloc_security(struct ib_qp_security *qp_sec)
> +{
> +       struct ib_security_struct *sec;
> +
> +       sec = kzalloc(sizeof(*sec), GFP_ATOMIC);
> +       if (!sec)
> +               return -ENOMEM;
> +       sec->sid = current_sid();
> +
> +       qp_sec->q_security = sec;
> +       return 0;
> +}

If you get rid of the ip_qp_security struct, you can just return the
blob instead of an int (NULL on error).  Same with the MAD allocator
below.

Also, and this may be more important for the MAD allocator below (I'm
still pretty IB-ignorant), can you forsee the need/desire to have the
QP/MAD label different from the process which creates them?  How often
will other SELinux domains need to interact with these objects?

> +static void selinux_ib_qp_free_security(struct ib_qp_security *qp_sec)
> +{
> +       struct ib_security_struct *sec = qp_sec->q_security;
> +
> +       qp_sec->q_security = NULL;
> +       kfree(sec);
> +}
> +
> +static int selinux_ib_mad_agent_alloc_security(struct ib_mad_agent *mad_agent)
> +{
> +       struct ib_security_struct *sec;
> +
> +       sec = kzalloc(sizeof(*sec), GFP_ATOMIC);
> +       if (!sec)
> +               return -ENOMEM;
> +       sec->sid = current_sid();
> +
> +       mad_agent->m_security = sec;
> +       return 0;
> +}
> +
> +static void selinux_ib_mad_agent_free_security(struct ib_mad_agent *mad_agent)
> +{
> +       struct ib_security_struct *sec = mad_agent->m_security;
> +
> +       mad_agent->m_security = NULL;
> +       kfree(sec);
> +}
>  #endif

-- 
paul moore
security @ redhat

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

* Re: [PATCH 02/12] selinux: Create policydb version for Infiniband support
  2016-06-30 20:17       ` Paul Moore
@ 2016-06-30 20:59         ` Daniel Jurgens
  -1 siblings, 0 replies; 128+ messages in thread
From: Daniel Jurgens @ 2016-06-30 20:59 UTC (permalink / raw)
  To: Paul Moore
  Cc: 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, Yevgeny Petrilin

On 6/30/2016 3:17 PM, Paul Moore wrote:
> On Thu, Jun 23, 2016 at 3:52 PM, 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 End 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>
>> ---
>>  security/selinux/include/security.h |   3 +-
>>  security/selinux/ss/policydb.c      | 129 +++++++++++++++++++++++++++++++-----
>>  security/selinux/ss/policydb.h      |  27 +++++---
>>  3 files changed, 135 insertions(+), 24 deletions(-)
> ...
>
>> diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
>> index 992a315..78b819c 100644
>> --- a/security/selinux/ss/policydb.c
>> +++ b/security/selinux/ss/policydb.c
>> @@ -2219,6 +2229,58 @@ 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.
>> +                                */
> Any particular reason why you reusing an IPv6 address format here?
> Why not use a u64 for the prefix and u16/u32 fields for the partition
> keys?
The subnet prefix is the high order bytes of an IPv6 address and there is infrastructure in place in the userland utilities that deal with IPv6 addresses (parsing them with a :: to eliminate the need to fill out the 0's for example).

Regarding u16, the policy is packed with everything in u32, as you can see in OCON_NODE6 and OCON_PORT handling.
>> +                               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_END_PORT:
> This is a little bit of bikeshedding, but is there such thing as an IB
> "port" that isn't an *end* "port"?  Could we simply use OCON_IB_PORT?
Jason Gunthorpe requested that the name be end_port  in the RFC series.
>> +                               rc = next_entry(buf, fp, sizeof(u32) * 2);
>> +                               if (rc)
>> +                                       goto out;
>> +                               len = le32_to_cpu(buf[0]);
>> +
>> +                               rc = str_read(&c->u.ib_end_port.dev_name, GFP_KERNEL,
>> +                                             fp,
>> +                                             len);
>> +                               if (rc)
>> +                                       goto out;
>> +
>> +                               c->u.ib_end_port.port = le32_to_cpu(buf[1]);
> No range checking on the port value like you do on the partition keys above?

I can add a similar check.

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

* Re: [PATCH 02/12] selinux: Create policydb version for Infiniband support
@ 2016-06-30 20:59         ` Daniel Jurgens
  0 siblings, 0 replies; 128+ messages in thread
From: Daniel Jurgens @ 2016-06-30 20:59 UTC (permalink / raw)
  To: Paul Moore
  Cc: chrisw, paul, sds, eparis, dledford, sean.hefty, hal.rosenstock,
	selinux, linux-security-module, linux-rdma, Yevgeny Petrilin

On 6/30/2016 3:17 PM, Paul Moore wrote:
> On Thu, Jun 23, 2016 at 3:52 PM, 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 End 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>
>> ---
>>  security/selinux/include/security.h |   3 +-
>>  security/selinux/ss/policydb.c      | 129 +++++++++++++++++++++++++++++++-----
>>  security/selinux/ss/policydb.h      |  27 +++++---
>>  3 files changed, 135 insertions(+), 24 deletions(-)
> ...
>
>> diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
>> index 992a315..78b819c 100644
>> --- a/security/selinux/ss/policydb.c
>> +++ b/security/selinux/ss/policydb.c
>> @@ -2219,6 +2229,58 @@ 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.
>> +                                */
> Any particular reason why you reusing an IPv6 address format here?
> Why not use a u64 for the prefix and u16/u32 fields for the partition
> keys?
The subnet prefix is the high order bytes of an IPv6 address and there is infrastructure in place in the userland utilities that deal with IPv6 addresses (parsing them with a :: to eliminate the need to fill out the 0's for example).

Regarding u16, the policy is packed with everything in u32, as you can see in OCON_NODE6 and OCON_PORT handling.
>> +                               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_END_PORT:
> This is a little bit of bikeshedding, but is there such thing as an IB
> "port" that isn't an *end* "port"?  Could we simply use OCON_IB_PORT?
Jason Gunthorpe requested that the name be end_port  in the RFC series.
>> +                               rc = next_entry(buf, fp, sizeof(u32) * 2);
>> +                               if (rc)
>> +                                       goto out;
>> +                               len = le32_to_cpu(buf[0]);
>> +
>> +                               rc = str_read(&c->u.ib_end_port.dev_name, GFP_KERNEL,
>> +                                             fp,
>> +                                             len);
>> +                               if (rc)
>> +                                       goto out;
>> +
>> +                               c->u.ib_end_port.port = le32_to_cpu(buf[1]);
> No range checking on the port value like you do on the partition keys above?

I can add a similar check.

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

* Re: [PATCH 04/12] selinux: Allocate and free infiniband security hooks
  2016-06-30 20:42         ` Paul Moore
@ 2016-06-30 21:06             ` Casey Schaufler
  -1 siblings, 0 replies; 128+ messages in thread
From: Casey Schaufler @ 2016-06-30 21:06 UTC (permalink / raw)
  To: Paul Moore, Dan Jurgens
  Cc: 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

On 6/30/2016 1:42 PM, Paul Moore wrote:
> On Thu, Jun 23, 2016 at 3:52 PM, Dan Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org> wrote:
>> From: Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
>>
>> Implement and attach hooks to allocate and free Infiniband QP and MAD
>> agent security structures.
>>
>> Signed-off-by: Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
>> Reviewed-by: Eli Cohen <eli-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
>> ---
>>  include/rdma/ib_mad.h             |  1 +
>>  include/rdma/ib_verbs.h           |  1 +
>>  security/selinux/hooks.c          | 53 +++++++++++++++++++++++++++++++++++++++
>>  security/selinux/include/objsec.h |  5 ++++
>>  4 files changed, 60 insertions(+)
>>
>> diff --git a/include/rdma/ib_mad.h b/include/rdma/ib_mad.h
>> index c8a773f..a1ed025 100644
>> --- a/include/rdma/ib_mad.h
>> +++ b/include/rdma/ib_mad.h
>> @@ -537,6 +537,7 @@ struct ib_mad_agent {
>>         u32                     flags;
>>         u8                      port_num;
>>         u8                      rmpp_version;
>> +       void                    *m_security;
> General convention is to just call the LSM blobs "security" unless
> there is already a field with that name.

Not that it really matters all that much, but an unadorned "security"
makes it unnecessarily difficult to match "p->security" to the data
involved when you're looking at keys, creds and ipc. I like having
the prefix. I think the other fields in the structure should have it,
too, but as I'm not an acknowledged authority on good style I hesitate
to suggest it in general.

>
>>  };
>>
>>  /**
>> diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
>> index 3f6780b..e522acb 100644
>> --- a/include/rdma/ib_verbs.h
>> +++ b/include/rdma/ib_verbs.h
>> @@ -1454,6 +1454,7 @@ struct ib_qp {
>>         void                   *qp_context;
>>         u32                     qp_num;
>>         enum ib_qp_type         qp_type;
>> +       struct ib_qp_security  *qp_sec;
> See my earlier question/comment about just using a void pointer here.

I think that this is in response to my comments to the
effect that I would like to see the LSM infrastructure
using the inode like (inode->i_security) to the xfrm
(void *) approach. I haven't been looking at the IB patches
too carefully to date. It's possible I have not been clear.

>
>>  };
>>
>>  struct ib_mr {
>> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
>> index 6a8841d..4f13ea4 100644
>> --- a/security/selinux/hooks.c
>> +++ b/security/selinux/hooks.c
>> @@ -17,6 +17,7 @@
>>   *     Paul Moore <paul-r2n+y4ga6xFZroRs9YW3xA@public.gmane.org>
>>   *  Copyright (C) 2007 Hitachi Software Engineering Co., Ltd.
>>   *                    Yuichi Nakamura <ynakam-FkO1umbPgv4fag7Bw7Dlfw@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 version 2,
>> @@ -83,6 +84,8 @@
>>  #include <linux/export.h>
>>  #include <linux/msg.h>
>>  #include <linux/shm.h>
>> +#include <rdma/ib_verbs.h>
>> +#include <rdma/ib_mad.h>
>>
>>  #include "avc.h"
>>  #include "objsec.h"
>> @@ -6015,6 +6018,47 @@ static void selinux_unregister_ib_flush_callback(void)
>>         mutex_unlock(&ib_flush_mutex);
>>  }
>>
>> +static int selinux_ib_qp_alloc_security(struct ib_qp_security *qp_sec)
>> +{
>> +       struct ib_security_struct *sec;
>> +
>> +       sec = kzalloc(sizeof(*sec), GFP_ATOMIC);
>> +       if (!sec)
>> +               return -ENOMEM;
>> +       sec->sid = current_sid();
>> +
>> +       qp_sec->q_security = sec;
>> +       return 0;
>> +}
> If you get rid of the ip_qp_security struct, you can just return the
> blob instead of an int (NULL on error).  Same with the MAD allocator
> below.
>
> Also, and this may be more important for the MAD allocator below (I'm
> still pretty IB-ignorant), can you forsee the need/desire to have the
> QP/MAD label different from the process which creates them?  How often
> will other SELinux domains need to interact with these objects?
>
>> +static void selinux_ib_qp_free_security(struct ib_qp_security *qp_sec)
>> +{
>> +       struct ib_security_struct *sec = qp_sec->q_security;
>> +
>> +       qp_sec->q_security = NULL;
>> +       kfree(sec);
>> +}
>> +
>> +static int selinux_ib_mad_agent_alloc_security(struct ib_mad_agent *mad_agent)
>> +{
>> +       struct ib_security_struct *sec;
>> +
>> +       sec = kzalloc(sizeof(*sec), GFP_ATOMIC);
>> +       if (!sec)
>> +               return -ENOMEM;
>> +       sec->sid = current_sid();
>> +
>> +       mad_agent->m_security = sec;
>> +       return 0;
>> +}
>> +
>> +static void selinux_ib_mad_agent_free_security(struct ib_mad_agent *mad_agent)
>> +{
>> +       struct ib_security_struct *sec = mad_agent->m_security;
>> +
>> +       mad_agent->m_security = NULL;
>> +       kfree(sec);
>> +}
>>  #endif

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

* Re: [PATCH 04/12] selinux: Allocate and free infiniband security hooks
@ 2016-06-30 21:06             ` Casey Schaufler
  0 siblings, 0 replies; 128+ messages in thread
From: Casey Schaufler @ 2016-06-30 21:06 UTC (permalink / raw)
  To: Paul Moore, Dan Jurgens
  Cc: chrisw, paul, sds, eparis, dledford, sean.hefty, hal.rosenstock,
	selinux, linux-security-module, linux-rdma, yevgenyp

On 6/30/2016 1:42 PM, Paul Moore wrote:
> On Thu, Jun 23, 2016 at 3:52 PM, Dan Jurgens <danielj@mellanox.com> wrote:
>> From: Daniel Jurgens <danielj@mellanox.com>
>>
>> Implement and attach hooks to allocate and free Infiniband QP and MAD
>> agent security structures.
>>
>> Signed-off-by: Daniel Jurgens <danielj@mellanox.com>
>> Reviewed-by: Eli Cohen <eli@mellanox.com>
>> ---
>>  include/rdma/ib_mad.h             |  1 +
>>  include/rdma/ib_verbs.h           |  1 +
>>  security/selinux/hooks.c          | 53 +++++++++++++++++++++++++++++++++++++++
>>  security/selinux/include/objsec.h |  5 ++++
>>  4 files changed, 60 insertions(+)
>>
>> diff --git a/include/rdma/ib_mad.h b/include/rdma/ib_mad.h
>> index c8a773f..a1ed025 100644
>> --- a/include/rdma/ib_mad.h
>> +++ b/include/rdma/ib_mad.h
>> @@ -537,6 +537,7 @@ struct ib_mad_agent {
>>         u32                     flags;
>>         u8                      port_num;
>>         u8                      rmpp_version;
>> +       void                    *m_security;
> General convention is to just call the LSM blobs "security" unless
> there is already a field with that name.

Not that it really matters all that much, but an unadorned "security"
makes it unnecessarily difficult to match "p->security" to the data
involved when you're looking at keys, creds and ipc. I like having
the prefix. I think the other fields in the structure should have it,
too, but as I'm not an acknowledged authority on good style I hesitate
to suggest it in general.

>
>>  };
>>
>>  /**
>> diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
>> index 3f6780b..e522acb 100644
>> --- a/include/rdma/ib_verbs.h
>> +++ b/include/rdma/ib_verbs.h
>> @@ -1454,6 +1454,7 @@ struct ib_qp {
>>         void                   *qp_context;
>>         u32                     qp_num;
>>         enum ib_qp_type         qp_type;
>> +       struct ib_qp_security  *qp_sec;
> See my earlier question/comment about just using a void pointer here.

I think that this is in response to my comments to the
effect that I would like to see the LSM infrastructure
using the inode like (inode->i_security) to the xfrm
(void *) approach. I haven't been looking at the IB patches
too carefully to date. It's possible I have not been clear.

>
>>  };
>>
>>  struct ib_mr {
>> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
>> index 6a8841d..4f13ea4 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,
>> @@ -83,6 +84,8 @@
>>  #include <linux/export.h>
>>  #include <linux/msg.h>
>>  #include <linux/shm.h>
>> +#include <rdma/ib_verbs.h>
>> +#include <rdma/ib_mad.h>
>>
>>  #include "avc.h"
>>  #include "objsec.h"
>> @@ -6015,6 +6018,47 @@ static void selinux_unregister_ib_flush_callback(void)
>>         mutex_unlock(&ib_flush_mutex);
>>  }
>>
>> +static int selinux_ib_qp_alloc_security(struct ib_qp_security *qp_sec)
>> +{
>> +       struct ib_security_struct *sec;
>> +
>> +       sec = kzalloc(sizeof(*sec), GFP_ATOMIC);
>> +       if (!sec)
>> +               return -ENOMEM;
>> +       sec->sid = current_sid();
>> +
>> +       qp_sec->q_security = sec;
>> +       return 0;
>> +}
> If you get rid of the ip_qp_security struct, you can just return the
> blob instead of an int (NULL on error).  Same with the MAD allocator
> below.
>
> Also, and this may be more important for the MAD allocator below (I'm
> still pretty IB-ignorant), can you forsee the need/desire to have the
> QP/MAD label different from the process which creates them?  How often
> will other SELinux domains need to interact with these objects?
>
>> +static void selinux_ib_qp_free_security(struct ib_qp_security *qp_sec)
>> +{
>> +       struct ib_security_struct *sec = qp_sec->q_security;
>> +
>> +       qp_sec->q_security = NULL;
>> +       kfree(sec);
>> +}
>> +
>> +static int selinux_ib_mad_agent_alloc_security(struct ib_mad_agent *mad_agent)
>> +{
>> +       struct ib_security_struct *sec;
>> +
>> +       sec = kzalloc(sizeof(*sec), GFP_ATOMIC);
>> +       if (!sec)
>> +               return -ENOMEM;
>> +       sec->sid = current_sid();
>> +
>> +       mad_agent->m_security = sec;
>> +       return 0;
>> +}
>> +
>> +static void selinux_ib_mad_agent_free_security(struct ib_mad_agent *mad_agent)
>> +{
>> +       struct ib_security_struct *sec = mad_agent->m_security;
>> +
>> +       mad_agent->m_security = NULL;
>> +       kfree(sec);
>> +}
>>  #endif

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

* Re: [PATCH 01/12] security: Add LSM hooks for Infiniband security
  2016-06-30 20:27       ` Paul Moore
@ 2016-06-30 21:09         ` Daniel Jurgens
  -1 siblings, 0 replies; 128+ messages in thread
From: Daniel Jurgens @ 2016-06-30 21:09 UTC (permalink / raw)
  To: Paul Moore
  Cc: 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, Yevgeny Petrilin

On 6/30/2016 3:28 PM, Paul Moore wrote:
> On Thu, Jun 23, 2016 at 3:52 PM, Dan Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org> wrote:
>> From: Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
>>
>> Add nine new hooks
>>  1. Allocate security contexts for Infiniband QPs.
>>  2. Free security contexts for Infiniband QPs.
>>  3. Allocate security contexts for Infiniband MAD agents.
>>  4. Free security contexts for Infiniband MAD agents.
>>  5. Enforce QP access to Pkeys
>>  6. Enforce MAD agent access to Pkeys
>>  7. Enforce MAD agent access to Infiniband End Ports for sending Subnet
>>     Management Packets (SMP)
>>  8. A hook to register a callback to receive notifications of
>>     security policy or enforcement changes.  Restricting a QPs access to
>>     a pkey will be done during setup and not on a per packet basis
>>     access must be enforced again.
>>  9. A hook to unregister the callback.
>>
>> Signed-off-by: Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
>> Reviewed-by: Eli Cohen <eli-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
>> ---
>>  include/linux/lsm_hooks.h | 71 ++++++++++++++++++++++++++++++++++++++++
>>  include/linux/security.h  | 63 +++++++++++++++++++++++++++++++++++
>>  include/rdma/ib_verbs.h   |  4 +++
>>  security/Kconfig          |  9 +++++
>>  security/security.c       | 83 +++++++++++++++++++++++++++++++++++++++++++++++
>>  5 files changed, 230 insertions(+)
> I'd recommend putting the IB hook calls into this patch as well, it
> helps make the hooks a bit more concrete as you can see where, and how
> they are called.
Do you mean add them with SELinux hook implementations?  Or with the the IB/Core code where they are called?  I tried as best as I could to avoid mingling LSM, IB/Core, and SELinux changes.  Hoping to minimize the burden of a single patch needing acceptance from multiple maintainers and synchronization problems that could create.  I could split this up and add the hooks where they are actually used if you don't think that's problem though.

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

* Re: [PATCH 01/12] security: Add LSM hooks for Infiniband security
@ 2016-06-30 21:09         ` Daniel Jurgens
  0 siblings, 0 replies; 128+ messages in thread
From: Daniel Jurgens @ 2016-06-30 21:09 UTC (permalink / raw)
  To: Paul Moore
  Cc: chrisw, paul, sds, eparis, dledford, sean.hefty, hal.rosenstock,
	selinux, linux-security-module, linux-rdma, Yevgeny Petrilin

On 6/30/2016 3:28 PM, Paul Moore wrote:
> On Thu, Jun 23, 2016 at 3:52 PM, Dan Jurgens <danielj@mellanox.com> wrote:
>> From: Daniel Jurgens <danielj@mellanox.com>
>>
>> Add nine new hooks
>>  1. Allocate security contexts for Infiniband QPs.
>>  2. Free security contexts for Infiniband QPs.
>>  3. Allocate security contexts for Infiniband MAD agents.
>>  4. Free security contexts for Infiniband MAD agents.
>>  5. Enforce QP access to Pkeys
>>  6. Enforce MAD agent access to Pkeys
>>  7. Enforce MAD agent access to Infiniband End Ports for sending Subnet
>>     Management Packets (SMP)
>>  8. A hook to register a callback to receive notifications of
>>     security policy or enforcement changes.  Restricting a QPs access to
>>     a pkey will be done during setup and not on a per packet basis
>>     access must be enforced again.
>>  9. A hook to unregister the callback.
>>
>> Signed-off-by: Daniel Jurgens <danielj@mellanox.com>
>> Reviewed-by: Eli Cohen <eli@mellanox.com>
>> ---
>>  include/linux/lsm_hooks.h | 71 ++++++++++++++++++++++++++++++++++++++++
>>  include/linux/security.h  | 63 +++++++++++++++++++++++++++++++++++
>>  include/rdma/ib_verbs.h   |  4 +++
>>  security/Kconfig          |  9 +++++
>>  security/security.c       | 83 +++++++++++++++++++++++++++++++++++++++++++++++
>>  5 files changed, 230 insertions(+)
> I'd recommend putting the IB hook calls into this patch as well, it
> helps make the hooks a bit more concrete as you can see where, and how
> they are called.
Do you mean add them with SELinux hook implementations?  Or with the the IB/Core code where they are called?  I tried as best as I could to avoid mingling LSM, IB/Core, and SELinux changes.  Hoping to minimize the burden of a single patch needing acceptance from multiple maintainers and synchronization problems that could create.  I could split this up and add the hooks where they are actually used if you don't think that's problem though.

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

* Re: [PATCH 02/12] selinux: Create policydb version for Infiniband support
  2016-06-30 20:59         ` Daniel Jurgens
@ 2016-06-30 21:18             ` Paul Moore
  -1 siblings, 0 replies; 128+ messages in thread
From: Paul Moore @ 2016-06-30 21:18 UTC (permalink / raw)
  To: Daniel Jurgens
  Cc: 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, Yevgeny Petrilin

On Thu, Jun 30, 2016 at 4:59 PM, Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org> wrote:
> On 6/30/2016 3:17 PM, Paul Moore wrote:
>> On Thu, Jun 23, 2016 at 3:52 PM, 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 End 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>
>>> ---
>>>  security/selinux/include/security.h |   3 +-
>>>  security/selinux/ss/policydb.c      | 129 +++++++++++++++++++++++++++++++-----
>>>  security/selinux/ss/policydb.h      |  27 +++++---
>>>  3 files changed, 135 insertions(+), 24 deletions(-)
>> ...
>>
>>> diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
>>> index 992a315..78b819c 100644
>>> --- a/security/selinux/ss/policydb.c
>>> +++ b/security/selinux/ss/policydb.c
>>> @@ -2219,6 +2229,58 @@ 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.
>>> +                                */
>> Any particular reason why you reusing an IPv6 address format here?
>> Why not use a u64 for the prefix and u16/u32 fields for the partition
>> keys?
>
> The subnet prefix is the high order bytes of an IPv6 address and there is infrastructure in place in the userland utilities that deal with IPv6 addresses (parsing them with a :: to eliminate the need to fill out the 0's for example).

Okay, as long as it is a proper IPv6 address, that's fine.

> Regarding u16, the policy is packed with everything in u32, as you can see in OCON_NODE6 and OCON_PORT handling.
>>> +                               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_END_PORT:
>> This is a little bit of bikeshedding, but is there such thing as an IB
>> "port" that isn't an *end* "port"?  Could we simply use OCON_IB_PORT?
>
> Jason Gunthorpe requested that the name be end_port  in the RFC series.

His reasoning?  Is there a IB port concept that isn't an end port?

-- 
paul moore
security @ redhat
--
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] 128+ messages in thread

* Re: [PATCH 02/12] selinux: Create policydb version for Infiniband support
@ 2016-06-30 21:18             ` Paul Moore
  0 siblings, 0 replies; 128+ messages in thread
From: Paul Moore @ 2016-06-30 21:18 UTC (permalink / raw)
  To: Daniel Jurgens
  Cc: chrisw, paul, sds, eparis, dledford, sean.hefty, hal.rosenstock,
	selinux, linux-security-module, linux-rdma, Yevgeny Petrilin

On Thu, Jun 30, 2016 at 4:59 PM, Daniel Jurgens <danielj@mellanox.com> wrote:
> On 6/30/2016 3:17 PM, Paul Moore wrote:
>> On Thu, Jun 23, 2016 at 3:52 PM, 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 End 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>
>>> ---
>>>  security/selinux/include/security.h |   3 +-
>>>  security/selinux/ss/policydb.c      | 129 +++++++++++++++++++++++++++++++-----
>>>  security/selinux/ss/policydb.h      |  27 +++++---
>>>  3 files changed, 135 insertions(+), 24 deletions(-)
>> ...
>>
>>> diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
>>> index 992a315..78b819c 100644
>>> --- a/security/selinux/ss/policydb.c
>>> +++ b/security/selinux/ss/policydb.c
>>> @@ -2219,6 +2229,58 @@ 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.
>>> +                                */
>> Any particular reason why you reusing an IPv6 address format here?
>> Why not use a u64 for the prefix and u16/u32 fields for the partition
>> keys?
>
> The subnet prefix is the high order bytes of an IPv6 address and there is infrastructure in place in the userland utilities that deal with IPv6 addresses (parsing them with a :: to eliminate the need to fill out the 0's for example).

Okay, as long as it is a proper IPv6 address, that's fine.

> Regarding u16, the policy is packed with everything in u32, as you can see in OCON_NODE6 and OCON_PORT handling.
>>> +                               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_END_PORT:
>> This is a little bit of bikeshedding, but is there such thing as an IB
>> "port" that isn't an *end* "port"?  Could we simply use OCON_IB_PORT?
>
> Jason Gunthorpe requested that the name be end_port  in the RFC series.

His reasoning?  Is there a IB port concept that isn't an end port?

-- 
paul moore
security @ redhat

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

* Re: [PATCH 01/12] security: Add LSM hooks for Infiniband security
  2016-06-30 21:09         ` Daniel Jurgens
  (?)
@ 2016-06-30 21:27         ` Paul Moore
  2016-06-30 21:34             ` Daniel Jurgens
  -1 siblings, 1 reply; 128+ messages in thread
From: Paul Moore @ 2016-06-30 21:27 UTC (permalink / raw)
  To: Daniel Jurgens
  Cc: chrisw, paul, sds, eparis, dledford, sean.hefty, hal.rosenstock,
	selinux, linux-security-module, linux-rdma, Yevgeny Petrilin

On Thu, Jun 30, 2016 at 5:09 PM, Daniel Jurgens <danielj@mellanox.com> wrote:
> On 6/30/2016 3:28 PM, Paul Moore wrote:
>> On Thu, Jun 23, 2016 at 3:52 PM, Dan Jurgens <danielj@mellanox.com> wrote:
>>> From: Daniel Jurgens <danielj@mellanox.com>
>>>
>>> Add nine new hooks
>>>  1. Allocate security contexts for Infiniband QPs.
>>>  2. Free security contexts for Infiniband QPs.
>>>  3. Allocate security contexts for Infiniband MAD agents.
>>>  4. Free security contexts for Infiniband MAD agents.
>>>  5. Enforce QP access to Pkeys
>>>  6. Enforce MAD agent access to Pkeys
>>>  7. Enforce MAD agent access to Infiniband End Ports for sending Subnet
>>>     Management Packets (SMP)
>>>  8. A hook to register a callback to receive notifications of
>>>     security policy or enforcement changes.  Restricting a QPs access to
>>>     a pkey will be done during setup and not on a per packet basis
>>>     access must be enforced again.
>>>  9. A hook to unregister the callback.
>>>
>>> Signed-off-by: Daniel Jurgens <danielj@mellanox.com>
>>> Reviewed-by: Eli Cohen <eli@mellanox.com>
>>> ---
>>>  include/linux/lsm_hooks.h | 71 ++++++++++++++++++++++++++++++++++++++++
>>>  include/linux/security.h  | 63 +++++++++++++++++++++++++++++++++++
>>>  include/rdma/ib_verbs.h   |  4 +++
>>>  security/Kconfig          |  9 +++++
>>>  security/security.c       | 83 +++++++++++++++++++++++++++++++++++++++++++++++
>>>  5 files changed, 230 insertions(+)
>> I'd recommend putting the IB hook calls into this patch as well, it
>> helps make the hooks a bit more concrete as you can see where, and how
>> they are called.
>
> Do you mean add them with SELinux hook implementations?  Or with the the IB/Core code where they are called?

I mean the IB changes.  That way a single patch has both the hook
declarations and their calling locations; it helps make the hooks a
bit less abstract.

The SELinux hook implementations should be kept separate.

> I tried as best as I could to avoid mingling LSM, IB/Core, and SELinux changes.  Hoping to minimize the burden of a single patch needing acceptance from multiple maintainers and synchronization problems that could create.  I could split this up and add the hooks where they are actually used if you don't think that's problem though.

Ultimately the entire patchset needs to get acceptance from the IB and
SELinux folks, with no objections from any of the other LSM
maintainers.  My guess is, I'll probably be the one who ends up
merging this as it's more SELinux than anything else, but I'll want a
thumbs-up/ACK from the IB folks before I do that.

-- 
paul moore
security @ redhat

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

* Re: [PATCH 01/12] security: Add LSM hooks for Infiniband security
  2016-06-30 20:33       ` Paul Moore
@ 2016-06-30 21:27         ` Daniel Jurgens
  -1 siblings, 0 replies; 128+ messages in thread
From: Daniel Jurgens @ 2016-06-30 21:27 UTC (permalink / raw)
  To: Paul Moore
  Cc: 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, Yevgeny Petrilin

On 6/30/2016 3:33 PM, Paul Moore wrote:
> On Thu, Jun 23, 2016 at 3:52 PM, Dan Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org> wrote:
>
>> diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
>> index 432bed5..3f6780b 100644
>> --- a/include/rdma/ib_verbs.h
>> +++ b/include/rdma/ib_verbs.h
>> @@ -1428,6 +1428,10 @@ struct ib_srq {
>>         } ext;
>>  };
>>
>> +struct ib_qp_security {
>> +       void *q_security;
>> +};
> Sorry, I missed this earlier and didn't realize it until I was going
> through 4/12 ... why both with ib_qp_security?  Why not just use a
> straight void pointer?
>
In the RFC series Casey Schaufler asked me to not use void blobs to make module stacking easier.  Also, in the IB/Core part of the series much is added to the ib_qp_security structure to track security info needed for proper enforcement.

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

* Re: [PATCH 01/12] security: Add LSM hooks for Infiniband security
@ 2016-06-30 21:27         ` Daniel Jurgens
  0 siblings, 0 replies; 128+ messages in thread
From: Daniel Jurgens @ 2016-06-30 21:27 UTC (permalink / raw)
  To: Paul Moore
  Cc: chrisw, paul, sds, eparis, dledford, sean.hefty, hal.rosenstock,
	selinux, linux-security-module, linux-rdma, Yevgeny Petrilin

On 6/30/2016 3:33 PM, Paul Moore wrote:
> On Thu, Jun 23, 2016 at 3:52 PM, Dan Jurgens <danielj@mellanox.com> wrote:
>
>> diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
>> index 432bed5..3f6780b 100644
>> --- a/include/rdma/ib_verbs.h
>> +++ b/include/rdma/ib_verbs.h
>> @@ -1428,6 +1428,10 @@ struct ib_srq {
>>         } ext;
>>  };
>>
>> +struct ib_qp_security {
>> +       void *q_security;
>> +};
> Sorry, I missed this earlier and didn't realize it until I was going
> through 4/12 ... why both with ib_qp_security?  Why not just use a
> straight void pointer?
>
In the RFC series Casey Schaufler asked me to not use void blobs to make module stacking easier.  Also, in the IB/Core part of the series much is added to the ib_qp_security structure to track security info needed for proper enforcement.

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

* Re: [PATCH 01/12] security: Add LSM hooks for Infiniband security
  2016-06-30 21:27         ` Daniel Jurgens
@ 2016-06-30 21:30             ` Paul Moore
  -1 siblings, 0 replies; 128+ messages in thread
From: Paul Moore @ 2016-06-30 21:30 UTC (permalink / raw)
  To: Daniel Jurgens
  Cc: 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, Yevgeny Petrilin

On Thu, Jun 30, 2016 at 5:27 PM, Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org> wrote:
> On 6/30/2016 3:33 PM, Paul Moore wrote:
>> On Thu, Jun 23, 2016 at 3:52 PM, Dan Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org> wrote:
>>
>>> diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
>>> index 432bed5..3f6780b 100644
>>> --- a/include/rdma/ib_verbs.h
>>> +++ b/include/rdma/ib_verbs.h
>>> @@ -1428,6 +1428,10 @@ struct ib_srq {
>>>         } ext;
>>>  };
>>>
>>> +struct ib_qp_security {
>>> +       void *q_security;
>>> +};
>> Sorry, I missed this earlier and didn't realize it until I was going
>> through 4/12 ... why both with ib_qp_security?  Why not just use a
>> straight void pointer?
>>
> In the RFC series Casey Schaufler asked me to not use void blobs to make module stacking easier.

I'm not entirely sure that is what he had in mind, but ...

> Also, in the IB/Core part of the series much is added to the ib_qp_security structure to track security info needed for proper enforcement.

... okay, I'll reserve further comment until I get there.

-- 
paul moore
security @ redhat
--
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] 128+ messages in thread

* Re: [PATCH 01/12] security: Add LSM hooks for Infiniband security
@ 2016-06-30 21:30             ` Paul Moore
  0 siblings, 0 replies; 128+ messages in thread
From: Paul Moore @ 2016-06-30 21:30 UTC (permalink / raw)
  To: Daniel Jurgens
  Cc: chrisw, paul, sds, eparis, dledford, sean.hefty, hal.rosenstock,
	selinux, linux-security-module, linux-rdma, Yevgeny Petrilin

On Thu, Jun 30, 2016 at 5:27 PM, Daniel Jurgens <danielj@mellanox.com> wrote:
> On 6/30/2016 3:33 PM, Paul Moore wrote:
>> On Thu, Jun 23, 2016 at 3:52 PM, Dan Jurgens <danielj@mellanox.com> wrote:
>>
>>> diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
>>> index 432bed5..3f6780b 100644
>>> --- a/include/rdma/ib_verbs.h
>>> +++ b/include/rdma/ib_verbs.h
>>> @@ -1428,6 +1428,10 @@ struct ib_srq {
>>>         } ext;
>>>  };
>>>
>>> +struct ib_qp_security {
>>> +       void *q_security;
>>> +};
>> Sorry, I missed this earlier and didn't realize it until I was going
>> through 4/12 ... why both with ib_qp_security?  Why not just use a
>> straight void pointer?
>>
> In the RFC series Casey Schaufler asked me to not use void blobs to make module stacking easier.

I'm not entirely sure that is what he had in mind, but ...

> Also, in the IB/Core part of the series much is added to the ib_qp_security structure to track security info needed for proper enforcement.

... okay, I'll reserve further comment until I get there.

-- 
paul moore
security @ redhat

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

* Re: [PATCH 02/12] selinux: Create policydb version for Infiniband support
  2016-06-30 21:18             ` Paul Moore
@ 2016-06-30 21:32               ` Daniel Jurgens
  -1 siblings, 0 replies; 128+ messages in thread
From: Daniel Jurgens @ 2016-06-30 21:32 UTC (permalink / raw)
  To: Paul Moore
  Cc: 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, Yevgeny Petrilin

On 6/30/2016 4:18 PM, Paul Moore wrote:
> On Thu, Jun 30, 2016 at 4:59 PM, Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org> wrote:
>> On 6/30/2016 3:17 PM, Paul Moore wrote:
>>> On Thu, Jun 23, 2016 at 3:52 PM, 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 End 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>
>>>> ---
>>>>  security/selinux/include/security.h |   3 +-
>>>>  security/selinux/ss/policydb.c      | 129 +++++++++++++++++++++++++++++++-----
>>>>  security/selinux/ss/policydb.h      |  27 +++++---
>>>>  3 files changed, 135 insertions(+), 24 deletions(-)
>>> ...
>>>
>>>> diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
>>>> index 992a315..78b819c 100644
>>>> --- a/security/selinux/ss/policydb.c
>>>> +++ b/security/selinux/ss/policydb.c
>>>> @@ -2219,6 +2229,58 @@ 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.
>>>> +                                */
>>> Any particular reason why you reusing an IPv6 address format here?
>>> Why not use a u64 for the prefix and u16/u32 fields for the partition
>>> keys?
>> The subnet prefix is the high order bytes of an IPv6 address and there is infrastructure in place in the userland utilities that deal with IPv6 addresses (parsing them with a :: to eliminate the need to fill out the 0's for example).
> Okay, as long as it is a proper IPv6 address, that's fine.
>
>> Regarding u16, the policy is packed with everything in u32, as you can see in OCON_NODE6 and OCON_PORT handling.
>>>> +                               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_END_PORT:
>>> This is a little bit of bikeshedding, but is there such thing as an IB
>>> "port" that isn't an *end* "port"?  Could we simply use OCON_IB_PORT?
>> Jason Gunthorpe requested that the name be end_port  in the RFC series.
> His reasoning?  Is there a IB port concept that isn't an end port?
The IB spec defines them as such.  I had called them ib_devices previously though so it's possible he would tolerate "port" instead.
--
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] 128+ messages in thread

* Re: [PATCH 02/12] selinux: Create policydb version for Infiniband support
@ 2016-06-30 21:32               ` Daniel Jurgens
  0 siblings, 0 replies; 128+ messages in thread
From: Daniel Jurgens @ 2016-06-30 21:32 UTC (permalink / raw)
  To: Paul Moore
  Cc: chrisw, paul, sds, eparis, dledford, sean.hefty, hal.rosenstock,
	selinux, linux-security-module, linux-rdma, Yevgeny Petrilin

On 6/30/2016 4:18 PM, Paul Moore wrote:
> On Thu, Jun 30, 2016 at 4:59 PM, Daniel Jurgens <danielj@mellanox.com> wrote:
>> On 6/30/2016 3:17 PM, Paul Moore wrote:
>>> On Thu, Jun 23, 2016 at 3:52 PM, 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 End 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>
>>>> ---
>>>>  security/selinux/include/security.h |   3 +-
>>>>  security/selinux/ss/policydb.c      | 129 +++++++++++++++++++++++++++++++-----
>>>>  security/selinux/ss/policydb.h      |  27 +++++---
>>>>  3 files changed, 135 insertions(+), 24 deletions(-)
>>> ...
>>>
>>>> diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
>>>> index 992a315..78b819c 100644
>>>> --- a/security/selinux/ss/policydb.c
>>>> +++ b/security/selinux/ss/policydb.c
>>>> @@ -2219,6 +2229,58 @@ 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.
>>>> +                                */
>>> Any particular reason why you reusing an IPv6 address format here?
>>> Why not use a u64 for the prefix and u16/u32 fields for the partition
>>> keys?
>> The subnet prefix is the high order bytes of an IPv6 address and there is infrastructure in place in the userland utilities that deal with IPv6 addresses (parsing them with a :: to eliminate the need to fill out the 0's for example).
> Okay, as long as it is a proper IPv6 address, that's fine.
>
>> Regarding u16, the policy is packed with everything in u32, as you can see in OCON_NODE6 and OCON_PORT handling.
>>>> +                               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_END_PORT:
>>> This is a little bit of bikeshedding, but is there such thing as an IB
>>> "port" that isn't an *end* "port"?  Could we simply use OCON_IB_PORT?
>> Jason Gunthorpe requested that the name be end_port  in the RFC series.
> His reasoning?  Is there a IB port concept that isn't an end port?
The IB spec defines them as such.  I had called them ib_devices previously though so it's possible he would tolerate "port" instead.

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

* Re: [PATCH 01/12] security: Add LSM hooks for Infiniband security
  2016-06-30 21:27         ` Paul Moore
@ 2016-06-30 21:34             ` Daniel Jurgens
  0 siblings, 0 replies; 128+ messages in thread
From: Daniel Jurgens @ 2016-06-30 21:34 UTC (permalink / raw)
  To: Paul Moore
  Cc: 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, Yevgeny Petrilin

On 6/30/2016 4:27 PM, Paul Moore wrote:
> On Thu, Jun 30, 2016 at 5:09 PM, Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org> wrote:
>> On 6/30/2016 3:28 PM, Paul Moore wrote:
>>> On Thu, Jun 23, 2016 at 3:52 PM, Dan Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org> wrote:
>>>> From: Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
>>>>
>>>> Add nine new hooks
>>>>  1. Allocate security contexts for Infiniband QPs.
>>>>  2. Free security contexts for Infiniband QPs.
>>>>  3. Allocate security contexts for Infiniband MAD agents.
>>>>  4. Free security contexts for Infiniband MAD agents.
>>>>  5. Enforce QP access to Pkeys
>>>>  6. Enforce MAD agent access to Pkeys
>>>>  7. Enforce MAD agent access to Infiniband End Ports for sending Subnet
>>>>     Management Packets (SMP)
>>>>  8. A hook to register a callback to receive notifications of
>>>>     security policy or enforcement changes.  Restricting a QPs access to
>>>>     a pkey will be done during setup and not on a per packet basis
>>>>     access must be enforced again.
>>>>  9. A hook to unregister the callback.
>>>>
>>>> Signed-off-by: Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
>>>> Reviewed-by: Eli Cohen <eli-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
>>>> ---
>>>>  include/linux/lsm_hooks.h | 71 ++++++++++++++++++++++++++++++++++++++++
>>>>  include/linux/security.h  | 63 +++++++++++++++++++++++++++++++++++
>>>>  include/rdma/ib_verbs.h   |  4 +++
>>>>  security/Kconfig          |  9 +++++
>>>>  security/security.c       | 83 +++++++++++++++++++++++++++++++++++++++++++++++
>>>>  5 files changed, 230 insertions(+)
>>> I'd recommend putting the IB hook calls into this patch as well, it
>>> helps make the hooks a bit more concrete as you can see where, and how
>>> they are called.
>> Do you mean add them with SELinux hook implementations?  Or with the the IB/Core code where they are called?
> I mean the IB changes.  That way a single patch has both the hook
> declarations and their calling locations; it helps make the hooks a
> bit less abstract.
>
> The SELinux hook implementations should be kept separate.
>
>> I tried as best as I could to avoid mingling LSM, IB/Core, and SELinux changes.  Hoping to minimize the burden of a single patch needing acceptance from multiple maintainers and synchronization problems that could create.  I could split this up and add the hooks where they are actually used if you don't think that's problem though.
> Ultimately the entire patchset needs to get acceptance from the IB and
> SELinux folks, with no objections from any of the other LSM
> maintainers.  My guess is, I'll probably be the one who ends up
> merging this as it's more SELinux than anything else, but I'll want a
> thumbs-up/ACK from the IB folks before I do that.
OK, I can split this patch up and squash to the respective IB core patches where they are first used.
--
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] 128+ messages in thread

* Re: [PATCH 01/12] security: Add LSM hooks for Infiniband security
@ 2016-06-30 21:34             ` Daniel Jurgens
  0 siblings, 0 replies; 128+ messages in thread
From: Daniel Jurgens @ 2016-06-30 21:34 UTC (permalink / raw)
  To: Paul Moore
  Cc: chrisw, paul, sds, eparis, dledford, sean.hefty, hal.rosenstock,
	selinux, linux-security-module, linux-rdma, Yevgeny Petrilin

On 6/30/2016 4:27 PM, Paul Moore wrote:
> On Thu, Jun 30, 2016 at 5:09 PM, Daniel Jurgens <danielj@mellanox.com> wrote:
>> On 6/30/2016 3:28 PM, Paul Moore wrote:
>>> On Thu, Jun 23, 2016 at 3:52 PM, Dan Jurgens <danielj@mellanox.com> wrote:
>>>> From: Daniel Jurgens <danielj@mellanox.com>
>>>>
>>>> Add nine new hooks
>>>>  1. Allocate security contexts for Infiniband QPs.
>>>>  2. Free security contexts for Infiniband QPs.
>>>>  3. Allocate security contexts for Infiniband MAD agents.
>>>>  4. Free security contexts for Infiniband MAD agents.
>>>>  5. Enforce QP access to Pkeys
>>>>  6. Enforce MAD agent access to Pkeys
>>>>  7. Enforce MAD agent access to Infiniband End Ports for sending Subnet
>>>>     Management Packets (SMP)
>>>>  8. A hook to register a callback to receive notifications of
>>>>     security policy or enforcement changes.  Restricting a QPs access to
>>>>     a pkey will be done during setup and not on a per packet basis
>>>>     access must be enforced again.
>>>>  9. A hook to unregister the callback.
>>>>
>>>> Signed-off-by: Daniel Jurgens <danielj@mellanox.com>
>>>> Reviewed-by: Eli Cohen <eli@mellanox.com>
>>>> ---
>>>>  include/linux/lsm_hooks.h | 71 ++++++++++++++++++++++++++++++++++++++++
>>>>  include/linux/security.h  | 63 +++++++++++++++++++++++++++++++++++
>>>>  include/rdma/ib_verbs.h   |  4 +++
>>>>  security/Kconfig          |  9 +++++
>>>>  security/security.c       | 83 +++++++++++++++++++++++++++++++++++++++++++++++
>>>>  5 files changed, 230 insertions(+)
>>> I'd recommend putting the IB hook calls into this patch as well, it
>>> helps make the hooks a bit more concrete as you can see where, and how
>>> they are called.
>> Do you mean add them with SELinux hook implementations?  Or with the the IB/Core code where they are called?
> I mean the IB changes.  That way a single patch has both the hook
> declarations and their calling locations; it helps make the hooks a
> bit less abstract.
>
> The SELinux hook implementations should be kept separate.
>
>> I tried as best as I could to avoid mingling LSM, IB/Core, and SELinux changes.  Hoping to minimize the burden of a single patch needing acceptance from multiple maintainers and synchronization problems that could create.  I could split this up and add the hooks where they are actually used if you don't think that's problem though.
> Ultimately the entire patchset needs to get acceptance from the IB and
> SELinux folks, with no objections from any of the other LSM
> maintainers.  My guess is, I'll probably be the one who ends up
> merging this as it's more SELinux than anything else, but I'll want a
> thumbs-up/ACK from the IB folks before I do that.
OK, I can split this patch up and squash to the respective IB core patches where they are first used.

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

* Re: [PATCH 02/12] selinux: Create policydb version for Infiniband support
  2016-06-30 21:32               ` Daniel Jurgens
@ 2016-06-30 21:37                   ` Paul Moore
  -1 siblings, 0 replies; 128+ messages in thread
From: Paul Moore @ 2016-06-30 21:37 UTC (permalink / raw)
  To: Daniel Jurgens
  Cc: 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, Yevgeny Petrilin

On Thu, Jun 30, 2016 at 5:32 PM, Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org> wrote:
> On 6/30/2016 4:18 PM, Paul Moore wrote:
>> On Thu, Jun 30, 2016 at 4:59 PM, Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org> wrote:
>>> On 6/30/2016 3:17 PM, Paul Moore wrote:
>>>> On Thu, Jun 23, 2016 at 3:52 PM, 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 End 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>
>>>>> ---
>>>>>  security/selinux/include/security.h |   3 +-
>>>>>  security/selinux/ss/policydb.c      | 129 +++++++++++++++++++++++++++++++-----
>>>>>  security/selinux/ss/policydb.h      |  27 +++++---
>>>>>  3 files changed, 135 insertions(+), 24 deletions(-)

...
                       }
>>>>> +                       case OCON_IB_END_PORT:
>>>> This is a little bit of bikeshedding, but is there such thing as an IB
>>>> "port" that isn't an *end* "port"?  Could we simply use OCON_IB_PORT?
>>> Jason Gunthorpe requested that the name be end_port  in the RFC series.
>> His reasoning?  Is there a IB port concept that isn't an end port?
> The IB spec defines them as such.  I had called them ib_devices previously though so it's possible he would tolerate "port" instead.

Okay, if that is what they are called that's fine with me.  Perhaps
just squash the macro to OCON_IB_ENDPORT or similar; all those
underscores are messing with my mental parser.

-- 
paul moore
security @ redhat
--
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] 128+ messages in thread

* Re: [PATCH 02/12] selinux: Create policydb version for Infiniband support
@ 2016-06-30 21:37                   ` Paul Moore
  0 siblings, 0 replies; 128+ messages in thread
From: Paul Moore @ 2016-06-30 21:37 UTC (permalink / raw)
  To: Daniel Jurgens
  Cc: chrisw, paul, sds, eparis, dledford, sean.hefty, hal.rosenstock,
	selinux, linux-security-module, linux-rdma, Yevgeny Petrilin

On Thu, Jun 30, 2016 at 5:32 PM, Daniel Jurgens <danielj@mellanox.com> wrote:
> On 6/30/2016 4:18 PM, Paul Moore wrote:
>> On Thu, Jun 30, 2016 at 4:59 PM, Daniel Jurgens <danielj@mellanox.com> wrote:
>>> On 6/30/2016 3:17 PM, Paul Moore wrote:
>>>> On Thu, Jun 23, 2016 at 3:52 PM, 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 End 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>
>>>>> ---
>>>>>  security/selinux/include/security.h |   3 +-
>>>>>  security/selinux/ss/policydb.c      | 129 +++++++++++++++++++++++++++++++-----
>>>>>  security/selinux/ss/policydb.h      |  27 +++++---
>>>>>  3 files changed, 135 insertions(+), 24 deletions(-)

...
                       }
>>>>> +                       case OCON_IB_END_PORT:
>>>> This is a little bit of bikeshedding, but is there such thing as an IB
>>>> "port" that isn't an *end* "port"?  Could we simply use OCON_IB_PORT?
>>> Jason Gunthorpe requested that the name be end_port  in the RFC series.
>> His reasoning?  Is there a IB port concept that isn't an end port?
> The IB spec defines them as such.  I had called them ib_devices previously though so it's possible he would tolerate "port" instead.

Okay, if that is what they are called that's fine with me.  Perhaps
just squash the macro to OCON_IB_ENDPORT or similar; all those
underscores are messing with my mental parser.

-- 
paul moore
security @ redhat

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

* Re: [PATCH 04/12] selinux: Allocate and free infiniband security hooks
  2016-06-30 21:06             ` Casey Schaufler
@ 2016-06-30 21:48               ` Daniel Jurgens
  -1 siblings, 0 replies; 128+ messages in thread
From: Daniel Jurgens @ 2016-06-30 21:48 UTC (permalink / raw)
  To: Casey Schaufler, Paul Moore
  Cc: 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, Yevgeny Petrilin

On 6/30/2016 4:06 PM, Casey Schaufler wrote:
> On 6/30/2016 1:42 PM, Paul Moore wrote:
>> On Thu, Jun 23, 2016 at 3:52 PM, Dan Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org> wrote:
>>> From: Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
>>>
>>> Implement and attach hooks to allocate and free Infiniband QP and MAD
>>> agent security structures.
>>>
>>> Signed-off-by: Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
>>> Reviewed-by: Eli Cohen <eli-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
>>> ---
>>>  include/rdma/ib_mad.h             |  1 +
>>>  include/rdma/ib_verbs.h           |  1 +
>>>  security/selinux/hooks.c          | 53 +++++++++++++++++++++++++++++++++++++++
>>>  security/selinux/include/objsec.h |  5 ++++
>>>  4 files changed, 60 insertions(+)
>>>
>>> diff --git a/include/rdma/ib_mad.h b/include/rdma/ib_mad.h
>>> index c8a773f..a1ed025 100644
>>> --- a/include/rdma/ib_mad.h
>>> +++ b/include/rdma/ib_mad.h
>>> @@ -537,6 +537,7 @@ struct ib_mad_agent {
>>>         u32                     flags;
>>>         u8                      port_num;
>>>         u8                      rmpp_version;
>>> +       void                    *m_security;
>> General convention is to just call the LSM blobs "security" unless
>> there is already a field with that name.
> Not that it really matters all that much, but an unadorned "security"
> makes it unnecessarily difficult to match "p->security" to the data
> involved when you're looking at keys, creds and ipc. I like having
> the prefix. I think the other fields in the structure should have it,
> too, but as I'm not an acknowledged authority on good style I hesitate
> to suggest it in general.

Now that you mention it I think this was part of your comment about not using void*.

>>>  };
>>>
>>>  /**
>>> diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
>>> index 3f6780b..e522acb 100644
>>> --- a/include/rdma/ib_verbs.h
>>> +++ b/include/rdma/ib_verbs.h
>>> @@ -1454,6 +1454,7 @@ struct ib_qp {
>>>         void                   *qp_context;
>>>         u32                     qp_num;
>>>         enum ib_qp_type         qp_type;
>>> +       struct ib_qp_security  *qp_sec;
>> See my earlier question/comment about just using a void pointer here.
> I think that this is in response to my comments to the
> effect that I would like to see the LSM infrastructure
> using the inode like (inode->i_security) to the xfrm
> (void *) approach. I haven't been looking at the IB patches
> too carefully to date. It's possible I have not been clear.
My understanding at the time was that by using something other than a void * different security modules could maintain their own opaque blobs with in and keep the same prototype for the hook.  It's possible I misunderstood you, but it made sense to me.  I don't know of any plans for other security modules to support Infiniband, but this leaves the door open.
>>>  };
>>>
>>>  struct ib_mr {
>>> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
>>> index 6a8841d..4f13ea4 100644
>>> --- a/security/selinux/hooks.c
>>> +++ b/security/selinux/hooks.c
>>> @@ -17,6 +17,7 @@
>>>   *     Paul Moore <paul-r2n+y4ga6xFZroRs9YW3xA@public.gmane.org>
>>>   *  Copyright (C) 2007 Hitachi Software Engineering Co., Ltd.
>>>   *                    Yuichi Nakamura <ynakam-FkO1umbPgv4fag7Bw7Dlfw@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 version 2,
>>> @@ -83,6 +84,8 @@
>>>  #include <linux/export.h>
>>>  #include <linux/msg.h>
>>>  #include <linux/shm.h>
>>> +#include <rdma/ib_verbs.h>
>>> +#include <rdma/ib_mad.h>
>>>
>>>  #include "avc.h"
>>>  #include "objsec.h"
>>> @@ -6015,6 +6018,47 @@ static void selinux_unregister_ib_flush_callback(void)
>>>         mutex_unlock(&ib_flush_mutex);
>>>  }
>>>
>>> +static int selinux_ib_qp_alloc_security(struct ib_qp_security *qp_sec)
>>> +{
>>> +       struct ib_security_struct *sec;
>>> +
>>> +       sec = kzalloc(sizeof(*sec), GFP_ATOMIC);
>>> +       if (!sec)
>>> +               return -ENOMEM;
>>> +       sec->sid = current_sid();
>>> +
>>> +       qp_sec->q_security = sec;
>>> +       return 0;
>>> +}
>> If you get rid of the ip_qp_security struct, you can just return the
>> blob instead of an int (NULL on error).  Same with the MAD allocator
>> below.
>>
>> Also, and this may be more important for the MAD allocator below (I'm
>> still pretty IB-ignorant), can you forsee the need/desire to have the
>> QP/MAD label different from the process which creates them?  How often
>> will other SELinux domains need to interact with these objects?
>>
>>> +static void selinux_ib_qp_free_security(struct ib_qp_security *qp_sec)
>>> +{
>>> +       struct ib_security_struct *sec = qp_sec->q_security;
>>> +
>>> +       qp_sec->q_security = NULL;
>>> +       kfree(sec);
>>> +}
>>> +
>>> +static int selinux_ib_mad_agent_alloc_security(struct ib_mad_agent *mad_agent)
>>> +{
>>> +       struct ib_security_struct *sec;
>>> +
>>> +       sec = kzalloc(sizeof(*sec), GFP_ATOMIC);
>>> +       if (!sec)
>>> +               return -ENOMEM;
>>> +       sec->sid = current_sid();
>>> +
>>> +       mad_agent->m_security = sec;
>>> +       return 0;
>>> +}
>>> +
>>> +static void selinux_ib_mad_agent_free_security(struct ib_mad_agent *mad_agent)
>>> +{
>>> +       struct ib_security_struct *sec = mad_agent->m_security;
>>> +
>>> +       mad_agent->m_security = NULL;
>>> +       kfree(sec);
>>> +}
>>>  #endif
>

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

* Re: [PATCH 04/12] selinux: Allocate and free infiniband security hooks
@ 2016-06-30 21:48               ` Daniel Jurgens
  0 siblings, 0 replies; 128+ messages in thread
From: Daniel Jurgens @ 2016-06-30 21:48 UTC (permalink / raw)
  To: Casey Schaufler, Paul Moore
  Cc: chrisw, paul, sds, eparis, dledford, sean.hefty, hal.rosenstock,
	selinux, linux-security-module, linux-rdma, Yevgeny Petrilin

On 6/30/2016 4:06 PM, Casey Schaufler wrote:
> On 6/30/2016 1:42 PM, Paul Moore wrote:
>> On Thu, Jun 23, 2016 at 3:52 PM, Dan Jurgens <danielj@mellanox.com> wrote:
>>> From: Daniel Jurgens <danielj@mellanox.com>
>>>
>>> Implement and attach hooks to allocate and free Infiniband QP and MAD
>>> agent security structures.
>>>
>>> Signed-off-by: Daniel Jurgens <danielj@mellanox.com>
>>> Reviewed-by: Eli Cohen <eli@mellanox.com>
>>> ---
>>>  include/rdma/ib_mad.h             |  1 +
>>>  include/rdma/ib_verbs.h           |  1 +
>>>  security/selinux/hooks.c          | 53 +++++++++++++++++++++++++++++++++++++++
>>>  security/selinux/include/objsec.h |  5 ++++
>>>  4 files changed, 60 insertions(+)
>>>
>>> diff --git a/include/rdma/ib_mad.h b/include/rdma/ib_mad.h
>>> index c8a773f..a1ed025 100644
>>> --- a/include/rdma/ib_mad.h
>>> +++ b/include/rdma/ib_mad.h
>>> @@ -537,6 +537,7 @@ struct ib_mad_agent {
>>>         u32                     flags;
>>>         u8                      port_num;
>>>         u8                      rmpp_version;
>>> +       void                    *m_security;
>> General convention is to just call the LSM blobs "security" unless
>> there is already a field with that name.
> Not that it really matters all that much, but an unadorned "security"
> makes it unnecessarily difficult to match "p->security" to the data
> involved when you're looking at keys, creds and ipc. I like having
> the prefix. I think the other fields in the structure should have it,
> too, but as I'm not an acknowledged authority on good style I hesitate
> to suggest it in general.

Now that you mention it I think this was part of your comment about not using void*.

>>>  };
>>>
>>>  /**
>>> diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
>>> index 3f6780b..e522acb 100644
>>> --- a/include/rdma/ib_verbs.h
>>> +++ b/include/rdma/ib_verbs.h
>>> @@ -1454,6 +1454,7 @@ struct ib_qp {
>>>         void                   *qp_context;
>>>         u32                     qp_num;
>>>         enum ib_qp_type         qp_type;
>>> +       struct ib_qp_security  *qp_sec;
>> See my earlier question/comment about just using a void pointer here.
> I think that this is in response to my comments to the
> effect that I would like to see the LSM infrastructure
> using the inode like (inode->i_security) to the xfrm
> (void *) approach. I haven't been looking at the IB patches
> too carefully to date. It's possible I have not been clear.
My understanding at the time was that by using something other than a void * different security modules could maintain their own opaque blobs with in and keep the same prototype for the hook.  It's possible I misunderstood you, but it made sense to me.  I don't know of any plans for other security modules to support Infiniband, but this leaves the door open.
>>>  };
>>>
>>>  struct ib_mr {
>>> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
>>> index 6a8841d..4f13ea4 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,
>>> @@ -83,6 +84,8 @@
>>>  #include <linux/export.h>
>>>  #include <linux/msg.h>
>>>  #include <linux/shm.h>
>>> +#include <rdma/ib_verbs.h>
>>> +#include <rdma/ib_mad.h>
>>>
>>>  #include "avc.h"
>>>  #include "objsec.h"
>>> @@ -6015,6 +6018,47 @@ static void selinux_unregister_ib_flush_callback(void)
>>>         mutex_unlock(&ib_flush_mutex);
>>>  }
>>>
>>> +static int selinux_ib_qp_alloc_security(struct ib_qp_security *qp_sec)
>>> +{
>>> +       struct ib_security_struct *sec;
>>> +
>>> +       sec = kzalloc(sizeof(*sec), GFP_ATOMIC);
>>> +       if (!sec)
>>> +               return -ENOMEM;
>>> +       sec->sid = current_sid();
>>> +
>>> +       qp_sec->q_security = sec;
>>> +       return 0;
>>> +}
>> If you get rid of the ip_qp_security struct, you can just return the
>> blob instead of an int (NULL on error).  Same with the MAD allocator
>> below.
>>
>> Also, and this may be more important for the MAD allocator below (I'm
>> still pretty IB-ignorant), can you forsee the need/desire to have the
>> QP/MAD label different from the process which creates them?  How often
>> will other SELinux domains need to interact with these objects?
>>
>>> +static void selinux_ib_qp_free_security(struct ib_qp_security *qp_sec)
>>> +{
>>> +       struct ib_security_struct *sec = qp_sec->q_security;
>>> +
>>> +       qp_sec->q_security = NULL;
>>> +       kfree(sec);
>>> +}
>>> +
>>> +static int selinux_ib_mad_agent_alloc_security(struct ib_mad_agent *mad_agent)
>>> +{
>>> +       struct ib_security_struct *sec;
>>> +
>>> +       sec = kzalloc(sizeof(*sec), GFP_ATOMIC);
>>> +       if (!sec)
>>> +               return -ENOMEM;
>>> +       sec->sid = current_sid();
>>> +
>>> +       mad_agent->m_security = sec;
>>> +       return 0;
>>> +}
>>> +
>>> +static void selinux_ib_mad_agent_free_security(struct ib_mad_agent *mad_agent)
>>> +{
>>> +       struct ib_security_struct *sec = mad_agent->m_security;
>>> +
>>> +       mad_agent->m_security = NULL;
>>> +       kfree(sec);
>>> +}
>>>  #endif
>

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

* Re: [PATCH 02/12] selinux: Create policydb version for Infiniband support
  2016-06-30 15:01       ` Yuval Shaia
@ 2016-07-01 12:50           ` Leon Romanovsky
  -1 siblings, 0 replies; 128+ messages in thread
From: Leon Romanovsky @ 2016-07-01 12:50 UTC (permalink / raw)
  To: Yuval Shaia
  Cc: Dan Jurgens, 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

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

On Thu, Jun 30, 2016 at 06:01:42PM +0300, Yuval Shaia wrote:
> On Thu, Jun 23, 2016 at 10:52:48PM +0300, Dan Jurgens wrote:
> > From: Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
> > +				rc = next_entry(nodebuf, fp, sizeof(u32) * 6);
> > +				if (rc)
> > +					goto out;
> > +
> > +				c->u.pkey.subnet_prefix = be64_to_cpu(*((__be64 *)nodebuf));
> 
> More than 80 characters

Yes, we prefer code readability over checkpatch warning.

> 
> > +				/* 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_END_PORT:
> > +				rc = next_entry(buf, fp, sizeof(u32) * 2);
> > +				if (rc)
> > +					goto out;
> > +				len = le32_to_cpu(buf[0]);
> > +
> > +				rc = str_read(&c->u.ib_end_port.dev_name, GFP_KERNEL,
> 
> More than 80 characters?

I would recommend to place all in one line.

> 
> > +					      fp,
> > +					      len);
> > +				if (rc)
> > +					goto out;
> > +
> > +				c->u.ib_end_port.port = le32_to_cpu(buf[1]);
> > +
> > +				rc = context_read_and_validate(&c->context[0],
> > +							       p,
> > +							       fp);
> > +				if (rc)
> > +					goto out;
> > +				break;
> >  			}
> >  		}
> >  	}
> > @@ -3147,6 +3209,43 @@ static int ocontext_write(struct policydb *p, struct policydb_compat_info *info,
> 
> More than 80 characters

Agree

> 
> >  				if (rc)
> >  					return rc;
> >  				break;
> > +			case OCON_PKEY: {
> 
> Is "{" needed?

No, I agree, need to remove.

> 
> > +				__be64 *sbn_pfx = (__be64 *)nodebuf;
> > +				*sbn_pfx = 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_END_PORT:
> > +				len = strlen(c->u.ib_end_port.dev_name);
> > +				buf[0] = cpu_to_le32(len);
> > +				buf[1] = cpu_to_le32(c->u.ib_end_port.port);
> > +				rc = put_entry(buf, sizeof(u32), 2, fp);
> > +				if (rc)
> > +					return rc;
> > +				rc = put_entry(c->u.ib_end_port.dev_name, 1, len, fp);
> 
> More than 80 characters?

Readability

> 
> > +				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..751bf604 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;
> > +		} ib_end_port;
> >  	} 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_END_PORT 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
> --
> 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

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

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

* Re: [PATCH 02/12] selinux: Create policydb version for Infiniband support
@ 2016-07-01 12:50           ` Leon Romanovsky
  0 siblings, 0 replies; 128+ messages in thread
From: Leon Romanovsky @ 2016-07-01 12:50 UTC (permalink / raw)
  To: Yuval Shaia
  Cc: Dan Jurgens, chrisw, paul, sds, eparis, dledford, sean.hefty,
	hal.rosenstock, selinux, linux-security-module, linux-rdma,
	yevgenyp

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

On Thu, Jun 30, 2016 at 06:01:42PM +0300, Yuval Shaia wrote:
> On Thu, Jun 23, 2016 at 10:52:48PM +0300, Dan Jurgens wrote:
> > From: Daniel Jurgens <danielj@mellanox.com>
> > +				rc = next_entry(nodebuf, fp, sizeof(u32) * 6);
> > +				if (rc)
> > +					goto out;
> > +
> > +				c->u.pkey.subnet_prefix = be64_to_cpu(*((__be64 *)nodebuf));
> 
> More than 80 characters

Yes, we prefer code readability over checkpatch warning.

> 
> > +				/* 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_END_PORT:
> > +				rc = next_entry(buf, fp, sizeof(u32) * 2);
> > +				if (rc)
> > +					goto out;
> > +				len = le32_to_cpu(buf[0]);
> > +
> > +				rc = str_read(&c->u.ib_end_port.dev_name, GFP_KERNEL,
> 
> More than 80 characters?

I would recommend to place all in one line.

> 
> > +					      fp,
> > +					      len);
> > +				if (rc)
> > +					goto out;
> > +
> > +				c->u.ib_end_port.port = le32_to_cpu(buf[1]);
> > +
> > +				rc = context_read_and_validate(&c->context[0],
> > +							       p,
> > +							       fp);
> > +				if (rc)
> > +					goto out;
> > +				break;
> >  			}
> >  		}
> >  	}
> > @@ -3147,6 +3209,43 @@ static int ocontext_write(struct policydb *p, struct policydb_compat_info *info,
> 
> More than 80 characters

Agree

> 
> >  				if (rc)
> >  					return rc;
> >  				break;
> > +			case OCON_PKEY: {
> 
> Is "{" needed?

No, I agree, need to remove.

> 
> > +				__be64 *sbn_pfx = (__be64 *)nodebuf;
> > +				*sbn_pfx = 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_END_PORT:
> > +				len = strlen(c->u.ib_end_port.dev_name);
> > +				buf[0] = cpu_to_le32(len);
> > +				buf[1] = cpu_to_le32(c->u.ib_end_port.port);
> > +				rc = put_entry(buf, sizeof(u32), 2, fp);
> > +				if (rc)
> > +					return rc;
> > +				rc = put_entry(c->u.ib_end_port.dev_name, 1, len, fp);
> 
> More than 80 characters?

Readability

> 
> > +				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..751bf604 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;
> > +		} ib_end_port;
> >  	} 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_END_PORT 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@vger.kernel.org
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> --
> 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: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

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

* Re: [PATCH 02/12] selinux: Create policydb version for Infiniband support
  2016-07-01 12:50           ` Leon Romanovsky
@ 2016-07-01 13:49             ` Daniel Jurgens
  -1 siblings, 0 replies; 128+ messages in thread
From: Daniel Jurgens @ 2016-07-01 13:49 UTC (permalink / raw)
  To: Leon Romanovsky, Yuval Shaia
  Cc: linux-rdma-u79uwXL29TY76Z2rM5mHXA,
	linux-security-module-u79uwXL29TY76Z2rM5mHXA,
	chrisw-69jw2NvuJkxg9hUCZPvPmw, dledford-H+wXaHxf7aLQT0dZR+AlfA,
	selinux-+05T5uksL2qpZYMLLGbcSA,
	sean.hefty-ral2JQCrhuEAvxtiuMwx3w, sds-+05T5uksL2qpZYMLLGbcSA,
	hal.rosenstock-Re5JQEeQqe8AvxtiuMwx3w

On 7/1/2016 7:50 AM, Leon Romanovsky wrote:
> On Thu, Jun 30, 2016 at 06:01:42PM +0300, Yuval Shaia wrote:
>> On Thu, Jun 23, 2016 at 10:52:48PM +0300, Dan Jurgens wrote:
>>
>>>  				if (rc)
>>>  					return rc;
>>>  				break;
>>> +			case OCON_PKEY: {
>> Is "{" needed?
> No, I agree, need to remove.
The { is needed here, unless the variable sbn_pfx is defined at function scope.
>
>>> +				__be64 *sbn_pfx = (__be64 *)nodebuf;
>>> +				*sbn_pfx = cpu_to_be64(c->u.pkey.subnet_prefix);


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

* Re: [PATCH 02/12] selinux: Create policydb version for Infiniband support
@ 2016-07-01 13:49             ` Daniel Jurgens
  0 siblings, 0 replies; 128+ messages in thread
From: Daniel Jurgens @ 2016-07-01 13:49 UTC (permalink / raw)
  To: Leon Romanovsky, Yuval Shaia
  Cc: chrisw, paul, sds, eparis, dledford, sean.hefty, hal.rosenstock,
	selinux, linux-security-module, linux-rdma, Yevgeny Petrilin

On 7/1/2016 7:50 AM, Leon Romanovsky wrote:
> On Thu, Jun 30, 2016 at 06:01:42PM +0300, Yuval Shaia wrote:
>> On Thu, Jun 23, 2016 at 10:52:48PM +0300, Dan Jurgens wrote:
>>
>>>  				if (rc)
>>>  					return rc;
>>>  				break;
>>> +			case OCON_PKEY: {
>> Is "{" needed?
> No, I agree, need to remove.
The { is needed here, unless the variable sbn_pfx is defined at function scope.
>
>>> +				__be64 *sbn_pfx = (__be64 *)nodebuf;
>>> +				*sbn_pfx = cpu_to_be64(c->u.pkey.subnet_prefix);

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

* Re: [PATCH 05/12] selinux: Implement Infiniband PKey "Access" access vector
  2016-06-23 19:52     ` Dan Jurgens
@ 2016-07-01 16:29         ` Paul Moore
  -1 siblings, 0 replies; 128+ messages in thread
From: Paul Moore @ 2016-07-01 16:29 UTC (permalink / raw)
  To: Dan Jurgens
  Cc: 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

On Thu, Jun 23, 2016 at 3:52 PM, Dan Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org> wrote:
> From: Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
>
> Add a type and access vector for PKeys. Implement the qp_pkey_access
> and mad_agent_pkey_access hooks to check that the caller has
> permission to access the PKey on the given subnet prefix.  Add an
> interface to get the PKey SID. Walk the PKey ocontexts to find an entry
> for the given subnet prefix and pkey.
>
> Signed-off-by: Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
> Reviewed-by: Eli Cohen <eli-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
> ---
>  include/linux/lsm_audit.h                        |  7 ++++
>  security/selinux/hooks.c                         | 41 ++++++++++++++++++++++++
>  security/selinux/include/classmap.h              |  2 ++
>  security/selinux/include/initial_sid_to_string.h |  1 +
>  security/selinux/include/security.h              |  2 ++
>  security/selinux/ss/services.c                   | 41 ++++++++++++++++++++++++
>  6 files changed, 94 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 {

Please correct me if I'm wrong, but I don't recall seeing any code in
the patchset which actually logs the extra IB information in the audit
record, did I miss it?

> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index 4f13ea4..5a40b10 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -6018,6 +6018,44 @@ static void selinux_unregister_ib_flush_callback(void)
>         mutex_unlock(&ib_flush_mutex);
>  }
>
> +static int selinux_pkey_access(u64 subnet_prefix, u16 pkey_val, void *security)
> +{
> +       struct common_audit_data ad;
> +       int err;
> +       u32 sid = 0;
> +       struct ib_security_struct *sec = security;
> +       struct lsm_pkey_audit pkey;
> +
> +       err = security_pkey_sid(subnet_prefix, pkey_val, &sid);
> +
> +       if (err)
> +               goto out;

Pet peeve of mine, just do the return here directly, there is no need
to jump to out.

> +       ad.type = LSM_AUDIT_DATA_PKEY;
> +       pkey.subnet_prefix = subnet_prefix;
> +       pkey.pkey = pkey_val;
> +       ad.u.pkey = &pkey;
> +       err = avc_has_perm(sec->sid, sid,
> +                          SECCLASS_INFINIBAND_PKEY,
> +                          INFINIBAND_PKEY__ACCESS, &ad);

Similar, just return avc_has_perm() directly.

> +out:
> +       return err;
> +}
> +
> +static int selinux_ib_qp_pkey_access(u64 subnet_prefix, u16 pkey_val,
> +                                    struct ib_qp_security *qp_sec)
> +{
> +       return selinux_pkey_access(subnet_prefix, pkey_val,
> +                                  qp_sec->q_security);
> +}
> +
> +static int selinux_ib_mad_agent_pkey_access(u64 subnet_prefix, u16 pkey_val,
> +                                           struct ib_mad_agent *mad_agent)
> +{
> +       return selinux_pkey_access(subnet_prefix, pkey_val,
> +                                       mad_agent->m_security);
> +}
> +
>  static int selinux_ib_qp_alloc_security(struct ib_qp_security *qp_sec)
>  {
>         struct ib_security_struct *sec;
> @@ -6248,6 +6286,9 @@ static struct security_hook_list selinux_hooks[] = {
>                       selinux_register_ib_flush_callback),
>         LSM_HOOK_INIT(unregister_ib_flush_callback,
>                       selinux_unregister_ib_flush_callback),
> +       LSM_HOOK_INIT(ib_qp_pkey_access, selinux_ib_qp_pkey_access),
> +       LSM_HOOK_INIT(ib_mad_agent_pkey_access,
> +                     selinux_ib_mad_agent_pkey_access),
>         LSM_HOOK_INIT(ib_qp_alloc_security,
>                       selinux_ib_qp_alloc_security),
>         LSM_HOOK_INIT(ib_qp_free_security,
> diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h
> index 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/initial_sid_to_string.h b/security/selinux/include/initial_sid_to_string.h
> index a59b64e..8f2eefc 100644
> --- a/security/selinux/include/initial_sid_to_string.h
> +++ b/security/selinux/include/initial_sid_to_string.h
> @@ -29,5 +29,6 @@ static const char *initial_sid_to_string[] =
>      "policy",
>      "scmp_packet",
>      "devnull",
> +    "pkey",
>  };
>
> 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..49701a5 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_PKEY;
> +       }
> +
> +out:
> +       read_unlock(&policy_rwlock);
> +       return rc;
> +}

I wondered about this earlier in the patchset when we were discussing
the policy format, and I'm still wondering; perhaps you can help me
understand IB a bit better ...

>From what I gather, the partition key is the IB security boundary, not
the subnet, is that true?  If so, why are we including the subnet with
the partition key value/label?  I understand the low/high pkey range
as a way of simplifying the policy, but I don't quite understand the
point of tying the subnet to the partition key label.  Would you ever
want to have multiple labels for a single partition key, or should it
be a single label for the partition key regardless of the subnet?

-- 
paul moore
security @ redhat
--
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] 128+ messages in thread

* Re: [PATCH 05/12] selinux: Implement Infiniband PKey "Access" access vector
@ 2016-07-01 16:29         ` Paul Moore
  0 siblings, 0 replies; 128+ messages in thread
From: Paul Moore @ 2016-07-01 16:29 UTC (permalink / raw)
  To: Dan Jurgens
  Cc: chrisw, paul, sds, eparis, dledford, sean.hefty, hal.rosenstock,
	selinux, linux-security-module, linux-rdma, yevgenyp

On Thu, Jun 23, 2016 at 3:52 PM, Dan Jurgens <danielj@mellanox.com> wrote:
> From: Daniel Jurgens <danielj@mellanox.com>
>
> Add a type and access vector for PKeys. Implement the qp_pkey_access
> and mad_agent_pkey_access hooks 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>
> Reviewed-by: Eli Cohen <eli@mellanox.com>
> ---
>  include/linux/lsm_audit.h                        |  7 ++++
>  security/selinux/hooks.c                         | 41 ++++++++++++++++++++++++
>  security/selinux/include/classmap.h              |  2 ++
>  security/selinux/include/initial_sid_to_string.h |  1 +
>  security/selinux/include/security.h              |  2 ++
>  security/selinux/ss/services.c                   | 41 ++++++++++++++++++++++++
>  6 files changed, 94 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 {

Please correct me if I'm wrong, but I don't recall seeing any code in
the patchset which actually logs the extra IB information in the audit
record, did I miss it?

> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index 4f13ea4..5a40b10 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -6018,6 +6018,44 @@ static void selinux_unregister_ib_flush_callback(void)
>         mutex_unlock(&ib_flush_mutex);
>  }
>
> +static int selinux_pkey_access(u64 subnet_prefix, u16 pkey_val, void *security)
> +{
> +       struct common_audit_data ad;
> +       int err;
> +       u32 sid = 0;
> +       struct ib_security_struct *sec = security;
> +       struct lsm_pkey_audit pkey;
> +
> +       err = security_pkey_sid(subnet_prefix, pkey_val, &sid);
> +
> +       if (err)
> +               goto out;

Pet peeve of mine, just do the return here directly, there is no need
to jump to out.

> +       ad.type = LSM_AUDIT_DATA_PKEY;
> +       pkey.subnet_prefix = subnet_prefix;
> +       pkey.pkey = pkey_val;
> +       ad.u.pkey = &pkey;
> +       err = avc_has_perm(sec->sid, sid,
> +                          SECCLASS_INFINIBAND_PKEY,
> +                          INFINIBAND_PKEY__ACCESS, &ad);

Similar, just return avc_has_perm() directly.

> +out:
> +       return err;
> +}
> +
> +static int selinux_ib_qp_pkey_access(u64 subnet_prefix, u16 pkey_val,
> +                                    struct ib_qp_security *qp_sec)
> +{
> +       return selinux_pkey_access(subnet_prefix, pkey_val,
> +                                  qp_sec->q_security);
> +}
> +
> +static int selinux_ib_mad_agent_pkey_access(u64 subnet_prefix, u16 pkey_val,
> +                                           struct ib_mad_agent *mad_agent)
> +{
> +       return selinux_pkey_access(subnet_prefix, pkey_val,
> +                                       mad_agent->m_security);
> +}
> +
>  static int selinux_ib_qp_alloc_security(struct ib_qp_security *qp_sec)
>  {
>         struct ib_security_struct *sec;
> @@ -6248,6 +6286,9 @@ static struct security_hook_list selinux_hooks[] = {
>                       selinux_register_ib_flush_callback),
>         LSM_HOOK_INIT(unregister_ib_flush_callback,
>                       selinux_unregister_ib_flush_callback),
> +       LSM_HOOK_INIT(ib_qp_pkey_access, selinux_ib_qp_pkey_access),
> +       LSM_HOOK_INIT(ib_mad_agent_pkey_access,
> +                     selinux_ib_mad_agent_pkey_access),
>         LSM_HOOK_INIT(ib_qp_alloc_security,
>                       selinux_ib_qp_alloc_security),
>         LSM_HOOK_INIT(ib_qp_free_security,
> diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h
> index 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/initial_sid_to_string.h b/security/selinux/include/initial_sid_to_string.h
> index a59b64e..8f2eefc 100644
> --- a/security/selinux/include/initial_sid_to_string.h
> +++ b/security/selinux/include/initial_sid_to_string.h
> @@ -29,5 +29,6 @@ static const char *initial_sid_to_string[] =
>      "policy",
>      "scmp_packet",
>      "devnull",
> +    "pkey",
>  };
>
> 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..49701a5 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_PKEY;
> +       }
> +
> +out:
> +       read_unlock(&policy_rwlock);
> +       return rc;
> +}

I wondered about this earlier in the patchset when we were discussing
the policy format, and I'm still wondering; perhaps you can help me
understand IB a bit better ...

>From what I gather, the partition key is the IB security boundary, not
the subnet, is that true?  If so, why are we including the subnet with
the partition key value/label?  I understand the low/high pkey range
as a way of simplifying the policy, but I don't quite understand the
point of tying the subnet to the partition key label.  Would you ever
want to have multiple labels for a single partition key, or should it
be a single label for the partition key regardless of the subnet?

-- 
paul moore
security @ redhat

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

* Re: [PATCH 05/12] selinux: Implement Infiniband PKey "Access" access vector
  2016-07-01 16:29         ` Paul Moore
@ 2016-07-01 18:21           ` Daniel Jurgens
  -1 siblings, 0 replies; 128+ messages in thread
From: Daniel Jurgens @ 2016-07-01 18:21 UTC (permalink / raw)
  To: Paul Moore
  Cc: 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, Yevgeny Petrilin

On 7/1/2016 11:29 AM, Paul Moore wrote:
> On Thu, Jun 23, 2016 at 3:52 PM, Dan Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org> wrote:
>> From: Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
>>
>> Add a type and access vector for PKeys. Implement the qp_pkey_access
>> and mad_agent_pkey_access hooks to check that the caller has
>> permission to access the PKey on the given subnet prefix.  Add an
>> interface to get the PKey SID. Walk the PKey ocontexts to find an entry
>> for the given subnet prefix and pkey.
>>
>> Signed-off-by: Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
>> Reviewed-by: Eli Cohen <eli-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
>> ---
>>  include/linux/lsm_audit.h                        |  7 ++++
>>  security/selinux/hooks.c                         | 41 ++++++++++++++++++++++++
>>  security/selinux/include/classmap.h              |  2 ++
>>  security/selinux/include/initial_sid_to_string.h |  1 +
>>  security/selinux/include/security.h              |  2 ++
>>  security/selinux/ss/services.c                   | 41 ++++++++++++++++++++++++
>>  6 files changed, 94 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 {
> Please correct me if I'm wrong, but I don't recall seeing any code in
> the patchset which actually logs the extra IB information in the audit
> record, did I miss it?
I didn't make any changes to the audit logging.  The messages look like this.
[245259.895597] audit: type=1400 audit(1467392186.710:631): avc:  denied  { access } for  pid=27519 comm="ib_write_bw" scontext=root:sysadm_r:sysadm_t:s0 tcontext=system_u:object_r:staff_allowed_pkey_t:s0 tclass=infiniband_pkey permissive=1

> I wondered about this earlier in the patchset when we were discussing
> the policy format, and I'm still wondering; perhaps you can help me
> understand IB a bit better ...
>
> From what I gather, the partition key is the IB security boundary, not
> the subnet, is that true?  If so, why are we including the subnet with
> the partition key value/label?  I understand the low/high pkey range
> as a way of simplifying the policy, but I don't quite understand the
> point of tying the subnet to the partition key label.  Would you ever
> want to have multiple labels for a single partition key, or should it
> be a single label for the partition key regardless of the subnet?
>
Each subnet can have a different partition configuration and a node can be on multiple subnets.  By specifying the subnet prefix along with the pkey value the user has flexibility to have different policy for different subnets, instead of a global PKey space that would require coordinating the partition configuration across all subnets.

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

* Re: [PATCH 05/12] selinux: Implement Infiniband PKey "Access" access vector
@ 2016-07-01 18:21           ` Daniel Jurgens
  0 siblings, 0 replies; 128+ messages in thread
From: Daniel Jurgens @ 2016-07-01 18:21 UTC (permalink / raw)
  To: Paul Moore
  Cc: chrisw, paul, sds, eparis, dledford, sean.hefty, hal.rosenstock,
	selinux, linux-security-module, linux-rdma, Yevgeny Petrilin

On 7/1/2016 11:29 AM, Paul Moore wrote:
> On Thu, Jun 23, 2016 at 3:52 PM, Dan Jurgens <danielj@mellanox.com> wrote:
>> From: Daniel Jurgens <danielj@mellanox.com>
>>
>> Add a type and access vector for PKeys. Implement the qp_pkey_access
>> and mad_agent_pkey_access hooks 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>
>> Reviewed-by: Eli Cohen <eli@mellanox.com>
>> ---
>>  include/linux/lsm_audit.h                        |  7 ++++
>>  security/selinux/hooks.c                         | 41 ++++++++++++++++++++++++
>>  security/selinux/include/classmap.h              |  2 ++
>>  security/selinux/include/initial_sid_to_string.h |  1 +
>>  security/selinux/include/security.h              |  2 ++
>>  security/selinux/ss/services.c                   | 41 ++++++++++++++++++++++++
>>  6 files changed, 94 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 {
> Please correct me if I'm wrong, but I don't recall seeing any code in
> the patchset which actually logs the extra IB information in the audit
> record, did I miss it?
I didn't make any changes to the audit logging.  The messages look like this.
[245259.895597] audit: type=1400 audit(1467392186.710:631): avc:  denied  { access } for  pid=27519 comm="ib_write_bw" scontext=root:sysadm_r:sysadm_t:s0 tcontext=system_u:object_r:staff_allowed_pkey_t:s0 tclass=infiniband_pkey permissive=1

> I wondered about this earlier in the patchset when we were discussing
> the policy format, and I'm still wondering; perhaps you can help me
> understand IB a bit better ...
>
> From what I gather, the partition key is the IB security boundary, not
> the subnet, is that true?  If so, why are we including the subnet with
> the partition key value/label?  I understand the low/high pkey range
> as a way of simplifying the policy, but I don't quite understand the
> point of tying the subnet to the partition key label.  Would you ever
> want to have multiple labels for a single partition key, or should it
> be a single label for the partition key regardless of the subnet?
>
Each subnet can have a different partition configuration and a node can be on multiple subnets.  By specifying the subnet prefix along with the pkey value the user has flexibility to have different policy for different subnets, instead of a global PKey space that would require coordinating the partition configuration across all subnets.

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

* Re: [PATCH 06/12] selinux: Add IB End Port SMP access vector
  2016-06-23 19:52     ` Dan Jurgens
@ 2016-07-01 18:48         ` Paul Moore
  -1 siblings, 0 replies; 128+ messages in thread
From: Paul Moore @ 2016-07-01 18:48 UTC (permalink / raw)
  To: Dan Jurgens
  Cc: 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

On Thu, Jun 23, 2016 at 3:52 PM, Dan Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org> wrote:
> From: Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
>
> Add a type for Infiniband end ports and an access vector for subnet
> management packets. Implement the ib_end_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
> end port, which walks the IB_END_PORT ocontexts to find an entry for the
> given name and port.
>
> Signed-off-by: Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
> Reviewed-by: Eli Cohen <eli-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
> ---
>  include/linux/lsm_audit.h                        | 32 +++++++++++-------
>  security/selinux/hooks.c                         | 27 +++++++++++++++
>  security/selinux/include/classmap.h              |  2 ++
>  security/selinux/include/initial_sid_to_string.h |  1 +
>  security/selinux/include/security.h              |  2 ++
>  security/selinux/ss/services.c                   | 43 ++++++++++++++++++++++++
>  6 files changed, 95 insertions(+), 12 deletions(-)
>
> diff --git a/include/linux/lsm_audit.h b/include/linux/lsm_audit.h
> index 8ff7eae..acf6de7 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_end_port_audit {
> +       char    dev_name[IB_DEVICE_NAME_MAX];
> +       u8      port;
> +};
> +
>  /* Auxiliary data to use in generating the audit record. */
>  struct common_audit_data {
>         char type;
> -#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_END_PORT     13

Some more nit picking ... if you convert "END_PORT" in the other macro
to "ENDPORT" as we discussed, please do the same here.


>         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_end_port_audit *ib_end_port;
>         } u;
>         /* this union contains LSM specific data */
>         union {
> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index 5a40b10..fc44542 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -6056,6 +6056,32 @@ static int selinux_ib_mad_agent_pkey_access(u64 subnet_prefix, u16 pkey_val,
>                                         mad_agent->m_security);
>  }
>
> +static int selinux_ib_end_port_smp(const char *dev_name, u8 port,
> +                                  struct ib_mad_agent *mad_agent)
> +{
> +       struct common_audit_data ad;
> +       int err;
> +       u32 sid = 0;
> +       struct ib_security_struct *sec = mad_agent->m_security;
> +       struct lsm_ib_end_port_audit ib_end_port;
> +
> +       err = security_ib_end_port_sid(dev_name, port, &sid);
> +
> +       if (err)
> +               goto out;

Just return, don't jump then return.

> +       ad.type = LSM_AUDIT_DATA_IB_END_PORT;
> +       strncpy(ib_end_port.dev_name, dev_name, sizeof(ib_end_port.dev_name));

Do we need to force a NULL byte string terminator here?

> +       ib_end_port.port = port;
> +       ad.u.ib_end_port = &ib_end_port;
> +       err = avc_has_perm(sec->sid, sid,
> +                          SECCLASS_INFINIBAND_END_PORT,
> +                          INFINIBAND_END_PORT__SMP, &ad);
> +
> +out:
> +       return err;
> +}
> +
>  static int selinux_ib_qp_alloc_security(struct ib_qp_security *qp_sec)
>  {
>         struct ib_security_struct *sec;
> @@ -6289,6 +6315,7 @@ static struct security_hook_list selinux_hooks[] = {
>         LSM_HOOK_INIT(ib_qp_pkey_access, selinux_ib_qp_pkey_access),
>         LSM_HOOK_INIT(ib_mad_agent_pkey_access,
>                       selinux_ib_mad_agent_pkey_access),
> +       LSM_HOOK_INIT(ib_end_port_smp, selinux_ib_end_port_smp),
>         LSM_HOOK_INIT(ib_qp_alloc_security,
>                       selinux_ib_qp_alloc_security),
>         LSM_HOOK_INIT(ib_qp_free_security,
> diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h
> index d42dd4d..21972c8 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_end_port",
> +         { "smp", NULL } },

Is "smp" really the best permission name?  It doesn't seem very
descriptive or verb-like.

Also, "infiniband_endport" and not "infiniband_end_port" please.

>         { NULL }
>    };
> diff --git a/security/selinux/include/initial_sid_to_string.h b/security/selinux/include/initial_sid_to_string.h
> index 8f2eefc..ba47169 100644
> --- a/security/selinux/include/initial_sid_to_string.h
> +++ b/security/selinux/include/initial_sid_to_string.h
> @@ -30,5 +30,6 @@ static const char *initial_sid_to_string[] =
>      "scmp_packet",
>      "devnull",
>      "pkey",
> +    "ib_end_port",

I'm pretty sure you know what I'm going to suggest here ...

>  };
>
> diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
> index 8f1a66e..f5d9d4e 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_end_port_sid(const char *dev_name, u8 port, u32 *out_sid);
> +
>  int security_netif_sid(char *name, u32 *if_sid);
>
>  int security_node_sid(u16 domain, void *addr, u32 addrlen,
> diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
> index 49701a5..9afabee 100644
> --- a/security/selinux/ss/services.c
> +++ b/security/selinux/ss/services.c
> @@ -53,6 +53,7 @@
>  #include <linux/flex_array.h>
>  #include <linux/vmalloc.h>
>  #include <net/netlabel.h>
> +#include <rdma/ib_verbs.h>

Why is this here?

>  #include "flask.h"
>  #include "avc.h"
> @@ -2270,6 +2271,48 @@ out:
>  }
>
>  /**
> + * security_ib_end_port_sid - Obtain the SID for a subnet management interface.
> + * @dev_name: device name
> + * @port: port number
> + * @out_sid: security identifier
> + */
> +int security_ib_end_port_sid(const char *dev_name, u8 port, u32 *out_sid)
> +{
> +       struct ocontext *c;
> +       int rc = 0;
> +
> +       read_lock(&policy_rwlock);
> +
> +       c = policydb.ocontexts[OCON_IB_END_PORT];
> +       while (c) {
> +               if (c->u.ib_end_port.port == port &&
> +                   !strncmp(c->u.ib_end_port.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_IB_END_PORT;
> +       }
> +
> +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
>
> --
> 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

-- 
paul moore
security @ redhat
--
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] 128+ messages in thread

* Re: [PATCH 06/12] selinux: Add IB End Port SMP access vector
@ 2016-07-01 18:48         ` Paul Moore
  0 siblings, 0 replies; 128+ messages in thread
From: Paul Moore @ 2016-07-01 18:48 UTC (permalink / raw)
  To: Dan Jurgens
  Cc: chrisw, paul, sds, eparis, dledford, sean.hefty, hal.rosenstock,
	selinux, linux-security-module, linux-rdma, yevgenyp

On Thu, Jun 23, 2016 at 3:52 PM, Dan Jurgens <danielj@mellanox.com> wrote:
> From: Daniel Jurgens <danielj@mellanox.com>
>
> Add a type for Infiniband end ports and an access vector for subnet
> management packets. Implement the ib_end_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
> end port, which walks the IB_END_PORT ocontexts to find an entry for the
> given name and port.
>
> Signed-off-by: Daniel Jurgens <danielj@mellanox.com>
> Reviewed-by: Eli Cohen <eli@mellanox.com>
> ---
>  include/linux/lsm_audit.h                        | 32 +++++++++++-------
>  security/selinux/hooks.c                         | 27 +++++++++++++++
>  security/selinux/include/classmap.h              |  2 ++
>  security/selinux/include/initial_sid_to_string.h |  1 +
>  security/selinux/include/security.h              |  2 ++
>  security/selinux/ss/services.c                   | 43 ++++++++++++++++++++++++
>  6 files changed, 95 insertions(+), 12 deletions(-)
>
> diff --git a/include/linux/lsm_audit.h b/include/linux/lsm_audit.h
> index 8ff7eae..acf6de7 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_end_port_audit {
> +       char    dev_name[IB_DEVICE_NAME_MAX];
> +       u8      port;
> +};
> +
>  /* Auxiliary data to use in generating the audit record. */
>  struct common_audit_data {
>         char type;
> -#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_END_PORT     13

Some more nit picking ... if you convert "END_PORT" in the other macro
to "ENDPORT" as we discussed, please do the same here.


>         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_end_port_audit *ib_end_port;
>         } u;
>         /* this union contains LSM specific data */
>         union {
> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index 5a40b10..fc44542 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -6056,6 +6056,32 @@ static int selinux_ib_mad_agent_pkey_access(u64 subnet_prefix, u16 pkey_val,
>                                         mad_agent->m_security);
>  }
>
> +static int selinux_ib_end_port_smp(const char *dev_name, u8 port,
> +                                  struct ib_mad_agent *mad_agent)
> +{
> +       struct common_audit_data ad;
> +       int err;
> +       u32 sid = 0;
> +       struct ib_security_struct *sec = mad_agent->m_security;
> +       struct lsm_ib_end_port_audit ib_end_port;
> +
> +       err = security_ib_end_port_sid(dev_name, port, &sid);
> +
> +       if (err)
> +               goto out;

Just return, don't jump then return.

> +       ad.type = LSM_AUDIT_DATA_IB_END_PORT;
> +       strncpy(ib_end_port.dev_name, dev_name, sizeof(ib_end_port.dev_name));

Do we need to force a NULL byte string terminator here?

> +       ib_end_port.port = port;
> +       ad.u.ib_end_port = &ib_end_port;
> +       err = avc_has_perm(sec->sid, sid,
> +                          SECCLASS_INFINIBAND_END_PORT,
> +                          INFINIBAND_END_PORT__SMP, &ad);
> +
> +out:
> +       return err;
> +}
> +
>  static int selinux_ib_qp_alloc_security(struct ib_qp_security *qp_sec)
>  {
>         struct ib_security_struct *sec;
> @@ -6289,6 +6315,7 @@ static struct security_hook_list selinux_hooks[] = {
>         LSM_HOOK_INIT(ib_qp_pkey_access, selinux_ib_qp_pkey_access),
>         LSM_HOOK_INIT(ib_mad_agent_pkey_access,
>                       selinux_ib_mad_agent_pkey_access),
> +       LSM_HOOK_INIT(ib_end_port_smp, selinux_ib_end_port_smp),
>         LSM_HOOK_INIT(ib_qp_alloc_security,
>                       selinux_ib_qp_alloc_security),
>         LSM_HOOK_INIT(ib_qp_free_security,
> diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h
> index d42dd4d..21972c8 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_end_port",
> +         { "smp", NULL } },

Is "smp" really the best permission name?  It doesn't seem very
descriptive or verb-like.

Also, "infiniband_endport" and not "infiniband_end_port" please.

>         { NULL }
>    };
> diff --git a/security/selinux/include/initial_sid_to_string.h b/security/selinux/include/initial_sid_to_string.h
> index 8f2eefc..ba47169 100644
> --- a/security/selinux/include/initial_sid_to_string.h
> +++ b/security/selinux/include/initial_sid_to_string.h
> @@ -30,5 +30,6 @@ static const char *initial_sid_to_string[] =
>      "scmp_packet",
>      "devnull",
>      "pkey",
> +    "ib_end_port",

I'm pretty sure you know what I'm going to suggest here ...

>  };
>
> diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
> index 8f1a66e..f5d9d4e 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_end_port_sid(const char *dev_name, u8 port, u32 *out_sid);
> +
>  int security_netif_sid(char *name, u32 *if_sid);
>
>  int security_node_sid(u16 domain, void *addr, u32 addrlen,
> diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
> index 49701a5..9afabee 100644
> --- a/security/selinux/ss/services.c
> +++ b/security/selinux/ss/services.c
> @@ -53,6 +53,7 @@
>  #include <linux/flex_array.h>
>  #include <linux/vmalloc.h>
>  #include <net/netlabel.h>
> +#include <rdma/ib_verbs.h>

Why is this here?

>  #include "flask.h"
>  #include "avc.h"
> @@ -2270,6 +2271,48 @@ out:
>  }
>
>  /**
> + * security_ib_end_port_sid - Obtain the SID for a subnet management interface.
> + * @dev_name: device name
> + * @port: port number
> + * @out_sid: security identifier
> + */
> +int security_ib_end_port_sid(const char *dev_name, u8 port, u32 *out_sid)
> +{
> +       struct ocontext *c;
> +       int rc = 0;
> +
> +       read_lock(&policy_rwlock);
> +
> +       c = policydb.ocontexts[OCON_IB_END_PORT];
> +       while (c) {
> +               if (c->u.ib_end_port.port == port &&
> +                   !strncmp(c->u.ib_end_port.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_IB_END_PORT;
> +       }
> +
> +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
>
> --
> 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

-- 
paul moore
security @ redhat

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

* Re: [PATCH 07/12] selinux: Add a cache for quicker retreival of PKey SIDs
  2016-06-23 19:52     ` Dan Jurgens
@ 2016-07-01 18:51         ` Paul Moore
  -1 siblings, 0 replies; 128+ messages in thread
From: Paul Moore @ 2016-07-01 18:51 UTC (permalink / raw)
  To: Dan Jurgens
  Cc: 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

On Thu, Jun 23, 2016 at 3:52 PM, Dan Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org> wrote:
> 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>
> Reviewed-by: Eli Cohen <eli-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
> ---
>  security/selinux/Makefile         |   2 +-
>  security/selinux/hooks.c          |   5 +-
>  security/selinux/include/objsec.h |   6 +
>  security/selinux/include/pkey.h   |  31 +++++
>  security/selinux/pkey.c           | 243 ++++++++++++++++++++++++++++++++++++++
>  5 files changed, 285 insertions(+), 2 deletions(-)
>  create mode 100644 security/selinux/include/pkey.h
>  create mode 100644 security/selinux/pkey.c
>
> diff --git a/security/selinux/Makefile b/security/selinux/Makefile
> index 3411c33..a698df4 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 pkey.o exports.o \

I wonder if we should call this ibpkey.{c,o} instead of pkey.{c,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 fc44542..5c8cebb 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -92,6 +92,7 @@
>  #include "netif.h"
>  #include "netnode.h"
>  #include "netport.h"
> +#include "pkey.h"
>  #include "xfrm.h"
>  #include "netlabel.h"
>  #include "audit.h"
> @@ -172,6 +173,8 @@ static int selinux_cache_avc_callback(u32 event)
>                 sel_netnode_flush();
>                 sel_netport_flush();
>                 synchronize_net();
> +
> +               sel_pkey_flush();
>                 mutex_lock(&ib_flush_mutex);
>                 if (ib_flush_callback)
>                         ib_flush_callback();
> @@ -6026,7 +6029,7 @@ static int selinux_pkey_access(u64 subnet_prefix, u16 pkey_val, void *security)
>         struct ib_security_struct *sec = security;
>         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)
>                 goto out;
> 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 */
> +};

See my earlier questions about partition keys and subnets.

-- 
paul moore
security @ redhat
--
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] 128+ messages in thread

* Re: [PATCH 07/12] selinux: Add a cache for quicker retreival of PKey SIDs
@ 2016-07-01 18:51         ` Paul Moore
  0 siblings, 0 replies; 128+ messages in thread
From: Paul Moore @ 2016-07-01 18:51 UTC (permalink / raw)
  To: Dan Jurgens
  Cc: chrisw, paul, sds, eparis, dledford, sean.hefty, hal.rosenstock,
	selinux, linux-security-module, linux-rdma, yevgenyp

On Thu, Jun 23, 2016 at 3:52 PM, Dan Jurgens <danielj@mellanox.com> wrote:
> 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>
> Reviewed-by: Eli Cohen <eli@mellanox.com>
> ---
>  security/selinux/Makefile         |   2 +-
>  security/selinux/hooks.c          |   5 +-
>  security/selinux/include/objsec.h |   6 +
>  security/selinux/include/pkey.h   |  31 +++++
>  security/selinux/pkey.c           | 243 ++++++++++++++++++++++++++++++++++++++
>  5 files changed, 285 insertions(+), 2 deletions(-)
>  create mode 100644 security/selinux/include/pkey.h
>  create mode 100644 security/selinux/pkey.c
>
> diff --git a/security/selinux/Makefile b/security/selinux/Makefile
> index 3411c33..a698df4 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 pkey.o exports.o \

I wonder if we should call this ibpkey.{c,o} instead of pkey.{c,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 fc44542..5c8cebb 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -92,6 +92,7 @@
>  #include "netif.h"
>  #include "netnode.h"
>  #include "netport.h"
> +#include "pkey.h"
>  #include "xfrm.h"
>  #include "netlabel.h"
>  #include "audit.h"
> @@ -172,6 +173,8 @@ static int selinux_cache_avc_callback(u32 event)
>                 sel_netnode_flush();
>                 sel_netport_flush();
>                 synchronize_net();
> +
> +               sel_pkey_flush();
>                 mutex_lock(&ib_flush_mutex);
>                 if (ib_flush_callback)
>                         ib_flush_callback();
> @@ -6026,7 +6029,7 @@ static int selinux_pkey_access(u64 subnet_prefix, u16 pkey_val, void *security)
>         struct ib_security_struct *sec = security;
>         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)
>                 goto out;
> 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 */
> +};

See my earlier questions about partition keys and subnets.

-- 
paul moore
security @ redhat

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

* Re: [PATCH 04/12] selinux: Allocate and free infiniband security hooks
  2016-06-30 21:48               ` Daniel Jurgens
@ 2016-07-01 18:54                   ` Paul Moore
  -1 siblings, 0 replies; 128+ messages in thread
From: Paul Moore @ 2016-07-01 18:54 UTC (permalink / raw)
  To: Daniel Jurgens
  Cc: Casey Schaufler, 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, Yevgeny Petrilin

On Thu, Jun 30, 2016 at 5:48 PM, Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org> wrote:
> On 6/30/2016 4:06 PM, Casey Schaufler wrote:
>> On 6/30/2016 1:42 PM, Paul Moore wrote:

>>>>  };
>>>>
>>>>  /**
>>>> diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
>>>> index 3f6780b..e522acb 100644
>>>> --- a/include/rdma/ib_verbs.h
>>>> +++ b/include/rdma/ib_verbs.h
>>>> @@ -1454,6 +1454,7 @@ struct ib_qp {
>>>>         void                   *qp_context;
>>>>         u32                     qp_num;
>>>>         enum ib_qp_type         qp_type;
>>>> +       struct ib_qp_security  *qp_sec;
>>> See my earlier question/comment about just using a void pointer here.
>>
>> I think that this is in response to my comments to the
>> effect that I would like to see the LSM infrastructure
>> using the inode like (inode->i_security) to the xfrm
>> (void *) approach. I haven't been looking at the IB patches
>> too carefully to date. It's possible I have not been clear.
>
> My understanding at the time was that by using something other than a void * different security modules could maintain their own opaque blobs with in and keep the same prototype for the hook.  It's possible I misunderstood you, but it made sense to me.  I don't know of any plans for other security modules to support Infiniband, but this leaves the door open.

All of what you describe above can still happen with a void pointer;
in some ways it is even easier with a void pointer.

-- 
paul moore
security @ redhat
--
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] 128+ messages in thread

* Re: [PATCH 04/12] selinux: Allocate and free infiniband security hooks
@ 2016-07-01 18:54                   ` Paul Moore
  0 siblings, 0 replies; 128+ messages in thread
From: Paul Moore @ 2016-07-01 18:54 UTC (permalink / raw)
  To: Daniel Jurgens
  Cc: Casey Schaufler, chrisw, paul, sds, eparis, dledford, sean.hefty,
	hal.rosenstock, selinux, linux-security-module, linux-rdma,
	Yevgeny Petrilin

On Thu, Jun 30, 2016 at 5:48 PM, Daniel Jurgens <danielj@mellanox.com> wrote:
> On 6/30/2016 4:06 PM, Casey Schaufler wrote:
>> On 6/30/2016 1:42 PM, Paul Moore wrote:

>>>>  };
>>>>
>>>>  /**
>>>> diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
>>>> index 3f6780b..e522acb 100644
>>>> --- a/include/rdma/ib_verbs.h
>>>> +++ b/include/rdma/ib_verbs.h
>>>> @@ -1454,6 +1454,7 @@ struct ib_qp {
>>>>         void                   *qp_context;
>>>>         u32                     qp_num;
>>>>         enum ib_qp_type         qp_type;
>>>> +       struct ib_qp_security  *qp_sec;
>>> See my earlier question/comment about just using a void pointer here.
>>
>> I think that this is in response to my comments to the
>> effect that I would like to see the LSM infrastructure
>> using the inode like (inode->i_security) to the xfrm
>> (void *) approach. I haven't been looking at the IB patches
>> too carefully to date. It's possible I have not been clear.
>
> My understanding at the time was that by using something other than a void * different security modules could maintain their own opaque blobs with in and keep the same prototype for the hook.  It's possible I misunderstood you, but it made sense to me.  I don't know of any plans for other security modules to support Infiniband, but this leaves the door open.

All of what you describe above can still happen with a void pointer;
in some ways it is even easier with a void pointer.

-- 
paul moore
security @ redhat

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

* Re: [PATCH 05/12] selinux: Implement Infiniband PKey "Access" access vector
  2016-07-01 18:21           ` Daniel Jurgens
  (?)
@ 2016-07-01 18:58           ` Paul Moore
  2016-07-01 19:16               ` Daniel Jurgens
  -1 siblings, 1 reply; 128+ messages in thread
From: Paul Moore @ 2016-07-01 18:58 UTC (permalink / raw)
  To: Daniel Jurgens
  Cc: chrisw, paul, sds, eparis, dledford, sean.hefty, hal.rosenstock,
	selinux, linux-security-module, linux-rdma, Yevgeny Petrilin

On Fri, Jul 1, 2016 at 2:21 PM, Daniel Jurgens <danielj@mellanox.com> wrote:
> On 7/1/2016 11:29 AM, Paul Moore wrote:
>> On Thu, Jun 23, 2016 at 3:52 PM, Dan Jurgens <danielj@mellanox.com> wrote:
>>> From: Daniel Jurgens <danielj@mellanox.com>
>>>
>>> Add a type and access vector for PKeys. Implement the qp_pkey_access
>>> and mad_agent_pkey_access hooks 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>
>>> Reviewed-by: Eli Cohen <eli@mellanox.com>
>>> ---
>>>  include/linux/lsm_audit.h                        |  7 ++++
>>>  security/selinux/hooks.c                         | 41 ++++++++++++++++++++++++
>>>  security/selinux/include/classmap.h              |  2 ++
>>>  security/selinux/include/initial_sid_to_string.h |  1 +
>>>  security/selinux/include/security.h              |  2 ++
>>>  security/selinux/ss/services.c                   | 41 ++++++++++++++++++++++++
>>>  6 files changed, 94 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 {
>> Please correct me if I'm wrong, but I don't recall seeing any code in
>> the patchset which actually logs the extra IB information in the audit
>> record, did I miss it?
>
> I didn't make any changes to the audit logging.  The messages look like this.
> [245259.895597] audit: type=1400 audit(1467392186.710:631): avc:  denied  { access } for  pid=27519 comm="ib_write_bw" scontext=root:sysadm_r:sysadm_t:s0 tcontext=system_u:object_r:staff_allowed_pkey_t:s0 tclass=infiniband_pkey permissive=1

So why are you adding fields to the common_audit_data structure?  If
you don't think the IB specific data is worth recording in the audit
log, don't record it in the structure.  If you do believe it is
important to record these IB details, please write the necessary code.

>> I wondered about this earlier in the patchset when we were discussing
>> the policy format, and I'm still wondering; perhaps you can help me
>> understand IB a bit better ...
>>
>> From what I gather, the partition key is the IB security boundary, not
>> the subnet, is that true?  If so, why are we including the subnet with
>> the partition key value/label?  I understand the low/high pkey range
>> as a way of simplifying the policy, but I don't quite understand the
>> point of tying the subnet to the partition key label.  Would you ever
>> want to have multiple labels for a single partition key, or should it
>> be a single label for the partition key regardless of the subnet?
>>
> Each subnet can have a different partition configuration and a node can be on multiple subnets.  By specifying the subnet prefix along with the pkey value the user has flexibility to have different policy for different subnets, instead of a global PKey space that would require coordinating the partition configuration across all subnets.

Perhaps a better explanation of partitions and subnets are in order,
especially for those of like me who are new to IB.

-- 
paul moore
security @ redhat

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

* Re: [PATCH 04/12] selinux: Allocate and free infiniband security hooks
  2016-07-01 18:54                   ` Paul Moore
@ 2016-07-01 18:59                     ` Daniel Jurgens
  -1 siblings, 0 replies; 128+ messages in thread
From: Daniel Jurgens @ 2016-07-01 18:59 UTC (permalink / raw)
  To: Paul Moore
  Cc: Casey Schaufler, 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, Yevgeny Petrilin

On 7/1/2016 1:54 PM, Paul Moore wrote:
> On Thu, Jun 30, 2016 at 5:48 PM, Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org> wrote:
>> On 6/30/2016 4:06 PM, Casey Schaufler wrote:
>>> On 6/30/2016 1:42 PM, Paul Moore wrote:
>>>>>  };
>>>>>
>>>>>  /**
>>>>> diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
>>>>> index 3f6780b..e522acb 100644
>>>>> --- a/include/rdma/ib_verbs.h
>>>>> +++ b/include/rdma/ib_verbs.h
>>>>> @@ -1454,6 +1454,7 @@ struct ib_qp {
>>>>>         void                   *qp_context;
>>>>>         u32                     qp_num;
>>>>>         enum ib_qp_type         qp_type;
>>>>> +       struct ib_qp_security  *qp_sec;
>>>> See my earlier question/comment about just using a void pointer here.
>>> I think that this is in response to my comments to the
>>> effect that I would like to see the LSM infrastructure
>>> using the inode like (inode->i_security) to the xfrm
>>> (void *) approach. I haven't been looking at the IB patches
>>> too carefully to date. It's possible I have not been clear.
>> My understanding at the time was that by using something other than a void * different security modules could maintain their own opaque blobs with in and keep the same prototype for the hook.  It's possible I misunderstood you, but it made sense to me.  I don't know of any plans for other security modules to support Infiniband, but this leaves the door open.
> All of what you describe above can still happen with a void pointer;
> in some ways it is even easier with a void pointer.

If multiple security modules register an alloc_security hook for example, how would you coordinate between them to allocate the memory?
--
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] 128+ messages in thread

* Re: [PATCH 04/12] selinux: Allocate and free infiniband security hooks
@ 2016-07-01 18:59                     ` Daniel Jurgens
  0 siblings, 0 replies; 128+ messages in thread
From: Daniel Jurgens @ 2016-07-01 18:59 UTC (permalink / raw)
  To: Paul Moore
  Cc: Casey Schaufler, chrisw, paul, sds, eparis, dledford, sean.hefty,
	hal.rosenstock, selinux, linux-security-module, linux-rdma,
	Yevgeny Petrilin

On 7/1/2016 1:54 PM, Paul Moore wrote:
> On Thu, Jun 30, 2016 at 5:48 PM, Daniel Jurgens <danielj@mellanox.com> wrote:
>> On 6/30/2016 4:06 PM, Casey Schaufler wrote:
>>> On 6/30/2016 1:42 PM, Paul Moore wrote:
>>>>>  };
>>>>>
>>>>>  /**
>>>>> diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
>>>>> index 3f6780b..e522acb 100644
>>>>> --- a/include/rdma/ib_verbs.h
>>>>> +++ b/include/rdma/ib_verbs.h
>>>>> @@ -1454,6 +1454,7 @@ struct ib_qp {
>>>>>         void                   *qp_context;
>>>>>         u32                     qp_num;
>>>>>         enum ib_qp_type         qp_type;
>>>>> +       struct ib_qp_security  *qp_sec;
>>>> See my earlier question/comment about just using a void pointer here.
>>> I think that this is in response to my comments to the
>>> effect that I would like to see the LSM infrastructure
>>> using the inode like (inode->i_security) to the xfrm
>>> (void *) approach. I haven't been looking at the IB patches
>>> too carefully to date. It's possible I have not been clear.
>> My understanding at the time was that by using something other than a void * different security modules could maintain their own opaque blobs with in and keep the same prototype for the hook.  It's possible I misunderstood you, but it made sense to me.  I don't know of any plans for other security modules to support Infiniband, but this leaves the door open.
> All of what you describe above can still happen with a void pointer;
> in some ways it is even easier with a void pointer.

If multiple security modules register an alloc_security hook for example, how would you coordinate between them to allocate the memory?

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

* Re: [PATCH 05/12] selinux: Implement Infiniband PKey "Access" access vector
  2016-07-01 18:58           ` Paul Moore
@ 2016-07-01 19:16               ` Daniel Jurgens
  0 siblings, 0 replies; 128+ messages in thread
From: Daniel Jurgens @ 2016-07-01 19:16 UTC (permalink / raw)
  To: Paul Moore
  Cc: 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, Yevgeny Petrilin

On 7/1/2016 1:59 PM, Paul Moore wrote:
> On Fri, Jul 1, 2016 at 2:21 PM, Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org> wrote:
>> On 7/1/2016 11:29 AM, Paul Moore wrote:
>>> I wondered about this earlier in the patchset when we were discussing
>>> the policy format, and I'm still wondering; perhaps you can help me
>>> understand IB a bit better ...
>>>
>>> From what I gather, the partition key is the IB security boundary, not
>>> the subnet, is that true?  If so, why are we including the subnet with
>>> the partition key value/label?  I understand the low/high pkey range
>>> as a way of simplifying the policy, but I don't quite understand the
>>> point of tying the subnet to the partition key label.  Would you ever
>>> want to have multiple labels for a single partition key, or should it
>>> be a single label for the partition key regardless of the subnet?
>>>
>> Each subnet can have a different partition configuration and a node can be on multiple subnets.  By specifying the subnet prefix along with the pkey value the user has flexibility to have different policy for different subnets, instead of a global PKey space that would require coordinating the partition configuration across all subnets.
> Perhaps a better explanation of partitions and subnets are in order,
> especially for those of like me who are new to IB.
>

A subnet is a set of ports managed by a common subnet manager, which sets up the partition configuration.  A partition is a virtual fabric, similar to an VLAN.  If there are multiple IB ports each could be connected to a different subnet.  By including the subnet prefix in the label the subnets can use the same PKey values and policy can restrict access appropriately.  Without that mechanism if one of the subnets had a partition with PKey 1 the other partition couldn't reuse that PKey if a different security policy is desired for that subnet.

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

* Re: [PATCH 05/12] selinux: Implement Infiniband PKey "Access" access vector
@ 2016-07-01 19:16               ` Daniel Jurgens
  0 siblings, 0 replies; 128+ messages in thread
From: Daniel Jurgens @ 2016-07-01 19:16 UTC (permalink / raw)
  To: Paul Moore
  Cc: chrisw, paul, sds, eparis, dledford, sean.hefty, hal.rosenstock,
	selinux, linux-security-module, linux-rdma, Yevgeny Petrilin

On 7/1/2016 1:59 PM, Paul Moore wrote:
> On Fri, Jul 1, 2016 at 2:21 PM, Daniel Jurgens <danielj@mellanox.com> wrote:
>> On 7/1/2016 11:29 AM, Paul Moore wrote:
>>> I wondered about this earlier in the patchset when we were discussing
>>> the policy format, and I'm still wondering; perhaps you can help me
>>> understand IB a bit better ...
>>>
>>> From what I gather, the partition key is the IB security boundary, not
>>> the subnet, is that true?  If so, why are we including the subnet with
>>> the partition key value/label?  I understand the low/high pkey range
>>> as a way of simplifying the policy, but I don't quite understand the
>>> point of tying the subnet to the partition key label.  Would you ever
>>> want to have multiple labels for a single partition key, or should it
>>> be a single label for the partition key regardless of the subnet?
>>>
>> Each subnet can have a different partition configuration and a node can be on multiple subnets.  By specifying the subnet prefix along with the pkey value the user has flexibility to have different policy for different subnets, instead of a global PKey space that would require coordinating the partition configuration across all subnets.
> Perhaps a better explanation of partitions and subnets are in order,
> especially for those of like me who are new to IB.
>

A subnet is a set of ports managed by a common subnet manager, which sets up the partition configuration.  A partition is a virtual fabric, similar to an VLAN.  If there are multiple IB ports each could be connected to a different subnet.  By including the subnet prefix in the label the subnets can use the same PKey values and policy can restrict access appropriately.  Without that mechanism if one of the subnets had a partition with PKey 1 the other partition couldn't reuse that PKey if a different security policy is desired for that subnet.

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

* Re: [PATCH 04/12] selinux: Allocate and free infiniband security hooks
  2016-07-01 18:59                     ` Daniel Jurgens
  (?)
@ 2016-07-01 19:17                     ` Paul Moore
  2016-07-01 20:13                       ` Casey Schaufler
  -1 siblings, 1 reply; 128+ messages in thread
From: Paul Moore @ 2016-07-01 19:17 UTC (permalink / raw)
  To: Daniel Jurgens
  Cc: Casey Schaufler, chrisw, paul, sds, eparis, dledford, sean.hefty,
	hal.rosenstock, selinux, linux-security-module, linux-rdma,
	Yevgeny Petrilin

On Fri, Jul 1, 2016 at 2:59 PM, Daniel Jurgens <danielj@mellanox.com> wrote:
> On 7/1/2016 1:54 PM, Paul Moore wrote:
>> On Thu, Jun 30, 2016 at 5:48 PM, Daniel Jurgens <danielj@mellanox.com> wrote:
>>> On 6/30/2016 4:06 PM, Casey Schaufler wrote:
>>>> On 6/30/2016 1:42 PM, Paul Moore wrote:
>>>>>>  };
>>>>>>
>>>>>>  /**
>>>>>> diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
>>>>>> index 3f6780b..e522acb 100644
>>>>>> --- a/include/rdma/ib_verbs.h
>>>>>> +++ b/include/rdma/ib_verbs.h
>>>>>> @@ -1454,6 +1454,7 @@ struct ib_qp {
>>>>>>         void                   *qp_context;
>>>>>>         u32                     qp_num;
>>>>>>         enum ib_qp_type         qp_type;
>>>>>> +       struct ib_qp_security  *qp_sec;
>>>>> See my earlier question/comment about just using a void pointer here.
>>>> I think that this is in response to my comments to the
>>>> effect that I would like to see the LSM infrastructure
>>>> using the inode like (inode->i_security) to the xfrm
>>>> (void *) approach. I haven't been looking at the IB patches
>>>> too carefully to date. It's possible I have not been clear.
>>> My understanding at the time was that by using something other than a void * different security modules could maintain their own opaque blobs with in and keep the same prototype for the hook.  It's possible I misunderstood you, but it made sense to me.  I don't know of any plans for other security modules to support Infiniband, but this leaves the door open.
>> All of what you describe above can still happen with a void pointer;
>> in some ways it is even easier with a void pointer.
>
> If multiple security modules register an alloc_security hook for example, how would you coordinate between them to allocate the memory?

You worry about that in the LSM framework and hide the details behind
the void pointer.  For example, you create an array/list of LSM
specific blobs and just stash a pointer to the head of the data in the
void pointer.

-- 
paul moore
security @ redhat

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

* Re: [PATCH 05/12] selinux: Implement Infiniband PKey "Access" access vector
  2016-07-01 19:16               ` Daniel Jurgens
@ 2016-07-01 19:26                   ` Paul Moore
  -1 siblings, 0 replies; 128+ messages in thread
From: Paul Moore @ 2016-07-01 19:26 UTC (permalink / raw)
  To: Daniel Jurgens
  Cc: 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, Yevgeny Petrilin

On Fri, Jul 1, 2016 at 3:16 PM, Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org> wrote:
> On 7/1/2016 1:59 PM, Paul Moore wrote:
>> On Fri, Jul 1, 2016 at 2:21 PM, Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org> wrote:
>>> On 7/1/2016 11:29 AM, Paul Moore wrote:
>>>> I wondered about this earlier in the patchset when we were discussing
>>>> the policy format, and I'm still wondering; perhaps you can help me
>>>> understand IB a bit better ...
>>>>
>>>> From what I gather, the partition key is the IB security boundary, not
>>>> the subnet, is that true?  If so, why are we including the subnet with
>>>> the partition key value/label?  I understand the low/high pkey range
>>>> as a way of simplifying the policy, but I don't quite understand the
>>>> point of tying the subnet to the partition key label.  Would you ever
>>>> want to have multiple labels for a single partition key, or should it
>>>> be a single label for the partition key regardless of the subnet?
>>>>
>>> Each subnet can have a different partition configuration and a node can be on multiple subnets.  By specifying the subnet prefix along with the pkey value the user has flexibility to have different policy for different subnets, instead of a global PKey space that would require coordinating the partition configuration across all subnets.
>> Perhaps a better explanation of partitions and subnets are in order,
>> especially for those of like me who are new to IB.
>>
>
> A subnet is a set of ports managed by a common subnet manager, which sets up the partition configuration.

So there can be multiple partitions inside a subnet and not multiple
subnets inside a partition?

> A partition is a virtual fabric, similar to an VLAN.

Yeah, I've read that in multiple places and I think that is what I
find confusing as it doesn't seem to mesh with my understanding of
what you are intending.

> If there are multiple IB ports each could be connected to a different subnet.

Ports are just end points, I get that.  That's important, but it isn't
helping me understand the relationship between subnets and partitions,
that is where I'm struggling at the moment.

> By including the subnet prefix in the label the subnets can use the same PKey values and policy can restrict access appropriately.

This doesn't make any sense to me right now.

> Without that mechanism if one of the subnets had a partition with PKey 1 the other partition couldn't reuse that PKey if a different security policy is desired for that subnet.

<blank stare>

-- 
paul moore
security @ redhat
--
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] 128+ messages in thread

* Re: [PATCH 05/12] selinux: Implement Infiniband PKey "Access" access vector
@ 2016-07-01 19:26                   ` Paul Moore
  0 siblings, 0 replies; 128+ messages in thread
From: Paul Moore @ 2016-07-01 19:26 UTC (permalink / raw)
  To: Daniel Jurgens
  Cc: chrisw, paul, sds, eparis, dledford, sean.hefty, hal.rosenstock,
	selinux, linux-security-module, linux-rdma, Yevgeny Petrilin

On Fri, Jul 1, 2016 at 3:16 PM, Daniel Jurgens <danielj@mellanox.com> wrote:
> On 7/1/2016 1:59 PM, Paul Moore wrote:
>> On Fri, Jul 1, 2016 at 2:21 PM, Daniel Jurgens <danielj@mellanox.com> wrote:
>>> On 7/1/2016 11:29 AM, Paul Moore wrote:
>>>> I wondered about this earlier in the patchset when we were discussing
>>>> the policy format, and I'm still wondering; perhaps you can help me
>>>> understand IB a bit better ...
>>>>
>>>> From what I gather, the partition key is the IB security boundary, not
>>>> the subnet, is that true?  If so, why are we including the subnet with
>>>> the partition key value/label?  I understand the low/high pkey range
>>>> as a way of simplifying the policy, but I don't quite understand the
>>>> point of tying the subnet to the partition key label.  Would you ever
>>>> want to have multiple labels for a single partition key, or should it
>>>> be a single label for the partition key regardless of the subnet?
>>>>
>>> Each subnet can have a different partition configuration and a node can be on multiple subnets.  By specifying the subnet prefix along with the pkey value the user has flexibility to have different policy for different subnets, instead of a global PKey space that would require coordinating the partition configuration across all subnets.
>> Perhaps a better explanation of partitions and subnets are in order,
>> especially for those of like me who are new to IB.
>>
>
> A subnet is a set of ports managed by a common subnet manager, which sets up the partition configuration.

So there can be multiple partitions inside a subnet and not multiple
subnets inside a partition?

> A partition is a virtual fabric, similar to an VLAN.

Yeah, I've read that in multiple places and I think that is what I
find confusing as it doesn't seem to mesh with my understanding of
what you are intending.

> If there are multiple IB ports each could be connected to a different subnet.

Ports are just end points, I get that.  That's important, but it isn't
helping me understand the relationship between subnets and partitions,
that is where I'm struggling at the moment.

> By including the subnet prefix in the label the subnets can use the same PKey values and policy can restrict access appropriately.

This doesn't make any sense to me right now.

> Without that mechanism if one of the subnets had a partition with PKey 1 the other partition couldn't reuse that PKey if a different security policy is desired for that subnet.

<blank stare>

-- 
paul moore
security @ redhat

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

* Re: [PATCH 05/12] selinux: Implement Infiniband PKey "Access" access vector
  2016-07-01 19:26                   ` Paul Moore
@ 2016-07-01 19:57                     ` Daniel Jurgens
  -1 siblings, 0 replies; 128+ messages in thread
From: Daniel Jurgens @ 2016-07-01 19:57 UTC (permalink / raw)
  To: Paul Moore
  Cc: 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, Yevgeny Petrilin

On 7/1/2016 2:26 PM, Paul Moore wrote:
> On Fri, Jul 1, 2016 at 3:16 PM, Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org> wrote:
>> On 7/1/2016 1:59 PM, Paul Moore wrote:
>>> On Fri, Jul 1, 2016 at 2:21 PM, Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org> wrote:
>>>> On 7/1/2016 11:29 AM, Paul Moore wrote:
>>>>> I wondered about this earlier in the patchset when we were discussing
>>>>> the policy format, and I'm still wondering; perhaps you can help me
>>>>> understand IB a bit better ...
>>>>>
>>>>> From what I gather, the partition key is the IB security boundary, not
>>>>> the subnet, is that true?  If so, why are we including the subnet with
>>>>> the partition key value/label?  I understand the low/high pkey range
>>>>> as a way of simplifying the policy, but I don't quite understand the
>>>>> point of tying the subnet to the partition key label.  Would you ever
>>>>> want to have multiple labels for a single partition key, or should it
>>>>> be a single label for the partition key regardless of the subnet?
>>>>>
>>>> Each subnet can have a different partition configuration and a node can be on multiple subnets.  By specifying the subnet prefix along with the pkey value the user has flexibility to have different policy for different subnets, instead of a global PKey space that would require coordinating the partition configuration across all subnets.
>>> Perhaps a better explanation of partitions and subnets are in order,
>>> especially for those of like me who are new to IB.
>>>
>> A subnet is a set of ports managed by a common subnet manager, which sets up the partition configuration.
> So there can be multiple partitions inside a subnet and not multiple
> subnets inside a partition?

Yes, a each subnet can have many partitions.  The partitions are contained within that subnet, a different subnet can have a partition that uses same PKey value, but that's a different partition.  So if we have 2 subnets, fe80:: and fe81:: they can each have a partition that uses PKey X but it doesn't mean nodes with access to that partition on 0xfe80 can reach nodes on 0xfe81 on that partition.

>
>> A partition is a virtual fabric, similar to an VLAN.
> Yeah, I've read that in multiple places and I think that is what I
> find confusing as it doesn't seem to mesh with my understanding of
> what you are intending.
>
>> If there are multiple IB ports each could be connected to a different subnet.
> Ports are just end points, I get that.  That's important, but it isn't
> helping me understand the relationship between subnets and partitions,
> that is where I'm struggling at the moment.

Subnets have one or more partitions.  Partitions belong to one subnet.

>> By including the subnet prefix in the label the subnets can use the same PKey values and policy can restrict access appropriately.
> This doesn't make any sense to me right now.
>
>> Without that mechanism if one of the subnets had a partition with PKey 1 the other partition couldn't reuse that PKey if a different security policy is desired for that subnet.
> <blank stare>
Going back to the example above assume fe80:: has a partition using PKey 0x8001 and we grant a user access.  Without the subnet prefix in the label we are granting that user the ability to use pkey 0x8001 on any partition available.  So subnet fe81:: can't use PKey 0x8001 if it doesn't want to grant that same user access.  By labeling with the subnet prefix we can grant access to PKey 0x8001 on subnet fe80:: only, leaving the subnet manager on fe81:: the ability to use that same PKey but not grant access to said user.
--
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] 128+ messages in thread

* Re: [PATCH 05/12] selinux: Implement Infiniband PKey "Access" access vector
@ 2016-07-01 19:57                     ` Daniel Jurgens
  0 siblings, 0 replies; 128+ messages in thread
From: Daniel Jurgens @ 2016-07-01 19:57 UTC (permalink / raw)
  To: Paul Moore
  Cc: chrisw, paul, sds, eparis, dledford, sean.hefty, hal.rosenstock,
	selinux, linux-security-module, linux-rdma, Yevgeny Petrilin

On 7/1/2016 2:26 PM, Paul Moore wrote:
> On Fri, Jul 1, 2016 at 3:16 PM, Daniel Jurgens <danielj@mellanox.com> wrote:
>> On 7/1/2016 1:59 PM, Paul Moore wrote:
>>> On Fri, Jul 1, 2016 at 2:21 PM, Daniel Jurgens <danielj@mellanox.com> wrote:
>>>> On 7/1/2016 11:29 AM, Paul Moore wrote:
>>>>> I wondered about this earlier in the patchset when we were discussing
>>>>> the policy format, and I'm still wondering; perhaps you can help me
>>>>> understand IB a bit better ...
>>>>>
>>>>> From what I gather, the partition key is the IB security boundary, not
>>>>> the subnet, is that true?  If so, why are we including the subnet with
>>>>> the partition key value/label?  I understand the low/high pkey range
>>>>> as a way of simplifying the policy, but I don't quite understand the
>>>>> point of tying the subnet to the partition key label.  Would you ever
>>>>> want to have multiple labels for a single partition key, or should it
>>>>> be a single label for the partition key regardless of the subnet?
>>>>>
>>>> Each subnet can have a different partition configuration and a node can be on multiple subnets.  By specifying the subnet prefix along with the pkey value the user has flexibility to have different policy for different subnets, instead of a global PKey space that would require coordinating the partition configuration across all subnets.
>>> Perhaps a better explanation of partitions and subnets are in order,
>>> especially for those of like me who are new to IB.
>>>
>> A subnet is a set of ports managed by a common subnet manager, which sets up the partition configuration.
> So there can be multiple partitions inside a subnet and not multiple
> subnets inside a partition?

Yes, a each subnet can have many partitions.  The partitions are contained within that subnet, a different subnet can have a partition that uses same PKey value, but that's a different partition.  So if we have 2 subnets, fe80:: and fe81:: they can each have a partition that uses PKey X but it doesn't mean nodes with access to that partition on 0xfe80 can reach nodes on 0xfe81 on that partition.

>
>> A partition is a virtual fabric, similar to an VLAN.
> Yeah, I've read that in multiple places and I think that is what I
> find confusing as it doesn't seem to mesh with my understanding of
> what you are intending.
>
>> If there are multiple IB ports each could be connected to a different subnet.
> Ports are just end points, I get that.  That's important, but it isn't
> helping me understand the relationship between subnets and partitions,
> that is where I'm struggling at the moment.

Subnets have one or more partitions.  Partitions belong to one subnet.

>> By including the subnet prefix in the label the subnets can use the same PKey values and policy can restrict access appropriately.
> This doesn't make any sense to me right now.
>
>> Without that mechanism if one of the subnets had a partition with PKey 1 the other partition couldn't reuse that PKey if a different security policy is desired for that subnet.
> <blank stare>
Going back to the example above assume fe80:: has a partition using PKey 0x8001 and we grant a user access.  Without the subnet prefix in the label we are granting that user the ability to use pkey 0x8001 on any partition available.  So subnet fe81:: can't use PKey 0x8001 if it doesn't want to grant that same user access.  By labeling with the subnet prefix we can grant access to PKey 0x8001 on subnet fe80:: only, leaving the subnet manager on fe81:: the ability to use that same PKey but not grant access to said user.

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

* Re: [PATCH 04/12] selinux: Allocate and free infiniband security hooks
  2016-07-01 19:17                     ` Paul Moore
@ 2016-07-01 20:13                       ` Casey Schaufler
  2016-07-01 20:46                           ` Daniel Jurgens
  0 siblings, 1 reply; 128+ messages in thread
From: Casey Schaufler @ 2016-07-01 20:13 UTC (permalink / raw)
  To: Paul Moore, Daniel Jurgens
  Cc: chrisw, paul, sds, eparis, dledford, sean.hefty, hal.rosenstock,
	selinux, linux-security-module, linux-rdma, Yevgeny Petrilin

On 7/1/2016 12:17 PM, Paul Moore wrote:
> On Fri, Jul 1, 2016 at 2:59 PM, Daniel Jurgens <danielj@mellanox.com> wrote:
>> On 7/1/2016 1:54 PM, Paul Moore wrote:
>>> On Thu, Jun 30, 2016 at 5:48 PM, Daniel Jurgens <danielj@mellanox.com> wrote:
>>>> On 6/30/2016 4:06 PM, Casey Schaufler wrote:
>>>>> On 6/30/2016 1:42 PM, Paul Moore wrote:
>>>>>>>  };
>>>>>>>
>>>>>>>  /**
>>>>>>> diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
>>>>>>> index 3f6780b..e522acb 100644
>>>>>>> --- a/include/rdma/ib_verbs.h
>>>>>>> +++ b/include/rdma/ib_verbs.h
>>>>>>> @@ -1454,6 +1454,7 @@ struct ib_qp {
>>>>>>>         void                   *qp_context;
>>>>>>>         u32                     qp_num;
>>>>>>>         enum ib_qp_type         qp_type;
>>>>>>> +       struct ib_qp_security  *qp_sec;
>>>>>> See my earlier question/comment about just using a void pointer here.
>>>>> I think that this is in response to my comments to the
>>>>> effect that I would like to see the LSM infrastructure
>>>>> using the inode like (inode->i_security) to the xfrm
>>>>> (void *) approach. I haven't been looking at the IB patches
>>>>> too carefully to date. It's possible I have not been clear.
>>>> My understanding at the time was that by using something other than a void * different security modules could maintain their own opaque blobs with in and keep the same prototype for the hook.  It's possible I misunderstood you, but it made sense to me.  I don't know of any plans for other security modules to support Infiniband, but this leaves the door open.
>>> All of what you describe above can still happen with a void pointer;
>>> in some ways it is even easier with a void pointer.
>> If multiple security modules register an alloc_security hook for example, how would you coordinate between them to allocate the memory?
> You worry about that in the LSM framework and hide the details behind
> the void pointer.  For example, you create an array/list of LSM
> specific blobs and just stash a pointer to the head of the data in the
> void pointer.

Don't worry about it at this point. Patches pending.
If I have to change modules to accommodate the
infrastructure I'm not afraid to do so.




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

* Re: [PATCH 05/12] selinux: Implement Infiniband PKey "Access" access vector
  2016-07-01 19:57                     ` Daniel Jurgens
@ 2016-07-01 20:42                         ` Paul Moore
  -1 siblings, 0 replies; 128+ messages in thread
From: Paul Moore @ 2016-07-01 20:42 UTC (permalink / raw)
  To: Daniel Jurgens
  Cc: 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, Yevgeny Petrilin

On Fri, Jul 1, 2016 at 3:57 PM, Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org> wrote:
> On 7/1/2016 2:26 PM, Paul Moore wrote:
>> On Fri, Jul 1, 2016 at 3:16 PM, Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org> wrote:
>>> On 7/1/2016 1:59 PM, Paul Moore wrote:
>>>> On Fri, Jul 1, 2016 at 2:21 PM, Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org> wrote:
>>>>> On 7/1/2016 11:29 AM, Paul Moore wrote:
>>>>>> I wondered about this earlier in the patchset when we were discussing
>>>>>> the policy format, and I'm still wondering; perhaps you can help me
>>>>>> understand IB a bit better ...
>>>>>>
>>>>>> From what I gather, the partition key is the IB security boundary, not
>>>>>> the subnet, is that true?  If so, why are we including the subnet with
>>>>>> the partition key value/label?  I understand the low/high pkey range
>>>>>> as a way of simplifying the policy, but I don't quite understand the
>>>>>> point of tying the subnet to the partition key label.  Would you ever
>>>>>> want to have multiple labels for a single partition key, or should it
>>>>>> be a single label for the partition key regardless of the subnet?
>>>>>>
>>>>> Each subnet can have a different partition configuration and a node can be on multiple subnets.  By specifying the subnet prefix along with the pkey value the user has flexibility to have different policy for different subnets, instead of a global PKey space that would require coordinating the partition configuration across all subnets.
>>>> Perhaps a better explanation of partitions and subnets are in order,
>>>> especially for those of like me who are new to IB.
>>>>
>>> A subnet is a set of ports managed by a common subnet manager, which sets up the partition configuration.
>> So there can be multiple partitions inside a subnet and not multiple
>> subnets inside a partition?
>
> Yes, a each subnet can have many partitions.  The partitions are contained within that subnet, a different subnet can have a partition that uses same PKey value, but that's a different partition.  So if we have 2 subnets, fe80:: and fe81:: they can each have a partition that uses PKey X but it doesn't mean nodes with access to that partition on 0xfe80 can reach nodes on 0xfe81 on that partition.

Thanks, that clears things up.  Originally I thought it was the other
way around which we causing a lot of confusion on my part.

-- 
paul moore
security @ redhat
--
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] 128+ messages in thread

* Re: [PATCH 05/12] selinux: Implement Infiniband PKey "Access" access vector
@ 2016-07-01 20:42                         ` Paul Moore
  0 siblings, 0 replies; 128+ messages in thread
From: Paul Moore @ 2016-07-01 20:42 UTC (permalink / raw)
  To: Daniel Jurgens
  Cc: chrisw, paul, sds, eparis, dledford, sean.hefty, hal.rosenstock,
	selinux, linux-security-module, linux-rdma, Yevgeny Petrilin

On Fri, Jul 1, 2016 at 3:57 PM, Daniel Jurgens <danielj@mellanox.com> wrote:
> On 7/1/2016 2:26 PM, Paul Moore wrote:
>> On Fri, Jul 1, 2016 at 3:16 PM, Daniel Jurgens <danielj@mellanox.com> wrote:
>>> On 7/1/2016 1:59 PM, Paul Moore wrote:
>>>> On Fri, Jul 1, 2016 at 2:21 PM, Daniel Jurgens <danielj@mellanox.com> wrote:
>>>>> On 7/1/2016 11:29 AM, Paul Moore wrote:
>>>>>> I wondered about this earlier in the patchset when we were discussing
>>>>>> the policy format, and I'm still wondering; perhaps you can help me
>>>>>> understand IB a bit better ...
>>>>>>
>>>>>> From what I gather, the partition key is the IB security boundary, not
>>>>>> the subnet, is that true?  If so, why are we including the subnet with
>>>>>> the partition key value/label?  I understand the low/high pkey range
>>>>>> as a way of simplifying the policy, but I don't quite understand the
>>>>>> point of tying the subnet to the partition key label.  Would you ever
>>>>>> want to have multiple labels for a single partition key, or should it
>>>>>> be a single label for the partition key regardless of the subnet?
>>>>>>
>>>>> Each subnet can have a different partition configuration and a node can be on multiple subnets.  By specifying the subnet prefix along with the pkey value the user has flexibility to have different policy for different subnets, instead of a global PKey space that would require coordinating the partition configuration across all subnets.
>>>> Perhaps a better explanation of partitions and subnets are in order,
>>>> especially for those of like me who are new to IB.
>>>>
>>> A subnet is a set of ports managed by a common subnet manager, which sets up the partition configuration.
>> So there can be multiple partitions inside a subnet and not multiple
>> subnets inside a partition?
>
> Yes, a each subnet can have many partitions.  The partitions are contained within that subnet, a different subnet can have a partition that uses same PKey value, but that's a different partition.  So if we have 2 subnets, fe80:: and fe81:: they can each have a partition that uses PKey X but it doesn't mean nodes with access to that partition on 0xfe80 can reach nodes on 0xfe81 on that partition.

Thanks, that clears things up.  Originally I thought it was the other
way around which we causing a lot of confusion on my part.

-- 
paul moore
security @ redhat

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

* Re: [PATCH 04/12] selinux: Allocate and free infiniband security hooks
  2016-07-01 20:13                       ` Casey Schaufler
@ 2016-07-01 20:46                           ` Daniel Jurgens
  0 siblings, 0 replies; 128+ messages in thread
From: Daniel Jurgens @ 2016-07-01 20:46 UTC (permalink / raw)
  To: Casey Schaufler, Paul Moore
  Cc: 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, Yevgeny Petrilin

On 7/1/2016 3:13 PM, Casey Schaufler wrote:
> On 7/1/2016 12:17 PM, Paul Moore wrote:
>> On Fri, Jul 1, 2016 at 2:59 PM, Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org> wrote:
>>> On 7/1/2016 1:54 PM, Paul Moore wrote:
>>>> On Thu, Jun 30, 2016 at 5:48 PM, Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org> wrote:
>>>>> On 6/30/2016 4:06 PM, Casey Schaufler wrote:
>>>>>> On 6/30/2016 1:42 PM, Paul Moore wrote:
>>>>>>>>  };
>>>>>>>>
>>>>>>>>  /**
>>>>>>>> diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
>>>>>>>> index 3f6780b..e522acb 100644
>>>>>>>> --- a/include/rdma/ib_verbs.h
>>>>>>>> +++ b/include/rdma/ib_verbs.h
>>>>>>>> @@ -1454,6 +1454,7 @@ struct ib_qp {
>>>>>>>>         void                   *qp_context;
>>>>>>>>         u32                     qp_num;
>>>>>>>>         enum ib_qp_type         qp_type;
>>>>>>>> +       struct ib_qp_security  *qp_sec;
>>>>>>> See my earlier question/comment about just using a void pointer here.
>>>>>> I think that this is in response to my comments to the
>>>>>> effect that I would like to see the LSM infrastructure
>>>>>> using the inode like (inode->i_security) to the xfrm
>>>>>> (void *) approach. I haven't been looking at the IB patches
>>>>>> too carefully to date. It's possible I have not been clear.
>>>>> My understanding at the time was that by using something other than a void * different security modules could maintain their own opaque blobs with in and keep the same prototype for the hook.  It's possible I misunderstood you, but it made sense to me.  I don't know of any plans for other security modules to support Infiniband, but this leaves the door open.
>>>> All of what you describe above can still happen with a void pointer;
>>>> in some ways it is even easier with a void pointer.
>>> If multiple security modules register an alloc_security hook for example, how would you coordinate between them to allocate the memory?
>> You worry about that in the LSM framework and hide the details behind
>> the void pointer.  For example, you create an array/list of LSM
>> specific blobs and just stash a pointer to the head of the data in the
>> void pointer.
> Don't worry about it at this point. Patches pending.
> If I have to change modules to accommodate the
> infrastructure I'm not afraid to do so.

So I should revert to void* blobs?  I just want to be clear before making the change.
--
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] 128+ messages in thread

* Re: [PATCH 04/12] selinux: Allocate and free infiniband security hooks
@ 2016-07-01 20:46                           ` Daniel Jurgens
  0 siblings, 0 replies; 128+ messages in thread
From: Daniel Jurgens @ 2016-07-01 20:46 UTC (permalink / raw)
  To: Casey Schaufler, Paul Moore
  Cc: chrisw, paul, sds, eparis, dledford, sean.hefty, hal.rosenstock,
	selinux, linux-security-module, linux-rdma, Yevgeny Petrilin

On 7/1/2016 3:13 PM, Casey Schaufler wrote:
> On 7/1/2016 12:17 PM, Paul Moore wrote:
>> On Fri, Jul 1, 2016 at 2:59 PM, Daniel Jurgens <danielj@mellanox.com> wrote:
>>> On 7/1/2016 1:54 PM, Paul Moore wrote:
>>>> On Thu, Jun 30, 2016 at 5:48 PM, Daniel Jurgens <danielj@mellanox.com> wrote:
>>>>> On 6/30/2016 4:06 PM, Casey Schaufler wrote:
>>>>>> On 6/30/2016 1:42 PM, Paul Moore wrote:
>>>>>>>>  };
>>>>>>>>
>>>>>>>>  /**
>>>>>>>> diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
>>>>>>>> index 3f6780b..e522acb 100644
>>>>>>>> --- a/include/rdma/ib_verbs.h
>>>>>>>> +++ b/include/rdma/ib_verbs.h
>>>>>>>> @@ -1454,6 +1454,7 @@ struct ib_qp {
>>>>>>>>         void                   *qp_context;
>>>>>>>>         u32                     qp_num;
>>>>>>>>         enum ib_qp_type         qp_type;
>>>>>>>> +       struct ib_qp_security  *qp_sec;
>>>>>>> See my earlier question/comment about just using a void pointer here.
>>>>>> I think that this is in response to my comments to the
>>>>>> effect that I would like to see the LSM infrastructure
>>>>>> using the inode like (inode->i_security) to the xfrm
>>>>>> (void *) approach. I haven't been looking at the IB patches
>>>>>> too carefully to date. It's possible I have not been clear.
>>>>> My understanding at the time was that by using something other than a void * different security modules could maintain their own opaque blobs with in and keep the same prototype for the hook.  It's possible I misunderstood you, but it made sense to me.  I don't know of any plans for other security modules to support Infiniband, but this leaves the door open.
>>>> All of what you describe above can still happen with a void pointer;
>>>> in some ways it is even easier with a void pointer.
>>> If multiple security modules register an alloc_security hook for example, how would you coordinate between them to allocate the memory?
>> You worry about that in the LSM framework and hide the details behind
>> the void pointer.  For example, you create an array/list of LSM
>> specific blobs and just stash a pointer to the head of the data in the
>> void pointer.
> Don't worry about it at this point. Patches pending.
> If I have to change modules to accommodate the
> infrastructure I'm not afraid to do so.

So I should revert to void* blobs?  I just want to be clear before making the change.

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

* Re: [PATCH 02/12] selinux: Create policydb version for Infiniband support
  2016-07-01 13:49             ` Daniel Jurgens
@ 2016-07-01 20:48                 ` Leon Romanovsky
  -1 siblings, 0 replies; 128+ messages in thread
From: Leon Romanovsky @ 2016-07-01 20:48 UTC (permalink / raw)
  To: Daniel Jurgens
  Cc: Yuval Shaia, 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, Yevgeny Petrilin

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

On Fri, Jul 01, 2016 at 01:49:49PM +0000, Daniel Jurgens wrote:
> On 7/1/2016 7:50 AM, Leon Romanovsky wrote:
> > On Thu, Jun 30, 2016 at 06:01:42PM +0300, Yuval Shaia wrote:
> >> On Thu, Jun 23, 2016 at 10:52:48PM +0300, Dan Jurgens wrote:
> >>
> >>>  				if (rc)
> >>>  					return rc;
> >>>  				break;
> >>> +			case OCON_PKEY: {
> >> Is "{" needed?
> > No, I agree, need to remove.
> The { is needed here, unless the variable sbn_pfx is defined at function scope.

Daniel,
It will be better to avoid this one time variable, it doesn't add too
much benefit to the code.

> >
> >>> +				__be64 *sbn_pfx = (__be64 *)nodebuf;
> >>> +				*sbn_pfx = cpu_to_be64(c->u.pkey.subnet_prefix);
> 
> --
> 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

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

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

* Re: [PATCH 02/12] selinux: Create policydb version for Infiniband support
@ 2016-07-01 20:48                 ` Leon Romanovsky
  0 siblings, 0 replies; 128+ messages in thread
From: Leon Romanovsky @ 2016-07-01 20:48 UTC (permalink / raw)
  To: Daniel Jurgens
  Cc: Yuval Shaia, chrisw, paul, sds, eparis, dledford, sean.hefty,
	hal.rosenstock, selinux, linux-security-module, linux-rdma,
	Yevgeny Petrilin

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

On Fri, Jul 01, 2016 at 01:49:49PM +0000, Daniel Jurgens wrote:
> On 7/1/2016 7:50 AM, Leon Romanovsky wrote:
> > On Thu, Jun 30, 2016 at 06:01:42PM +0300, Yuval Shaia wrote:
> >> On Thu, Jun 23, 2016 at 10:52:48PM +0300, Dan Jurgens wrote:
> >>
> >>>  				if (rc)
> >>>  					return rc;
> >>>  				break;
> >>> +			case OCON_PKEY: {
> >> Is "{" needed?
> > No, I agree, need to remove.
> The { is needed here, unless the variable sbn_pfx is defined at function scope.

Daniel,
It will be better to avoid this one time variable, it doesn't add too
much benefit to the code.

> >
> >>> +				__be64 *sbn_pfx = (__be64 *)nodebuf;
> >>> +				*sbn_pfx = cpu_to_be64(c->u.pkey.subnet_prefix);
> 
> --
> 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: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

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

* Re: [PATCH 04/12] selinux: Allocate and free infiniband security hooks
  2016-07-01 20:46                           ` Daniel Jurgens
@ 2016-07-01 21:16                               ` Casey Schaufler
  -1 siblings, 0 replies; 128+ messages in thread
From: Casey Schaufler @ 2016-07-01 21:16 UTC (permalink / raw)
  To: Daniel Jurgens, Paul Moore
  Cc: 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, Yevgeny Petrilin

On 7/1/2016 1:46 PM, Daniel Jurgens wrote:
> On 7/1/2016 3:13 PM, Casey Schaufler wrote:
>> On 7/1/2016 12:17 PM, Paul Moore wrote:
>>> On Fri, Jul 1, 2016 at 2:59 PM, Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org> wrote:
>>>> On 7/1/2016 1:54 PM, Paul Moore wrote:
>>>>> On Thu, Jun 30, 2016 at 5:48 PM, Daniel Jurgens <danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org> wrote:
>>>>>> On 6/30/2016 4:06 PM, Casey Schaufler wrote:
>>>>>>> On 6/30/2016 1:42 PM, Paul Moore wrote:
>>>>>>>>>  };
>>>>>>>>>
>>>>>>>>>  /**
>>>>>>>>> diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
>>>>>>>>> index 3f6780b..e522acb 100644
>>>>>>>>> --- a/include/rdma/ib_verbs.h
>>>>>>>>> +++ b/include/rdma/ib_verbs.h
>>>>>>>>> @@ -1454,6 +1454,7 @@ struct ib_qp {
>>>>>>>>>         void                   *qp_context;
>>>>>>>>>         u32                     qp_num;
>>>>>>>>>         enum ib_qp_type         qp_type;
>>>>>>>>> +       struct ib_qp_security  *qp_sec;
>>>>>>>> See my earlier question/comment about just using a void pointer here.
>>>>>>> I think that this is in response to my comments to the
>>>>>>> effect that I would like to see the LSM infrastructure
>>>>>>> using the inode like (inode->i_security) to the xfrm
>>>>>>> (void *) approach. I haven't been looking at the IB patches
>>>>>>> too carefully to date. It's possible I have not been clear.
>>>>>> My understanding at the time was that by using something other than a void * different security modules could maintain their own opaque blobs with in and keep the same prototype for the hook.  It's possible I misunderstood you, but it made sense to me.  I don't know of any plans for other security modules to support Infiniband, but this leaves the door open.
>>>>> All of what you describe above can still happen with a void pointer;
>>>>> in some ways it is even easier with a void pointer.
>>>> If multiple security modules register an alloc_security hook for example, how would you coordinate between them to allocate the memory?
>>> You worry about that in the LSM framework and hide the details behind
>>> the void pointer.  For example, you create an array/list of LSM
>>> specific blobs and just stash a pointer to the head of the data in the
>>> void pointer.
>> Don't worry about it at this point. Patches pending.
>> If I have to change modules to accommodate the
>> infrastructure I'm not afraid to do so.
> So I should revert to void* blobs?  I just want to be clear before making the change.
>
Whichever you're really comfortable with.

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

* Re: [PATCH 04/12] selinux: Allocate and free infiniband security hooks
@ 2016-07-01 21:16                               ` Casey Schaufler
  0 siblings, 0 replies; 128+ messages in thread
From: Casey Schaufler @ 2016-07-01 21:16 UTC (permalink / raw)
  To: Daniel Jurgens, Paul Moore
  Cc: chrisw, paul, sds, eparis, dledford, sean.hefty, hal.rosenstock,
	selinux, linux-security-module, linux-rdma, Yevgeny Petrilin

On 7/1/2016 1:46 PM, Daniel Jurgens wrote:
> On 7/1/2016 3:13 PM, Casey Schaufler wrote:
>> On 7/1/2016 12:17 PM, Paul Moore wrote:
>>> On Fri, Jul 1, 2016 at 2:59 PM, Daniel Jurgens <danielj@mellanox.com> wrote:
>>>> On 7/1/2016 1:54 PM, Paul Moore wrote:
>>>>> On Thu, Jun 30, 2016 at 5:48 PM, Daniel Jurgens <danielj@mellanox.com> wrote:
>>>>>> On 6/30/2016 4:06 PM, Casey Schaufler wrote:
>>>>>>> On 6/30/2016 1:42 PM, Paul Moore wrote:
>>>>>>>>>  };
>>>>>>>>>
>>>>>>>>>  /**
>>>>>>>>> diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
>>>>>>>>> index 3f6780b..e522acb 100644
>>>>>>>>> --- a/include/rdma/ib_verbs.h
>>>>>>>>> +++ b/include/rdma/ib_verbs.h
>>>>>>>>> @@ -1454,6 +1454,7 @@ struct ib_qp {
>>>>>>>>>         void                   *qp_context;
>>>>>>>>>         u32                     qp_num;
>>>>>>>>>         enum ib_qp_type         qp_type;
>>>>>>>>> +       struct ib_qp_security  *qp_sec;
>>>>>>>> See my earlier question/comment about just using a void pointer here.
>>>>>>> I think that this is in response to my comments to the
>>>>>>> effect that I would like to see the LSM infrastructure
>>>>>>> using the inode like (inode->i_security) to the xfrm
>>>>>>> (void *) approach. I haven't been looking at the IB patches
>>>>>>> too carefully to date. It's possible I have not been clear.
>>>>>> My understanding at the time was that by using something other than a void * different security modules could maintain their own opaque blobs with in and keep the same prototype for the hook.  It's possible I misunderstood you, but it made sense to me.  I don't know of any plans for other security modules to support Infiniband, but this leaves the door open.
>>>>> All of what you describe above can still happen with a void pointer;
>>>>> in some ways it is even easier with a void pointer.
>>>> If multiple security modules register an alloc_security hook for example, how would you coordinate between them to allocate the memory?
>>> You worry about that in the LSM framework and hide the details behind
>>> the void pointer.  For example, you create an array/list of LSM
>>> specific blobs and just stash a pointer to the head of the data in the
>>> void pointer.
>> Don't worry about it at this point. Patches pending.
>> If I have to change modules to accommodate the
>> infrastructure I'm not afraid to do so.
> So I should revert to void* blobs?  I just want to be clear before making the change.
>
Whichever you're really comfortable with.

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

* Re: [PATCH 04/12] selinux: Allocate and free infiniband security hooks
  2016-07-01 20:46                           ` Daniel Jurgens
  (?)
  (?)
@ 2016-07-01 22:15                           ` Paul Moore
  -1 siblings, 0 replies; 128+ messages in thread
From: Paul Moore @ 2016-07-01 22:15 UTC (permalink / raw)
  To: Daniel Jurgens
  Cc: Casey Schaufler, chrisw, paul, sds, eparis, dledford, sean.hefty,
	hal.rosenstock, selinux, linux-security-module, linux-rdma,
	Yevgeny Petrilin

On Fri, Jul 1, 2016 at 4:46 PM, Daniel Jurgens <danielj@mellanox.com> wrote:
> On 7/1/2016 3:13 PM, Casey Schaufler wrote:
>> On 7/1/2016 12:17 PM, Paul Moore wrote:
>>> On Fri, Jul 1, 2016 at 2:59 PM, Daniel Jurgens <danielj@mellanox.com> wrote:
>>>> On 7/1/2016 1:54 PM, Paul Moore wrote:
>>>>> On Thu, Jun 30, 2016 at 5:48 PM, Daniel Jurgens <danielj@mellanox.com> wrote:
>>>>>> On 6/30/2016 4:06 PM, Casey Schaufler wrote:
>>>>>>> On 6/30/2016 1:42 PM, Paul Moore wrote:
>>>>>>>>>  };
>>>>>>>>>
>>>>>>>>>  /**
>>>>>>>>> diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
>>>>>>>>> index 3f6780b..e522acb 100644
>>>>>>>>> --- a/include/rdma/ib_verbs.h
>>>>>>>>> +++ b/include/rdma/ib_verbs.h
>>>>>>>>> @@ -1454,6 +1454,7 @@ struct ib_qp {
>>>>>>>>>         void                   *qp_context;
>>>>>>>>>         u32                     qp_num;
>>>>>>>>>         enum ib_qp_type         qp_type;
>>>>>>>>> +       struct ib_qp_security  *qp_sec;
>>>>>>>> See my earlier question/comment about just using a void pointer here.
>>>>>>> I think that this is in response to my comments to the
>>>>>>> effect that I would like to see the LSM infrastructure
>>>>>>> using the inode like (inode->i_security) to the xfrm
>>>>>>> (void *) approach. I haven't been looking at the IB patches
>>>>>>> too carefully to date. It's possible I have not been clear.
>>>>>> My understanding at the time was that by using something other than a void * different security modules could maintain their own opaque blobs with in and keep the same prototype for the hook.  It's possible I misunderstood you, but it made sense to me.  I don't know of any plans for other security modules to support Infiniband, but this leaves the door open.
>>>>> All of what you describe above can still happen with a void pointer;
>>>>> in some ways it is even easier with a void pointer.
>>>> If multiple security modules register an alloc_security hook for example, how would you coordinate between them to allocate the memory?
>>> You worry about that in the LSM framework and hide the details behind
>>> the void pointer.  For example, you create an array/list of LSM
>>> specific blobs and just stash a pointer to the head of the data in the
>>> void pointer.
>> Don't worry about it at this point. Patches pending.
>> If I have to change modules to accommodate the
>> infrastructure I'm not afraid to do so.
>
> So I should revert to void* blobs?  I just want to be clear before making the change.

Yes.

-- 
paul moore
security @ redhat

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

* Re: [PATCH 05/12] selinux: Implement Infiniband PKey "Access" access vector
  2016-06-23 19:52     ` Dan Jurgens
  (?)
  (?)
@ 2016-07-11 14:46     ` Stephen Smalley
  2016-07-11 19:03         ` Daniel Jurgens
       [not found]       ` <1c637b46-7352-b369-4891-4b695ff80b3b-+05T5uksL2qpZYMLLGbcSA@public.gmane.org>
  -1 siblings, 2 replies; 128+ messages in thread
From: Stephen Smalley @ 2016-07-11 14:46 UTC (permalink / raw)
  To: Dan Jurgens, chrisw, paul, eparis, dledford, sean.hefty, hal.rosenstock
  Cc: linux-rdma, linux-security-module, selinux

On 06/23/2016 03:52 PM, Dan Jurgens wrote:
> From: Daniel Jurgens <danielj@mellanox.com>
> 
> Add a type and access vector for PKeys. Implement the qp_pkey_access
> and mad_agent_pkey_access hooks 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>
> Reviewed-by: Eli Cohen <eli@mellanox.com>
> ---
>  include/linux/lsm_audit.h                        |  7 ++++
>  security/selinux/hooks.c                         | 41 ++++++++++++++++++++++++
>  security/selinux/include/classmap.h              |  2 ++
>  security/selinux/include/initial_sid_to_string.h |  1 +
>  security/selinux/include/security.h              |  2 ++
>  security/selinux/ss/services.c                   | 41 ++++++++++++++++++++++++
>  6 files changed, 94 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/selinux/hooks.c b/security/selinux/hooks.c
> index 4f13ea4..5a40b10 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -6018,6 +6018,44 @@ static void selinux_unregister_ib_flush_callback(void)
>  	mutex_unlock(&ib_flush_mutex);
>  }
>  
> +static int selinux_pkey_access(u64 subnet_prefix, u16 pkey_val, void *security)
> +{
> +	struct common_audit_data ad;
> +	int err;
> +	u32 sid = 0;
> +	struct ib_security_struct *sec = security;
> +	struct lsm_pkey_audit pkey;
> +
> +	err = security_pkey_sid(subnet_prefix, pkey_val, &sid);
> +
> +	if (err)
> +		goto out;
> +
> +	ad.type = LSM_AUDIT_DATA_PKEY;
> +	pkey.subnet_prefix = subnet_prefix;
> +	pkey.pkey = pkey_val;
> +	ad.u.pkey = &pkey;
> +	err = avc_has_perm(sec->sid, sid,
> +			   SECCLASS_INFINIBAND_PKEY,
> +			   INFINIBAND_PKEY__ACCESS, &ad);
> +out:
> +	return err;
> +}
> +
> +static int selinux_ib_qp_pkey_access(u64 subnet_prefix, u16 pkey_val,
> +				     struct ib_qp_security *qp_sec)
> +{
> +	return selinux_pkey_access(subnet_prefix, pkey_val,
> +				   qp_sec->q_security);
> +}
> +
> +static int selinux_ib_mad_agent_pkey_access(u64 subnet_prefix, u16 pkey_val,
> +					    struct ib_mad_agent *mad_agent)
> +{
> +	return selinux_pkey_access(subnet_prefix, pkey_val,
> +					mad_agent->m_security);
> +}
> +
>  static int selinux_ib_qp_alloc_security(struct ib_qp_security *qp_sec)
>  {
>  	struct ib_security_struct *sec;
> @@ -6248,6 +6286,9 @@ static struct security_hook_list selinux_hooks[] = {
>  		      selinux_register_ib_flush_callback),
>  	LSM_HOOK_INIT(unregister_ib_flush_callback,
>  		      selinux_unregister_ib_flush_callback),
> +	LSM_HOOK_INIT(ib_qp_pkey_access, selinux_ib_qp_pkey_access),
> +	LSM_HOOK_INIT(ib_mad_agent_pkey_access,
> +		      selinux_ib_mad_agent_pkey_access),
>  	LSM_HOOK_INIT(ib_qp_alloc_security,
>  		      selinux_ib_qp_alloc_security),
>  	LSM_HOOK_INIT(ib_qp_free_security,
> diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h
> index 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/initial_sid_to_string.h b/security/selinux/include/initial_sid_to_string.h
> index a59b64e..8f2eefc 100644
> --- a/security/selinux/include/initial_sid_to_string.h
> +++ b/security/selinux/include/initial_sid_to_string.h
> @@ -29,5 +29,6 @@ static const char *initial_sid_to_string[] =
>      "policy",
>      "scmp_packet",
>      "devnull",
> +    "pkey",

I don't think we can/should add any more initial SIDs until we have
dynamic discovery support for them.  At present, we'll have problems
with old kernel with new policy and with new kernel with old policy when
the number of initial SIDs changes.

>  };
>  
> 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..49701a5 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_PKEY;

Could we just use SECINITSID_UNLABELED as the default?

> +	}
> +
> +out:
> +	read_unlock(&policy_rwlock);
> +	return rc;
> +}
> +
> +/**
>   * security_netif_sid - Obtain the SID for a network interface.
>   * @name: interface name
>   * @if_sid: interface SID
> 


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

* Re: [PATCH 05/12] selinux: Implement Infiniband PKey "Access" access vector
  2016-07-11 14:46     ` Stephen Smalley
@ 2016-07-11 19:03         ` Daniel Jurgens
       [not found]       ` <1c637b46-7352-b369-4891-4b695ff80b3b-+05T5uksL2qpZYMLLGbcSA@public.gmane.org>
  1 sibling, 0 replies; 128+ messages in thread
From: Daniel Jurgens @ 2016-07-11 19:03 UTC (permalink / raw)
  To: Stephen Smalley, chrisw-69jw2NvuJkxg9hUCZPvPmw,
	paul-r2n+y4ga6xFZroRs9YW3xA, eparis-FjpueFixGhCM4zKIHC2jIg,
	dledford-H+wXaHxf7aLQT0dZR+AlfA,
	sean.hefty-ral2JQCrhuEAvxtiuMwx3w,
	hal.rosenstock-Re5JQEeQqe8AvxtiuMwx3w
  Cc: linux-rdma-u79uwXL29TY76Z2rM5mHXA,
	linux-security-module-u79uwXL29TY76Z2rM5mHXA,
	selinux-+05T5uksL2qpZYMLLGbcSA

On 7/11/2016 9:45 AM, Stephen Smalley wrote:
> On 06/23/2016 03:52 PM, Dan Jurgens wrote:
>> diff --git a/security/selinux/include/initial_sid_to_string.h b/security/selinux/include/initial_sid_to_string.h
>> index a59b64e..8f2eefc 100644
>> --- a/security/selinux/include/initial_sid_to_string.h
>> +++ b/security/selinux/include/initial_sid_to_string.h
>> @@ -29,5 +29,6 @@ static const char *initial_sid_to_string[] =
>>      "policy",
>>      "scmp_packet",
>>      "devnull",
>> +    "pkey",
> I don't think we can/should add any more initial SIDs until we have
> dynamic discovery support for them.  At present, we'll have problems
> with old kernel with new policy and with new kernel with old policy when
> the number of initial SIDs changes.
>
>> +	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_PKEY;
> Could we just use SECINITSID_UNLABELED as the default?
>
I don't see why that would be a problem.  I'll take the same comment for the "[PATCH 06/12] selinux: Add IB End Port SMP access vector".


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

* Re: [PATCH 05/12] selinux: Implement Infiniband PKey "Access" access vector
@ 2016-07-11 19:03         ` Daniel Jurgens
  0 siblings, 0 replies; 128+ messages in thread
From: Daniel Jurgens @ 2016-07-11 19:03 UTC (permalink / raw)
  To: Stephen Smalley, chrisw, paul, eparis, dledford, sean.hefty,
	hal.rosenstock
  Cc: linux-rdma, linux-security-module, selinux

On 7/11/2016 9:45 AM, Stephen Smalley wrote:
> On 06/23/2016 03:52 PM, Dan Jurgens wrote:
>> diff --git a/security/selinux/include/initial_sid_to_string.h b/security/selinux/include/initial_sid_to_string.h
>> index a59b64e..8f2eefc 100644
>> --- a/security/selinux/include/initial_sid_to_string.h
>> +++ b/security/selinux/include/initial_sid_to_string.h
>> @@ -29,5 +29,6 @@ static const char *initial_sid_to_string[] =
>>      "policy",
>>      "scmp_packet",
>>      "devnull",
>> +    "pkey",
> I don't think we can/should add any more initial SIDs until we have
> dynamic discovery support for them.  At present, we'll have problems
> with old kernel with new policy and with new kernel with old policy when
> the number of initial SIDs changes.
>
>> +	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_PKEY;
> Could we just use SECINITSID_UNLABELED as the default?
>
I don't see why that would be a problem.  I'll take the same comment for the "[PATCH 06/12] selinux: Add IB End Port SMP access vector".

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

* Re: [PATCH 05/12] selinux: Implement Infiniband PKey "Access" access vector
  2016-07-11 14:46     ` Stephen Smalley
@ 2016-07-12 20:28           ` Paul Moore
       [not found]       ` <1c637b46-7352-b369-4891-4b695ff80b3b-+05T5uksL2qpZYMLLGbcSA@public.gmane.org>
  1 sibling, 0 replies; 128+ messages in thread
From: Paul Moore @ 2016-07-12 20:28 UTC (permalink / raw)
  To: Dan Jurgens, Stephen Smalley
  Cc: chrisw-69jw2NvuJkxg9hUCZPvPmw, Eric Paris,
	dledford-H+wXaHxf7aLQT0dZR+AlfA,
	sean.hefty-ral2JQCrhuEAvxtiuMwx3w,
	hal.rosenstock-Re5JQEeQqe8AvxtiuMwx3w,
	linux-rdma-u79uwXL29TY76Z2rM5mHXA,
	linux-security-module-u79uwXL29TY76Z2rM5mHXA,
	selinux-+05T5uksL2qpZYMLLGbcSA

On Mon, Jul 11, 2016 at 10:46 AM, Stephen Smalley <sds-+05T5uksL2qpZYMLLGbcSA@public.gmane.org> wrote:
> I don't think we can/should add any more initial SIDs until we have
> dynamic discovery support for them.  At present, we'll have problems
> with old kernel with new policy and with new kernel with old policy when
> the number of initial SIDs changes.

Seems like a reasonable policy to me.

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

* Re: [PATCH 05/12] selinux: Implement Infiniband PKey "Access" access vector
@ 2016-07-12 20:28           ` Paul Moore
  0 siblings, 0 replies; 128+ messages in thread
From: Paul Moore @ 2016-07-12 20:28 UTC (permalink / raw)
  To: Dan Jurgens, Stephen Smalley
  Cc: chrisw, Eric Paris, dledford, sean.hefty, hal.rosenstock,
	linux-rdma, linux-security-module, selinux

On Mon, Jul 11, 2016 at 10:46 AM, Stephen Smalley <sds@tycho.nsa.gov> wrote:
> I don't think we can/should add any more initial SIDs until we have
> dynamic discovery support for them.  At present, we'll have problems
> with old kernel with new policy and with new kernel with old policy when
> the number of initial SIDs changes.

Seems like a reasonable policy to me.

-- 
paul moore
www.paul-moore.com

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

end of thread, other threads:[~2016-07-12 20:29 UTC | newest]

Thread overview: 128+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-06-23 19:52 [PATCH 00/12] SELinux support for Infiniband RDMA Dan Jurgens
2016-06-23 19:52 ` Dan Jurgens
2016-06-23 19:52 ` [PATCH 01/12] security: Add LSM hooks for Infiniband security Dan Jurgens
     [not found]   ` <1466711578-64398-2-git-send-email-danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
2016-06-30 14:57     ` Yuval Shaia
2016-06-30 14:57       ` Yuval Shaia
2016-06-30 20:27     ` Paul Moore
2016-06-30 20:27       ` Paul Moore
2016-06-30 21:09       ` Daniel Jurgens
2016-06-30 21:09         ` Daniel Jurgens
2016-06-30 21:27         ` Paul Moore
2016-06-30 21:34           ` Daniel Jurgens
2016-06-30 21:34             ` Daniel Jurgens
2016-06-30 20:33     ` Paul Moore
2016-06-30 20:33       ` Paul Moore
2016-06-30 21:27       ` Daniel Jurgens
2016-06-30 21:27         ` Daniel Jurgens
     [not found]         ` <AM4PR0501MB2257674DEA1F81F53A35AC21C4240-dp/nxUn679hpbkYrVjfdjcDSnupUy6xnnBOFsp37pqbUKgpGm//BTAC/G2K4zDHf@public.gmane.org>
2016-06-30 21:30           ` Paul Moore
2016-06-30 21:30             ` Paul Moore
2016-06-23 19:52 ` [PATCH 02/12] selinux: Create policydb version for Infiniband support Dan Jurgens
     [not found]   ` <1466711578-64398-3-git-send-email-danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
2016-06-30 15:01     ` Yuval Shaia
2016-06-30 15:01       ` Yuval Shaia
     [not found]       ` <20160630150140.GB22107-Hxa29pjIrETlQW142y8m19+IiqhCXseY@public.gmane.org>
2016-07-01 12:50         ` Leon Romanovsky
2016-07-01 12:50           ` Leon Romanovsky
2016-07-01 13:49           ` Daniel Jurgens
2016-07-01 13:49             ` Daniel Jurgens
     [not found]             ` <DB6PR0501MB2261C7D467873122250A1F3EC4250-wTfl6qNNZ1NK98U9gK7MJ8DSnupUy6xnnBOFsp37pqbUKgpGm//BTAC/G2K4zDHf@public.gmane.org>
2016-07-01 20:48               ` Leon Romanovsky
2016-07-01 20:48                 ` Leon Romanovsky
2016-06-30 20:17     ` Paul Moore
2016-06-30 20:17       ` Paul Moore
2016-06-30 20:59       ` Daniel Jurgens
2016-06-30 20:59         ` Daniel Jurgens
     [not found]         ` <AM4PR0501MB22579221434714783B0AFC68C4240-dp/nxUn679hpbkYrVjfdjcDSnupUy6xnnBOFsp37pqbUKgpGm//BTAC/G2K4zDHf@public.gmane.org>
2016-06-30 21:18           ` Paul Moore
2016-06-30 21:18             ` Paul Moore
2016-06-30 21:32             ` Daniel Jurgens
2016-06-30 21:32               ` Daniel Jurgens
     [not found]               ` <AM4PR0501MB2257CB8E6F84835315734487C4240-dp/nxUn679hpbkYrVjfdjcDSnupUy6xnnBOFsp37pqbUKgpGm//BTAC/G2K4zDHf@public.gmane.org>
2016-06-30 21:37                 ` Paul Moore
2016-06-30 21:37                   ` Paul Moore
2016-06-23 19:52 ` [PATCH 10/12] IB/core: Enforce PKey security on management datagrams Dan Jurgens
     [not found] ` <1466711578-64398-1-git-send-email-danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
2016-06-23 19:52   ` [PATCH 03/12] selinux: Implement Infiniband flush callback Dan Jurgens
2016-06-23 19:52     ` Dan Jurgens
     [not found]     ` <1466711578-64398-4-git-send-email-danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
2016-06-30 15:10       ` Yuval Shaia
2016-06-30 15:10         ` Yuval Shaia
2016-06-30 15:44         ` Daniel Jurgens
2016-06-30 15:44           ` Daniel Jurgens
     [not found]           ` <AM4PR0501MB22578AA5FF8B4062F650C581C4240-dp/nxUn679hpbkYrVjfdjcDSnupUy6xnnBOFsp37pqbUKgpGm//BTAC/G2K4zDHf@public.gmane.org>
2016-06-30 19:52             ` Paul Moore
2016-06-30 19:52               ` Paul Moore
     [not found]               ` <CAGH-Kgtn0EFxYc+UOvVQk-0Bco0oOG=STZA+aGYza4TmbNXq3A-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2016-06-30 20:16                 ` Casey Schaufler
2016-06-30 20:16                   ` Casey Schaufler
     [not found]                   ` <13cf2b8b-1d4e-e61f-80fe-110af2a719cf-iSGtlc1asvQWG2LlvL+J4A@public.gmane.org>
2016-06-30 20:24                     ` Paul Moore
2016-06-30 20:24                       ` Paul Moore
2016-06-30 20:39               ` Daniel Jurgens
2016-06-30 20:39                 ` Daniel Jurgens
2016-06-23 19:52   ` [PATCH 04/12] selinux: Allocate and free infiniband security hooks Dan Jurgens
2016-06-23 19:52     ` Dan Jurgens
     [not found]     ` <1466711578-64398-5-git-send-email-danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
2016-06-30 15:15       ` Yuval Shaia
2016-06-30 15:15         ` Yuval Shaia
2016-06-30 20:42       ` Paul Moore
2016-06-30 20:42         ` Paul Moore
     [not found]         ` <CAGH-KgvtN8T7e5bKq0jJZvSzrGfFwA2VpmPf5gJuqdLZi6odEw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2016-06-30 21:06           ` Casey Schaufler
2016-06-30 21:06             ` Casey Schaufler
2016-06-30 21:48             ` Daniel Jurgens
2016-06-30 21:48               ` Daniel Jurgens
     [not found]               ` <AM4PR0501MB2257ADAB527392547179F779C4240-dp/nxUn679hpbkYrVjfdjcDSnupUy6xnnBOFsp37pqbUKgpGm//BTAC/G2K4zDHf@public.gmane.org>
2016-07-01 18:54                 ` Paul Moore
2016-07-01 18:54                   ` Paul Moore
2016-07-01 18:59                   ` Daniel Jurgens
2016-07-01 18:59                     ` Daniel Jurgens
2016-07-01 19:17                     ` Paul Moore
2016-07-01 20:13                       ` Casey Schaufler
2016-07-01 20:46                         ` Daniel Jurgens
2016-07-01 20:46                           ` Daniel Jurgens
     [not found]                           ` <DB6PR0501MB226138FF74D031F6BD1C48C6C4250-wTfl6qNNZ1NK98U9gK7MJ8DSnupUy6xnnBOFsp37pqbUKgpGm//BTAC/G2K4zDHf@public.gmane.org>
2016-07-01 21:16                             ` Casey Schaufler
2016-07-01 21:16                               ` Casey Schaufler
2016-07-01 22:15                           ` Paul Moore
2016-06-23 19:52   ` [PATCH 05/12] selinux: Implement Infiniband PKey "Access" access vector Dan Jurgens
2016-06-23 19:52     ` Dan Jurgens
     [not found]     ` <1466711578-64398-6-git-send-email-danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
2016-06-30 15:23       ` Yuval Shaia
2016-06-30 15:23         ` Yuval Shaia
2016-06-30 15:35         ` Daniel Jurgens
2016-06-30 15:35           ` Daniel Jurgens
2016-07-01 16:29       ` Paul Moore
2016-07-01 16:29         ` Paul Moore
2016-07-01 18:21         ` Daniel Jurgens
2016-07-01 18:21           ` Daniel Jurgens
2016-07-01 18:58           ` Paul Moore
2016-07-01 19:16             ` Daniel Jurgens
2016-07-01 19:16               ` Daniel Jurgens
     [not found]               ` <DB6PR0501MB22614C80007D7408544B4B30C4250-wTfl6qNNZ1NK98U9gK7MJ8DSnupUy6xnnBOFsp37pqbUKgpGm//BTAC/G2K4zDHf@public.gmane.org>
2016-07-01 19:26                 ` Paul Moore
2016-07-01 19:26                   ` Paul Moore
2016-07-01 19:57                   ` Daniel Jurgens
2016-07-01 19:57                     ` Daniel Jurgens
     [not found]                     ` <DB6PR0501MB2261C903AB4CE9644604B9E8C4250-wTfl6qNNZ1NK98U9gK7MJ8DSnupUy6xnnBOFsp37pqbUKgpGm//BTAC/G2K4zDHf@public.gmane.org>
2016-07-01 20:42                       ` Paul Moore
2016-07-01 20:42                         ` Paul Moore
2016-07-11 14:46     ` Stephen Smalley
2016-07-11 19:03       ` Daniel Jurgens
2016-07-11 19:03         ` Daniel Jurgens
     [not found]       ` <1c637b46-7352-b369-4891-4b695ff80b3b-+05T5uksL2qpZYMLLGbcSA@public.gmane.org>
2016-07-12 20:28         ` Paul Moore
2016-07-12 20:28           ` Paul Moore
2016-06-23 19:52   ` [PATCH 06/12] selinux: Add IB End Port SMP " Dan Jurgens
2016-06-23 19:52     ` Dan Jurgens
2016-06-30 15:31     ` Yuval Shaia
     [not found]     ` <1466711578-64398-7-git-send-email-danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
2016-07-01 18:48       ` Paul Moore
2016-07-01 18:48         ` Paul Moore
2016-06-23 19:52   ` [PATCH 07/12] selinux: Add a cache for quicker retreival of PKey SIDs Dan Jurgens
2016-06-23 19:52     ` Dan Jurgens
     [not found]     ` <1466711578-64398-8-git-send-email-danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
2016-06-23 21:59       ` kbuild test robot
2016-06-23 21:59         ` kbuild test robot
2016-06-30 15:41       ` Yuval Shaia
2016-06-30 15:41         ` Yuval Shaia
2016-07-01 18:51       ` Paul Moore
2016-07-01 18:51         ` Paul Moore
2016-06-23 19:52   ` [PATCH 08/12] IB/core: IB cache enhancements to support Infiniband security Dan Jurgens
2016-06-23 19:52     ` Dan Jurgens
     [not found]     ` <1466711578-64398-9-git-send-email-danielj-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
2016-06-30 15:47       ` Yuval Shaia
2016-06-30 15:47         ` Yuval Shaia
2016-06-23 19:52   ` [PATCH 09/12] IB/core: Enforce PKey security on QPs Dan Jurgens
2016-06-23 19:52     ` Dan Jurgens
2016-06-23 19:52   ` [PATCH 11/12] IB/core: Enforce Infiniband device SMI security Dan Jurgens
2016-06-23 19:52     ` Dan Jurgens
2016-06-23 19:52   ` [PATCH 12/12] IB/core: Implement the Infiniband flush callback Dan Jurgens
2016-06-23 19:52     ` Dan Jurgens
2016-06-30 14:43   ` [PATCH 00/12] SELinux support for Infiniband RDMA Yuval Shaia
2016-06-30 14:43     ` Yuval Shaia
2016-06-30 14:47     ` Daniel Jurgens
2016-06-30 14:47       ` Daniel Jurgens
2016-06-29 17:33 ` Paul Moore
2016-06-29 19:09   ` Daniel Jurgens
2016-06-29 19:09     ` Daniel Jurgens
     [not found]     ` <DB6PR0501MB22611E2BA664DD033571AEDEC4230-wTfl6qNNZ1NK98U9gK7MJ8DSnupUy6xnnBOFsp37pqbUKgpGm//BTAC/G2K4zDHf@public.gmane.org>
2016-06-30 15:18       ` Paul Moore

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