Commit 103ae675 authored by James Morris's avatar James Morris

Merge branch 'next' of git://git.infradead.org/users/pcmoore/selinux into next

parents a3d64df8 4fbe63d1
......@@ -139,7 +139,7 @@ struct netlbl_lsm_cache {
};
/**
* struct netlbl_lsm_secattr_catmap - NetLabel LSM secattr category bitmap
* struct netlbl_lsm_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
......@@ -162,10 +162,10 @@ struct netlbl_lsm_cache {
#define NETLBL_CATMAP_SIZE (NETLBL_CATMAP_MAPSIZE * \
NETLBL_CATMAP_MAPCNT)
#define NETLBL_CATMAP_BIT (NETLBL_CATMAP_MAPTYPE)0x01
struct netlbl_lsm_secattr_catmap {
struct netlbl_lsm_catmap {
u32 startbit;
NETLBL_CATMAP_MAPTYPE bitmap[NETLBL_CATMAP_MAPCNT];
struct netlbl_lsm_secattr_catmap *next;
struct netlbl_lsm_catmap *next;
};
/**
......@@ -209,7 +209,7 @@ struct netlbl_lsm_secattr {
struct netlbl_lsm_cache *cache;
struct {
struct {
struct netlbl_lsm_secattr_catmap *cat;
struct netlbl_lsm_catmap *cat;
u32 lvl;
} mls;
u32 secid;
......@@ -258,7 +258,7 @@ static inline void netlbl_secattr_cache_free(struct netlbl_lsm_cache *cache)
}
/**
* netlbl_secattr_catmap_alloc - Allocate a LSM secattr catmap
* netlbl_catmap_alloc - Allocate a LSM secattr catmap
* @flags: memory allocation flags
*
* Description:
......@@ -266,30 +266,28 @@ static inline void netlbl_secattr_cache_free(struct netlbl_lsm_cache *cache)
* on failure.
*
*/
static inline struct netlbl_lsm_secattr_catmap *netlbl_secattr_catmap_alloc(
gfp_t flags)
static inline struct netlbl_lsm_catmap *netlbl_catmap_alloc(gfp_t flags)
{
return kzalloc(sizeof(struct netlbl_lsm_secattr_catmap), flags);
return kzalloc(sizeof(struct netlbl_lsm_catmap), flags);
}
/**
* netlbl_secattr_catmap_free - Free a LSM secattr catmap
* netlbl_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)
static inline void netlbl_catmap_free(struct netlbl_lsm_catmap *catmap)
{
struct netlbl_lsm_secattr_catmap *iter;
struct netlbl_lsm_catmap *iter;
do {
while (catmap) {
iter = catmap;
catmap = catmap->next;
kfree(iter);
} while (catmap);
}
}
/**
......@@ -321,7 +319,7 @@ static inline void netlbl_secattr_destroy(struct netlbl_lsm_secattr *secattr)
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);
netlbl_catmap_free(secattr->attr.mls.cat);
}
/**
......@@ -390,17 +388,22 @@ int netlbl_cfg_cipsov4_map_add(u32 doi,
/*
* LSM security attribute operations
*/
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);
int netlbl_catmap_walk(struct netlbl_lsm_catmap *catmap, u32 offset);
int netlbl_catmap_walkrng(struct netlbl_lsm_catmap *catmap, u32 offset);
int netlbl_catmap_getlong(struct netlbl_lsm_catmap *catmap,
u32 *offset,
unsigned long *bitmap);
int netlbl_catmap_setbit(struct netlbl_lsm_catmap **catmap,
u32 bit,
gfp_t flags);
int netlbl_catmap_setrng(struct netlbl_lsm_catmap **catmap,
u32 start,
u32 end,
gfp_t flags);
int netlbl_catmap_setlong(struct netlbl_lsm_catmap **catmap,
u32 offset,
unsigned long bitmap,
gfp_t flags);
/*
* LSM protocol operations (NetLabel LSM/kernel API)
......@@ -492,30 +495,39 @@ static inline int netlbl_cfg_cipsov4_map_add(u32 doi,
{
return -ENOSYS;
}
static inline int netlbl_secattr_catmap_walk(
struct netlbl_lsm_secattr_catmap *catmap,
u32 offset)
static inline int netlbl_catmap_walk(struct netlbl_lsm_catmap *catmap,
u32 offset)
{
return -ENOENT;
}
static inline int netlbl_secattr_catmap_walk_rng(
struct netlbl_lsm_secattr_catmap *catmap,
u32 offset)
static inline int netlbl_catmap_walkrng(struct netlbl_lsm_catmap *catmap,
u32 offset)
{
return -ENOENT;
}
static inline int netlbl_secattr_catmap_setbit(
struct netlbl_lsm_secattr_catmap *catmap,
u32 bit,
gfp_t flags)
static inline int netlbl_catmap_getlong(struct netlbl_lsm_catmap *catmap,
u32 *offset,
unsigned long *bitmap)
{
return 0;
}
static inline int netlbl_secattr_catmap_setrng(
struct netlbl_lsm_secattr_catmap *catmap,
u32 start,
u32 end,
gfp_t flags)
static inline int netlbl_catmap_setbit(struct netlbl_lsm_catmap **catmap,
u32 bit,
gfp_t flags)
{
return 0;
}
static inline int netlbl_catmap_setrng(struct netlbl_lsm_catmap **catmap,
u32 start,
u32 end,
gfp_t flags)
{
return 0;
}
static int netlbl_catmap_setlong(struct netlbl_lsm_catmap **catmap,
u32 offset,
unsigned long bitmap,
gfp_t flags)
{
return 0;
}
......
......@@ -890,8 +890,8 @@ static int cipso_v4_map_cat_rbm_hton(const struct cipso_v4_doi *doi_def,
}
for (;;) {
host_spot = netlbl_secattr_catmap_walk(secattr->attr.mls.cat,
host_spot + 1);
host_spot = netlbl_catmap_walk(secattr->attr.mls.cat,
host_spot + 1);
if (host_spot < 0)
break;
......@@ -973,7 +973,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->attr.mls.cat,
ret_val = netlbl_catmap_setbit(&secattr->attr.mls.cat,
host_spot,
GFP_ATOMIC);
if (ret_val != 0)
......@@ -1039,8 +1039,7 @@ 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->attr.mls.cat,
cat + 1);
cat = netlbl_catmap_walk(secattr->attr.mls.cat, cat + 1);
if (cat < 0)
break;
if ((cat_iter + 2) > net_cat_len)
......@@ -1075,9 +1074,9 @@ 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->attr.mls.cat,
get_unaligned_be16(&net_cat[iter]),
GFP_ATOMIC);
ret_val = netlbl_catmap_setbit(&secattr->attr.mls.cat,
get_unaligned_be16(&net_cat[iter]),
GFP_ATOMIC);
if (ret_val != 0)
return ret_val;
}
......@@ -1155,8 +1154,7 @@ static int cipso_v4_map_cat_rng_hton(const struct cipso_v4_doi *doi_def,
return -ENOSPC;
for (;;) {
iter = netlbl_secattr_catmap_walk(secattr->attr.mls.cat,
iter + 1);
iter = netlbl_catmap_walk(secattr->attr.mls.cat, iter + 1);
if (iter < 0)
break;
cat_size += (iter == 0 ? 0 : sizeof(u16));
......@@ -1164,8 +1162,7 @@ static int cipso_v4_map_cat_rng_hton(const struct cipso_v4_doi *doi_def,
return -ENOSPC;
array[array_cnt++] = iter;
iter = netlbl_secattr_catmap_walk_rng(secattr->attr.mls.cat,
iter);
iter = netlbl_catmap_walkrng(secattr->attr.mls.cat, iter);
if (iter < 0)
return -EFAULT;
cat_size += sizeof(u16);
......@@ -1217,10 +1214,10 @@ 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->attr.mls.cat,
cat_low,
cat_high,
GFP_ATOMIC);
ret_val = netlbl_catmap_setrng(&secattr->attr.mls.cat,
cat_low,
cat_high,
GFP_ATOMIC);
if (ret_val != 0)
return ret_val;
}
......@@ -1335,16 +1332,12 @@ static int cipso_v4_parsetag_rbm(const struct cipso_v4_doi *doi_def,
secattr->flags |= NETLBL_SECATTR_MLS_LVL;
if (tag_len > 4) {
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->attr.mls.cat);
netlbl_catmap_free(secattr->attr.mls.cat);
return ret_val;
}
......@@ -1430,16 +1423,12 @@ static int cipso_v4_parsetag_enum(const struct cipso_v4_doi *doi_def,
secattr->flags |= NETLBL_SECATTR_MLS_LVL;
if (tag_len > 4) {
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->attr.mls.cat);
netlbl_catmap_free(secattr->attr.mls.cat);
return ret_val;
}
......@@ -1524,16 +1513,12 @@ static int cipso_v4_parsetag_rng(const struct cipso_v4_doi *doi_def,
secattr->flags |= NETLBL_SECATTR_MLS_LVL;
if (tag_len > 4) {
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->attr.mls.cat);
netlbl_catmap_free(secattr->attr.mls.cat);
return ret_val;
}
......
This diff is collapsed.
......@@ -86,51 +86,36 @@ int ebitmap_cpy(struct ebitmap *dst, struct ebitmap *src)
*
*/
int ebitmap_netlbl_export(struct ebitmap *ebmap,
struct netlbl_lsm_secattr_catmap **catmap)
struct netlbl_lsm_catmap **catmap)
{
struct ebitmap_node *e_iter = ebmap->node;
struct netlbl_lsm_secattr_catmap *c_iter;
u32 cmap_idx, cmap_sft;
int i;
/* NetLabel's NETLBL_CATMAP_MAPTYPE is defined as an array of u64,
* however, it is not always compatible with an array of unsigned long
* in ebitmap_node.
* In addition, you should pay attention the following implementation
* assumes unsigned long has a width equal with or less than 64-bit.
*/
unsigned long e_map;
u32 offset;
unsigned int iter;
int rc;
if (e_iter == NULL) {
*catmap = NULL;
return 0;
}
c_iter = netlbl_secattr_catmap_alloc(GFP_ATOMIC);
if (c_iter == NULL)
return -ENOMEM;
*catmap = c_iter;
c_iter->startbit = e_iter->startbit & ~(NETLBL_CATMAP_SIZE - 1);
if (*catmap != NULL)
netlbl_catmap_free(*catmap);
*catmap = NULL;
while (e_iter) {
for (i = 0; i < EBITMAP_UNIT_NUMS; i++) {
unsigned int delta, e_startbit, c_endbit;
e_startbit = e_iter->startbit + i * EBITMAP_UNIT_SIZE;
c_endbit = c_iter->startbit + NETLBL_CATMAP_SIZE;
if (e_startbit >= c_endbit) {
c_iter->next
= netlbl_secattr_catmap_alloc(GFP_ATOMIC);
if (c_iter->next == NULL)
offset = e_iter->startbit;
for (iter = 0; iter < EBITMAP_UNIT_NUMS; iter++) {
e_map = e_iter->maps[iter];
if (e_map != 0) {
rc = netlbl_catmap_setlong(catmap,
offset,
e_map,
GFP_ATOMIC);
if (rc != 0)
goto netlbl_export_failure;
c_iter = c_iter->next;
c_iter->startbit
= e_startbit & ~(NETLBL_CATMAP_SIZE - 1);
}
delta = e_startbit - c_iter->startbit;
cmap_idx = delta / NETLBL_CATMAP_MAPSIZE;
cmap_sft = delta % NETLBL_CATMAP_MAPSIZE;
c_iter->bitmap[cmap_idx]
|= e_iter->maps[i] << cmap_sft;
offset += EBITMAP_UNIT_SIZE;
}
e_iter = e_iter->next;
}
......@@ -138,7 +123,7 @@ int ebitmap_netlbl_export(struct ebitmap *ebmap,
return 0;
netlbl_export_failure:
netlbl_secattr_catmap_free(*catmap);
netlbl_catmap_free(*catmap);
return -ENOMEM;
}
......@@ -153,58 +138,44 @@ int ebitmap_netlbl_export(struct ebitmap *ebmap,
*
*/
int ebitmap_netlbl_import(struct ebitmap *ebmap,
struct netlbl_lsm_secattr_catmap *catmap)
struct netlbl_lsm_catmap *catmap)
{
int rc;
struct ebitmap_node *e_iter = NULL;
struct ebitmap_node *emap_prev = NULL;
struct netlbl_lsm_secattr_catmap *c_iter = catmap;
u32 c_idx, c_pos, e_idx, e_sft;
/* NetLabel's NETLBL_CATMAP_MAPTYPE is defined as an array of u64,
* however, it is not always compatible with an array of unsigned long
* in ebitmap_node.
* In addition, you should pay attention the following implementation
* assumes unsigned long has a width equal with or less than 64-bit.
*/
do {
for (c_idx = 0; c_idx < NETLBL_CATMAP_MAPCNT; c_idx++) {
unsigned int delta;
u64 map = c_iter->bitmap[c_idx];
if (!map)
continue;
struct ebitmap_node *e_prev = NULL;
u32 offset = 0, idx;
unsigned long bitmap;
for (;;) {
rc = netlbl_catmap_getlong(catmap, &offset, &bitmap);
if (rc < 0)
goto netlbl_import_failure;
if (offset == (u32)-1)
return 0;
c_pos = c_iter->startbit
+ c_idx * NETLBL_CATMAP_MAPSIZE;
if (!e_iter
|| c_pos >= e_iter->startbit + EBITMAP_SIZE) {
e_iter = kzalloc(sizeof(*e_iter), GFP_ATOMIC);
if (!e_iter)
goto netlbl_import_failure;
e_iter->startbit
= c_pos - (c_pos % EBITMAP_SIZE);
if (emap_prev == NULL)
ebmap->node = e_iter;
else
emap_prev->next = e_iter;
emap_prev = e_iter;
}
delta = c_pos - e_iter->startbit;
e_idx = delta / EBITMAP_UNIT_SIZE;
e_sft = delta % EBITMAP_UNIT_SIZE;
while (map) {
e_iter->maps[e_idx++] |= map & (-1UL);
map = EBITMAP_SHIFT_UNIT_SIZE(map);
}
if (e_iter == NULL ||
offset >= e_iter->startbit + EBITMAP_SIZE) {
e_prev = e_iter;
e_iter = kzalloc(sizeof(*e_iter), GFP_ATOMIC);
if (e_iter == NULL)
goto netlbl_import_failure;
e_iter->startbit = offset & ~(EBITMAP_SIZE - 1);
if (e_prev == NULL)
ebmap->node = e_iter;
else
e_prev->next = e_iter;
ebmap->highbit = e_iter->startbit + EBITMAP_SIZE;
}
c_iter = c_iter->next;
} while (c_iter);
if (e_iter != NULL)
ebmap->highbit = e_iter->startbit + EBITMAP_SIZE;
else
ebitmap_destroy(ebmap);
/* offset will always be aligned to an unsigned long */
idx = EBITMAP_NODE_INDEX(e_iter, offset);
e_iter->maps[idx] = bitmap;
/* next */
offset += EBITMAP_UNIT_SIZE;
}
/* NOTE: we should never reach this return */
return 0;
netlbl_import_failure:
......
......@@ -132,17 +132,17 @@ int ebitmap_write(struct ebitmap *e, void *fp);
#ifdef CONFIG_NETLABEL
int ebitmap_netlbl_export(struct ebitmap *ebmap,
struct netlbl_lsm_secattr_catmap **catmap);
struct netlbl_lsm_catmap **catmap);
int ebitmap_netlbl_import(struct ebitmap *ebmap,
struct netlbl_lsm_secattr_catmap *catmap);
struct netlbl_lsm_catmap *catmap);
#else
static inline int ebitmap_netlbl_export(struct ebitmap *ebmap,
struct netlbl_lsm_secattr_catmap **catmap)
struct netlbl_lsm_catmap **catmap)
{
return -ENOMEM;
}
static inline int ebitmap_netlbl_import(struct ebitmap *ebmap,
struct netlbl_lsm_secattr_catmap *catmap)
struct netlbl_lsm_catmap *catmap)
{
return -ENOMEM;
}
......
......@@ -457,19 +457,16 @@ int smk_netlbl_mls(int level, char *catset, struct netlbl_lsm_secattr *sap,
sap->flags |= NETLBL_SECATTR_MLS_CAT;
sap->attr.mls.lvl = level;
sap->attr.mls.cat = netlbl_secattr_catmap_alloc(GFP_ATOMIC);
if (!sap->attr.mls.cat)
return -ENOMEM;
sap->attr.mls.cat->startbit = 0;
sap->attr.mls.cat = NULL;
for (cat = 1, cp = catset, byte = 0; byte < len; cp++, byte++)
for (m = 0x80; m != 0; m >>= 1, cat++) {
if ((m & *cp) == 0)
continue;
rc = netlbl_secattr_catmap_setbit(sap->attr.mls.cat,
cat, GFP_ATOMIC);
rc = netlbl_catmap_setbit(&sap->attr.mls.cat,
cat, GFP_ATOMIC);
if (rc < 0) {
netlbl_secattr_catmap_free(sap->attr.mls.cat);
netlbl_catmap_free(sap->attr.mls.cat);
return rc;
}
}
......
......@@ -3209,9 +3209,9 @@ static struct smack_known *smack_from_secattr(struct netlbl_lsm_secattr *sap,
break;
}
for (acat = -1, kcat = -1; acat == kcat; ) {
acat = netlbl_secattr_catmap_walk(
sap->attr.mls.cat, acat + 1);
kcat = netlbl_secattr_catmap_walk(
acat = netlbl_catmap_walk(sap->attr.mls.cat,
acat + 1);
kcat = netlbl_catmap_walk(
skp->smk_netlabel.attr.mls.cat,
kcat + 1);
if (acat < 0 || kcat < 0)
......
......@@ -787,7 +787,7 @@ static int cipso_seq_show(struct seq_file *s, void *v)
struct list_head *list = v;
struct smack_known *skp =
list_entry(list, struct smack_known, list);
struct netlbl_lsm_secattr_catmap *cmp = skp->smk_netlabel.attr.mls.cat;
struct netlbl_lsm_catmap *cmp = skp->smk_netlabel.attr.mls.cat;
char sep = '/';
int i;
......@@ -804,8 +804,8 @@ static int cipso_seq_show(struct seq_file *s, void *v)
seq_printf(s, "%s %3d", skp->smk_known, skp->smk_netlabel.attr.mls.lvl);
for (i = netlbl_secattr_catmap_walk(cmp, 0); i >= 0;
i = netlbl_secattr_catmap_walk(cmp, i + 1)) {
for (i = netlbl_catmap_walk(cmp, 0); i >= 0;
i = netlbl_catmap_walk(cmp, i + 1)) {
seq_printf(s, "%c%d", sep, i);
sep = ',';
}
......@@ -926,7 +926,7 @@ static ssize_t smk_set_cipso(struct file *file, const char __user *buf,
rc = smk_netlbl_mls(maplevel, mapcatset, &ncats, SMK_CIPSOLEN);
if (rc >= 0) {
netlbl_secattr_catmap_free(skp->smk_netlabel.attr.mls.cat);
netlbl_catmap_free(skp->smk_netlabel.attr.mls.cat);
skp->smk_netlabel.attr.mls.cat = ncats.attr.mls.cat;
skp->smk_netlabel.attr.mls.lvl = ncats.attr.mls.lvl;
rc = count;
......@@ -976,14 +976,14 @@ static int cipso2_seq_show(struct seq_file *s, void *v)
struct list_head *list = v;
struct smack_known *skp =
list_entry(list, struct smack_known, list);
struct netlbl_lsm_secattr_catmap *cmp = skp->smk_netlabel.attr.mls.cat;
struct netlbl_lsm_catmap *cmp = skp->smk_netlabel.attr.mls.cat;
char sep = '/';
int i;
seq_printf(s, "%s %3d", skp->smk_known, skp->smk_netlabel.attr.mls.lvl);
for (i = netlbl_secattr_catmap_walk(cmp, 0); i >= 0;
i = netlbl_secattr_catmap_walk(cmp, i + 1)) {
for (i = netlbl_catmap_walk(cmp, 0); i >= 0;
i = netlbl_catmap_walk(cmp, i + 1)) {
seq_printf(s, "%c%d", sep, i);
sep = ',';
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment