ebitmap.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. /*
  2. * Implementation of the extensible bitmap type.
  3. *
  4. * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
  5. */
  6. #include <linux/kernel.h>
  7. #include <linux/slab.h>
  8. #include <linux/errno.h>
  9. #include "ebitmap.h"
  10. #include "policydb.h"
  11. int ebitmap_cmp(struct ebitmap *e1, struct ebitmap *e2)
  12. {
  13. struct ebitmap_node *n1, *n2;
  14. if (e1->highbit != e2->highbit)
  15. return 0;
  16. n1 = e1->node;
  17. n2 = e2->node;
  18. while (n1 && n2 &&
  19. (n1->startbit == n2->startbit) &&
  20. (n1->map == n2->map)) {
  21. n1 = n1->next;
  22. n2 = n2->next;
  23. }
  24. if (n1 || n2)
  25. return 0;
  26. return 1;
  27. }
  28. int ebitmap_cpy(struct ebitmap *dst, struct ebitmap *src)
  29. {
  30. struct ebitmap_node *n, *new, *prev;
  31. ebitmap_init(dst);
  32. n = src->node;
  33. prev = NULL;
  34. while (n) {
  35. new = kzalloc(sizeof(*new), GFP_ATOMIC);
  36. if (!new) {
  37. ebitmap_destroy(dst);
  38. return -ENOMEM;
  39. }
  40. new->startbit = n->startbit;
  41. new->map = n->map;
  42. new->next = NULL;
  43. if (prev)
  44. prev->next = new;
  45. else
  46. dst->node = new;
  47. prev = new;
  48. n = n->next;
  49. }
  50. dst->highbit = src->highbit;
  51. return 0;
  52. }
  53. int ebitmap_contains(struct ebitmap *e1, struct ebitmap *e2)
  54. {
  55. struct ebitmap_node *n1, *n2;
  56. if (e1->highbit < e2->highbit)
  57. return 0;
  58. n1 = e1->node;
  59. n2 = e2->node;
  60. while (n1 && n2 && (n1->startbit <= n2->startbit)) {
  61. if (n1->startbit < n2->startbit) {
  62. n1 = n1->next;
  63. continue;
  64. }
  65. if ((n1->map & n2->map) != n2->map)
  66. return 0;
  67. n1 = n1->next;
  68. n2 = n2->next;
  69. }
  70. if (n2)
  71. return 0;
  72. return 1;
  73. }
  74. int ebitmap_get_bit(struct ebitmap *e, unsigned long bit)
  75. {
  76. struct ebitmap_node *n;
  77. if (e->highbit < bit)
  78. return 0;
  79. n = e->node;
  80. while (n && (n->startbit <= bit)) {
  81. if ((n->startbit + MAPSIZE) > bit) {
  82. if (n->map & (MAPBIT << (bit - n->startbit)))
  83. return 1;
  84. else
  85. return 0;
  86. }
  87. n = n->next;
  88. }
  89. return 0;
  90. }
  91. int ebitmap_set_bit(struct ebitmap *e, unsigned long bit, int value)
  92. {
  93. struct ebitmap_node *n, *prev, *new;
  94. prev = NULL;
  95. n = e->node;
  96. while (n && n->startbit <= bit) {
  97. if ((n->startbit + MAPSIZE) > bit) {
  98. if (value) {
  99. n->map |= (MAPBIT << (bit - n->startbit));
  100. } else {
  101. n->map &= ~(MAPBIT << (bit - n->startbit));
  102. if (!n->map) {
  103. /* drop this node from the bitmap */
  104. if (!n->next) {
  105. /*
  106. * this was the highest map
  107. * within the bitmap
  108. */
  109. if (prev)
  110. e->highbit = prev->startbit + MAPSIZE;
  111. else
  112. e->highbit = 0;
  113. }
  114. if (prev)
  115. prev->next = n->next;
  116. else
  117. e->node = n->next;
  118. kfree(n);
  119. }
  120. }
  121. return 0;
  122. }
  123. prev = n;
  124. n = n->next;
  125. }
  126. if (!value)
  127. return 0;
  128. new = kzalloc(sizeof(*new), GFP_ATOMIC);
  129. if (!new)
  130. return -ENOMEM;
  131. new->startbit = bit & ~(MAPSIZE - 1);
  132. new->map = (MAPBIT << (bit - new->startbit));
  133. if (!n)
  134. /* this node will be the highest map within the bitmap */
  135. e->highbit = new->startbit + MAPSIZE;
  136. if (prev) {
  137. new->next = prev->next;
  138. prev->next = new;
  139. } else {
  140. new->next = e->node;
  141. e->node = new;
  142. }
  143. return 0;
  144. }
  145. void ebitmap_destroy(struct ebitmap *e)
  146. {
  147. struct ebitmap_node *n, *temp;
  148. if (!e)
  149. return;
  150. n = e->node;
  151. while (n) {
  152. temp = n;
  153. n = n->next;
  154. kfree(temp);
  155. }
  156. e->highbit = 0;
  157. e->node = NULL;
  158. return;
  159. }
  160. int ebitmap_read(struct ebitmap *e, void *fp)
  161. {
  162. int rc;
  163. struct ebitmap_node *n, *l;
  164. __le32 buf[3];
  165. u32 mapsize, count, i;
  166. __le64 map;
  167. ebitmap_init(e);
  168. rc = next_entry(buf, fp, sizeof buf);
  169. if (rc < 0)
  170. goto out;
  171. mapsize = le32_to_cpu(buf[0]);
  172. e->highbit = le32_to_cpu(buf[1]);
  173. count = le32_to_cpu(buf[2]);
  174. if (mapsize != MAPSIZE) {
  175. printk(KERN_ERR "security: ebitmap: map size %u does not "
  176. "match my size %Zd (high bit was %d)\n", mapsize,
  177. MAPSIZE, e->highbit);
  178. goto bad;
  179. }
  180. if (!e->highbit) {
  181. e->node = NULL;
  182. goto ok;
  183. }
  184. if (e->highbit & (MAPSIZE - 1)) {
  185. printk(KERN_ERR "security: ebitmap: high bit (%d) is not a "
  186. "multiple of the map size (%Zd)\n", e->highbit, MAPSIZE);
  187. goto bad;
  188. }
  189. l = NULL;
  190. for (i = 0; i < count; i++) {
  191. rc = next_entry(buf, fp, sizeof(u32));
  192. if (rc < 0) {
  193. printk(KERN_ERR "security: ebitmap: truncated map\n");
  194. goto bad;
  195. }
  196. n = kzalloc(sizeof(*n), GFP_KERNEL);
  197. if (!n) {
  198. printk(KERN_ERR "security: ebitmap: out of memory\n");
  199. rc = -ENOMEM;
  200. goto bad;
  201. }
  202. n->startbit = le32_to_cpu(buf[0]);
  203. if (n->startbit & (MAPSIZE - 1)) {
  204. printk(KERN_ERR "security: ebitmap start bit (%d) is "
  205. "not a multiple of the map size (%Zd)\n",
  206. n->startbit, MAPSIZE);
  207. goto bad_free;
  208. }
  209. if (n->startbit > (e->highbit - MAPSIZE)) {
  210. printk(KERN_ERR "security: ebitmap start bit (%d) is "
  211. "beyond the end of the bitmap (%Zd)\n",
  212. n->startbit, (e->highbit - MAPSIZE));
  213. goto bad_free;
  214. }
  215. rc = next_entry(&map, fp, sizeof(u64));
  216. if (rc < 0) {
  217. printk(KERN_ERR "security: ebitmap: truncated map\n");
  218. goto bad_free;
  219. }
  220. n->map = le64_to_cpu(map);
  221. if (!n->map) {
  222. printk(KERN_ERR "security: ebitmap: null map in "
  223. "ebitmap (startbit %d)\n", n->startbit);
  224. goto bad_free;
  225. }
  226. if (l) {
  227. if (n->startbit <= l->startbit) {
  228. printk(KERN_ERR "security: ebitmap: start "
  229. "bit %d comes after start bit %d\n",
  230. n->startbit, l->startbit);
  231. goto bad_free;
  232. }
  233. l->next = n;
  234. } else
  235. e->node = n;
  236. l = n;
  237. }
  238. ok:
  239. rc = 0;
  240. out:
  241. return rc;
  242. bad_free:
  243. kfree(n);
  244. bad:
  245. if (!rc)
  246. rc = -EINVAL;
  247. ebitmap_destroy(e);
  248. goto out;
  249. }