summaryrefslogtreecommitdiff
path: root/security
diff options
context:
space:
mode:
Diffstat (limited to 'security')
-rw-r--r--security/selinux/ss/ebitmap.c133
-rw-r--r--security/selinux/ss/ebitmap.h8
-rw-r--r--security/smack/smack_access.c11
-rw-r--r--security/smack/smack_lsm.c6
-rw-r--r--security/smack/smackfs.c14
5 files changed, 70 insertions, 102 deletions
diff --git a/security/selinux/ss/ebitmap.c b/security/selinux/ss/ebitmap.c
index 820313a04d49..afe6a269ec17 100644
--- a/security/selinux/ss/ebitmap.c
+++ b/security/selinux/ss/ebitmap.c
@@ -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 @@ netlbl_export_failure:
*
*/
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:
diff --git a/security/selinux/ss/ebitmap.h b/security/selinux/ss/ebitmap.h
index 712c8a7b8e8b..9637b8c71085 100644
--- a/security/selinux/ss/ebitmap.h
+++ b/security/selinux/ss/ebitmap.h
@@ -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;
}
diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c
index c062e9467b62..f97d0842e621 100644
--- a/security/smack/smack_access.c
+++ b/security/smack/smack_access.c
@@ -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;
}
}
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index f2c30801ce41..e6ab307ce86e 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -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)
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
index 32b248820840..3c720ff10591 100644
--- a/security/smack/smackfs.c
+++ b/security/smack/smackfs.c
@@ -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 = ',';
}