aboutsummaryrefslogtreecommitdiffstats
path: root/net/netlabel
diff options
context:
space:
mode:
authorPaul Moore <paul.moore@hp.com>2006-11-29 13:18:18 -0500
committerDavid S. Miller <davem@sunset.davemloft.net>2006-12-03 00:31:36 -0500
commit02752760359db6b00a3ffb1acfc13ef8d9eb1e3f (patch)
tree796cd65fd4cd732b295e61dac194efbf36b78842 /net/netlabel
parentef91fd522ba3c88d9c68261c243567bc4c5a8f55 (diff)
NetLabel: convert to an extensibile/sparse category bitmap
The original NetLabel category bitmap was a straight char bitmap which worked fine for the initial release as it only supported 240 bits due to limitations in the CIPSO restricted bitmap tag (tag type 0x01). This patch converts that straight char bitmap into an extensibile/sparse bitmap in order to lay the foundation for other CIPSO tag types and protocols. This patch also has a nice side effect in that all of the security attributes passed by NetLabel into the LSM are now in a format which is in the host's native byte/bit ordering which makes the LSM specific code much simpler; look at the changes in security/selinux/ss/ebitmap.c as an example. Signed-off-by: Paul Moore <paul.moore@hp.com> Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'net/netlabel')
-rw-r--r--net/netlabel/netlabel_kapi.c201
1 files changed, 201 insertions, 0 deletions
diff --git a/net/netlabel/netlabel_kapi.c b/net/netlabel/netlabel_kapi.c
index b35ebf94918c..e03a3282c551 100644
--- a/net/netlabel/netlabel_kapi.c
+++ b/net/netlabel/netlabel_kapi.c
@@ -40,6 +40,207 @@
40#include "netlabel_user.h" 40#include "netlabel_user.h"
41 41
42/* 42/*
43 * Security Attribute Functions
44 */
45
46/**
47 * netlbl_secattr_catmap_walk - Walk a LSM secattr catmap looking for a bit
48 * @catmap: the category bitmap
49 * @offset: the offset to start searching at, in bits
50 *
51 * Description:
52 * This function walks a LSM secattr category bitmap starting at @offset and
53 * returns the spot of the first set bit or -ENOENT if no bits are set.
54 *
55 */
56int netlbl_secattr_catmap_walk(struct netlbl_lsm_secattr_catmap *catmap,
57 u32 offset)
58{
59 struct netlbl_lsm_secattr_catmap *iter = catmap;
60 u32 node_idx;
61 u32 node_bit;
62 NETLBL_CATMAP_MAPTYPE bitmap;
63
64 if (offset > iter->startbit) {
65 while (offset >= (iter->startbit + NETLBL_CATMAP_SIZE)) {
66 iter = iter->next;
67 if (iter == NULL)
68 return -ENOENT;
69 }
70 node_idx = (offset - iter->startbit) / NETLBL_CATMAP_MAPSIZE;
71 node_bit = offset - iter->startbit -
72 (NETLBL_CATMAP_MAPSIZE * node_idx);
73 } else {
74 node_idx = 0;
75 node_bit = 0;
76 }
77 bitmap = iter->bitmap[node_idx] >> node_bit;
78
79 for (;;) {
80 if (bitmap != 0) {
81 while ((bitmap & NETLBL_CATMAP_BIT) == 0) {
82 bitmap >>= 1;
83 node_bit++;
84 }
85 return iter->startbit +
86 (NETLBL_CATMAP_MAPSIZE * node_idx) + node_bit;
87 }
88 if (++node_idx >= NETLBL_CATMAP_MAPCNT) {
89 if (iter->next != NULL) {
90 iter = iter->next;
91 node_idx = 0;
92 } else
93 return -ENOENT;
94 }
95 bitmap = iter->bitmap[node_idx];
96 node_bit = 0;
97 }
98
99 return -ENOENT;
100}
101
102/**
103 * netlbl_secattr_catmap_walk_rng - Find the end of a string of set bits
104 * @catmap: the category bitmap
105 * @offset: the offset to start searching at, in bits
106 *
107 * Description:
108 * This function walks a LSM secattr category bitmap starting at @offset and
109 * returns the spot of the first cleared bit or -ENOENT if the offset is past
110 * the end of the bitmap.
111 *
112 */
113int netlbl_secattr_catmap_walk_rng(struct netlbl_lsm_secattr_catmap *catmap,
114 u32 offset)
115{
116 struct netlbl_lsm_secattr_catmap *iter = catmap;
117 u32 node_idx;
118 u32 node_bit;
119 NETLBL_CATMAP_MAPTYPE bitmask;
120 NETLBL_CATMAP_MAPTYPE bitmap;
121
122 if (offset > iter->startbit) {
123 while (offset >= (iter->startbit + NETLBL_CATMAP_SIZE)) {
124 iter = iter->next;
125 if (iter == NULL)
126 return -ENOENT;
127 }
128 node_idx = (offset - iter->startbit) / NETLBL_CATMAP_MAPSIZE;
129 node_bit = offset - iter->startbit -
130 (NETLBL_CATMAP_MAPSIZE * node_idx);
131 } else {
132 node_idx = 0;
133 node_bit = 0;
134 }
135 bitmask = NETLBL_CATMAP_BIT << node_bit;
136
137 for (;;) {
138 bitmap = iter->bitmap[node_idx];
139 while (bitmask != 0 && (bitmap & bitmask) != 0) {
140 bitmask <<= 1;
141 node_bit++;
142 }
143
144 if (bitmask != 0)
145 return iter->startbit +
146 (NETLBL_CATMAP_MAPSIZE * node_idx) +
147 node_bit - 1;
148 else if (++node_idx >= NETLBL_CATMAP_MAPCNT) {
149 if (iter->next == NULL)
150 return iter->startbit + NETLBL_CATMAP_SIZE - 1;
151 iter = iter->next;
152 node_idx = 0;
153 }
154 bitmask = NETLBL_CATMAP_BIT;
155 node_bit = 0;
156 }
157
158 return -ENOENT;
159}
160
161/**
162 * netlbl_secattr_catmap_setbit - Set a bit in a LSM secattr catmap
163 * @catmap: the category bitmap
164 * @bit: the bit to set
165 * @flags: memory allocation flags
166 *
167 * Description:
168 * Set the bit specified by @bit in @catmap. Returns zero on success,
169 * negative values on failure.
170 *
171 */
172int netlbl_secattr_catmap_setbit(struct netlbl_lsm_secattr_catmap *catmap,
173 u32 bit,
174 gfp_t flags)
175{
176 struct netlbl_lsm_secattr_catmap *iter = catmap;
177 u32 node_bit;
178 u32 node_idx;
179
180 while (iter->next != NULL &&
181 bit >= (iter->startbit + NETLBL_CATMAP_SIZE))
182 iter = iter->next;
183 if (bit >= (iter->startbit + NETLBL_CATMAP_SIZE)) {
184 iter->next = netlbl_secattr_catmap_alloc(flags);
185 if (iter->next == NULL)
186 return -ENOMEM;
187 iter = iter->next;
188 iter->startbit = bit & ~(NETLBL_CATMAP_SIZE - 1);
189 }
190
191 /* gcc always rounds to zero when doing integer division */
192 node_idx = (bit - iter->startbit) / NETLBL_CATMAP_MAPSIZE;
193 node_bit = bit - iter->startbit - (NETLBL_CATMAP_MAPSIZE * node_idx);
194 iter->bitmap[node_idx] |= NETLBL_CATMAP_BIT << node_bit;
195
196 return 0;
197}
198
199/**
200 * netlbl_secattr_catmap_setrng - Set a range of bits in a LSM secattr catmap
201 * @catmap: the category bitmap
202 * @start: the starting bit
203 * @end: the last bit in the string
204 * @flags: memory allocation flags
205 *
206 * Description:
207 * Set a range of bits, starting at @start and ending with @end. Returns zero
208 * on success, negative values on failure.
209 *
210 */
211int netlbl_secattr_catmap_setrng(struct netlbl_lsm_secattr_catmap *catmap,
212 u32 start,
213 u32 end,
214 gfp_t flags)
215{
216 int ret_val = 0;
217 struct netlbl_lsm_secattr_catmap *iter = catmap;
218 u32 iter_max_spot;
219 u32 spot;
220
221 /* XXX - This could probably be made a bit faster by combining writes
222 * to the catmap instead of setting a single bit each time, but for
223 * right now skipping to the start of the range in the catmap should
224 * be a nice improvement over calling the individual setbit function
225 * repeatedly from a loop. */
226
227 while (iter->next != NULL &&
228 start >= (iter->startbit + NETLBL_CATMAP_SIZE))
229 iter = iter->next;
230 iter_max_spot = iter->startbit + NETLBL_CATMAP_SIZE;
231
232 for (spot = start; spot <= end && ret_val == 0; spot++) {
233 if (spot >= iter_max_spot && iter->next != NULL) {
234 iter = iter->next;
235 iter_max_spot = iter->startbit + NETLBL_CATMAP_SIZE;
236 }
237 ret_val = netlbl_secattr_catmap_setbit(iter, spot, GFP_ATOMIC);
238 }
239
240 return ret_val;
241}
242
243/*
43 * LSM Functions 244 * LSM Functions
44 */ 245 */
45 246