2005-04-16 15:20:36 -07:00
/*
* Implementation of the multi - level security ( MLS ) policy .
*
* Author : Stephen Smalley , < sds @ epoch . ncsc . mil >
*/
/*
* Updated : Trusted Computer Solutions , Inc . < dgoeddel @ trustedcs . com >
*
* Support for enhanced MLS infrastructure .
*
2006-02-24 15:44:05 -06:00
* Copyright ( C ) 2004 - 2006 Trusted Computer Solutions , Inc .
2005-04-16 15:20:36 -07:00
*/
2006-08-04 23:17:57 -07:00
/*
2011-08-01 11:10:33 +00:00
* Updated : Hewlett - Packard < paul @ paul - moore . com >
2006-08-04 23:17:57 -07:00
*
2006-11-29 13:18:18 -05:00
* Added support to import / export the MLS label from NetLabel
2006-08-04 23:17:57 -07:00
*
* ( c ) Copyright Hewlett - Packard Development Company , L . P . , 2006
*/
2005-04-16 15:20:36 -07:00
# include <linux/kernel.h>
# include <linux/slab.h>
# include <linux/string.h>
# include <linux/errno.h>
2006-11-29 13:18:18 -05:00
# include <net/netlabel.h>
2005-07-28 01:07:37 -07:00
# include "sidtab.h"
2005-04-16 15:20:36 -07:00
# include "mls.h"
# include "policydb.h"
# include "services.h"
/*
* Return the length in bytes for the MLS fields of the
* security context string representation of ` context ' .
*/
2008-04-18 17:38:32 -04:00
int mls_compute_context_len ( struct context * context )
2005-04-16 15:20:36 -07:00
{
SELinux: improve performance when AVC misses.
* We add ebitmap_for_each_positive_bit() which enables to walk on
any positive bit on the given ebitmap, to improve its performance
using common bit-operations defined in linux/bitops.h.
In the previous version, this logic was implemented using a combination
of ebitmap_for_each_bit() and ebitmap_node_get_bit(), but is was worse
in performance aspect.
This logic is most frequestly used to compute a new AVC entry,
so this patch can improve SELinux performance when AVC misses are happen.
* struct ebitmap_node is redefined as an array of "unsigned long", to get
suitable for using find_next_bit() which is fasted than iteration of
shift and logical operation, and to maximize memory usage allocated
from general purpose slab.
* Any ebitmap_for_each_bit() are repleced by the new implementation
in ss/service.c and ss/mls.c. Some of related implementation are
changed, however, there is no incompatibility with the previous
version.
* The width of any new line are less or equal than 80-chars.
The following benchmark shows the effect of this patch, when we
access many files which have different security context one after
another. The number is more than /selinux/avc/cache_threshold, so
any access always causes AVC misses.
selinux-2.6 selinux-2.6-ebitmap
AVG: 22.763 [s] 8.750 [s]
STD: 0.265 0.019
------------------------------------------
1st: 22.558 [s] 8.786 [s]
2nd: 22.458 [s] 8.750 [s]
3rd: 22.478 [s] 8.754 [s]
4th: 22.724 [s] 8.745 [s]
5th: 22.918 [s] 8.748 [s]
6th: 22.905 [s] 8.764 [s]
7th: 23.238 [s] 8.726 [s]
8th: 22.822 [s] 8.729 [s]
Signed-off-by: KaiGai Kohei <kaigai@ak.jp.nec.com>
Acked-by: Stephen Smalley <sds@tycho.nsa.gov>
Signed-off-by: James Morris <jmorris@namei.org>
2007-09-29 02:20:55 +09:00
int i , l , len , head , prev ;
char * nm ;
struct ebitmap * e ;
2005-09-03 15:55:16 -07:00
struct ebitmap_node * node ;
2005-04-16 15:20:36 -07:00
2010-02-03 16:40:20 +01:00
if ( ! policydb . mls_enabled )
2005-04-16 15:20:36 -07:00
return 0 ;
len = 1 ; /* for the beginning ":" */
for ( l = 0 ; l < 2 ; l + + ) {
SELinux: improve performance when AVC misses.
* We add ebitmap_for_each_positive_bit() which enables to walk on
any positive bit on the given ebitmap, to improve its performance
using common bit-operations defined in linux/bitops.h.
In the previous version, this logic was implemented using a combination
of ebitmap_for_each_bit() and ebitmap_node_get_bit(), but is was worse
in performance aspect.
This logic is most frequestly used to compute a new AVC entry,
so this patch can improve SELinux performance when AVC misses are happen.
* struct ebitmap_node is redefined as an array of "unsigned long", to get
suitable for using find_next_bit() which is fasted than iteration of
shift and logical operation, and to maximize memory usage allocated
from general purpose slab.
* Any ebitmap_for_each_bit() are repleced by the new implementation
in ss/service.c and ss/mls.c. Some of related implementation are
changed, however, there is no incompatibility with the previous
version.
* The width of any new line are less or equal than 80-chars.
The following benchmark shows the effect of this patch, when we
access many files which have different security context one after
another. The number is more than /selinux/avc/cache_threshold, so
any access always causes AVC misses.
selinux-2.6 selinux-2.6-ebitmap
AVG: 22.763 [s] 8.750 [s]
STD: 0.265 0.019
------------------------------------------
1st: 22.558 [s] 8.786 [s]
2nd: 22.458 [s] 8.750 [s]
3rd: 22.478 [s] 8.754 [s]
4th: 22.724 [s] 8.745 [s]
5th: 22.918 [s] 8.748 [s]
6th: 22.905 [s] 8.764 [s]
7th: 23.238 [s] 8.726 [s]
8th: 22.822 [s] 8.729 [s]
Signed-off-by: KaiGai Kohei <kaigai@ak.jp.nec.com>
Acked-by: Stephen Smalley <sds@tycho.nsa.gov>
Signed-off-by: James Morris <jmorris@namei.org>
2007-09-29 02:20:55 +09:00
int index_sens = context - > range . level [ l ] . sens ;
2010-11-29 15:47:09 -05:00
len + = strlen ( sym_name ( & policydb , SYM_LEVELS , index_sens - 1 ) ) ;
2005-04-16 15:20:36 -07:00
SELinux: improve performance when AVC misses.
* We add ebitmap_for_each_positive_bit() which enables to walk on
any positive bit on the given ebitmap, to improve its performance
using common bit-operations defined in linux/bitops.h.
In the previous version, this logic was implemented using a combination
of ebitmap_for_each_bit() and ebitmap_node_get_bit(), but is was worse
in performance aspect.
This logic is most frequestly used to compute a new AVC entry,
so this patch can improve SELinux performance when AVC misses are happen.
* struct ebitmap_node is redefined as an array of "unsigned long", to get
suitable for using find_next_bit() which is fasted than iteration of
shift and logical operation, and to maximize memory usage allocated
from general purpose slab.
* Any ebitmap_for_each_bit() are repleced by the new implementation
in ss/service.c and ss/mls.c. Some of related implementation are
changed, however, there is no incompatibility with the previous
version.
* The width of any new line are less or equal than 80-chars.
The following benchmark shows the effect of this patch, when we
access many files which have different security context one after
another. The number is more than /selinux/avc/cache_threshold, so
any access always causes AVC misses.
selinux-2.6 selinux-2.6-ebitmap
AVG: 22.763 [s] 8.750 [s]
STD: 0.265 0.019
------------------------------------------
1st: 22.558 [s] 8.786 [s]
2nd: 22.458 [s] 8.750 [s]
3rd: 22.478 [s] 8.754 [s]
4th: 22.724 [s] 8.745 [s]
5th: 22.918 [s] 8.748 [s]
6th: 22.905 [s] 8.764 [s]
7th: 23.238 [s] 8.726 [s]
8th: 22.822 [s] 8.729 [s]
Signed-off-by: KaiGai Kohei <kaigai@ak.jp.nec.com>
Acked-by: Stephen Smalley <sds@tycho.nsa.gov>
Signed-off-by: James Morris <jmorris@namei.org>
2007-09-29 02:20:55 +09:00
/* categories */
head = - 2 ;
prev = - 2 ;
e = & context - > range . level [ l ] . cat ;
ebitmap_for_each_positive_bit ( e , node , i ) {
if ( i - prev > 1 ) {
/* one or more negative bits are skipped */
if ( head ! = prev ) {
2010-11-29 15:47:09 -05:00
nm = sym_name ( & policydb , SYM_CATS , prev ) ;
SELinux: improve performance when AVC misses.
* We add ebitmap_for_each_positive_bit() which enables to walk on
any positive bit on the given ebitmap, to improve its performance
using common bit-operations defined in linux/bitops.h.
In the previous version, this logic was implemented using a combination
of ebitmap_for_each_bit() and ebitmap_node_get_bit(), but is was worse
in performance aspect.
This logic is most frequestly used to compute a new AVC entry,
so this patch can improve SELinux performance when AVC misses are happen.
* struct ebitmap_node is redefined as an array of "unsigned long", to get
suitable for using find_next_bit() which is fasted than iteration of
shift and logical operation, and to maximize memory usage allocated
from general purpose slab.
* Any ebitmap_for_each_bit() are repleced by the new implementation
in ss/service.c and ss/mls.c. Some of related implementation are
changed, however, there is no incompatibility with the previous
version.
* The width of any new line are less or equal than 80-chars.
The following benchmark shows the effect of this patch, when we
access many files which have different security context one after
another. The number is more than /selinux/avc/cache_threshold, so
any access always causes AVC misses.
selinux-2.6 selinux-2.6-ebitmap
AVG: 22.763 [s] 8.750 [s]
STD: 0.265 0.019
------------------------------------------
1st: 22.558 [s] 8.786 [s]
2nd: 22.458 [s] 8.750 [s]
3rd: 22.478 [s] 8.754 [s]
4th: 22.724 [s] 8.745 [s]
5th: 22.918 [s] 8.748 [s]
6th: 22.905 [s] 8.764 [s]
7th: 23.238 [s] 8.726 [s]
8th: 22.822 [s] 8.729 [s]
Signed-off-by: KaiGai Kohei <kaigai@ak.jp.nec.com>
Acked-by: Stephen Smalley <sds@tycho.nsa.gov>
Signed-off-by: James Morris <jmorris@namei.org>
2007-09-29 02:20:55 +09:00
len + = strlen ( nm ) + 1 ;
}
2010-11-29 15:47:09 -05:00
nm = sym_name ( & policydb , SYM_CATS , i ) ;
SELinux: improve performance when AVC misses.
* We add ebitmap_for_each_positive_bit() which enables to walk on
any positive bit on the given ebitmap, to improve its performance
using common bit-operations defined in linux/bitops.h.
In the previous version, this logic was implemented using a combination
of ebitmap_for_each_bit() and ebitmap_node_get_bit(), but is was worse
in performance aspect.
This logic is most frequestly used to compute a new AVC entry,
so this patch can improve SELinux performance when AVC misses are happen.
* struct ebitmap_node is redefined as an array of "unsigned long", to get
suitable for using find_next_bit() which is fasted than iteration of
shift and logical operation, and to maximize memory usage allocated
from general purpose slab.
* Any ebitmap_for_each_bit() are repleced by the new implementation
in ss/service.c and ss/mls.c. Some of related implementation are
changed, however, there is no incompatibility with the previous
version.
* The width of any new line are less or equal than 80-chars.
The following benchmark shows the effect of this patch, when we
access many files which have different security context one after
another. The number is more than /selinux/avc/cache_threshold, so
any access always causes AVC misses.
selinux-2.6 selinux-2.6-ebitmap
AVG: 22.763 [s] 8.750 [s]
STD: 0.265 0.019
------------------------------------------
1st: 22.558 [s] 8.786 [s]
2nd: 22.458 [s] 8.750 [s]
3rd: 22.478 [s] 8.754 [s]
4th: 22.724 [s] 8.745 [s]
5th: 22.918 [s] 8.748 [s]
6th: 22.905 [s] 8.764 [s]
7th: 23.238 [s] 8.726 [s]
8th: 22.822 [s] 8.729 [s]
Signed-off-by: KaiGai Kohei <kaigai@ak.jp.nec.com>
Acked-by: Stephen Smalley <sds@tycho.nsa.gov>
Signed-off-by: James Morris <jmorris@namei.org>
2007-09-29 02:20:55 +09:00
len + = strlen ( nm ) + 1 ;
head = i ;
2005-04-16 15:20:36 -07:00
}
SELinux: improve performance when AVC misses.
* We add ebitmap_for_each_positive_bit() which enables to walk on
any positive bit on the given ebitmap, to improve its performance
using common bit-operations defined in linux/bitops.h.
In the previous version, this logic was implemented using a combination
of ebitmap_for_each_bit() and ebitmap_node_get_bit(), but is was worse
in performance aspect.
This logic is most frequestly used to compute a new AVC entry,
so this patch can improve SELinux performance when AVC misses are happen.
* struct ebitmap_node is redefined as an array of "unsigned long", to get
suitable for using find_next_bit() which is fasted than iteration of
shift and logical operation, and to maximize memory usage allocated
from general purpose slab.
* Any ebitmap_for_each_bit() are repleced by the new implementation
in ss/service.c and ss/mls.c. Some of related implementation are
changed, however, there is no incompatibility with the previous
version.
* The width of any new line are less or equal than 80-chars.
The following benchmark shows the effect of this patch, when we
access many files which have different security context one after
another. The number is more than /selinux/avc/cache_threshold, so
any access always causes AVC misses.
selinux-2.6 selinux-2.6-ebitmap
AVG: 22.763 [s] 8.750 [s]
STD: 0.265 0.019
------------------------------------------
1st: 22.558 [s] 8.786 [s]
2nd: 22.458 [s] 8.750 [s]
3rd: 22.478 [s] 8.754 [s]
4th: 22.724 [s] 8.745 [s]
5th: 22.918 [s] 8.748 [s]
6th: 22.905 [s] 8.764 [s]
7th: 23.238 [s] 8.726 [s]
8th: 22.822 [s] 8.729 [s]
Signed-off-by: KaiGai Kohei <kaigai@ak.jp.nec.com>
Acked-by: Stephen Smalley <sds@tycho.nsa.gov>
Signed-off-by: James Morris <jmorris@namei.org>
2007-09-29 02:20:55 +09:00
prev = i ;
}
if ( prev ! = head ) {
2010-11-29 15:47:09 -05:00
nm = sym_name ( & policydb , SYM_CATS , prev ) ;
SELinux: improve performance when AVC misses.
* We add ebitmap_for_each_positive_bit() which enables to walk on
any positive bit on the given ebitmap, to improve its performance
using common bit-operations defined in linux/bitops.h.
In the previous version, this logic was implemented using a combination
of ebitmap_for_each_bit() and ebitmap_node_get_bit(), but is was worse
in performance aspect.
This logic is most frequestly used to compute a new AVC entry,
so this patch can improve SELinux performance when AVC misses are happen.
* struct ebitmap_node is redefined as an array of "unsigned long", to get
suitable for using find_next_bit() which is fasted than iteration of
shift and logical operation, and to maximize memory usage allocated
from general purpose slab.
* Any ebitmap_for_each_bit() are repleced by the new implementation
in ss/service.c and ss/mls.c. Some of related implementation are
changed, however, there is no incompatibility with the previous
version.
* The width of any new line are less or equal than 80-chars.
The following benchmark shows the effect of this patch, when we
access many files which have different security context one after
another. The number is more than /selinux/avc/cache_threshold, so
any access always causes AVC misses.
selinux-2.6 selinux-2.6-ebitmap
AVG: 22.763 [s] 8.750 [s]
STD: 0.265 0.019
------------------------------------------
1st: 22.558 [s] 8.786 [s]
2nd: 22.458 [s] 8.750 [s]
3rd: 22.478 [s] 8.754 [s]
4th: 22.724 [s] 8.745 [s]
5th: 22.918 [s] 8.748 [s]
6th: 22.905 [s] 8.764 [s]
7th: 23.238 [s] 8.726 [s]
8th: 22.822 [s] 8.729 [s]
Signed-off-by: KaiGai Kohei <kaigai@ak.jp.nec.com>
Acked-by: Stephen Smalley <sds@tycho.nsa.gov>
Signed-off-by: James Morris <jmorris@namei.org>
2007-09-29 02:20:55 +09:00
len + = strlen ( nm ) + 1 ;
2005-04-16 15:20:36 -07:00
}
if ( l = = 0 ) {
if ( mls_level_eq ( & context - > range . level [ 0 ] ,
SELinux: improve performance when AVC misses.
* We add ebitmap_for_each_positive_bit() which enables to walk on
any positive bit on the given ebitmap, to improve its performance
using common bit-operations defined in linux/bitops.h.
In the previous version, this logic was implemented using a combination
of ebitmap_for_each_bit() and ebitmap_node_get_bit(), but is was worse
in performance aspect.
This logic is most frequestly used to compute a new AVC entry,
so this patch can improve SELinux performance when AVC misses are happen.
* struct ebitmap_node is redefined as an array of "unsigned long", to get
suitable for using find_next_bit() which is fasted than iteration of
shift and logical operation, and to maximize memory usage allocated
from general purpose slab.
* Any ebitmap_for_each_bit() are repleced by the new implementation
in ss/service.c and ss/mls.c. Some of related implementation are
changed, however, there is no incompatibility with the previous
version.
* The width of any new line are less or equal than 80-chars.
The following benchmark shows the effect of this patch, when we
access many files which have different security context one after
another. The number is more than /selinux/avc/cache_threshold, so
any access always causes AVC misses.
selinux-2.6 selinux-2.6-ebitmap
AVG: 22.763 [s] 8.750 [s]
STD: 0.265 0.019
------------------------------------------
1st: 22.558 [s] 8.786 [s]
2nd: 22.458 [s] 8.750 [s]
3rd: 22.478 [s] 8.754 [s]
4th: 22.724 [s] 8.745 [s]
5th: 22.918 [s] 8.748 [s]
6th: 22.905 [s] 8.764 [s]
7th: 23.238 [s] 8.726 [s]
8th: 22.822 [s] 8.729 [s]
Signed-off-by: KaiGai Kohei <kaigai@ak.jp.nec.com>
Acked-by: Stephen Smalley <sds@tycho.nsa.gov>
Signed-off-by: James Morris <jmorris@namei.org>
2007-09-29 02:20:55 +09:00
& context - > range . level [ 1 ] ) )
2005-04-16 15:20:36 -07:00
break ;
else
len + + ;
}
}
return len ;
}
/*
* Write the security context string representation of
* the MLS fields of ` context ' into the string ` * scontext ' .
* Update ` * scontext ' to point to the end of the MLS fields .
*/
void mls_sid_to_context ( struct context * context ,
2008-04-18 17:38:32 -04:00
char * * scontext )
2005-04-16 15:20:36 -07:00
{
SELinux: improve performance when AVC misses.
* We add ebitmap_for_each_positive_bit() which enables to walk on
any positive bit on the given ebitmap, to improve its performance
using common bit-operations defined in linux/bitops.h.
In the previous version, this logic was implemented using a combination
of ebitmap_for_each_bit() and ebitmap_node_get_bit(), but is was worse
in performance aspect.
This logic is most frequestly used to compute a new AVC entry,
so this patch can improve SELinux performance when AVC misses are happen.
* struct ebitmap_node is redefined as an array of "unsigned long", to get
suitable for using find_next_bit() which is fasted than iteration of
shift and logical operation, and to maximize memory usage allocated
from general purpose slab.
* Any ebitmap_for_each_bit() are repleced by the new implementation
in ss/service.c and ss/mls.c. Some of related implementation are
changed, however, there is no incompatibility with the previous
version.
* The width of any new line are less or equal than 80-chars.
The following benchmark shows the effect of this patch, when we
access many files which have different security context one after
another. The number is more than /selinux/avc/cache_threshold, so
any access always causes AVC misses.
selinux-2.6 selinux-2.6-ebitmap
AVG: 22.763 [s] 8.750 [s]
STD: 0.265 0.019
------------------------------------------
1st: 22.558 [s] 8.786 [s]
2nd: 22.458 [s] 8.750 [s]
3rd: 22.478 [s] 8.754 [s]
4th: 22.724 [s] 8.745 [s]
5th: 22.918 [s] 8.748 [s]
6th: 22.905 [s] 8.764 [s]
7th: 23.238 [s] 8.726 [s]
8th: 22.822 [s] 8.729 [s]
Signed-off-by: KaiGai Kohei <kaigai@ak.jp.nec.com>
Acked-by: Stephen Smalley <sds@tycho.nsa.gov>
Signed-off-by: James Morris <jmorris@namei.org>
2007-09-29 02:20:55 +09:00
char * scontextp , * nm ;
int i , l , head , prev ;
struct ebitmap * e ;
2005-09-03 15:55:16 -07:00
struct ebitmap_node * node ;
2005-04-16 15:20:36 -07:00
2010-02-03 16:40:20 +01:00
if ( ! policydb . mls_enabled )
2005-04-16 15:20:36 -07:00
return ;
scontextp = * scontext ;
* scontextp = ' : ' ;
scontextp + + ;
for ( l = 0 ; l < 2 ; l + + ) {
2010-11-29 15:47:09 -05:00
strcpy ( scontextp , sym_name ( & policydb , SYM_LEVELS ,
context - > range . level [ l ] . sens - 1 ) ) ;
SELinux: improve performance when AVC misses.
* We add ebitmap_for_each_positive_bit() which enables to walk on
any positive bit on the given ebitmap, to improve its performance
using common bit-operations defined in linux/bitops.h.
In the previous version, this logic was implemented using a combination
of ebitmap_for_each_bit() and ebitmap_node_get_bit(), but is was worse
in performance aspect.
This logic is most frequestly used to compute a new AVC entry,
so this patch can improve SELinux performance when AVC misses are happen.
* struct ebitmap_node is redefined as an array of "unsigned long", to get
suitable for using find_next_bit() which is fasted than iteration of
shift and logical operation, and to maximize memory usage allocated
from general purpose slab.
* Any ebitmap_for_each_bit() are repleced by the new implementation
in ss/service.c and ss/mls.c. Some of related implementation are
changed, however, there is no incompatibility with the previous
version.
* The width of any new line are less or equal than 80-chars.
The following benchmark shows the effect of this patch, when we
access many files which have different security context one after
another. The number is more than /selinux/avc/cache_threshold, so
any access always causes AVC misses.
selinux-2.6 selinux-2.6-ebitmap
AVG: 22.763 [s] 8.750 [s]
STD: 0.265 0.019
------------------------------------------
1st: 22.558 [s] 8.786 [s]
2nd: 22.458 [s] 8.750 [s]
3rd: 22.478 [s] 8.754 [s]
4th: 22.724 [s] 8.745 [s]
5th: 22.918 [s] 8.748 [s]
6th: 22.905 [s] 8.764 [s]
7th: 23.238 [s] 8.726 [s]
8th: 22.822 [s] 8.729 [s]
Signed-off-by: KaiGai Kohei <kaigai@ak.jp.nec.com>
Acked-by: Stephen Smalley <sds@tycho.nsa.gov>
Signed-off-by: James Morris <jmorris@namei.org>
2007-09-29 02:20:55 +09:00
scontextp + = strlen ( scontextp ) ;
2005-04-16 15:20:36 -07:00
/* categories */
SELinux: improve performance when AVC misses.
* We add ebitmap_for_each_positive_bit() which enables to walk on
any positive bit on the given ebitmap, to improve its performance
using common bit-operations defined in linux/bitops.h.
In the previous version, this logic was implemented using a combination
of ebitmap_for_each_bit() and ebitmap_node_get_bit(), but is was worse
in performance aspect.
This logic is most frequestly used to compute a new AVC entry,
so this patch can improve SELinux performance when AVC misses are happen.
* struct ebitmap_node is redefined as an array of "unsigned long", to get
suitable for using find_next_bit() which is fasted than iteration of
shift and logical operation, and to maximize memory usage allocated
from general purpose slab.
* Any ebitmap_for_each_bit() are repleced by the new implementation
in ss/service.c and ss/mls.c. Some of related implementation are
changed, however, there is no incompatibility with the previous
version.
* The width of any new line are less or equal than 80-chars.
The following benchmark shows the effect of this patch, when we
access many files which have different security context one after
another. The number is more than /selinux/avc/cache_threshold, so
any access always causes AVC misses.
selinux-2.6 selinux-2.6-ebitmap
AVG: 22.763 [s] 8.750 [s]
STD: 0.265 0.019
------------------------------------------
1st: 22.558 [s] 8.786 [s]
2nd: 22.458 [s] 8.750 [s]
3rd: 22.478 [s] 8.754 [s]
4th: 22.724 [s] 8.745 [s]
5th: 22.918 [s] 8.748 [s]
6th: 22.905 [s] 8.764 [s]
7th: 23.238 [s] 8.726 [s]
8th: 22.822 [s] 8.729 [s]
Signed-off-by: KaiGai Kohei <kaigai@ak.jp.nec.com>
Acked-by: Stephen Smalley <sds@tycho.nsa.gov>
Signed-off-by: James Morris <jmorris@namei.org>
2007-09-29 02:20:55 +09:00
head = - 2 ;
prev = - 2 ;
e = & context - > range . level [ l ] . cat ;
ebitmap_for_each_positive_bit ( e , node , i ) {
if ( i - prev > 1 ) {
/* one or more negative bits are skipped */
if ( prev ! = head ) {
if ( prev - head > 1 )
2005-04-16 15:20:36 -07:00
* scontextp + + = ' . ' ;
else
* scontextp + + = ' , ' ;
2010-11-29 15:47:09 -05:00
nm = sym_name ( & policydb , SYM_CATS , prev ) ;
SELinux: improve performance when AVC misses.
* We add ebitmap_for_each_positive_bit() which enables to walk on
any positive bit on the given ebitmap, to improve its performance
using common bit-operations defined in linux/bitops.h.
In the previous version, this logic was implemented using a combination
of ebitmap_for_each_bit() and ebitmap_node_get_bit(), but is was worse
in performance aspect.
This logic is most frequestly used to compute a new AVC entry,
so this patch can improve SELinux performance when AVC misses are happen.
* struct ebitmap_node is redefined as an array of "unsigned long", to get
suitable for using find_next_bit() which is fasted than iteration of
shift and logical operation, and to maximize memory usage allocated
from general purpose slab.
* Any ebitmap_for_each_bit() are repleced by the new implementation
in ss/service.c and ss/mls.c. Some of related implementation are
changed, however, there is no incompatibility with the previous
version.
* The width of any new line are less or equal than 80-chars.
The following benchmark shows the effect of this patch, when we
access many files which have different security context one after
another. The number is more than /selinux/avc/cache_threshold, so
any access always causes AVC misses.
selinux-2.6 selinux-2.6-ebitmap
AVG: 22.763 [s] 8.750 [s]
STD: 0.265 0.019
------------------------------------------
1st: 22.558 [s] 8.786 [s]
2nd: 22.458 [s] 8.750 [s]
3rd: 22.478 [s] 8.754 [s]
4th: 22.724 [s] 8.745 [s]
5th: 22.918 [s] 8.748 [s]
6th: 22.905 [s] 8.764 [s]
7th: 23.238 [s] 8.726 [s]
8th: 22.822 [s] 8.729 [s]
Signed-off-by: KaiGai Kohei <kaigai@ak.jp.nec.com>
Acked-by: Stephen Smalley <sds@tycho.nsa.gov>
Signed-off-by: James Morris <jmorris@namei.org>
2007-09-29 02:20:55 +09:00
strcpy ( scontextp , nm ) ;
scontextp + = strlen ( nm ) ;
2005-04-16 15:20:36 -07:00
}
SELinux: improve performance when AVC misses.
* We add ebitmap_for_each_positive_bit() which enables to walk on
any positive bit on the given ebitmap, to improve its performance
using common bit-operations defined in linux/bitops.h.
In the previous version, this logic was implemented using a combination
of ebitmap_for_each_bit() and ebitmap_node_get_bit(), but is was worse
in performance aspect.
This logic is most frequestly used to compute a new AVC entry,
so this patch can improve SELinux performance when AVC misses are happen.
* struct ebitmap_node is redefined as an array of "unsigned long", to get
suitable for using find_next_bit() which is fasted than iteration of
shift and logical operation, and to maximize memory usage allocated
from general purpose slab.
* Any ebitmap_for_each_bit() are repleced by the new implementation
in ss/service.c and ss/mls.c. Some of related implementation are
changed, however, there is no incompatibility with the previous
version.
* The width of any new line are less or equal than 80-chars.
The following benchmark shows the effect of this patch, when we
access many files which have different security context one after
another. The number is more than /selinux/avc/cache_threshold, so
any access always causes AVC misses.
selinux-2.6 selinux-2.6-ebitmap
AVG: 22.763 [s] 8.750 [s]
STD: 0.265 0.019
------------------------------------------
1st: 22.558 [s] 8.786 [s]
2nd: 22.458 [s] 8.750 [s]
3rd: 22.478 [s] 8.754 [s]
4th: 22.724 [s] 8.745 [s]
5th: 22.918 [s] 8.748 [s]
6th: 22.905 [s] 8.764 [s]
7th: 23.238 [s] 8.726 [s]
8th: 22.822 [s] 8.729 [s]
Signed-off-by: KaiGai Kohei <kaigai@ak.jp.nec.com>
Acked-by: Stephen Smalley <sds@tycho.nsa.gov>
Signed-off-by: James Morris <jmorris@namei.org>
2007-09-29 02:20:55 +09:00
if ( prev < 0 )
* scontextp + + = ' : ' ;
else
* scontextp + + = ' , ' ;
2010-11-29 15:47:09 -05:00
nm = sym_name ( & policydb , SYM_CATS , i ) ;
SELinux: improve performance when AVC misses.
* We add ebitmap_for_each_positive_bit() which enables to walk on
any positive bit on the given ebitmap, to improve its performance
using common bit-operations defined in linux/bitops.h.
In the previous version, this logic was implemented using a combination
of ebitmap_for_each_bit() and ebitmap_node_get_bit(), but is was worse
in performance aspect.
This logic is most frequestly used to compute a new AVC entry,
so this patch can improve SELinux performance when AVC misses are happen.
* struct ebitmap_node is redefined as an array of "unsigned long", to get
suitable for using find_next_bit() which is fasted than iteration of
shift and logical operation, and to maximize memory usage allocated
from general purpose slab.
* Any ebitmap_for_each_bit() are repleced by the new implementation
in ss/service.c and ss/mls.c. Some of related implementation are
changed, however, there is no incompatibility with the previous
version.
* The width of any new line are less or equal than 80-chars.
The following benchmark shows the effect of this patch, when we
access many files which have different security context one after
another. The number is more than /selinux/avc/cache_threshold, so
any access always causes AVC misses.
selinux-2.6 selinux-2.6-ebitmap
AVG: 22.763 [s] 8.750 [s]
STD: 0.265 0.019
------------------------------------------
1st: 22.558 [s] 8.786 [s]
2nd: 22.458 [s] 8.750 [s]
3rd: 22.478 [s] 8.754 [s]
4th: 22.724 [s] 8.745 [s]
5th: 22.918 [s] 8.748 [s]
6th: 22.905 [s] 8.764 [s]
7th: 23.238 [s] 8.726 [s]
8th: 22.822 [s] 8.729 [s]
Signed-off-by: KaiGai Kohei <kaigai@ak.jp.nec.com>
Acked-by: Stephen Smalley <sds@tycho.nsa.gov>
Signed-off-by: James Morris <jmorris@namei.org>
2007-09-29 02:20:55 +09:00
strcpy ( scontextp , nm ) ;
scontextp + = strlen ( nm ) ;
head = i ;
2005-04-16 15:20:36 -07:00
}
SELinux: improve performance when AVC misses.
* We add ebitmap_for_each_positive_bit() which enables to walk on
any positive bit on the given ebitmap, to improve its performance
using common bit-operations defined in linux/bitops.h.
In the previous version, this logic was implemented using a combination
of ebitmap_for_each_bit() and ebitmap_node_get_bit(), but is was worse
in performance aspect.
This logic is most frequestly used to compute a new AVC entry,
so this patch can improve SELinux performance when AVC misses are happen.
* struct ebitmap_node is redefined as an array of "unsigned long", to get
suitable for using find_next_bit() which is fasted than iteration of
shift and logical operation, and to maximize memory usage allocated
from general purpose slab.
* Any ebitmap_for_each_bit() are repleced by the new implementation
in ss/service.c and ss/mls.c. Some of related implementation are
changed, however, there is no incompatibility with the previous
version.
* The width of any new line are less or equal than 80-chars.
The following benchmark shows the effect of this patch, when we
access many files which have different security context one after
another. The number is more than /selinux/avc/cache_threshold, so
any access always causes AVC misses.
selinux-2.6 selinux-2.6-ebitmap
AVG: 22.763 [s] 8.750 [s]
STD: 0.265 0.019
------------------------------------------
1st: 22.558 [s] 8.786 [s]
2nd: 22.458 [s] 8.750 [s]
3rd: 22.478 [s] 8.754 [s]
4th: 22.724 [s] 8.745 [s]
5th: 22.918 [s] 8.748 [s]
6th: 22.905 [s] 8.764 [s]
7th: 23.238 [s] 8.726 [s]
8th: 22.822 [s] 8.729 [s]
Signed-off-by: KaiGai Kohei <kaigai@ak.jp.nec.com>
Acked-by: Stephen Smalley <sds@tycho.nsa.gov>
Signed-off-by: James Morris <jmorris@namei.org>
2007-09-29 02:20:55 +09:00
prev = i ;
2005-04-16 15:20:36 -07:00
}
SELinux: improve performance when AVC misses.
* We add ebitmap_for_each_positive_bit() which enables to walk on
any positive bit on the given ebitmap, to improve its performance
using common bit-operations defined in linux/bitops.h.
In the previous version, this logic was implemented using a combination
of ebitmap_for_each_bit() and ebitmap_node_get_bit(), but is was worse
in performance aspect.
This logic is most frequestly used to compute a new AVC entry,
so this patch can improve SELinux performance when AVC misses are happen.
* struct ebitmap_node is redefined as an array of "unsigned long", to get
suitable for using find_next_bit() which is fasted than iteration of
shift and logical operation, and to maximize memory usage allocated
from general purpose slab.
* Any ebitmap_for_each_bit() are repleced by the new implementation
in ss/service.c and ss/mls.c. Some of related implementation are
changed, however, there is no incompatibility with the previous
version.
* The width of any new line are less or equal than 80-chars.
The following benchmark shows the effect of this patch, when we
access many files which have different security context one after
another. The number is more than /selinux/avc/cache_threshold, so
any access always causes AVC misses.
selinux-2.6 selinux-2.6-ebitmap
AVG: 22.763 [s] 8.750 [s]
STD: 0.265 0.019
------------------------------------------
1st: 22.558 [s] 8.786 [s]
2nd: 22.458 [s] 8.750 [s]
3rd: 22.478 [s] 8.754 [s]
4th: 22.724 [s] 8.745 [s]
5th: 22.918 [s] 8.748 [s]
6th: 22.905 [s] 8.764 [s]
7th: 23.238 [s] 8.726 [s]
8th: 22.822 [s] 8.729 [s]
Signed-off-by: KaiGai Kohei <kaigai@ak.jp.nec.com>
Acked-by: Stephen Smalley <sds@tycho.nsa.gov>
Signed-off-by: James Morris <jmorris@namei.org>
2007-09-29 02:20:55 +09:00
if ( prev ! = head ) {
if ( prev - head > 1 )
2005-04-16 15:20:36 -07:00
* scontextp + + = ' . ' ;
else
* scontextp + + = ' , ' ;
2010-11-29 15:47:09 -05:00
nm = sym_name ( & policydb , SYM_CATS , prev ) ;
SELinux: improve performance when AVC misses.
* We add ebitmap_for_each_positive_bit() which enables to walk on
any positive bit on the given ebitmap, to improve its performance
using common bit-operations defined in linux/bitops.h.
In the previous version, this logic was implemented using a combination
of ebitmap_for_each_bit() and ebitmap_node_get_bit(), but is was worse
in performance aspect.
This logic is most frequestly used to compute a new AVC entry,
so this patch can improve SELinux performance when AVC misses are happen.
* struct ebitmap_node is redefined as an array of "unsigned long", to get
suitable for using find_next_bit() which is fasted than iteration of
shift and logical operation, and to maximize memory usage allocated
from general purpose slab.
* Any ebitmap_for_each_bit() are repleced by the new implementation
in ss/service.c and ss/mls.c. Some of related implementation are
changed, however, there is no incompatibility with the previous
version.
* The width of any new line are less or equal than 80-chars.
The following benchmark shows the effect of this patch, when we
access many files which have different security context one after
another. The number is more than /selinux/avc/cache_threshold, so
any access always causes AVC misses.
selinux-2.6 selinux-2.6-ebitmap
AVG: 22.763 [s] 8.750 [s]
STD: 0.265 0.019
------------------------------------------
1st: 22.558 [s] 8.786 [s]
2nd: 22.458 [s] 8.750 [s]
3rd: 22.478 [s] 8.754 [s]
4th: 22.724 [s] 8.745 [s]
5th: 22.918 [s] 8.748 [s]
6th: 22.905 [s] 8.764 [s]
7th: 23.238 [s] 8.726 [s]
8th: 22.822 [s] 8.729 [s]
Signed-off-by: KaiGai Kohei <kaigai@ak.jp.nec.com>
Acked-by: Stephen Smalley <sds@tycho.nsa.gov>
Signed-off-by: James Morris <jmorris@namei.org>
2007-09-29 02:20:55 +09:00
strcpy ( scontextp , nm ) ;
scontextp + = strlen ( nm ) ;
2005-04-16 15:20:36 -07:00
}
if ( l = = 0 ) {
if ( mls_level_eq ( & context - > range . level [ 0 ] ,
2008-04-18 17:38:32 -04:00
& context - > range . level [ 1 ] ) )
2005-04-16 15:20:36 -07:00
break ;
SELinux: improve performance when AVC misses.
* We add ebitmap_for_each_positive_bit() which enables to walk on
any positive bit on the given ebitmap, to improve its performance
using common bit-operations defined in linux/bitops.h.
In the previous version, this logic was implemented using a combination
of ebitmap_for_each_bit() and ebitmap_node_get_bit(), but is was worse
in performance aspect.
This logic is most frequestly used to compute a new AVC entry,
so this patch can improve SELinux performance when AVC misses are happen.
* struct ebitmap_node is redefined as an array of "unsigned long", to get
suitable for using find_next_bit() which is fasted than iteration of
shift and logical operation, and to maximize memory usage allocated
from general purpose slab.
* Any ebitmap_for_each_bit() are repleced by the new implementation
in ss/service.c and ss/mls.c. Some of related implementation are
changed, however, there is no incompatibility with the previous
version.
* The width of any new line are less or equal than 80-chars.
The following benchmark shows the effect of this patch, when we
access many files which have different security context one after
another. The number is more than /selinux/avc/cache_threshold, so
any access always causes AVC misses.
selinux-2.6 selinux-2.6-ebitmap
AVG: 22.763 [s] 8.750 [s]
STD: 0.265 0.019
------------------------------------------
1st: 22.558 [s] 8.786 [s]
2nd: 22.458 [s] 8.750 [s]
3rd: 22.478 [s] 8.754 [s]
4th: 22.724 [s] 8.745 [s]
5th: 22.918 [s] 8.748 [s]
6th: 22.905 [s] 8.764 [s]
7th: 23.238 [s] 8.726 [s]
8th: 22.822 [s] 8.729 [s]
Signed-off-by: KaiGai Kohei <kaigai@ak.jp.nec.com>
Acked-by: Stephen Smalley <sds@tycho.nsa.gov>
Signed-off-by: James Morris <jmorris@namei.org>
2007-09-29 02:20:55 +09:00
else
* scontextp + + = ' - ' ;
2005-04-16 15:20:36 -07:00
}
}
* scontext = scontextp ;
return ;
}
2007-11-07 10:08:00 -05:00
int mls_level_isvalid ( struct policydb * p , struct mls_level * l )
{
struct level_datum * levdatum ;
if ( ! l - > sens | | l - > sens > p - > p_levels . nprim )
return 0 ;
levdatum = hashtab_search ( p - > p_levels . table ,
2010-11-29 15:47:09 -05:00
sym_name ( p , SYM_LEVELS , l - > sens - 1 ) ) ;
2007-11-07 10:08:00 -05:00
if ( ! levdatum )
return 0 ;
2013-07-23 17:38:41 -04:00
/*
* Return 1 iff all the bits set in l - > cat are also be set in
* levdatum - > level - > cat and no bit in l - > cat is larger than
* p - > p_cats . nprim .
*/
return ebitmap_contains ( & levdatum - > level - > cat , & l - > cat ,
p - > p_cats . nprim ) ;
2007-11-07 10:08:00 -05:00
}
int mls_range_isvalid ( struct policydb * p , struct mls_range * r )
{
return ( mls_level_isvalid ( p , & r - > level [ 0 ] ) & &
mls_level_isvalid ( p , & r - > level [ 1 ] ) & &
mls_level_dom ( & r - > level [ 1 ] , & r - > level [ 0 ] ) ) ;
}
2005-04-16 15:20:36 -07:00
/*
* Return 1 if the MLS fields in the security context
* structure ` c ' are valid . Return 0 otherwise .
*/
int mls_context_isvalid ( struct policydb * p , struct context * c )
{
struct user_datum * usrdatum ;
2010-02-03 16:40:20 +01:00
if ( ! p - > mls_enabled )
2005-04-16 15:20:36 -07:00
return 1 ;
2007-11-07 10:08:00 -05:00
if ( ! mls_range_isvalid ( p , & c - > range ) )
2005-04-16 15:20:36 -07:00
return 0 ;
if ( c - > role = = OBJECT_R_VAL )
return 1 ;
/*
* User must be authorized for the MLS range .
*/
if ( ! c - > user | | c - > user > p - > p_users . nprim )
return 0 ;
usrdatum = p - > user_val_to_struct [ c - > user - 1 ] ;
if ( ! mls_range_contains ( usrdatum - > range , c - > range ) )
return 0 ; /* user may not be associated with range */
return 1 ;
}
/*
* Set the MLS fields in the security context structure
* ` context ' based on the string representation in
* the string ` * scontext ' . Update ` * scontext ' to
* point to the end of the string representation of
* the MLS fields .
*
* This function modifies the string in place , inserting
* NULL characters to terminate the MLS fields .
2005-07-28 01:07:37 -07:00
*
* If a def_sid is provided and no MLS field is present ,
* copy the MLS field of the associated default context .
* Used for upgraded to MLS systems where objects may lack
* MLS fields .
*
* Policy read - lock must be held for sidtab lookup .
*
2005-04-16 15:20:36 -07:00
*/
2008-05-07 13:03:20 -04:00
int mls_context_to_sid ( struct policydb * pol ,
char oldc ,
2005-04-16 15:20:36 -07:00
char * * scontext ,
2005-07-28 01:07:37 -07:00
struct context * context ,
struct sidtab * s ,
u32 def_sid )
2005-04-16 15:20:36 -07:00
{
char delim ;
char * scontextp , * p , * rngptr ;
struct level_datum * levdatum ;
struct cat_datum * catdatum , * rngdatum ;
int l , rc = - EINVAL ;
2010-02-03 16:40:20 +01:00
if ( ! pol - > mls_enabled ) {
2005-11-08 21:34:32 -08:00
if ( def_sid ! = SECSID_NULL & & oldc )
2010-04-09 19:30:29 +08:00
* scontext + = strlen ( * scontext ) + 1 ;
2005-04-16 15:20:36 -07:00
return 0 ;
2005-11-08 21:34:32 -08:00
}
2005-04-16 15:20:36 -07:00
2005-07-28 01:07:37 -07:00
/*
* No MLS component to the security context , try and map to
* default if provided .
*/
if ( ! oldc ) {
struct context * defcon ;
if ( def_sid = = SECSID_NULL )
goto out ;
defcon = sidtab_search ( s , def_sid ) ;
if ( ! defcon )
goto out ;
2006-12-12 13:02:41 -06:00
rc = mls_context_cpy ( context , defcon ) ;
2005-04-16 15:20:36 -07:00
goto out ;
2005-07-28 01:07:37 -07:00
}
2005-04-16 15:20:36 -07:00
/* Extract low sensitivity. */
scontextp = p = * scontext ;
while ( * p & & * p ! = ' : ' & & * p ! = ' - ' )
p + + ;
delim = * p ;
2008-07-20 23:57:01 +03:00
if ( delim ! = ' \0 ' )
* p + + = ' \0 ' ;
2005-04-16 15:20:36 -07:00
for ( l = 0 ; l < 2 ; l + + ) {
2008-05-07 13:03:20 -04:00
levdatum = hashtab_search ( pol - > p_levels . table , scontextp ) ;
2005-04-16 15:20:36 -07:00
if ( ! levdatum ) {
rc = - EINVAL ;
goto out ;
}
context - > range . level [ l ] . sens = levdatum - > level - > sens ;
if ( delim = = ' : ' ) {
/* Extract category set. */
while ( 1 ) {
scontextp = p ;
while ( * p & & * p ! = ' , ' & & * p ! = ' - ' )
p + + ;
delim = * p ;
2008-07-20 23:57:01 +03:00
if ( delim ! = ' \0 ' )
* p + + = ' \0 ' ;
2005-04-16 15:20:36 -07:00
/* Separate into range if exists */
2008-04-18 17:38:32 -04:00
rngptr = strchr ( scontextp , ' . ' ) ;
if ( rngptr ! = NULL ) {
2005-04-16 15:20:36 -07:00
/* Remove '.' */
2008-07-20 23:57:01 +03:00
* rngptr + + = ' \0 ' ;
2005-04-16 15:20:36 -07:00
}
2008-05-07 13:03:20 -04:00
catdatum = hashtab_search ( pol - > p_cats . table ,
2008-04-18 17:38:32 -04:00
scontextp ) ;
2005-04-16 15:20:36 -07:00
if ( ! catdatum ) {
rc = - EINVAL ;
goto out ;
}
rc = ebitmap_set_bit ( & context - > range . level [ l ] . cat ,
2008-04-18 17:38:32 -04:00
catdatum - > value - 1 , 1 ) ;
2005-04-16 15:20:36 -07:00
if ( rc )
goto out ;
/* If range, set all categories in range */
if ( rngptr ) {
int i ;
2008-05-07 13:03:20 -04:00
rngdatum = hashtab_search ( pol - > p_cats . table , rngptr ) ;
2005-04-16 15:20:36 -07:00
if ( ! rngdatum ) {
rc = - EINVAL ;
goto out ;
}
if ( catdatum - > value > = rngdatum - > value ) {
rc = - EINVAL ;
goto out ;
}
for ( i = catdatum - > value ; i < rngdatum - > value ; i + + ) {
rc = ebitmap_set_bit ( & context - > range . level [ l ] . cat , i , 1 ) ;
if ( rc )
goto out ;
}
}
if ( delim ! = ' , ' )
break ;
}
}
if ( delim = = ' - ' ) {
/* Extract high sensitivity. */
scontextp = p ;
while ( * p & & * p ! = ' : ' )
p + + ;
delim = * p ;
2008-07-20 23:57:01 +03:00
if ( delim ! = ' \0 ' )
* p + + = ' \0 ' ;
2005-04-16 15:20:36 -07:00
} else
break ;
}
if ( l = = 0 ) {
context - > range . level [ 1 ] . sens = context - > range . level [ 0 ] . sens ;
rc = ebitmap_cpy ( & context - > range . level [ 1 ] . cat ,
& context - > range . level [ 0 ] . cat ) ;
if ( rc )
goto out ;
}
* scontext = + + p ;
rc = 0 ;
out :
return rc ;
}
2006-02-24 15:44:05 -06:00
/*
* Set the MLS fields in the security context structure
* ` context ' based on the string representation in
* the string ` str ' . This function will allocate temporary memory with the
* given constraints of gfp_mask .
*/
int mls_from_string ( char * str , struct context * context , gfp_t gfp_mask )
{
char * tmpstr , * freestr ;
int rc ;
2010-02-03 16:40:20 +01:00
if ( ! policydb . mls_enabled )
2006-02-24 15:44:05 -06:00
return - EINVAL ;
/* we need freestr because mls_context_to_sid will change
the value of tmpstr */
tmpstr = freestr = kstrdup ( str , gfp_mask ) ;
if ( ! tmpstr ) {
rc = - ENOMEM ;
} else {
2008-05-07 13:03:20 -04:00
rc = mls_context_to_sid ( & policydb , ' : ' , & tmpstr , context ,
2008-04-18 17:38:32 -04:00
NULL , SECSID_NULL ) ;
2006-02-24 15:44:05 -06:00
kfree ( freestr ) ;
}
return rc ;
}
2005-04-16 15:20:36 -07:00
/*
* Copies the MLS range ` range ' into ` context ' .
*/
2010-02-03 16:40:20 +01:00
int mls_range_set ( struct context * context ,
2008-04-18 17:38:32 -04:00
struct mls_range * range )
2005-04-16 15:20:36 -07:00
{
int l , rc = 0 ;
/* Copy the MLS range into the context */
for ( l = 0 ; l < 2 ; l + + ) {
context - > range . level [ l ] . sens = range - > level [ l ] . sens ;
rc = ebitmap_cpy ( & context - > range . level [ l ] . cat ,
& range - > level [ l ] . cat ) ;
if ( rc )
break ;
}
return rc ;
}
int mls_setup_user_range ( struct context * fromcon , struct user_datum * user ,
2008-04-18 17:38:32 -04:00
struct context * usercon )
2005-04-16 15:20:36 -07:00
{
2010-02-03 16:40:20 +01:00
if ( policydb . mls_enabled ) {
2005-04-16 15:20:36 -07:00
struct mls_level * fromcon_sen = & ( fromcon - > range . level [ 0 ] ) ;
struct mls_level * fromcon_clr = & ( fromcon - > range . level [ 1 ] ) ;
struct mls_level * user_low = & ( user - > range . level [ 0 ] ) ;
struct mls_level * user_clr = & ( user - > range . level [ 1 ] ) ;
struct mls_level * user_def = & ( user - > dfltlevel ) ;
struct mls_level * usercon_sen = & ( usercon - > range . level [ 0 ] ) ;
struct mls_level * usercon_clr = & ( usercon - > range . level [ 1 ] ) ;
/* Honor the user's default level if we can */
2008-05-14 11:27:45 -04:00
if ( mls_level_between ( user_def , fromcon_sen , fromcon_clr ) )
2005-04-16 15:20:36 -07:00
* usercon_sen = * user_def ;
2008-05-14 11:27:45 -04:00
else if ( mls_level_between ( fromcon_sen , user_def , user_clr ) )
2005-04-16 15:20:36 -07:00
* usercon_sen = * fromcon_sen ;
2008-05-14 11:27:45 -04:00
else if ( mls_level_between ( fromcon_clr , user_low , user_def ) )
2005-04-16 15:20:36 -07:00
* usercon_sen = * user_low ;
2008-05-14 11:27:45 -04:00
else
2005-04-16 15:20:36 -07:00
return - EINVAL ;
/* Lower the clearance of available contexts
if the clearance of " fromcon " is lower than
that of the user ' s default clearance ( but
only if the " fromcon " clearance dominates
the user ' s computed sensitivity level ) */
2008-04-18 17:38:32 -04:00
if ( mls_level_dom ( user_clr , fromcon_clr ) )
2005-04-16 15:20:36 -07:00
* usercon_clr = * fromcon_clr ;
2008-04-18 17:38:32 -04:00
else if ( mls_level_dom ( fromcon_clr , user_clr ) )
2005-04-16 15:20:36 -07:00
* usercon_clr = * user_clr ;
2008-04-18 17:38:32 -04:00
else
2005-04-16 15:20:36 -07:00
return - EINVAL ;
}
return 0 ;
}
/*
* Convert the MLS fields in the security context
* structure ` c ' from the values specified in the
* policy ` oldp ' to the values specified in the policy ` newp ' .
*/
int mls_convert_context ( struct policydb * oldp ,
struct policydb * newp ,
struct context * c )
{
struct level_datum * levdatum ;
struct cat_datum * catdatum ;
struct ebitmap bitmap ;
2005-09-03 15:55:16 -07:00
struct ebitmap_node * node ;
2005-04-16 15:20:36 -07:00
int l , i ;
2010-02-03 16:40:20 +01:00
if ( ! policydb . mls_enabled )
2005-04-16 15:20:36 -07:00
return 0 ;
for ( l = 0 ; l < 2 ; l + + ) {
levdatum = hashtab_search ( newp - > p_levels . table ,
2010-11-29 15:47:09 -05:00
sym_name ( oldp , SYM_LEVELS ,
c - > range . level [ l ] . sens - 1 ) ) ;
2005-04-16 15:20:36 -07:00
if ( ! levdatum )
return - EINVAL ;
c - > range . level [ l ] . sens = levdatum - > level - > sens ;
ebitmap_init ( & bitmap ) ;
SELinux: improve performance when AVC misses.
* We add ebitmap_for_each_positive_bit() which enables to walk on
any positive bit on the given ebitmap, to improve its performance
using common bit-operations defined in linux/bitops.h.
In the previous version, this logic was implemented using a combination
of ebitmap_for_each_bit() and ebitmap_node_get_bit(), but is was worse
in performance aspect.
This logic is most frequestly used to compute a new AVC entry,
so this patch can improve SELinux performance when AVC misses are happen.
* struct ebitmap_node is redefined as an array of "unsigned long", to get
suitable for using find_next_bit() which is fasted than iteration of
shift and logical operation, and to maximize memory usage allocated
from general purpose slab.
* Any ebitmap_for_each_bit() are repleced by the new implementation
in ss/service.c and ss/mls.c. Some of related implementation are
changed, however, there is no incompatibility with the previous
version.
* The width of any new line are less or equal than 80-chars.
The following benchmark shows the effect of this patch, when we
access many files which have different security context one after
another. The number is more than /selinux/avc/cache_threshold, so
any access always causes AVC misses.
selinux-2.6 selinux-2.6-ebitmap
AVG: 22.763 [s] 8.750 [s]
STD: 0.265 0.019
------------------------------------------
1st: 22.558 [s] 8.786 [s]
2nd: 22.458 [s] 8.750 [s]
3rd: 22.478 [s] 8.754 [s]
4th: 22.724 [s] 8.745 [s]
5th: 22.918 [s] 8.748 [s]
6th: 22.905 [s] 8.764 [s]
7th: 23.238 [s] 8.726 [s]
8th: 22.822 [s] 8.729 [s]
Signed-off-by: KaiGai Kohei <kaigai@ak.jp.nec.com>
Acked-by: Stephen Smalley <sds@tycho.nsa.gov>
Signed-off-by: James Morris <jmorris@namei.org>
2007-09-29 02:20:55 +09:00
ebitmap_for_each_positive_bit ( & c - > range . level [ l ] . cat , node , i ) {
int rc ;
catdatum = hashtab_search ( newp - > p_cats . table ,
2010-11-29 15:47:09 -05:00
sym_name ( oldp , SYM_CATS , i ) ) ;
SELinux: improve performance when AVC misses.
* We add ebitmap_for_each_positive_bit() which enables to walk on
any positive bit on the given ebitmap, to improve its performance
using common bit-operations defined in linux/bitops.h.
In the previous version, this logic was implemented using a combination
of ebitmap_for_each_bit() and ebitmap_node_get_bit(), but is was worse
in performance aspect.
This logic is most frequestly used to compute a new AVC entry,
so this patch can improve SELinux performance when AVC misses are happen.
* struct ebitmap_node is redefined as an array of "unsigned long", to get
suitable for using find_next_bit() which is fasted than iteration of
shift and logical operation, and to maximize memory usage allocated
from general purpose slab.
* Any ebitmap_for_each_bit() are repleced by the new implementation
in ss/service.c and ss/mls.c. Some of related implementation are
changed, however, there is no incompatibility with the previous
version.
* The width of any new line are less or equal than 80-chars.
The following benchmark shows the effect of this patch, when we
access many files which have different security context one after
another. The number is more than /selinux/avc/cache_threshold, so
any access always causes AVC misses.
selinux-2.6 selinux-2.6-ebitmap
AVG: 22.763 [s] 8.750 [s]
STD: 0.265 0.019
------------------------------------------
1st: 22.558 [s] 8.786 [s]
2nd: 22.458 [s] 8.750 [s]
3rd: 22.478 [s] 8.754 [s]
4th: 22.724 [s] 8.745 [s]
5th: 22.918 [s] 8.748 [s]
6th: 22.905 [s] 8.764 [s]
7th: 23.238 [s] 8.726 [s]
8th: 22.822 [s] 8.729 [s]
Signed-off-by: KaiGai Kohei <kaigai@ak.jp.nec.com>
Acked-by: Stephen Smalley <sds@tycho.nsa.gov>
Signed-off-by: James Morris <jmorris@namei.org>
2007-09-29 02:20:55 +09:00
if ( ! catdatum )
return - EINVAL ;
rc = ebitmap_set_bit ( & bitmap , catdatum - > value - 1 , 1 ) ;
if ( rc )
return rc ;
2014-05-15 15:02:53 -04:00
cond_resched ( ) ;
2005-04-16 15:20:36 -07:00
}
ebitmap_destroy ( & c - > range . level [ l ] . cat ) ;
c - > range . level [ l ] . cat = bitmap ;
}
return 0 ;
}
int mls_compute_sid ( struct context * scontext ,
struct context * tcontext ,
u16 tclass ,
u32 specified ,
2011-03-02 13:32:33 +08:00
struct context * newcontext ,
bool sock )
2005-04-16 15:20:36 -07:00
{
2010-01-07 15:55:16 -05:00
struct range_trans rtr ;
struct mls_range * r ;
2012-03-20 14:35:12 -04:00
struct class_datum * cladatum ;
int default_range = 0 ;
2006-09-25 23:31:59 -07:00
2010-02-03 16:40:20 +01:00
if ( ! policydb . mls_enabled )
2005-04-16 15:20:36 -07:00
return 0 ;
switch ( specified ) {
case AVTAB_TRANSITION :
2006-09-25 23:31:59 -07:00
/* Look for a range transition rule. */
2010-01-07 15:55:16 -05:00
rtr . source_type = scontext - > type ;
rtr . target_type = tcontext - > type ;
rtr . target_class = tclass ;
r = hashtab_search ( policydb . range_tr , & rtr ) ;
if ( r )
return mls_range_set ( newcontext , r ) ;
2012-03-20 14:35:12 -04:00
if ( tclass & & tclass < = policydb . p_classes . nprim ) {
cladatum = policydb . class_val_to_struct [ tclass - 1 ] ;
if ( cladatum )
default_range = cladatum - > default_range ;
}
switch ( default_range ) {
case DEFAULT_SOURCE_LOW :
return mls_context_cpy_low ( newcontext , scontext ) ;
case DEFAULT_SOURCE_HIGH :
return mls_context_cpy_high ( newcontext , scontext ) ;
case DEFAULT_SOURCE_LOW_HIGH :
return mls_context_cpy ( newcontext , scontext ) ;
case DEFAULT_TARGET_LOW :
return mls_context_cpy_low ( newcontext , tcontext ) ;
case DEFAULT_TARGET_HIGH :
return mls_context_cpy_high ( newcontext , tcontext ) ;
case DEFAULT_TARGET_LOW_HIGH :
return mls_context_cpy ( newcontext , tcontext ) ;
}
2005-04-16 15:20:36 -07:00
/* Fallthrough */
case AVTAB_CHANGE :
2011-03-02 13:32:33 +08:00
if ( ( tclass = = policydb . process_class ) | | ( sock = = true ) )
2005-04-16 15:20:36 -07:00
/* Use the process MLS attributes. */
2006-12-12 13:02:41 -06:00
return mls_context_cpy ( newcontext , scontext ) ;
2005-04-16 15:20:36 -07:00
else
/* Use the process effective MLS attributes. */
2006-12-12 13:02:41 -06:00
return mls_context_cpy_low ( newcontext , scontext ) ;
2005-04-16 15:20:36 -07:00
case AVTAB_MEMBER :
2008-01-24 15:30:52 -05:00
/* Use the process effective MLS attributes. */
return mls_context_cpy_low ( newcontext , scontext ) ;
2009-12-03 03:48:28 -05:00
/* fall through */
2005-04-16 15:20:36 -07:00
}
return - EINVAL ;
}
2006-11-29 13:18:18 -05:00
# ifdef CONFIG_NETLABEL
2006-08-04 23:17:57 -07:00
/**
2006-11-29 13:18:18 -05:00
* mls_export_netlbl_lvl - Export the MLS sensitivity levels to NetLabel
2006-08-04 23:17:57 -07:00
* @ context : the security context
2006-11-29 13:18:18 -05:00
* @ secattr : the NetLabel security attributes
2006-08-04 23:17:57 -07:00
*
* Description :
2006-11-29 13:18:18 -05:00
* Given the security context copy the low MLS sensitivity level into the
* NetLabel MLS sensitivity level field .
2006-08-04 23:17:57 -07:00
*
*/
2006-11-29 13:18:18 -05:00
void mls_export_netlbl_lvl ( struct context * context ,
struct netlbl_lsm_secattr * secattr )
2006-08-04 23:17:57 -07:00
{
2010-02-03 16:40:20 +01:00
if ( ! policydb . mls_enabled )
2006-08-04 23:17:57 -07:00
return ;
2008-01-29 08:37:59 -05:00
secattr - > attr . mls . lvl = context - > range . level [ 0 ] . sens - 1 ;
2006-11-29 13:18:18 -05:00
secattr - > flags | = NETLBL_SECATTR_MLS_LVL ;
2006-08-04 23:17:57 -07:00
}
/**
2006-11-29 13:18:18 -05:00
* mls_import_netlbl_lvl - Import the NetLabel MLS sensitivity levels
2006-08-04 23:17:57 -07:00
* @ context : the security context
2006-11-29 13:18:18 -05:00
* @ secattr : the NetLabel security attributes
2006-08-04 23:17:57 -07:00
*
* Description :
2006-11-29 13:18:18 -05:00
* Given the security context and the NetLabel security attributes , copy the
* NetLabel MLS sensitivity level into the context .
2006-08-04 23:17:57 -07:00
*
*/
2006-11-29 13:18:18 -05:00
void mls_import_netlbl_lvl ( struct context * context ,
struct netlbl_lsm_secattr * secattr )
2006-08-04 23:17:57 -07:00
{
2010-02-03 16:40:20 +01:00
if ( ! policydb . mls_enabled )
2006-08-04 23:17:57 -07:00
return ;
2008-01-29 08:37:59 -05:00
context - > range . level [ 0 ] . sens = secattr - > attr . mls . lvl + 1 ;
2006-11-29 13:18:18 -05:00
context - > range . level [ 1 ] . sens = context - > range . level [ 0 ] . sens ;
2006-08-04 23:17:57 -07:00
}
/**
2006-11-29 13:18:18 -05:00
* mls_export_netlbl_cat - Export the MLS categories to NetLabel
2006-08-04 23:17:57 -07:00
* @ context : the security context
2006-11-29 13:18:18 -05:00
* @ secattr : the NetLabel security attributes
2006-08-04 23:17:57 -07:00
*
* Description :
2006-11-29 13:18:18 -05:00
* Given the security context copy the low MLS categories into the NetLabel
* MLS category field . Returns zero on success , negative values on failure .
2006-08-04 23:17:57 -07:00
*
*/
2006-11-29 13:18:18 -05:00
int mls_export_netlbl_cat ( struct context * context ,
struct netlbl_lsm_secattr * secattr )
2006-08-04 23:17:57 -07:00
{
2006-11-29 13:18:18 -05:00
int rc ;
2006-08-04 23:17:57 -07:00
2010-02-03 16:40:20 +01:00
if ( ! policydb . mls_enabled )
2006-08-04 23:17:57 -07:00
return 0 ;
2006-11-29 13:18:18 -05:00
rc = ebitmap_netlbl_export ( & context - > range . level [ 0 ] . cat ,
2008-01-29 08:37:59 -05:00
& secattr - > attr . mls . cat ) ;
if ( rc = = 0 & & secattr - > attr . mls . cat ! = NULL )
2006-11-29 13:18:18 -05:00
secattr - > flags | = NETLBL_SECATTR_MLS_CAT ;
2006-08-04 23:17:57 -07:00
return rc ;
}
/**
2006-11-29 13:18:18 -05:00
* mls_import_netlbl_cat - Import the MLS categories from NetLabel
2006-08-04 23:17:57 -07:00
* @ context : the security context
2006-11-29 13:18:18 -05:00
* @ secattr : the NetLabel security attributes
2006-08-04 23:17:57 -07:00
*
* Description :
2006-11-29 13:18:18 -05:00
* Copy the NetLabel security attributes into the SELinux context ; since the
* NetLabel security attribute only contains a single MLS category use it for
* both the low and high categories of the context . Returns zero on success ,
* negative values on failure .
2006-08-04 23:17:57 -07:00
*
*/
2006-11-29 13:18:18 -05:00
int mls_import_netlbl_cat ( struct context * context ,
struct netlbl_lsm_secattr * secattr )
2006-08-04 23:17:57 -07:00
{
2006-11-29 13:18:18 -05:00
int rc ;
2006-08-04 23:17:57 -07:00
2010-02-03 16:40:20 +01:00
if ( ! policydb . mls_enabled )
2006-08-04 23:17:57 -07:00
return 0 ;
2006-11-29 13:18:18 -05:00
rc = ebitmap_netlbl_import ( & context - > range . level [ 0 ] . cat ,
2008-01-29 08:37:59 -05:00
secattr - > attr . mls . cat ) ;
2015-02-17 15:30:23 -05:00
if ( rc )
2006-11-29 13:18:18 -05:00
goto import_netlbl_cat_failure ;
2015-02-17 15:30:23 -05:00
memcpy ( & context - > range . level [ 1 ] . cat , & context - > range . level [ 0 ] . cat ,
sizeof ( context - > range . level [ 0 ] . cat ) ) ;
2006-08-04 23:17:57 -07:00
return 0 ;
2006-11-29 13:18:18 -05:00
import_netlbl_cat_failure :
2006-08-04 23:17:57 -07:00
ebitmap_destroy ( & context - > range . level [ 0 ] . cat ) ;
return rc ;
}
2006-11-29 13:18:18 -05:00
# endif /* CONFIG_NETLABEL */