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

This commit is contained in:
James Morris
2014-08-02 22:58:02 +10:00
8 changed files with 364 additions and 272 deletions

View File

@@ -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;
struct ebitmap_node *e_prev = NULL;
u32 offset = 0, idx;
unsigned long bitmap;
/* 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.
*/
for (;;) {
rc = netlbl_catmap_getlong(catmap, &offset, &bitmap);
if (rc < 0)
goto netlbl_import_failure;
if (offset == (u32)-1)
return 0;
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;
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:

View File

@@ -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;
}