Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 41943
b: refs/heads/master
c: 0275276
h: refs/heads/master
i:
  41941: 35bc3b1
  41939: aef3cc1
  41935: a7698ca
v: v3
  • Loading branch information
Paul Moore authored and David S. Miller committed Dec 3, 2006
1 parent 2c75503 commit b6a4a88
Show file tree
Hide file tree
Showing 9 changed files with 569 additions and 353 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: ef91fd522ba3c88d9c68261c243567bc4c5a8f55
refs/heads/master: 02752760359db6b00a3ffb1acfc13ef8d9eb1e3f
102 changes: 99 additions & 3 deletions trunk/include/net/netlabel.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,22 @@ struct netlbl_lsm_cache {
void (*free) (const void *data);
void *data;
};
/* 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. */
#define NETLBL_CATMAP_MAPTYPE u64
#define NETLBL_CATMAP_MAPCNT 4
#define NETLBL_CATMAP_MAPSIZE (sizeof(NETLBL_CATMAP_MAPTYPE) * 8)
#define NETLBL_CATMAP_SIZE (NETLBL_CATMAP_MAPSIZE * \
NETLBL_CATMAP_MAPCNT)
#define NETLBL_CATMAP_BIT (NETLBL_CATMAP_MAPTYPE)0x01
struct netlbl_lsm_secattr_catmap {
u32 startbit;
NETLBL_CATMAP_MAPTYPE bitmap[NETLBL_CATMAP_MAPCNT];
struct netlbl_lsm_secattr_catmap *next;
};
#define NETLBL_SECATTR_NONE 0x00000000
#define NETLBL_SECATTR_DOMAIN 0x00000001
#define NETLBL_SECATTR_CACHE 0x00000002
Expand All @@ -122,8 +138,7 @@ struct netlbl_lsm_secattr {
char *domain;

u32 mls_lvl;
unsigned char *mls_cat;
size_t mls_cat_len;
struct netlbl_lsm_secattr_catmap *mls_cat;

struct netlbl_lsm_cache *cache;
};
Expand Down Expand Up @@ -170,6 +185,41 @@ static inline void netlbl_secattr_cache_free(struct netlbl_lsm_cache *cache)
kfree(cache);
}

/**
* netlbl_secattr_catmap_alloc - Allocate a LSM secattr catmap
* @flags: memory allocation flags
*
* Description:
* Allocate memory for a LSM secattr catmap, returns a pointer on success, NULL
* on failure.
*
*/
static inline struct netlbl_lsm_secattr_catmap *netlbl_secattr_catmap_alloc(
gfp_t flags)
{
return kzalloc(sizeof(struct netlbl_lsm_secattr_catmap), flags);
}

/**
* netlbl_secattr_catmap_free - Free a LSM secattr catmap
* @catmap: the category bitmap
*
* Description:
* Free a LSM secattr catmap.
*
*/
static inline void netlbl_secattr_catmap_free(
struct netlbl_lsm_secattr_catmap *catmap)
{
struct netlbl_lsm_secattr_catmap *iter;

do {
iter = catmap;
catmap = catmap->next;
kfree(iter);
} while (catmap);
}

/**
* netlbl_secattr_init - Initialize a netlbl_lsm_secattr struct
* @secattr: the struct to initialize
Expand Down Expand Up @@ -200,7 +250,8 @@ static inline void netlbl_secattr_destroy(struct netlbl_lsm_secattr *secattr)
if (secattr->cache)
netlbl_secattr_cache_free(secattr->cache);
kfree(secattr->domain);
kfree(secattr->mls_cat);
if (secattr->mls_cat)
netlbl_secattr_catmap_free(secattr->mls_cat);
}

/**
Expand Down Expand Up @@ -231,6 +282,51 @@ static inline void netlbl_secattr_free(struct netlbl_lsm_secattr *secattr)
kfree(secattr);
}

#ifdef CONFIG_NETLABEL
int netlbl_secattr_catmap_walk(struct netlbl_lsm_secattr_catmap *catmap,
u32 offset);
int netlbl_secattr_catmap_walk_rng(struct netlbl_lsm_secattr_catmap *catmap,
u32 offset);
int netlbl_secattr_catmap_setbit(struct netlbl_lsm_secattr_catmap *catmap,
u32 bit,
gfp_t flags);
int netlbl_secattr_catmap_setrng(struct netlbl_lsm_secattr_catmap *catmap,
u32 start,
u32 end,
gfp_t flags);
#else
static inline int netlbl_secattr_catmap_walk(
struct netlbl_lsm_secattr_catmap *catmap,
u32 offset)
{
return -ENOENT;
}

static inline int netlbl_secattr_catmap_walk_rng(
struct netlbl_lsm_secattr_catmap *catmap,
u32 offset)
{
return -ENOENT;
}

static inline int netlbl_secattr_catmap_setbit(
struct netlbl_lsm_secattr_catmap *catmap,
u32 bit,
gfp_t flags)
{
return 0;
}

static inline int netlbl_secattr_catmap_setrng(
struct netlbl_lsm_secattr_catmap *catmap,
u32 start,
u32 end,
gfp_t flags)
{
return 0;
}
#endif

/*
* LSM protocol operations
*/
Expand Down
168 changes: 69 additions & 99 deletions trunk/net/ipv4/cipso_ipv4.c
Original file line number Diff line number Diff line change
Expand Up @@ -819,8 +819,7 @@ static int cipso_v4_map_cat_rbm_valid(const struct cipso_v4_doi *doi_def,
/**
* cipso_v4_map_cat_rbm_hton - Perform a category mapping from host to network
* @doi_def: the DOI definition
* @host_cat: the category bitmap in host format
* @host_cat_len: the length of the host's category bitmap in bytes
* @secattr: the security attributes
* @net_cat: the zero'd out category bitmap in network/CIPSO format
* @net_cat_len: the length of the CIPSO bitmap in bytes
*
Expand All @@ -831,128 +830,111 @@ static int cipso_v4_map_cat_rbm_valid(const struct cipso_v4_doi *doi_def,
*
*/
static int cipso_v4_map_cat_rbm_hton(const struct cipso_v4_doi *doi_def,
const unsigned char *host_cat,
u32 host_cat_len,
const struct netlbl_lsm_secattr *secattr,
unsigned char *net_cat,
u32 net_cat_len)
{
int host_spot = -1;
u32 net_spot;
u32 net_spot = CIPSO_V4_INV_CAT;
u32 net_spot_max = 0;
u32 host_clen_bits = host_cat_len * 8;
u32 net_clen_bits = net_cat_len * 8;
u32 host_cat_size;
u32 *host_cat_array;
u32 host_cat_size = 0;
u32 *host_cat_array = NULL;

switch (doi_def->type) {
case CIPSO_V4_MAP_PASS:
net_spot_max = host_cat_len;
while (net_spot_max > 0 && host_cat[net_spot_max - 1] == 0)
net_spot_max--;
if (net_spot_max > net_cat_len)
return -EINVAL;
memcpy(net_cat, host_cat, net_spot_max);
return net_spot_max;
case CIPSO_V4_MAP_STD:
if (doi_def->type == CIPSO_V4_MAP_STD) {
host_cat_size = doi_def->map.std->cat.local_size;
host_cat_array = doi_def->map.std->cat.local;
for (;;) {
host_spot = cipso_v4_bitmap_walk(host_cat,
host_clen_bits,
host_spot + 1,
1);
if (host_spot < 0)
break;
}

for (;;) {
host_spot = netlbl_secattr_catmap_walk(secattr->mls_cat,
host_spot + 1);
if (host_spot < 0)
break;

switch (doi_def->type) {
case CIPSO_V4_MAP_PASS:
net_spot = host_spot;
break;
case CIPSO_V4_MAP_STD:
if (host_spot >= host_cat_size)
return -EPERM;

net_spot = host_cat_array[host_spot];
if (net_spot >= CIPSO_V4_INV_CAT)
return -EPERM;
if (net_spot >= net_clen_bits)
return -ENOSPC;
cipso_v4_bitmap_setbit(net_cat, net_spot, 1);

if (net_spot > net_spot_max)
net_spot_max = net_spot;
break;
}
if (net_spot >= net_clen_bits)
return -ENOSPC;
cipso_v4_bitmap_setbit(net_cat, net_spot, 1);

if (host_spot == -2)
return -EFAULT;

if (++net_spot_max % 8)
return net_spot_max / 8 + 1;
return net_spot_max / 8;
if (net_spot > net_spot_max)
net_spot_max = net_spot;
}

return -EINVAL;
if (++net_spot_max % 8)
return net_spot_max / 8 + 1;
return net_spot_max / 8;
}

/**
* cipso_v4_map_cat_rbm_ntoh - Perform a category mapping from network to host
* @doi_def: the DOI definition
* @net_cat: the category bitmap in network/CIPSO format
* @net_cat_len: the length of the CIPSO bitmap in bytes
* @host_cat: the zero'd out category bitmap in host format
* @host_cat_len: the length of the host's category bitmap in bytes
* @secattr: the security attributes
*
* Description:
* Perform a label mapping to translate a CIPSO bitmap to the correct local
* MLS category bitmap using the given DOI definition. Returns the minimum
* size in bytes of the host bitmap on success, negative values otherwise.
* MLS category bitmap using the given DOI definition. Returns zero on
* success, negative values on failure.
*
*/
static int cipso_v4_map_cat_rbm_ntoh(const struct cipso_v4_doi *doi_def,
const unsigned char *net_cat,
u32 net_cat_len,
unsigned char *host_cat,
u32 host_cat_len)
struct netlbl_lsm_secattr *secattr)
{
u32 host_spot;
u32 host_spot_max = 0;
int ret_val;
int net_spot = -1;
u32 host_spot = CIPSO_V4_INV_CAT;
u32 net_clen_bits = net_cat_len * 8;
u32 host_clen_bits = host_cat_len * 8;
u32 net_cat_size;
u32 *net_cat_array;
u32 net_cat_size = 0;
u32 *net_cat_array = NULL;

switch (doi_def->type) {
case CIPSO_V4_MAP_PASS:
if (net_cat_len > host_cat_len)
return -EINVAL;
memcpy(host_cat, net_cat, net_cat_len);
return net_cat_len;
case CIPSO_V4_MAP_STD:
if (doi_def->type == CIPSO_V4_MAP_STD) {
net_cat_size = doi_def->map.std->cat.cipso_size;
net_cat_array = doi_def->map.std->cat.cipso;
for (;;) {
net_spot = cipso_v4_bitmap_walk(net_cat,
net_clen_bits,
net_spot + 1,
1);
if (net_spot < 0)
break;
if (net_spot >= net_cat_size ||
net_cat_array[net_spot] >= CIPSO_V4_INV_CAT)
return -EPERM;
}

for (;;) {
net_spot = cipso_v4_bitmap_walk(net_cat,
net_clen_bits,
net_spot + 1,
1);
if (net_spot < 0) {
if (net_spot == -2)
return -EFAULT;
return 0;
}

switch (doi_def->type) {
case CIPSO_V4_MAP_PASS:
host_spot = net_spot;
break;
case CIPSO_V4_MAP_STD:
if (net_spot >= net_cat_size)
return -EPERM;
host_spot = net_cat_array[net_spot];
if (host_spot >= CIPSO_V4_INV_CAT)
return -EPERM;
if (host_spot >= host_clen_bits)
return -ENOSPC;
cipso_v4_bitmap_setbit(host_cat, host_spot, 1);

if (host_spot > host_spot_max)
host_spot_max = host_spot;
break;
}

if (net_spot == -2)
return -EFAULT;

if (++host_spot_max % 8)
return host_spot_max / 8 + 1;
return host_spot_max / 8;
ret_val = netlbl_secattr_catmap_setbit(secattr->mls_cat,
host_spot,
GFP_ATOMIC);
if (ret_val != 0)
return ret_val;
}

return -EINVAL;
Expand Down Expand Up @@ -1016,8 +998,7 @@ static int cipso_v4_gentag_rbm(const struct cipso_v4_doi *doi_def,

if (secattr->flags & NETLBL_SECATTR_MLS_CAT) {
ret_val = cipso_v4_map_cat_rbm_hton(doi_def,
secattr->mls_cat,
secattr->mls_cat_len,
secattr,
&buffer[4],
buffer_len - 4);
if (ret_val < 0)
Expand Down Expand Up @@ -1067,31 +1048,20 @@ static int cipso_v4_parsetag_rbm(const struct cipso_v4_doi *doi_def,
secattr->flags |= NETLBL_SECATTR_MLS_LVL;

if (tag_len > 4) {
switch (doi_def->type) {
case CIPSO_V4_MAP_PASS:
secattr->mls_cat_len = tag_len - 4;
break;
case CIPSO_V4_MAP_STD:
secattr->mls_cat_len =
doi_def->map.std->cat.local_size;
break;
}
secattr->mls_cat = kzalloc(secattr->mls_cat_len, GFP_ATOMIC);
secattr->mls_cat = netlbl_secattr_catmap_alloc(GFP_ATOMIC);
if (secattr->mls_cat == NULL)
return -ENOMEM;

ret_val = cipso_v4_map_cat_rbm_ntoh(doi_def,
&tag[4],
tag_len - 4,
secattr->mls_cat,
secattr->mls_cat_len);
if (ret_val < 0) {
kfree(secattr->mls_cat);
secattr);
if (ret_val != 0) {
netlbl_secattr_catmap_free(secattr->mls_cat);
return ret_val;
} else if (ret_val > 0) {
secattr->mls_cat_len = ret_val;
secattr->flags |= NETLBL_SECATTR_MLS_CAT;
}

secattr->flags |= NETLBL_SECATTR_MLS_CAT;
}

return 0;
Expand Down
Loading

0 comments on commit b6a4a88

Please sign in to comment.