Skip to content

Commit

Permalink
NetLabel: Add secid token support to the NetLabel secattr struct
Browse files Browse the repository at this point in the history
This patch adds support to the NetLabel LSM secattr struct for a secid token
and a type field, paving the way for full LSM/SELinux context support and
"static" or "fallback" labels.  In addition, this patch adds a fair amount
of documentation to the core NetLabel structures used as part of the
NetLabel kernel API.

Signed-off-by: Paul Moore <[email protected]>
Signed-off-by: James Morris <[email protected]>
  • Loading branch information
pcmoore authored and James Morris committed Jan 29, 2008
1 parent 1c3fad9 commit 16efd45
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 46 deletions.
91 changes: 73 additions & 18 deletions include/net/netlabel.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,17 +105,49 @@ struct netlbl_dom_map;
/* Domain mapping operations */
int netlbl_domhsh_remove(const char *domain, struct netlbl_audit *audit_info);

/* LSM security attributes */
/*
* LSM security attributes
*/

/**
* struct netlbl_lsm_cache - NetLabel LSM security attribute cache
* @refcount: atomic reference counter
* @free: LSM supplied function to free the cache data
* @data: LSM supplied cache data
*
* Description:
* This structure is provided for LSMs which wish to make use of the NetLabel
* caching mechanism to store LSM specific data/attributes in the NetLabel
* cache. If the LSM has to perform a lot of translation from the NetLabel
* security attributes into it's own internal representation then the cache
* mechanism can provide a way to eliminate some or all of that translation
* overhead on a cache hit.
*
*/
struct netlbl_lsm_cache {
atomic_t refcount;
void (*free) (const void *data);
void *data;
};
/* The catmap bitmap field MUST be a power of two in length and large

/**
* struct netlbl_lsm_secattr_catmap - NetLabel LSM secattr category bitmap
* @startbit: the value of the lowest order bit in the bitmap
* @bitmap: the category bitmap
* @next: pointer to the next bitmap "node" or NULL
*
* Description:
* This structure is used to represent category bitmaps. Due to the large
* number of categories supported by most labeling protocols it is not
* practical to transfer a full bitmap internally so NetLabel adopts a sparse
* bitmap structure modeled after SELinux's ebitmap structure.
* The catmap bitmap field MUST be a power of two in length and large
* enough to hold at least 240 bits. Special care (i.e. check the code!)
* should be used when changing these values as the LSM implementation
* probably has functions which rely on the sizes of these types to speed
* processing. */
* processing.
*
*/
#define NETLBL_CATMAP_MAPTYPE u64
#define NETLBL_CATMAP_MAPCNT 4
#define NETLBL_CATMAP_MAPSIZE (sizeof(NETLBL_CATMAP_MAPTYPE) * 8)
Expand All @@ -127,22 +159,48 @@ struct netlbl_lsm_secattr_catmap {
NETLBL_CATMAP_MAPTYPE bitmap[NETLBL_CATMAP_MAPCNT];
struct netlbl_lsm_secattr_catmap *next;
};

/**
* struct netlbl_lsm_secattr - NetLabel LSM security attributes
* @flags: indicate which attributes are contained in this structure
* @type: indicate the NLTYPE of the attributes
* @domain: the NetLabel LSM domain
* @cache: NetLabel LSM specific cache
* @attr.mls: MLS sensitivity label
* @attr.mls.cat: MLS category bitmap
* @attr.mls.lvl: MLS sensitivity level
* @attr.secid: LSM specific secid token
*
* Description:
* This structure is used to pass security attributes between NetLabel and the
* LSM modules. The flags field is used to specify which fields within the
* struct are valid and valid values can be created by bitwise OR'ing the
* NETLBL_SECATTR_* defines. The domain field is typically set by the LSM to
* specify domain specific configuration settings and is not usually used by
* NetLabel itself when returning security attributes to the LSM.
*
*/
#define NETLBL_SECATTR_NONE 0x00000000
#define NETLBL_SECATTR_DOMAIN 0x00000001
#define NETLBL_SECATTR_CACHE 0x00000002
#define NETLBL_SECATTR_MLS_LVL 0x00000004
#define NETLBL_SECATTR_MLS_CAT 0x00000008
#define NETLBL_SECATTR_SECID 0x00000010
#define NETLBL_SECATTR_CACHEABLE (NETLBL_SECATTR_MLS_LVL | \
NETLBL_SECATTR_MLS_CAT)
NETLBL_SECATTR_MLS_CAT | \
NETLBL_SECATTR_SECID)
struct netlbl_lsm_secattr {
u32 flags;

u32 type;
char *domain;

u32 mls_lvl;
struct netlbl_lsm_secattr_catmap *mls_cat;

struct netlbl_lsm_cache *cache;
union {
struct {
struct netlbl_lsm_secattr_catmap *cat;
u32 lvl;
} mls;
u32 secid;
} attr;
};

/*
Expand Down Expand Up @@ -231,10 +289,7 @@ static inline void netlbl_secattr_catmap_free(
*/
static inline void netlbl_secattr_init(struct netlbl_lsm_secattr *secattr)
{
secattr->flags = 0;
secattr->domain = NULL;
secattr->mls_cat = NULL;
secattr->cache = NULL;
memset(secattr, 0, sizeof(*secattr));
}

/**
Expand All @@ -248,11 +303,11 @@ static inline void netlbl_secattr_init(struct netlbl_lsm_secattr *secattr)
*/
static inline void netlbl_secattr_destroy(struct netlbl_lsm_secattr *secattr)
{
if (secattr->cache)
netlbl_secattr_cache_free(secattr->cache);
kfree(secattr->domain);
if (secattr->mls_cat)
netlbl_secattr_catmap_free(secattr->mls_cat);
if (secattr->flags & NETLBL_SECATTR_CACHE)
netlbl_secattr_cache_free(secattr->cache);
if (secattr->flags & NETLBL_SECATTR_MLS_CAT)
netlbl_secattr_catmap_free(secattr->attr.mls.cat);
}

/**
Expand Down Expand Up @@ -300,7 +355,7 @@ int netlbl_secattr_catmap_setrng(struct netlbl_lsm_secattr_catmap *catmap,
gfp_t flags);

/*
* LSM protocol operations
* LSM protocol operations (NetLabel LSM/kernel API)
*/
int netlbl_enabled(void);
int netlbl_sock_setattr(struct sock *sk,
Expand Down
59 changes: 37 additions & 22 deletions net/ipv4/cipso_ipv4.c
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,7 @@ static int cipso_v4_cache_check(const unsigned char *key,
atomic_inc(&entry->lsm_data->refcount);
secattr->cache = entry->lsm_data;
secattr->flags |= NETLBL_SECATTR_CACHE;
secattr->type = NETLBL_NLTYPE_CIPSOV4;
if (prev_entry == NULL) {
spin_unlock_bh(&cipso_v4_cache[bkt].lock);
return 0;
Expand Down Expand Up @@ -865,7 +866,7 @@ static int cipso_v4_map_cat_rbm_hton(const struct cipso_v4_doi *doi_def,
}

for (;;) {
host_spot = netlbl_secattr_catmap_walk(secattr->mls_cat,
host_spot = netlbl_secattr_catmap_walk(secattr->attr.mls.cat,
host_spot + 1);
if (host_spot < 0)
break;
Expand Down Expand Up @@ -948,7 +949,7 @@ static int cipso_v4_map_cat_rbm_ntoh(const struct cipso_v4_doi *doi_def,
return -EPERM;
break;
}
ret_val = netlbl_secattr_catmap_setbit(secattr->mls_cat,
ret_val = netlbl_secattr_catmap_setbit(secattr->attr.mls.cat,
host_spot,
GFP_ATOMIC);
if (ret_val != 0)
Expand Down Expand Up @@ -1014,7 +1015,8 @@ static int cipso_v4_map_cat_enum_hton(const struct cipso_v4_doi *doi_def,
u32 cat_iter = 0;

for (;;) {
cat = netlbl_secattr_catmap_walk(secattr->mls_cat, cat + 1);
cat = netlbl_secattr_catmap_walk(secattr->attr.mls.cat,
cat + 1);
if (cat < 0)
break;
if ((cat_iter + 2) > net_cat_len)
Expand Down Expand Up @@ -1049,7 +1051,7 @@ static int cipso_v4_map_cat_enum_ntoh(const struct cipso_v4_doi *doi_def,
u32 iter;

for (iter = 0; iter < net_cat_len; iter += 2) {
ret_val = netlbl_secattr_catmap_setbit(secattr->mls_cat,
ret_val = netlbl_secattr_catmap_setbit(secattr->attr.mls.cat,
ntohs(get_unaligned((__be16 *)&net_cat[iter])),
GFP_ATOMIC);
if (ret_val != 0)
Expand Down Expand Up @@ -1130,15 +1132,17 @@ static int cipso_v4_map_cat_rng_hton(const struct cipso_v4_doi *doi_def,
return -ENOSPC;

for (;;) {
iter = netlbl_secattr_catmap_walk(secattr->mls_cat, iter + 1);
iter = netlbl_secattr_catmap_walk(secattr->attr.mls.cat,
iter + 1);
if (iter < 0)
break;
cat_size += (iter == 0 ? 0 : sizeof(u16));
if (cat_size > net_cat_len)
return -ENOSPC;
array[array_cnt++] = iter;

iter = netlbl_secattr_catmap_walk_rng(secattr->mls_cat, iter);
iter = netlbl_secattr_catmap_walk_rng(secattr->attr.mls.cat,
iter);
if (iter < 0)
return -EFAULT;
cat_size += sizeof(u16);
Expand Down Expand Up @@ -1191,7 +1195,7 @@ static int cipso_v4_map_cat_rng_ntoh(const struct cipso_v4_doi *doi_def,
else
cat_low = 0;

ret_val = netlbl_secattr_catmap_setrng(secattr->mls_cat,
ret_val = netlbl_secattr_catmap_setrng(secattr->attr.mls.cat,
cat_low,
cat_high,
GFP_ATOMIC);
Expand Down Expand Up @@ -1251,7 +1255,9 @@ static int cipso_v4_gentag_rbm(const struct cipso_v4_doi *doi_def,
if ((secattr->flags & NETLBL_SECATTR_MLS_LVL) == 0)
return -EPERM;

ret_val = cipso_v4_map_lvl_hton(doi_def, secattr->mls_lvl, &level);
ret_val = cipso_v4_map_lvl_hton(doi_def,
secattr->attr.mls.lvl,
&level);
if (ret_val != 0)
return ret_val;

Expand Down Expand Up @@ -1303,20 +1309,21 @@ static int cipso_v4_parsetag_rbm(const struct cipso_v4_doi *doi_def,
ret_val = cipso_v4_map_lvl_ntoh(doi_def, tag[3], &level);
if (ret_val != 0)
return ret_val;
secattr->mls_lvl = level;
secattr->attr.mls.lvl = level;
secattr->flags |= NETLBL_SECATTR_MLS_LVL;

if (tag_len > 4) {
secattr->mls_cat = netlbl_secattr_catmap_alloc(GFP_ATOMIC);
if (secattr->mls_cat == NULL)
secattr->attr.mls.cat =
netlbl_secattr_catmap_alloc(GFP_ATOMIC);
if (secattr->attr.mls.cat == NULL)
return -ENOMEM;

ret_val = cipso_v4_map_cat_rbm_ntoh(doi_def,
&tag[4],
tag_len - 4,
secattr);
if (ret_val != 0) {
netlbl_secattr_catmap_free(secattr->mls_cat);
netlbl_secattr_catmap_free(secattr->attr.mls.cat);
return ret_val;
}

Expand Down Expand Up @@ -1350,7 +1357,9 @@ static int cipso_v4_gentag_enum(const struct cipso_v4_doi *doi_def,
if (!(secattr->flags & NETLBL_SECATTR_MLS_LVL))
return -EPERM;

ret_val = cipso_v4_map_lvl_hton(doi_def, secattr->mls_lvl, &level);
ret_val = cipso_v4_map_lvl_hton(doi_def,
secattr->attr.mls.lvl,
&level);
if (ret_val != 0)
return ret_val;

Expand Down Expand Up @@ -1396,20 +1405,21 @@ static int cipso_v4_parsetag_enum(const struct cipso_v4_doi *doi_def,
ret_val = cipso_v4_map_lvl_ntoh(doi_def, tag[3], &level);
if (ret_val != 0)
return ret_val;
secattr->mls_lvl = level;
secattr->attr.mls.lvl = level;
secattr->flags |= NETLBL_SECATTR_MLS_LVL;

if (tag_len > 4) {
secattr->mls_cat = netlbl_secattr_catmap_alloc(GFP_ATOMIC);
if (secattr->mls_cat == NULL)
secattr->attr.mls.cat =
netlbl_secattr_catmap_alloc(GFP_ATOMIC);
if (secattr->attr.mls.cat == NULL)
return -ENOMEM;

ret_val = cipso_v4_map_cat_enum_ntoh(doi_def,
&tag[4],
tag_len - 4,
secattr);
if (ret_val != 0) {
netlbl_secattr_catmap_free(secattr->mls_cat);
netlbl_secattr_catmap_free(secattr->attr.mls.cat);
return ret_val;
}

Expand Down Expand Up @@ -1443,7 +1453,9 @@ static int cipso_v4_gentag_rng(const struct cipso_v4_doi *doi_def,
if (!(secattr->flags & NETLBL_SECATTR_MLS_LVL))
return -EPERM;

ret_val = cipso_v4_map_lvl_hton(doi_def, secattr->mls_lvl, &level);
ret_val = cipso_v4_map_lvl_hton(doi_def,
secattr->attr.mls.lvl,
&level);
if (ret_val != 0)
return ret_val;

Expand Down Expand Up @@ -1488,20 +1500,21 @@ static int cipso_v4_parsetag_rng(const struct cipso_v4_doi *doi_def,
ret_val = cipso_v4_map_lvl_ntoh(doi_def, tag[3], &level);
if (ret_val != 0)
return ret_val;
secattr->mls_lvl = level;
secattr->attr.mls.lvl = level;
secattr->flags |= NETLBL_SECATTR_MLS_LVL;

if (tag_len > 4) {
secattr->mls_cat = netlbl_secattr_catmap_alloc(GFP_ATOMIC);
if (secattr->mls_cat == NULL)
secattr->attr.mls.cat =
netlbl_secattr_catmap_alloc(GFP_ATOMIC);
if (secattr->attr.mls.cat == NULL)
return -ENOMEM;

ret_val = cipso_v4_map_cat_rng_ntoh(doi_def,
&tag[4],
tag_len - 4,
secattr);
if (ret_val != 0) {
netlbl_secattr_catmap_free(secattr->mls_cat);
netlbl_secattr_catmap_free(secattr->attr.mls.cat);
return ret_val;
}

Expand Down Expand Up @@ -1850,6 +1863,8 @@ static int cipso_v4_getattr(const unsigned char *cipso,
ret_val = cipso_v4_parsetag_rng(doi_def, &cipso[6], secattr);
break;
}
if (ret_val == 0)
secattr->type = NETLBL_NLTYPE_CIPSOV4;

getattr_return:
rcu_read_unlock();
Expand Down
1 change: 1 addition & 0 deletions net/netlabel/netlabel_unlabeled.c
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@ int netlbl_unlabel_getattr(struct netlbl_lsm_secattr *secattr)
if (netlabel_unlabel_acceptflg == 0)
return -ENOMSG;
netlbl_secattr_init(secattr);
secattr->type = NETLBL_NLTYPE_UNLABELED;
return 0;
}

Expand Down
10 changes: 5 additions & 5 deletions security/selinux/ss/mls.c
Original file line number Diff line number Diff line change
Expand Up @@ -562,7 +562,7 @@ void mls_export_netlbl_lvl(struct context *context,
if (!selinux_mls_enabled)
return;

secattr->mls_lvl = context->range.level[0].sens - 1;
secattr->attr.mls.lvl = context->range.level[0].sens - 1;
secattr->flags |= NETLBL_SECATTR_MLS_LVL;
}

Expand All @@ -582,7 +582,7 @@ void mls_import_netlbl_lvl(struct context *context,
if (!selinux_mls_enabled)
return;

context->range.level[0].sens = secattr->mls_lvl + 1;
context->range.level[0].sens = secattr->attr.mls.lvl + 1;
context->range.level[1].sens = context->range.level[0].sens;
}

Expand All @@ -605,8 +605,8 @@ int mls_export_netlbl_cat(struct context *context,
return 0;

rc = ebitmap_netlbl_export(&context->range.level[0].cat,
&secattr->mls_cat);
if (rc == 0 && secattr->mls_cat != NULL)
&secattr->attr.mls.cat);
if (rc == 0 && secattr->attr.mls.cat != NULL)
secattr->flags |= NETLBL_SECATTR_MLS_CAT;

return rc;
Expand All @@ -633,7 +633,7 @@ int mls_import_netlbl_cat(struct context *context,
return 0;

rc = ebitmap_netlbl_import(&context->range.level[0].cat,
secattr->mls_cat);
secattr->attr.mls.cat);
if (rc != 0)
goto import_netlbl_cat_failure;

Expand Down
Loading

0 comments on commit 16efd45

Please sign in to comment.