diff options
Diffstat (limited to 'security/selinux/ss/ebitmap.c')
| -rw-r--r-- | security/selinux/ss/ebitmap.c | 22 | 
1 files changed, 19 insertions, 3 deletions
diff --git a/security/selinux/ss/ebitmap.c b/security/selinux/ss/ebitmap.c index d42951fcbe8..820313a04d4 100644 --- a/security/selinux/ss/ebitmap.c +++ b/security/selinux/ss/ebitmap.c @@ -4,7 +4,7 @@   * Author : Stephen Smalley, <sds@epoch.ncsc.mil>   */  /* - * Updated: Hewlett-Packard <paul.moore@hp.com> + * Updated: Hewlett-Packard <paul@paul-moore.com>   *   *      Added support to import/export the NetLabel category bitmap   * @@ -213,7 +213,12 @@ netlbl_import_failure:  }  #endif /* CONFIG_NETLABEL */ -int ebitmap_contains(struct ebitmap *e1, struct ebitmap *e2) +/* + * Check to see if all the bits set in e2 are also set in e1. Optionally, + * if last_e2bit is non-zero, the highest set bit in e2 cannot exceed + * last_e2bit. + */ +int ebitmap_contains(struct ebitmap *e1, struct ebitmap *e2, u32 last_e2bit)  {  	struct ebitmap_node *n1, *n2;  	int i; @@ -223,14 +228,25 @@ int ebitmap_contains(struct ebitmap *e1, struct ebitmap *e2)  	n1 = e1->node;  	n2 = e2->node; +  	while (n1 && n2 && (n1->startbit <= n2->startbit)) {  		if (n1->startbit < n2->startbit) {  			n1 = n1->next;  			continue;  		} -		for (i = 0; i < EBITMAP_UNIT_NUMS; i++) { +		for (i = EBITMAP_UNIT_NUMS - 1; (i >= 0) && !n2->maps[i]; ) +			i--;	/* Skip trailing NULL map entries */ +		if (last_e2bit && (i >= 0)) { +			u32 lastsetbit = n2->startbit + i * EBITMAP_UNIT_SIZE + +					 __fls(n2->maps[i]); +			if (lastsetbit > last_e2bit) +				return 0; +		} + +		while (i >= 0) {  			if ((n1->maps[i] & n2->maps[i]) != n2->maps[i])  				return 0; +			i--;  		}  		n1 = n1->next;  | 
