diff mbox

[02/12] selinux: Create policydb version for Infiniband support

Message ID 1466711578-64398-3-git-send-email-danielj@mellanox.com (mailing list archive)
State New, archived
Headers show

Commit Message

Daniel Jurgens June 23, 2016, 7:52 p.m. UTC
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(-)

Comments

Yuval Shaia June 30, 2016, 3:01 p.m. UTC | #1
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
--
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 June 30, 2016, 8:17 p.m. UTC | #2
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;
>                         }
>                 }
>         }
Daniel Jurgens June 30, 2016, 8:59 p.m. UTC | #3
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.

--
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 June 30, 2016, 9:18 p.m. UTC | #4
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?
Daniel Jurgens June 30, 2016, 9:32 p.m. UTC | #5
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.
--
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 June 30, 2016, 9:37 p.m. UTC | #6
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.
Leon Romanovsky July 1, 2016, 12:50 p.m. UTC | #7
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
Daniel Jurgens July 1, 2016, 1:49 p.m. UTC | #8
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);

--
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
Leon Romanovsky July 1, 2016, 8:48 p.m. UTC | #9
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
diff mbox

Patch

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 {