ebitmap.c revision 255e72915d4cbddceb435e13d81601755714e9f
1255e72915d4cbddceb435e13d81601755714e9fSE Android 2255e72915d4cbddceb435e13d81601755714e9fSE Android/* Author : Stephen Smalley, <sds@epoch.ncsc.mil> */ 3255e72915d4cbddceb435e13d81601755714e9fSE Android 4255e72915d4cbddceb435e13d81601755714e9fSE Android/* FLASK */ 5255e72915d4cbddceb435e13d81601755714e9fSE Android 6255e72915d4cbddceb435e13d81601755714e9fSE Android/* 7255e72915d4cbddceb435e13d81601755714e9fSE Android * Implementation of the extensible bitmap type. 8255e72915d4cbddceb435e13d81601755714e9fSE Android */ 9255e72915d4cbddceb435e13d81601755714e9fSE Android 10255e72915d4cbddceb435e13d81601755714e9fSE Android#include <stdlib.h> 11255e72915d4cbddceb435e13d81601755714e9fSE Android 12255e72915d4cbddceb435e13d81601755714e9fSE Android#include <sepol/policydb/ebitmap.h> 13255e72915d4cbddceb435e13d81601755714e9fSE Android#include <sepol/policydb/policydb.h> 14255e72915d4cbddceb435e13d81601755714e9fSE Android 15255e72915d4cbddceb435e13d81601755714e9fSE Android#include "debug.h" 16255e72915d4cbddceb435e13d81601755714e9fSE Android#include "private.h" 17255e72915d4cbddceb435e13d81601755714e9fSE Android 18255e72915d4cbddceb435e13d81601755714e9fSE Androidint ebitmap_or(ebitmap_t * dst, const ebitmap_t * e1, const ebitmap_t * e2) 19255e72915d4cbddceb435e13d81601755714e9fSE Android{ 20255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_node_t *n1, *n2, *new, *prev; 21255e72915d4cbddceb435e13d81601755714e9fSE Android 22255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_init(dst); 23255e72915d4cbddceb435e13d81601755714e9fSE Android 24255e72915d4cbddceb435e13d81601755714e9fSE Android n1 = e1->node; 25255e72915d4cbddceb435e13d81601755714e9fSE Android n2 = e2->node; 26255e72915d4cbddceb435e13d81601755714e9fSE Android prev = 0; 27255e72915d4cbddceb435e13d81601755714e9fSE Android while (n1 || n2) { 28255e72915d4cbddceb435e13d81601755714e9fSE Android new = (ebitmap_node_t *) malloc(sizeof(ebitmap_node_t)); 29255e72915d4cbddceb435e13d81601755714e9fSE Android if (!new) { 30255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_destroy(dst); 31255e72915d4cbddceb435e13d81601755714e9fSE Android return -ENOMEM; 32255e72915d4cbddceb435e13d81601755714e9fSE Android } 33255e72915d4cbddceb435e13d81601755714e9fSE Android memset(new, 0, sizeof(ebitmap_node_t)); 34255e72915d4cbddceb435e13d81601755714e9fSE Android if (n1 && n2 && n1->startbit == n2->startbit) { 35255e72915d4cbddceb435e13d81601755714e9fSE Android new->startbit = n1->startbit; 36255e72915d4cbddceb435e13d81601755714e9fSE Android new->map = n1->map | n2->map; 37255e72915d4cbddceb435e13d81601755714e9fSE Android n1 = n1->next; 38255e72915d4cbddceb435e13d81601755714e9fSE Android n2 = n2->next; 39255e72915d4cbddceb435e13d81601755714e9fSE Android } else if (!n2 || (n1 && n1->startbit < n2->startbit)) { 40255e72915d4cbddceb435e13d81601755714e9fSE Android new->startbit = n1->startbit; 41255e72915d4cbddceb435e13d81601755714e9fSE Android new->map = n1->map; 42255e72915d4cbddceb435e13d81601755714e9fSE Android n1 = n1->next; 43255e72915d4cbddceb435e13d81601755714e9fSE Android } else { 44255e72915d4cbddceb435e13d81601755714e9fSE Android new->startbit = n2->startbit; 45255e72915d4cbddceb435e13d81601755714e9fSE Android new->map = n2->map; 46255e72915d4cbddceb435e13d81601755714e9fSE Android n2 = n2->next; 47255e72915d4cbddceb435e13d81601755714e9fSE Android } 48255e72915d4cbddceb435e13d81601755714e9fSE Android 49255e72915d4cbddceb435e13d81601755714e9fSE Android new->next = 0; 50255e72915d4cbddceb435e13d81601755714e9fSE Android if (prev) 51255e72915d4cbddceb435e13d81601755714e9fSE Android prev->next = new; 52255e72915d4cbddceb435e13d81601755714e9fSE Android else 53255e72915d4cbddceb435e13d81601755714e9fSE Android dst->node = new; 54255e72915d4cbddceb435e13d81601755714e9fSE Android prev = new; 55255e72915d4cbddceb435e13d81601755714e9fSE Android } 56255e72915d4cbddceb435e13d81601755714e9fSE Android 57255e72915d4cbddceb435e13d81601755714e9fSE Android dst->highbit = (e1->highbit > e2->highbit) ? e1->highbit : e2->highbit; 58255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 59255e72915d4cbddceb435e13d81601755714e9fSE Android} 60255e72915d4cbddceb435e13d81601755714e9fSE Android 61255e72915d4cbddceb435e13d81601755714e9fSE Androidint ebitmap_union(ebitmap_t * dst, const ebitmap_t * e1) 62255e72915d4cbddceb435e13d81601755714e9fSE Android{ 63255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_t tmp; 64255e72915d4cbddceb435e13d81601755714e9fSE Android 65255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_or(&tmp, dst, e1)) 66255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 67255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_destroy(dst); 68255e72915d4cbddceb435e13d81601755714e9fSE Android dst->node = tmp.node; 69255e72915d4cbddceb435e13d81601755714e9fSE Android dst->highbit = tmp.highbit; 70255e72915d4cbddceb435e13d81601755714e9fSE Android 71255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 72255e72915d4cbddceb435e13d81601755714e9fSE Android} 73255e72915d4cbddceb435e13d81601755714e9fSE Android 74255e72915d4cbddceb435e13d81601755714e9fSE Androidint ebitmap_cmp(const ebitmap_t * e1, const ebitmap_t * e2) 75255e72915d4cbddceb435e13d81601755714e9fSE Android{ 76255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_node_t *n1, *n2; 77255e72915d4cbddceb435e13d81601755714e9fSE Android 78255e72915d4cbddceb435e13d81601755714e9fSE Android if (e1->highbit != e2->highbit) 79255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 80255e72915d4cbddceb435e13d81601755714e9fSE Android 81255e72915d4cbddceb435e13d81601755714e9fSE Android n1 = e1->node; 82255e72915d4cbddceb435e13d81601755714e9fSE Android n2 = e2->node; 83255e72915d4cbddceb435e13d81601755714e9fSE Android while (n1 && n2 && 84255e72915d4cbddceb435e13d81601755714e9fSE Android (n1->startbit == n2->startbit) && (n1->map == n2->map)) { 85255e72915d4cbddceb435e13d81601755714e9fSE Android n1 = n1->next; 86255e72915d4cbddceb435e13d81601755714e9fSE Android n2 = n2->next; 87255e72915d4cbddceb435e13d81601755714e9fSE Android } 88255e72915d4cbddceb435e13d81601755714e9fSE Android 89255e72915d4cbddceb435e13d81601755714e9fSE Android if (n1 || n2) 90255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 91255e72915d4cbddceb435e13d81601755714e9fSE Android 92255e72915d4cbddceb435e13d81601755714e9fSE Android return 1; 93255e72915d4cbddceb435e13d81601755714e9fSE Android} 94255e72915d4cbddceb435e13d81601755714e9fSE Android 95255e72915d4cbddceb435e13d81601755714e9fSE Androidint ebitmap_cpy(ebitmap_t * dst, const ebitmap_t * src) 96255e72915d4cbddceb435e13d81601755714e9fSE Android{ 97255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_node_t *n, *new, *prev; 98255e72915d4cbddceb435e13d81601755714e9fSE Android 99255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_init(dst); 100255e72915d4cbddceb435e13d81601755714e9fSE Android n = src->node; 101255e72915d4cbddceb435e13d81601755714e9fSE Android prev = 0; 102255e72915d4cbddceb435e13d81601755714e9fSE Android while (n) { 103255e72915d4cbddceb435e13d81601755714e9fSE Android new = (ebitmap_node_t *) malloc(sizeof(ebitmap_node_t)); 104255e72915d4cbddceb435e13d81601755714e9fSE Android if (!new) { 105255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_destroy(dst); 106255e72915d4cbddceb435e13d81601755714e9fSE Android return -ENOMEM; 107255e72915d4cbddceb435e13d81601755714e9fSE Android } 108255e72915d4cbddceb435e13d81601755714e9fSE Android memset(new, 0, sizeof(ebitmap_node_t)); 109255e72915d4cbddceb435e13d81601755714e9fSE Android new->startbit = n->startbit; 110255e72915d4cbddceb435e13d81601755714e9fSE Android new->map = n->map; 111255e72915d4cbddceb435e13d81601755714e9fSE Android new->next = 0; 112255e72915d4cbddceb435e13d81601755714e9fSE Android if (prev) 113255e72915d4cbddceb435e13d81601755714e9fSE Android prev->next = new; 114255e72915d4cbddceb435e13d81601755714e9fSE Android else 115255e72915d4cbddceb435e13d81601755714e9fSE Android dst->node = new; 116255e72915d4cbddceb435e13d81601755714e9fSE Android prev = new; 117255e72915d4cbddceb435e13d81601755714e9fSE Android n = n->next; 118255e72915d4cbddceb435e13d81601755714e9fSE Android } 119255e72915d4cbddceb435e13d81601755714e9fSE Android 120255e72915d4cbddceb435e13d81601755714e9fSE Android dst->highbit = src->highbit; 121255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 122255e72915d4cbddceb435e13d81601755714e9fSE Android} 123255e72915d4cbddceb435e13d81601755714e9fSE Android 124255e72915d4cbddceb435e13d81601755714e9fSE Androidint ebitmap_contains(const ebitmap_t * e1, const ebitmap_t * e2) 125255e72915d4cbddceb435e13d81601755714e9fSE Android{ 126255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_node_t *n1, *n2; 127255e72915d4cbddceb435e13d81601755714e9fSE Android 128255e72915d4cbddceb435e13d81601755714e9fSE Android if (e1->highbit < e2->highbit) 129255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 130255e72915d4cbddceb435e13d81601755714e9fSE Android 131255e72915d4cbddceb435e13d81601755714e9fSE Android n1 = e1->node; 132255e72915d4cbddceb435e13d81601755714e9fSE Android n2 = e2->node; 133255e72915d4cbddceb435e13d81601755714e9fSE Android while (n1 && n2 && (n1->startbit <= n2->startbit)) { 134255e72915d4cbddceb435e13d81601755714e9fSE Android if (n1->startbit < n2->startbit) { 135255e72915d4cbddceb435e13d81601755714e9fSE Android n1 = n1->next; 136255e72915d4cbddceb435e13d81601755714e9fSE Android continue; 137255e72915d4cbddceb435e13d81601755714e9fSE Android } 138255e72915d4cbddceb435e13d81601755714e9fSE Android if ((n1->map & n2->map) != n2->map) 139255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 140255e72915d4cbddceb435e13d81601755714e9fSE Android 141255e72915d4cbddceb435e13d81601755714e9fSE Android n1 = n1->next; 142255e72915d4cbddceb435e13d81601755714e9fSE Android n2 = n2->next; 143255e72915d4cbddceb435e13d81601755714e9fSE Android } 144255e72915d4cbddceb435e13d81601755714e9fSE Android 145255e72915d4cbddceb435e13d81601755714e9fSE Android if (n2) 146255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 147255e72915d4cbddceb435e13d81601755714e9fSE Android 148255e72915d4cbddceb435e13d81601755714e9fSE Android return 1; 149255e72915d4cbddceb435e13d81601755714e9fSE Android} 150255e72915d4cbddceb435e13d81601755714e9fSE Android 151255e72915d4cbddceb435e13d81601755714e9fSE Androidint ebitmap_get_bit(const ebitmap_t * e, unsigned int bit) 152255e72915d4cbddceb435e13d81601755714e9fSE Android{ 153255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_node_t *n; 154255e72915d4cbddceb435e13d81601755714e9fSE Android 155255e72915d4cbddceb435e13d81601755714e9fSE Android if (e->highbit < bit) 156255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 157255e72915d4cbddceb435e13d81601755714e9fSE Android 158255e72915d4cbddceb435e13d81601755714e9fSE Android n = e->node; 159255e72915d4cbddceb435e13d81601755714e9fSE Android while (n && (n->startbit <= bit)) { 160255e72915d4cbddceb435e13d81601755714e9fSE Android if ((n->startbit + MAPSIZE) > bit) { 161255e72915d4cbddceb435e13d81601755714e9fSE Android if (n->map & (MAPBIT << (bit - n->startbit))) 162255e72915d4cbddceb435e13d81601755714e9fSE Android return 1; 163255e72915d4cbddceb435e13d81601755714e9fSE Android else 164255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 165255e72915d4cbddceb435e13d81601755714e9fSE Android } 166255e72915d4cbddceb435e13d81601755714e9fSE Android n = n->next; 167255e72915d4cbddceb435e13d81601755714e9fSE Android } 168255e72915d4cbddceb435e13d81601755714e9fSE Android 169255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 170255e72915d4cbddceb435e13d81601755714e9fSE Android} 171255e72915d4cbddceb435e13d81601755714e9fSE Android 172255e72915d4cbddceb435e13d81601755714e9fSE Androidint ebitmap_set_bit(ebitmap_t * e, unsigned int bit, int value) 173255e72915d4cbddceb435e13d81601755714e9fSE Android{ 174255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_node_t *n, *prev, *new; 175255e72915d4cbddceb435e13d81601755714e9fSE Android uint32_t startbit = bit & ~(MAPSIZE - 1); 176255e72915d4cbddceb435e13d81601755714e9fSE Android uint32_t highbit = startbit + MAPSIZE; 177255e72915d4cbddceb435e13d81601755714e9fSE Android 178255e72915d4cbddceb435e13d81601755714e9fSE Android if (highbit == 0) { 179255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(NULL, "bitmap overflow, bit 0x%x", bit); 180255e72915d4cbddceb435e13d81601755714e9fSE Android return -EINVAL; 181255e72915d4cbddceb435e13d81601755714e9fSE Android } 182255e72915d4cbddceb435e13d81601755714e9fSE Android 183255e72915d4cbddceb435e13d81601755714e9fSE Android prev = 0; 184255e72915d4cbddceb435e13d81601755714e9fSE Android n = e->node; 185255e72915d4cbddceb435e13d81601755714e9fSE Android while (n && n->startbit <= bit) { 186255e72915d4cbddceb435e13d81601755714e9fSE Android if ((n->startbit + MAPSIZE) > bit) { 187255e72915d4cbddceb435e13d81601755714e9fSE Android if (value) { 188255e72915d4cbddceb435e13d81601755714e9fSE Android n->map |= (MAPBIT << (bit - n->startbit)); 189255e72915d4cbddceb435e13d81601755714e9fSE Android } else { 190255e72915d4cbddceb435e13d81601755714e9fSE Android n->map &= ~(MAPBIT << (bit - n->startbit)); 191255e72915d4cbddceb435e13d81601755714e9fSE Android if (!n->map) { 192255e72915d4cbddceb435e13d81601755714e9fSE Android /* drop this node from the bitmap */ 193255e72915d4cbddceb435e13d81601755714e9fSE Android 194255e72915d4cbddceb435e13d81601755714e9fSE Android if (!n->next) { 195255e72915d4cbddceb435e13d81601755714e9fSE Android /* 196255e72915d4cbddceb435e13d81601755714e9fSE Android * this was the highest map 197255e72915d4cbddceb435e13d81601755714e9fSE Android * within the bitmap 198255e72915d4cbddceb435e13d81601755714e9fSE Android */ 199255e72915d4cbddceb435e13d81601755714e9fSE Android if (prev) 200255e72915d4cbddceb435e13d81601755714e9fSE Android e->highbit = 201255e72915d4cbddceb435e13d81601755714e9fSE Android prev->startbit + 202255e72915d4cbddceb435e13d81601755714e9fSE Android MAPSIZE; 203255e72915d4cbddceb435e13d81601755714e9fSE Android else 204255e72915d4cbddceb435e13d81601755714e9fSE Android e->highbit = 0; 205255e72915d4cbddceb435e13d81601755714e9fSE Android } 206255e72915d4cbddceb435e13d81601755714e9fSE Android if (prev) 207255e72915d4cbddceb435e13d81601755714e9fSE Android prev->next = n->next; 208255e72915d4cbddceb435e13d81601755714e9fSE Android else 209255e72915d4cbddceb435e13d81601755714e9fSE Android e->node = n->next; 210255e72915d4cbddceb435e13d81601755714e9fSE Android 211255e72915d4cbddceb435e13d81601755714e9fSE Android free(n); 212255e72915d4cbddceb435e13d81601755714e9fSE Android } 213255e72915d4cbddceb435e13d81601755714e9fSE Android } 214255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 215255e72915d4cbddceb435e13d81601755714e9fSE Android } 216255e72915d4cbddceb435e13d81601755714e9fSE Android prev = n; 217255e72915d4cbddceb435e13d81601755714e9fSE Android n = n->next; 218255e72915d4cbddceb435e13d81601755714e9fSE Android } 219255e72915d4cbddceb435e13d81601755714e9fSE Android 220255e72915d4cbddceb435e13d81601755714e9fSE Android if (!value) 221255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 222255e72915d4cbddceb435e13d81601755714e9fSE Android 223255e72915d4cbddceb435e13d81601755714e9fSE Android new = (ebitmap_node_t *) malloc(sizeof(ebitmap_node_t)); 224255e72915d4cbddceb435e13d81601755714e9fSE Android if (!new) 225255e72915d4cbddceb435e13d81601755714e9fSE Android return -ENOMEM; 226255e72915d4cbddceb435e13d81601755714e9fSE Android memset(new, 0, sizeof(ebitmap_node_t)); 227255e72915d4cbddceb435e13d81601755714e9fSE Android 228255e72915d4cbddceb435e13d81601755714e9fSE Android new->startbit = startbit; 229255e72915d4cbddceb435e13d81601755714e9fSE Android new->map = (MAPBIT << (bit - new->startbit)); 230255e72915d4cbddceb435e13d81601755714e9fSE Android 231255e72915d4cbddceb435e13d81601755714e9fSE Android if (!n) { 232255e72915d4cbddceb435e13d81601755714e9fSE Android /* this node will be the highest map within the bitmap */ 233255e72915d4cbddceb435e13d81601755714e9fSE Android e->highbit = highbit; 234255e72915d4cbddceb435e13d81601755714e9fSE Android } 235255e72915d4cbddceb435e13d81601755714e9fSE Android 236255e72915d4cbddceb435e13d81601755714e9fSE Android if (prev) { 237255e72915d4cbddceb435e13d81601755714e9fSE Android new->next = prev->next; 238255e72915d4cbddceb435e13d81601755714e9fSE Android prev->next = new; 239255e72915d4cbddceb435e13d81601755714e9fSE Android } else { 240255e72915d4cbddceb435e13d81601755714e9fSE Android new->next = e->node; 241255e72915d4cbddceb435e13d81601755714e9fSE Android e->node = new; 242255e72915d4cbddceb435e13d81601755714e9fSE Android } 243255e72915d4cbddceb435e13d81601755714e9fSE Android 244255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 245255e72915d4cbddceb435e13d81601755714e9fSE Android} 246255e72915d4cbddceb435e13d81601755714e9fSE Android 247255e72915d4cbddceb435e13d81601755714e9fSE Androidvoid ebitmap_destroy(ebitmap_t * e) 248255e72915d4cbddceb435e13d81601755714e9fSE Android{ 249255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_node_t *n, *temp; 250255e72915d4cbddceb435e13d81601755714e9fSE Android 251255e72915d4cbddceb435e13d81601755714e9fSE Android if (!e) 252255e72915d4cbddceb435e13d81601755714e9fSE Android return; 253255e72915d4cbddceb435e13d81601755714e9fSE Android 254255e72915d4cbddceb435e13d81601755714e9fSE Android n = e->node; 255255e72915d4cbddceb435e13d81601755714e9fSE Android while (n) { 256255e72915d4cbddceb435e13d81601755714e9fSE Android temp = n; 257255e72915d4cbddceb435e13d81601755714e9fSE Android n = n->next; 258255e72915d4cbddceb435e13d81601755714e9fSE Android free(temp); 259255e72915d4cbddceb435e13d81601755714e9fSE Android } 260255e72915d4cbddceb435e13d81601755714e9fSE Android 261255e72915d4cbddceb435e13d81601755714e9fSE Android e->highbit = 0; 262255e72915d4cbddceb435e13d81601755714e9fSE Android e->node = 0; 263255e72915d4cbddceb435e13d81601755714e9fSE Android return; 264255e72915d4cbddceb435e13d81601755714e9fSE Android} 265255e72915d4cbddceb435e13d81601755714e9fSE Android 266255e72915d4cbddceb435e13d81601755714e9fSE Androidint ebitmap_read(ebitmap_t * e, void *fp) 267255e72915d4cbddceb435e13d81601755714e9fSE Android{ 268255e72915d4cbddceb435e13d81601755714e9fSE Android int rc; 269255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_node_t *n, *l; 270255e72915d4cbddceb435e13d81601755714e9fSE Android uint32_t buf[3], mapsize, count, i; 271255e72915d4cbddceb435e13d81601755714e9fSE Android uint64_t map; 272255e72915d4cbddceb435e13d81601755714e9fSE Android 273255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_init(e); 274255e72915d4cbddceb435e13d81601755714e9fSE Android 275255e72915d4cbddceb435e13d81601755714e9fSE Android rc = next_entry(buf, fp, sizeof(uint32_t) * 3); 276255e72915d4cbddceb435e13d81601755714e9fSE Android if (rc < 0) 277255e72915d4cbddceb435e13d81601755714e9fSE Android goto bad; 278255e72915d4cbddceb435e13d81601755714e9fSE Android 279255e72915d4cbddceb435e13d81601755714e9fSE Android mapsize = le32_to_cpu(buf[0]); 280255e72915d4cbddceb435e13d81601755714e9fSE Android e->highbit = le32_to_cpu(buf[1]); 281255e72915d4cbddceb435e13d81601755714e9fSE Android count = le32_to_cpu(buf[2]); 282255e72915d4cbddceb435e13d81601755714e9fSE Android 283255e72915d4cbddceb435e13d81601755714e9fSE Android if (mapsize != MAPSIZE) { 284255e72915d4cbddceb435e13d81601755714e9fSE Android printf 285255e72915d4cbddceb435e13d81601755714e9fSE Android ("security: ebitmap: map size %d does not match my size %zu (high bit was %d)\n", 286255e72915d4cbddceb435e13d81601755714e9fSE Android mapsize, MAPSIZE, e->highbit); 287255e72915d4cbddceb435e13d81601755714e9fSE Android goto bad; 288255e72915d4cbddceb435e13d81601755714e9fSE Android } 289255e72915d4cbddceb435e13d81601755714e9fSE Android if (!e->highbit) { 290255e72915d4cbddceb435e13d81601755714e9fSE Android e->node = NULL; 291255e72915d4cbddceb435e13d81601755714e9fSE Android goto ok; 292255e72915d4cbddceb435e13d81601755714e9fSE Android } 293255e72915d4cbddceb435e13d81601755714e9fSE Android if (e->highbit & (MAPSIZE - 1)) { 294255e72915d4cbddceb435e13d81601755714e9fSE Android printf 295255e72915d4cbddceb435e13d81601755714e9fSE Android ("security: ebitmap: high bit (%d) is not a multiple of the map size (%zu)\n", 296255e72915d4cbddceb435e13d81601755714e9fSE Android e->highbit, MAPSIZE); 297255e72915d4cbddceb435e13d81601755714e9fSE Android goto bad; 298255e72915d4cbddceb435e13d81601755714e9fSE Android } 299255e72915d4cbddceb435e13d81601755714e9fSE Android l = NULL; 300255e72915d4cbddceb435e13d81601755714e9fSE Android for (i = 0; i < count; i++) { 301255e72915d4cbddceb435e13d81601755714e9fSE Android rc = next_entry(buf, fp, sizeof(uint32_t)); 302255e72915d4cbddceb435e13d81601755714e9fSE Android if (rc < 0) { 303255e72915d4cbddceb435e13d81601755714e9fSE Android printf("security: ebitmap: truncated map\n"); 304255e72915d4cbddceb435e13d81601755714e9fSE Android goto bad; 305255e72915d4cbddceb435e13d81601755714e9fSE Android } 306255e72915d4cbddceb435e13d81601755714e9fSE Android n = (ebitmap_node_t *) malloc(sizeof(ebitmap_node_t)); 307255e72915d4cbddceb435e13d81601755714e9fSE Android if (!n) { 308255e72915d4cbddceb435e13d81601755714e9fSE Android printf("security: ebitmap: out of memory\n"); 309255e72915d4cbddceb435e13d81601755714e9fSE Android rc = -ENOMEM; 310255e72915d4cbddceb435e13d81601755714e9fSE Android goto bad; 311255e72915d4cbddceb435e13d81601755714e9fSE Android } 312255e72915d4cbddceb435e13d81601755714e9fSE Android memset(n, 0, sizeof(ebitmap_node_t)); 313255e72915d4cbddceb435e13d81601755714e9fSE Android 314255e72915d4cbddceb435e13d81601755714e9fSE Android n->startbit = le32_to_cpu(buf[0]); 315255e72915d4cbddceb435e13d81601755714e9fSE Android 316255e72915d4cbddceb435e13d81601755714e9fSE Android if (n->startbit & (MAPSIZE - 1)) { 317255e72915d4cbddceb435e13d81601755714e9fSE Android printf 318255e72915d4cbddceb435e13d81601755714e9fSE Android ("security: ebitmap start bit (%d) is not a multiple of the map size (%zu)\n", 319255e72915d4cbddceb435e13d81601755714e9fSE Android n->startbit, MAPSIZE); 320255e72915d4cbddceb435e13d81601755714e9fSE Android goto bad_free; 321255e72915d4cbddceb435e13d81601755714e9fSE Android } 322255e72915d4cbddceb435e13d81601755714e9fSE Android if (n->startbit > (e->highbit - MAPSIZE)) { 323255e72915d4cbddceb435e13d81601755714e9fSE Android printf 324255e72915d4cbddceb435e13d81601755714e9fSE Android ("security: ebitmap start bit (%d) is beyond the end of the bitmap (%zu)\n", 325255e72915d4cbddceb435e13d81601755714e9fSE Android n->startbit, (e->highbit - MAPSIZE)); 326255e72915d4cbddceb435e13d81601755714e9fSE Android goto bad_free; 327255e72915d4cbddceb435e13d81601755714e9fSE Android } 328255e72915d4cbddceb435e13d81601755714e9fSE Android rc = next_entry(&map, fp, sizeof(uint64_t)); 329255e72915d4cbddceb435e13d81601755714e9fSE Android if (rc < 0) { 330255e72915d4cbddceb435e13d81601755714e9fSE Android printf("security: ebitmap: truncated map\n"); 331255e72915d4cbddceb435e13d81601755714e9fSE Android goto bad_free; 332255e72915d4cbddceb435e13d81601755714e9fSE Android } 333255e72915d4cbddceb435e13d81601755714e9fSE Android n->map = le64_to_cpu(map); 334255e72915d4cbddceb435e13d81601755714e9fSE Android 335255e72915d4cbddceb435e13d81601755714e9fSE Android if (!n->map) { 336255e72915d4cbddceb435e13d81601755714e9fSE Android printf 337255e72915d4cbddceb435e13d81601755714e9fSE Android ("security: ebitmap: null map in ebitmap (startbit %d)\n", 338255e72915d4cbddceb435e13d81601755714e9fSE Android n->startbit); 339255e72915d4cbddceb435e13d81601755714e9fSE Android goto bad_free; 340255e72915d4cbddceb435e13d81601755714e9fSE Android } 341255e72915d4cbddceb435e13d81601755714e9fSE Android if (l) { 342255e72915d4cbddceb435e13d81601755714e9fSE Android if (n->startbit <= l->startbit) { 343255e72915d4cbddceb435e13d81601755714e9fSE Android printf 344255e72915d4cbddceb435e13d81601755714e9fSE Android ("security: ebitmap: start bit %d comes after start bit %d\n", 345255e72915d4cbddceb435e13d81601755714e9fSE Android n->startbit, l->startbit); 346255e72915d4cbddceb435e13d81601755714e9fSE Android goto bad_free; 347255e72915d4cbddceb435e13d81601755714e9fSE Android } 348255e72915d4cbddceb435e13d81601755714e9fSE Android l->next = n; 349255e72915d4cbddceb435e13d81601755714e9fSE Android } else 350255e72915d4cbddceb435e13d81601755714e9fSE Android e->node = n; 351255e72915d4cbddceb435e13d81601755714e9fSE Android 352255e72915d4cbddceb435e13d81601755714e9fSE Android l = n; 353255e72915d4cbddceb435e13d81601755714e9fSE Android } 354255e72915d4cbddceb435e13d81601755714e9fSE Android 355255e72915d4cbddceb435e13d81601755714e9fSE Android ok: 356255e72915d4cbddceb435e13d81601755714e9fSE Android rc = 0; 357255e72915d4cbddceb435e13d81601755714e9fSE Android out: 358255e72915d4cbddceb435e13d81601755714e9fSE Android return rc; 359255e72915d4cbddceb435e13d81601755714e9fSE Android bad_free: 360255e72915d4cbddceb435e13d81601755714e9fSE Android free(n); 361255e72915d4cbddceb435e13d81601755714e9fSE Android bad: 362255e72915d4cbddceb435e13d81601755714e9fSE Android if (!rc) 363255e72915d4cbddceb435e13d81601755714e9fSE Android rc = -EINVAL; 364255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_destroy(e); 365255e72915d4cbddceb435e13d81601755714e9fSE Android goto out; 366255e72915d4cbddceb435e13d81601755714e9fSE Android} 367255e72915d4cbddceb435e13d81601755714e9fSE Android 368255e72915d4cbddceb435e13d81601755714e9fSE Android/* FLASK */ 369