diff mbox

[1/9] checkpolicy: Add support for ibpkeycon labels

Message ID 1494363042-121766-2-git-send-email-danielj@mellanox.com (mailing list archive)
State Superseded
Headers show

Commit Message

Daniel Jurgens May 9, 2017, 8:50 p.m. UTC
From: Daniel Jurgens <danielj@mellanox.com>

Add checkpolicy support for scanning and parsing ibpkeycon labels. Also
create a new ocontext for Infiniband Pkeys and define a new policydb
version for infiniband support.

Signed-off-by: Daniel Jurgens <danielj@mellanox.com>
---
 checkpolicy/policy_define.c                |  110 ++++++++++++++++++++++++++++
 checkpolicy/policy_define.h                |    1 +
 checkpolicy/policy_parse.y                 |   15 ++++-
 checkpolicy/policy_scan.l                  |    3 +
 libsepol/include/sepol/policydb/policydb.h |   32 +++++---
 5 files changed, 148 insertions(+), 13 deletions(-)

Comments

Stephen Smalley May 10, 2017, 6:22 p.m. UTC | #1
On Tue, 2017-05-09 at 23:50 +0300, Dan Jurgens wrote:
> From: Daniel Jurgens <danielj@mellanox.com>
> 
> Add checkpolicy support for scanning and parsing ibpkeycon labels.
> Also
> create a new ocontext for Infiniband Pkeys and define a new policydb
> version for infiniband support.
> 
> Signed-off-by: Daniel Jurgens <danielj@mellanox.com>
> ---
>  checkpolicy/policy_define.c                |  110
> ++++++++++++++++++++++++++++
>  checkpolicy/policy_define.h                |    1 +
>  checkpolicy/policy_parse.y                 |   15 ++++-
>  checkpolicy/policy_scan.l                  |    3 +
>  libsepol/include/sepol/policydb/policydb.h |   32 +++++---
>  5 files changed, 148 insertions(+), 13 deletions(-)
> 
> diff --git a/checkpolicy/policy_define.c
> b/checkpolicy/policy_define.c
> index 949ca71..6f92bc5 100644
> --- a/checkpolicy/policy_define.c
> +++ b/checkpolicy/policy_define.c
> @@ -20,6 +20,7 @@
>   * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc.
>   * Copyright (C) 2003 - 2008 Tresys Technology, LLC
>   * Copyright (C) 2007 Red Hat Inc.
> + * Copyright (C) 2017 Mellanox Techonologies Inc.
>   *	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
>   *	the Free Software Foundation, version 2.
> @@ -4975,6 +4976,115 @@ int define_port_context(unsigned int low,
> unsigned int high)
>  	return -1;
>  }
>  
> +int define_ibpkey_context(unsigned int low, unsigned int high)
> +{
> +	ocontext_t *newc, *c, *l, *head;
> +	struct in6_addr subnet_prefix;
> +	char *id;
> +	int rc = 0;
> +
> +	if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
> +		yyerror("ibpkeycon not supported for target");
> +		return -1;
> +	}
> +
> +	if (pass == 1) {
> +		id = (char *)queue_remove(id_queue);
> +		free(id);
> +		parse_security_context(NULL);
> +		return 0;
> +	}
> +
> +	newc = malloc(sizeof(*newc));
> +	if (!newc) {
> +		yyerror("out of memory");
> +		return -1;
> +	}
> +	memset(newc, 0, sizeof(*newc));
> +
> +	id = queue_remove(id_queue);
> +	if (!id) {
> +		yyerror("failed to read the subnet prefix");
> +		rc = -1;
> +		goto out;
> +	}
> +
> +	rc = inet_pton(AF_INET6, id, &subnet_prefix);
> +	free(id);
> +	if (rc < 1) {
> +		yyerror("failed to parse the subnet prefix");
> +		if (rc == 0)
> +			rc = -1;
> +		goto out;
> +	}
> +
> +	if (subnet_prefix.s6_addr[2] || subnet_prefix.s6_addr[3]) {
> +		yyerror("subnet prefix should be 0's in the low
> order 64 bits.");
> +		rc = -1;
> +		goto out;
> +	}
> +
> +#ifdef DARWIN
> +	memcpy(&newc->u.ibpkey.subnet_prefix[0],
> &subnet_prefix.s6_addr[0],
> +	       sizeof(newc->u.ibpkey.subnet_prefix));
> +#else
> +	memcpy(&newc->u.ibpkey.subnet_prefix[0],
> &subnet_prefix.s6_addr32[0],
> +	       sizeof(newc->u.ibpkey.subnet_prefix));
> +#endif

We can just always use s6_addr instead of s6_addr32 and drop the
#ifdef.  Just pushed a commit to fix that elsewhere. Also we switched
from #ifdef DARWIN to __APPLE__ a while ago, but that won't matter once
you drop the #ifdef altogether.

> +
> +	newc->u.ibpkey.low_pkey = low;
> +	newc->u.ibpkey.high_pkey = high;
> +
> +	if (low > high) {
> +		yyerror2("low pkey %d exceeds high pkey %d", low,
> high);
> +		rc = -1;
> +		goto out;
> +	}
> +
> +	rc = parse_security_context(&newc->context[0]);
> +	if (rc)
> +		goto out;
> +
> +	/* Preserve the matching order specified in the
> configuration. */
> +	head = policydbp->ocontexts[OCON_IBPKEY];
> +	for (l = NULL, c = head; c; l = c, c = c->next) {
> +		unsigned int low2, high2;
> +
> +		low2 = c->u.ibpkey.low_pkey;
> +		high2 = c->u.ibpkey.high_pkey;
> +
> +		if (low == low2 && high == high2 &&
> +		    !memcmp(&c->u.ibpkey.subnet_prefix[0],
> +			    &newc->u.ibpkey.subnet_prefix[0],
> +			    sizeof(c->u.ibpkey.subnet_prefix))) {
> +			yyerror2("duplicate ibpkeycon entry for %d-
> %d ",
> +				 low, high);
> +			rc = -1;
> +			goto out;
> +		}
> +		if (low2 <= low && high2 >= high &&
> +		    !memcmp(&c->u.ibpkey.subnet_prefix[0],
> +			    &newc->u.ibpkey.subnet_prefix[0],
> +			    sizeof(c->u.ibpkey.subnet_prefix))) {
> +			yyerror2("ibpkeycon entry for %d-%d hidden
> by earlier entry for %d-%d",
> +				 low, high, low2, high2);
> +			rc = -1;
> +			goto out;
> +		}
> +	}
> +
> +	if (l)
> +		l->next = newc;
> +	else
> +		policydbp->ocontexts[OCON_IBPKEY] = newc;
> +
> +	return 0;
> +
> +out:
> +	free(newc);
> +	return rc;
> +}
> +
>  int define_netif_context(void)
>  {
>  	ocontext_t *newc, *c, *head;
> diff --git a/checkpolicy/policy_define.h
> b/checkpolicy/policy_define.h
> index 964baae..b019b1a 100644
> --- a/checkpolicy/policy_define.h
> +++ b/checkpolicy/policy_define.h
> @@ -43,6 +43,7 @@ int define_level(void);
>  int define_netif_context(void);
>  int define_permissive(void);
>  int define_polcap(void);
> +int define_ibpkey_context(unsigned int low, unsigned int high);
>  int define_port_context(unsigned int low, unsigned int high);
>  int define_pirq_context(unsigned int pirq);
>  int define_iomem_context(uint64_t low, uint64_t high);
> diff --git a/checkpolicy/policy_parse.y b/checkpolicy/policy_parse.y
> index 3b6a2f8..f50eab1 100644
> --- a/checkpolicy/policy_parse.y
> +++ b/checkpolicy/policy_parse.y
> @@ -21,6 +21,7 @@
>   * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc.
>   * Copyright (C) 2003 - 2008 Tresys Technology, LLC
>   * Copyright (C) 2007 Red Hat Inc.
> + * Copyright (C) 2017 Mellanox Technologies Inc.
>   *	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
>   *	the Free Software Foundation, version 2.
> @@ -134,6 +135,7 @@ typedef int (* require_func_t)(int pass);
>  %token TARGET
>  %token SAMEUSER
>  %token FSCON PORTCON NETIFCON NODECON 
> +%token IBPKEYCON
>  %token PIRQCON IOMEMCON IOPORTCON PCIDEVICECON DEVICETREECON
>  %token FSUSEXATTR FSUSETASK FSUSETRANS
>  %token GENFSCON
> @@ -169,7 +171,7 @@ base_policy             : { if
> (define_policy(pass, 0) == -1) return -1; }
>  			  opt_default_rules opt_mls te_rbac users
> opt_constraints 
>                           { if (pass == 1) { if
> (policydb_index_bools(policydbp)) return -1;}
>  			   else if (pass == 2) { if
> (policydb_index_others(NULL, policydbp, 0)) return -1;}}
> -			  initial_sid_contexts opt_fs_contexts
> opt_fs_uses opt_genfs_contexts net_contexts opt_dev_contexts
> +			  initial_sid_contexts opt_fs_contexts
> opt_fs_uses opt_genfs_contexts net_contexts opt_dev_contexts
> opt_ibpkey_contexts
>  			;
>  classes			: class_def 
>  			| classes class_def
> @@ -708,6 +710,17 @@ port_context_def	: PORTCON identifier
> number security_context_def
>  			| PORTCON identifier number '-' number
> security_context_def
>  			{if (define_port_context($3,$5)) return -1;}
>  			;
> +opt_ibpkey_contexts     : ibpkey_contexts
> +                        |
> +                        ;
> +ibpkey_contexts		: ibpkey_context_def
> +			| ibpkey_contexts ibpkey_context_def
> +			;
> +ibpkey_context_def	: IBPKEYCON ipv6_addr number
> security_context_def
> +			{if (define_ibpkey_context($3,$3)) return
> -1;}
> +			| IBPKEYCON ipv6_addr number '-' number
> security_context_def
> +			{if (define_ibpkey_context($3,$5)) return
> -1;}
> +			;
>  opt_netif_contexts      : netif_contexts 
>                          |
>                          ;
> diff --git a/checkpolicy/policy_scan.l b/checkpolicy/policy_scan.l
> index 2f7f221..07352cb 100644
> --- a/checkpolicy/policy_scan.l
> +++ b/checkpolicy/policy_scan.l
> @@ -12,6 +12,7 @@
>   *	Added support for binary policy modules
>   *
>   * Copyright (C) 2003-5 Tresys Technology, LLC
> + * Copyright (C) 2017 Mellanox Technologies Inc.
>   *	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
>   *	the Free Software Foundation, version 2.
> @@ -181,6 +182,8 @@ INCOMP |
>  incomp				{ return(INCOMP);}
>  fscon |
>  FSCON                           { return(FSCON);}
> +ibpkeycon |
> +IBPKEYCON			{ return(IBPKEYCON);}
>  portcon |
>  PORTCON				{ return(PORTCON);}
>  netifcon |                     
> diff --git a/libsepol/include/sepol/policydb/policydb.h
> b/libsepol/include/sepol/policydb/policydb.h
> index 4336a3f..5ecc623 100644
> --- a/libsepol/include/sepol/policydb/policydb.h
> +++ b/libsepol/include/sepol/policydb/policydb.h
> @@ -24,6 +24,7 @@
>   * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc.
>   * Copyright (C) 2003 - 2004 Tresys Technology, LLC
>   * Copyright (C) 2003 - 2004 Red Hat, Inc.
> + * Copyright (C) 2017 Mellanox Techonolgies Inc.
>   *
>   *  This library is free software; you can redistribute it and/or
>   *  modify it under the terms of the GNU Lesser General Public
> @@ -354,6 +355,11 @@ typedef struct ocontext {
>  			uint32_t low_ioport;
>  			uint32_t high_ioport;
>  		} ioport;
> +		struct {
> +			uint32_t subnet_prefix[4];
> +			uint16_t low_pkey;
> +			uint16_t high_pkey;
> +		} ibpkey;
>  	} u;
>  	union {
>  		uint32_t sclass;	/* security class for genfs
> */
> @@ -382,14 +388,14 @@ typedef 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_GENFS 7            /* needed for ocontext_supported */
> +#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_IBPKEY 7	/* Infiniband PKEY */
>  
>  /* object context array indices for Xen */
>  #define OCON_XEN_ISID  	    0    /* initial SIDs */
> @@ -400,7 +406,7 @@ typedef struct genfs {
>  #define OCON_XEN_DEVICETREE 5    /* device tree node */
>  
>  /* OCON_NUM needs to be the largest index in any platform's ocontext
> array */
> -#define OCON_NUM   7
> +#define OCON_NUM   8
>  
>  /* section: module information */
>  
> @@ -722,10 +728,11 @@ extern int
> policydb_set_target_platform(policydb_t *p, int platform);
>  #define POLICYDB_VERSION_CONSTRAINT_NAMES	29
>  #define POLICYDB_VERSION_XEN_DEVICETREE		30 /* Xen-
> specific */
>  #define POLICYDB_VERSION_XPERMS_IOCTL	30 /* Linux-specific */
> +#define POLICYDB_VERSION_INFINIBAND		31

This is Linux-specific too.

>  
>  /* Range of policy versions we understand*/
>  #define POLICYDB_VERSION_MIN	POLICYDB_VERSION_BASE
> -#define POLICYDB_VERSION_MAX	POLICYDB_VERSION_XPERMS_IOCTL
> +#define POLICYDB_VERSION_MAX	POLICYDB_VERSION_INFINIBAND
>  
>  /* Module versions and specific changes*/
>  #define MOD_POLICYDB_VERSION_BASE		4
> @@ -743,10 +750,11 @@ extern int
> policydb_set_target_platform(policydb_t *p, int platform);
>  #define MOD_POLICYDB_VERSION_TUNABLE_SEP	14
>  #define MOD_POLICYDB_VERSION_NEW_OBJECT_DEFAULTS	15
>  #define MOD_POLICYDB_VERSION_DEFAULT_TYPE	16
> -#define MOD_POLICYDB_VERSION_CONSTRAINT_NAMES  17
> +#define MOD_POLICYDB_VERSION_CONSTRAINT_NAMES	17
> +#define MOD_POLICYDB_VERSION_INFINIBAND		18
>  
>  #define MOD_POLICYDB_VERSION_MIN MOD_POLICYDB_VERSION_BASE
> -#define MOD_POLICYDB_VERSION_MAX
> MOD_POLICYDB_VERSION_CONSTRAINT_NAMES
> +#define MOD_POLICYDB_VERSION_MAX MOD_POLICYDB_VERSION_INFINIBAND
>  
>  #define POLICYDB_CONFIG_MLS    1

Hmmm...we never introduced a binary module version for xperms, since
the only user is presently Android and they don't use binary modules
and in general we'd like to get rid of binary modules altogether and
switch entirely to source modules (either .te modules with a te2cil
converter or cil modules).  But I guess you probably want to support
this in the interim for convenient usage within existing Fedora/RHEL
policies.
Daniel Jurgens May 10, 2017, 9:46 p.m. UTC | #2
On 5/10/2017 1:18 PM, Stephen Smalley wrote:
> On Tue, 2017-05-09 at 23:50 +0300, Dan Jurgens wrote:
>> From: Daniel Jurgens <danielj@mellanox.com>
>>
>>
>> +#ifdef DARWIN
>> +	memcpy(&newc->u.ibpkey.subnet_prefix[0],
>> &subnet_prefix.s6_addr[0],
>> +	       sizeof(newc->u.ibpkey.subnet_prefix));
>> +#else
>> +	memcpy(&newc->u.ibpkey.subnet_prefix[0],
>> &subnet_prefix.s6_addr32[0],
>> +	       sizeof(newc->u.ibpkey.subnet_prefix));
>> +#endif
> We can just always use s6_addr instead of s6_addr32 and drop the
> #ifdef.  Just pushed a commit to fix that elsewhere. Also we switched
> from #ifdef DARWIN to __APPLE__ a while ago, but that won't matter once
> you drop the #ifdef altogether.
OK
>
>> @@ -722,10 +728,11 @@ extern int
>> policydb_set_target_platform(policydb_t *p, int platform);
>>  #define POLICYDB_VERSION_CONSTRAINT_NAMES	29
>>  #define POLICYDB_VERSION_XEN_DEVICETREE		30 /* Xen-
>> specific */
>>  #define POLICYDB_VERSION_XPERMS_IOCTL	30 /* Linux-specific */
>> +#define POLICYDB_VERSION_INFINIBAND		31
> This is Linux-specific too.
I'll add a similar comment.
>
>>  
>>  /* Range of policy versions we understand*/
>>  #define POLICYDB_VERSION_MIN	POLICYDB_VERSION_BASE
>> -#define POLICYDB_VERSION_MAX	POLICYDB_VERSION_XPERMS_IOCTL
>> +#define POLICYDB_VERSION_MAX	POLICYDB_VERSION_INFINIBAND
>>  
>>  /* Module versions and specific changes*/
>>  #define MOD_POLICYDB_VERSION_BASE		4
>> @@ -743,10 +750,11 @@ extern int
>> policydb_set_target_platform(policydb_t *p, int platform);
>>  #define MOD_POLICYDB_VERSION_TUNABLE_SEP	14
>>  #define MOD_POLICYDB_VERSION_NEW_OBJECT_DEFAULTS	15
>>  #define MOD_POLICYDB_VERSION_DEFAULT_TYPE	16
>> -#define MOD_POLICYDB_VERSION_CONSTRAINT_NAMES  17
>> +#define MOD_POLICYDB_VERSION_CONSTRAINT_NAMES	17
>> +#define MOD_POLICYDB_VERSION_INFINIBAND		18
>>  
>>  #define MOD_POLICYDB_VERSION_MIN MOD_POLICYDB_VERSION_BASE
>> -#define MOD_POLICYDB_VERSION_MAX
>> MOD_POLICYDB_VERSION_CONSTRAINT_NAMES
>> +#define MOD_POLICYDB_VERSION_MAX MOD_POLICYDB_VERSION_INFINIBAND
>>  
>>  #define POLICYDB_CONFIG_MLS    1
> Hmmm...we never introduced a binary module version for xperms, since
> the only user is presently Android and they don't use binary modules
> and in general we'd like to get rid of binary modules altogether and
> switch entirely to source modules (either .te modules with a te2cil
> converter or cil modules).  But I guess you probably want to support
> this in the interim for convenient usage within existing Fedora/RHEL
> policies.
>
Yes, we want to pull this back into RHEL once it's available upstream.

Thank you for your quick review.  I'll continue going through your comments on the other patches and post a v1 after giving some more time for others to comment as well.
diff mbox

Patch

diff --git a/checkpolicy/policy_define.c b/checkpolicy/policy_define.c
index 949ca71..6f92bc5 100644
--- a/checkpolicy/policy_define.c
+++ b/checkpolicy/policy_define.c
@@ -20,6 +20,7 @@ 
  * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc.
  * Copyright (C) 2003 - 2008 Tresys Technology, LLC
  * Copyright (C) 2007 Red Hat Inc.
+ * Copyright (C) 2017 Mellanox Techonologies Inc.
  *	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
  *	the Free Software Foundation, version 2.
@@ -4975,6 +4976,115 @@  int define_port_context(unsigned int low, unsigned int high)
 	return -1;
 }
 
+int define_ibpkey_context(unsigned int low, unsigned int high)
+{
+	ocontext_t *newc, *c, *l, *head;
+	struct in6_addr subnet_prefix;
+	char *id;
+	int rc = 0;
+
+	if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
+		yyerror("ibpkeycon not supported for target");
+		return -1;
+	}
+
+	if (pass == 1) {
+		id = (char *)queue_remove(id_queue);
+		free(id);
+		parse_security_context(NULL);
+		return 0;
+	}
+
+	newc = malloc(sizeof(*newc));
+	if (!newc) {
+		yyerror("out of memory");
+		return -1;
+	}
+	memset(newc, 0, sizeof(*newc));
+
+	id = queue_remove(id_queue);
+	if (!id) {
+		yyerror("failed to read the subnet prefix");
+		rc = -1;
+		goto out;
+	}
+
+	rc = inet_pton(AF_INET6, id, &subnet_prefix);
+	free(id);
+	if (rc < 1) {
+		yyerror("failed to parse the subnet prefix");
+		if (rc == 0)
+			rc = -1;
+		goto out;
+	}
+
+	if (subnet_prefix.s6_addr[2] || subnet_prefix.s6_addr[3]) {
+		yyerror("subnet prefix should be 0's in the low order 64 bits.");
+		rc = -1;
+		goto out;
+	}
+
+#ifdef DARWIN
+	memcpy(&newc->u.ibpkey.subnet_prefix[0], &subnet_prefix.s6_addr[0],
+	       sizeof(newc->u.ibpkey.subnet_prefix));
+#else
+	memcpy(&newc->u.ibpkey.subnet_prefix[0], &subnet_prefix.s6_addr32[0],
+	       sizeof(newc->u.ibpkey.subnet_prefix));
+#endif
+
+	newc->u.ibpkey.low_pkey = low;
+	newc->u.ibpkey.high_pkey = high;
+
+	if (low > high) {
+		yyerror2("low pkey %d exceeds high pkey %d", low, high);
+		rc = -1;
+		goto out;
+	}
+
+	rc = parse_security_context(&newc->context[0]);
+	if (rc)
+		goto out;
+
+	/* Preserve the matching order specified in the configuration. */
+	head = policydbp->ocontexts[OCON_IBPKEY];
+	for (l = NULL, c = head; c; l = c, c = c->next) {
+		unsigned int low2, high2;
+
+		low2 = c->u.ibpkey.low_pkey;
+		high2 = c->u.ibpkey.high_pkey;
+
+		if (low == low2 && high == high2 &&
+		    !memcmp(&c->u.ibpkey.subnet_prefix[0],
+			    &newc->u.ibpkey.subnet_prefix[0],
+			    sizeof(c->u.ibpkey.subnet_prefix))) {
+			yyerror2("duplicate ibpkeycon entry for %d-%d ",
+				 low, high);
+			rc = -1;
+			goto out;
+		}
+		if (low2 <= low && high2 >= high &&
+		    !memcmp(&c->u.ibpkey.subnet_prefix[0],
+			    &newc->u.ibpkey.subnet_prefix[0],
+			    sizeof(c->u.ibpkey.subnet_prefix))) {
+			yyerror2("ibpkeycon entry for %d-%d hidden by earlier entry for %d-%d",
+				 low, high, low2, high2);
+			rc = -1;
+			goto out;
+		}
+	}
+
+	if (l)
+		l->next = newc;
+	else
+		policydbp->ocontexts[OCON_IBPKEY] = newc;
+
+	return 0;
+
+out:
+	free(newc);
+	return rc;
+}
+
 int define_netif_context(void)
 {
 	ocontext_t *newc, *c, *head;
diff --git a/checkpolicy/policy_define.h b/checkpolicy/policy_define.h
index 964baae..b019b1a 100644
--- a/checkpolicy/policy_define.h
+++ b/checkpolicy/policy_define.h
@@ -43,6 +43,7 @@  int define_level(void);
 int define_netif_context(void);
 int define_permissive(void);
 int define_polcap(void);
+int define_ibpkey_context(unsigned int low, unsigned int high);
 int define_port_context(unsigned int low, unsigned int high);
 int define_pirq_context(unsigned int pirq);
 int define_iomem_context(uint64_t low, uint64_t high);
diff --git a/checkpolicy/policy_parse.y b/checkpolicy/policy_parse.y
index 3b6a2f8..f50eab1 100644
--- a/checkpolicy/policy_parse.y
+++ b/checkpolicy/policy_parse.y
@@ -21,6 +21,7 @@ 
  * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc.
  * Copyright (C) 2003 - 2008 Tresys Technology, LLC
  * Copyright (C) 2007 Red Hat Inc.
+ * Copyright (C) 2017 Mellanox Technologies Inc.
  *	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
  *	the Free Software Foundation, version 2.
@@ -134,6 +135,7 @@  typedef int (* require_func_t)(int pass);
 %token TARGET
 %token SAMEUSER
 %token FSCON PORTCON NETIFCON NODECON 
+%token IBPKEYCON
 %token PIRQCON IOMEMCON IOPORTCON PCIDEVICECON DEVICETREECON
 %token FSUSEXATTR FSUSETASK FSUSETRANS
 %token GENFSCON
@@ -169,7 +171,7 @@  base_policy             : { if (define_policy(pass, 0) == -1) return -1; }
 			  opt_default_rules opt_mls te_rbac users opt_constraints 
                          { if (pass == 1) { if (policydb_index_bools(policydbp)) return -1;}
 			   else if (pass == 2) { if (policydb_index_others(NULL, policydbp, 0)) return -1;}}
-			  initial_sid_contexts opt_fs_contexts opt_fs_uses opt_genfs_contexts net_contexts opt_dev_contexts
+			  initial_sid_contexts opt_fs_contexts opt_fs_uses opt_genfs_contexts net_contexts opt_dev_contexts opt_ibpkey_contexts
 			;
 classes			: class_def 
 			| classes class_def
@@ -708,6 +710,17 @@  port_context_def	: PORTCON identifier number security_context_def
 			| PORTCON identifier number '-' number security_context_def
 			{if (define_port_context($3,$5)) return -1;}
 			;
+opt_ibpkey_contexts     : ibpkey_contexts
+                        |
+                        ;
+ibpkey_contexts		: ibpkey_context_def
+			| ibpkey_contexts ibpkey_context_def
+			;
+ibpkey_context_def	: IBPKEYCON ipv6_addr number security_context_def
+			{if (define_ibpkey_context($3,$3)) return -1;}
+			| IBPKEYCON ipv6_addr number '-' number security_context_def
+			{if (define_ibpkey_context($3,$5)) return -1;}
+			;
 opt_netif_contexts      : netif_contexts 
                         |
                         ;
diff --git a/checkpolicy/policy_scan.l b/checkpolicy/policy_scan.l
index 2f7f221..07352cb 100644
--- a/checkpolicy/policy_scan.l
+++ b/checkpolicy/policy_scan.l
@@ -12,6 +12,7 @@ 
  *	Added support for binary policy modules
  *
  * Copyright (C) 2003-5 Tresys Technology, LLC
+ * Copyright (C) 2017 Mellanox Technologies Inc.
  *	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
  *	the Free Software Foundation, version 2.
@@ -181,6 +182,8 @@  INCOMP |
 incomp				{ return(INCOMP);}
 fscon |
 FSCON                           { return(FSCON);}
+ibpkeycon |
+IBPKEYCON			{ return(IBPKEYCON);}
 portcon |
 PORTCON				{ return(PORTCON);}
 netifcon |                     
diff --git a/libsepol/include/sepol/policydb/policydb.h b/libsepol/include/sepol/policydb/policydb.h
index 4336a3f..5ecc623 100644
--- a/libsepol/include/sepol/policydb/policydb.h
+++ b/libsepol/include/sepol/policydb/policydb.h
@@ -24,6 +24,7 @@ 
  * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc.
  * Copyright (C) 2003 - 2004 Tresys Technology, LLC
  * Copyright (C) 2003 - 2004 Red Hat, Inc.
+ * Copyright (C) 2017 Mellanox Techonolgies Inc.
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Lesser General Public
@@ -354,6 +355,11 @@  typedef struct ocontext {
 			uint32_t low_ioport;
 			uint32_t high_ioport;
 		} ioport;
+		struct {
+			uint32_t subnet_prefix[4];
+			uint16_t low_pkey;
+			uint16_t high_pkey;
+		} ibpkey;
 	} u;
 	union {
 		uint32_t sclass;	/* security class for genfs */
@@ -382,14 +388,14 @@  typedef 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_GENFS 7            /* needed for ocontext_supported */
+#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_IBPKEY 7	/* Infiniband PKEY */
 
 /* object context array indices for Xen */
 #define OCON_XEN_ISID  	    0    /* initial SIDs */
@@ -400,7 +406,7 @@  typedef struct genfs {
 #define OCON_XEN_DEVICETREE 5    /* device tree node */
 
 /* OCON_NUM needs to be the largest index in any platform's ocontext array */
-#define OCON_NUM   7
+#define OCON_NUM   8
 
 /* section: module information */
 
@@ -722,10 +728,11 @@  extern int policydb_set_target_platform(policydb_t *p, int platform);
 #define POLICYDB_VERSION_CONSTRAINT_NAMES	29
 #define POLICYDB_VERSION_XEN_DEVICETREE		30 /* Xen-specific */
 #define POLICYDB_VERSION_XPERMS_IOCTL	30 /* Linux-specific */
+#define POLICYDB_VERSION_INFINIBAND		31
 
 /* Range of policy versions we understand*/
 #define POLICYDB_VERSION_MIN	POLICYDB_VERSION_BASE
-#define POLICYDB_VERSION_MAX	POLICYDB_VERSION_XPERMS_IOCTL
+#define POLICYDB_VERSION_MAX	POLICYDB_VERSION_INFINIBAND
 
 /* Module versions and specific changes*/
 #define MOD_POLICYDB_VERSION_BASE		4
@@ -743,10 +750,11 @@  extern int policydb_set_target_platform(policydb_t *p, int platform);
 #define MOD_POLICYDB_VERSION_TUNABLE_SEP	14
 #define MOD_POLICYDB_VERSION_NEW_OBJECT_DEFAULTS	15
 #define MOD_POLICYDB_VERSION_DEFAULT_TYPE	16
-#define MOD_POLICYDB_VERSION_CONSTRAINT_NAMES  17
+#define MOD_POLICYDB_VERSION_CONSTRAINT_NAMES	17
+#define MOD_POLICYDB_VERSION_INFINIBAND		18
 
 #define MOD_POLICYDB_VERSION_MIN MOD_POLICYDB_VERSION_BASE
-#define MOD_POLICYDB_VERSION_MAX MOD_POLICYDB_VERSION_CONSTRAINT_NAMES
+#define MOD_POLICYDB_VERSION_MAX MOD_POLICYDB_VERSION_INFINIBAND
 
 #define POLICYDB_CONFIG_MLS    1