aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorStephen Smalley <sds@tycho.nsa.gov>2005-09-03 18:55:16 -0400
committerLinus Torvalds <torvalds@evo.osdl.org>2005-09-05 03:05:50 -0400
commit782ebb992ec20b5afdd5786ee8c2f1b58b631f24 (patch)
treeadf0af44fa591d803ec6b9ab7541ff3e5745dd93 /security
parent720d6c29e146e96cca858057469951e91e0e6850 (diff)
[PATCH] selinux: Reduce memory use by avtab
This patch improves memory use by SELinux by both reducing the avtab node size and reducing the number of avtab nodes. The memory savings are substantial, e.g. on a 64-bit system after boot, James Morris reported the following data for the targeted and strict policies: #objs objsize kernmem Targeted: Before: 237888 40 9.1MB After: 19968 24 468KB Strict: Before: 571680 40 21.81MB After: 221052 24 5.06MB The improvement in memory use comes at a cost in the speed of security server computations of access vectors, but these computations are only required on AVC cache misses, and performance measurements by James Morris using a number of benchmarks have shown that the change does not cause any significant degradation. Note that a rebuilt policy via an updated policy toolchain (libsepol/checkpolicy) is required in order to gain the full benefits of this patch, although some memory savings benefits are immediately applied even to older policies (in particular, the reduction in avtab node size). Sources for the updated toolchain are presently available from the sourceforge CVS tree (http://sourceforge.net/cvs/?group_id=21266), and tarballs are available from http://www.flux.utah.edu/~sds. Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov> Signed-off-by: James Morris <jmorris@namei.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'security')
-rw-r--r--security/selinux/include/security.h3
-rw-r--r--security/selinux/ss/avtab.c192
-rw-r--r--security/selinux/ss/avtab.h37
-rw-r--r--security/selinux/ss/conditional.c205
-rw-r--r--security/selinux/ss/ebitmap.h30
-rw-r--r--security/selinux/ss/mls.c42
-rw-r--r--security/selinux/ss/policydb.c47
-rw-r--r--security/selinux/ss/policydb.h3
-rw-r--r--security/selinux/ss/services.c76
9 files changed, 400 insertions, 235 deletions
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index 71c0a19c9753..5f016c98056f 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -23,10 +23,11 @@
23#define POLICYDB_VERSION_NLCLASS 18 23#define POLICYDB_VERSION_NLCLASS 18
24#define POLICYDB_VERSION_VALIDATETRANS 19 24#define POLICYDB_VERSION_VALIDATETRANS 19
25#define POLICYDB_VERSION_MLS 19 25#define POLICYDB_VERSION_MLS 19
26#define POLICYDB_VERSION_AVTAB 20
26 27
27/* Range of policy versions we understand*/ 28/* Range of policy versions we understand*/
28#define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE 29#define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE
29#define POLICYDB_VERSION_MAX POLICYDB_VERSION_MLS 30#define POLICYDB_VERSION_MAX POLICYDB_VERSION_AVTAB
30 31
31#ifdef CONFIG_SECURITY_SELINUX_BOOTPARAM 32#ifdef CONFIG_SECURITY_SELINUX_BOOTPARAM
32extern int selinux_enabled; 33extern int selinux_enabled;
diff --git a/security/selinux/ss/avtab.c b/security/selinux/ss/avtab.c
index f238c034c44e..2e71af67b5d8 100644
--- a/security/selinux/ss/avtab.c
+++ b/security/selinux/ss/avtab.c
@@ -58,6 +58,7 @@ static int avtab_insert(struct avtab *h, struct avtab_key *key, struct avtab_dat
58{ 58{
59 int hvalue; 59 int hvalue;
60 struct avtab_node *prev, *cur, *newnode; 60 struct avtab_node *prev, *cur, *newnode;
61 u16 specified = key->specified & ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD);
61 62
62 if (!h) 63 if (!h)
63 return -EINVAL; 64 return -EINVAL;
@@ -69,7 +70,7 @@ static int avtab_insert(struct avtab *h, struct avtab_key *key, struct avtab_dat
69 if (key->source_type == cur->key.source_type && 70 if (key->source_type == cur->key.source_type &&
70 key->target_type == cur->key.target_type && 71 key->target_type == cur->key.target_type &&
71 key->target_class == cur->key.target_class && 72 key->target_class == cur->key.target_class &&
72 (datum->specified & cur->datum.specified)) 73 (specified & cur->key.specified))
73 return -EEXIST; 74 return -EEXIST;
74 if (key->source_type < cur->key.source_type) 75 if (key->source_type < cur->key.source_type)
75 break; 76 break;
@@ -98,6 +99,7 @@ avtab_insert_nonunique(struct avtab * h, struct avtab_key * key, struct avtab_da
98{ 99{
99 int hvalue; 100 int hvalue;
100 struct avtab_node *prev, *cur, *newnode; 101 struct avtab_node *prev, *cur, *newnode;
102 u16 specified = key->specified & ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD);
101 103
102 if (!h) 104 if (!h)
103 return NULL; 105 return NULL;
@@ -108,7 +110,7 @@ avtab_insert_nonunique(struct avtab * h, struct avtab_key * key, struct avtab_da
108 if (key->source_type == cur->key.source_type && 110 if (key->source_type == cur->key.source_type &&
109 key->target_type == cur->key.target_type && 111 key->target_type == cur->key.target_type &&
110 key->target_class == cur->key.target_class && 112 key->target_class == cur->key.target_class &&
111 (datum->specified & cur->datum.specified)) 113 (specified & cur->key.specified))
112 break; 114 break;
113 if (key->source_type < cur->key.source_type) 115 if (key->source_type < cur->key.source_type)
114 break; 116 break;
@@ -125,10 +127,11 @@ avtab_insert_nonunique(struct avtab * h, struct avtab_key * key, struct avtab_da
125 return newnode; 127 return newnode;
126} 128}
127 129
128struct avtab_datum *avtab_search(struct avtab *h, struct avtab_key *key, int specified) 130struct avtab_datum *avtab_search(struct avtab *h, struct avtab_key *key)
129{ 131{
130 int hvalue; 132 int hvalue;
131 struct avtab_node *cur; 133 struct avtab_node *cur;
134 u16 specified = key->specified & ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD);
132 135
133 if (!h) 136 if (!h)
134 return NULL; 137 return NULL;
@@ -138,7 +141,7 @@ struct avtab_datum *avtab_search(struct avtab *h, struct avtab_key *key, int spe
138 if (key->source_type == cur->key.source_type && 141 if (key->source_type == cur->key.source_type &&
139 key->target_type == cur->key.target_type && 142 key->target_type == cur->key.target_type &&
140 key->target_class == cur->key.target_class && 143 key->target_class == cur->key.target_class &&
141 (specified & cur->datum.specified)) 144 (specified & cur->key.specified))
142 return &cur->datum; 145 return &cur->datum;
143 146
144 if (key->source_type < cur->key.source_type) 147 if (key->source_type < cur->key.source_type)
@@ -159,10 +162,11 @@ struct avtab_datum *avtab_search(struct avtab *h, struct avtab_key *key, int spe
159 * conjunction with avtab_search_next_node() 162 * conjunction with avtab_search_next_node()
160 */ 163 */
161struct avtab_node* 164struct avtab_node*
162avtab_search_node(struct avtab *h, struct avtab_key *key, int specified) 165avtab_search_node(struct avtab *h, struct avtab_key *key)
163{ 166{
164 int hvalue; 167 int hvalue;
165 struct avtab_node *cur; 168 struct avtab_node *cur;
169 u16 specified = key->specified & ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD);
166 170
167 if (!h) 171 if (!h)
168 return NULL; 172 return NULL;
@@ -172,7 +176,7 @@ avtab_search_node(struct avtab *h, struct avtab_key *key, int specified)
172 if (key->source_type == cur->key.source_type && 176 if (key->source_type == cur->key.source_type &&
173 key->target_type == cur->key.target_type && 177 key->target_type == cur->key.target_type &&
174 key->target_class == cur->key.target_class && 178 key->target_class == cur->key.target_class &&
175 (specified & cur->datum.specified)) 179 (specified & cur->key.specified))
176 return cur; 180 return cur;
177 181
178 if (key->source_type < cur->key.source_type) 182 if (key->source_type < cur->key.source_type)
@@ -196,11 +200,12 @@ avtab_search_node_next(struct avtab_node *node, int specified)
196 if (!node) 200 if (!node)
197 return NULL; 201 return NULL;
198 202
203 specified &= ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD);
199 for (cur = node->next; cur; cur = cur->next) { 204 for (cur = node->next; cur; cur = cur->next) {
200 if (node->key.source_type == cur->key.source_type && 205 if (node->key.source_type == cur->key.source_type &&
201 node->key.target_type == cur->key.target_type && 206 node->key.target_type == cur->key.target_type &&
202 node->key.target_class == cur->key.target_class && 207 node->key.target_class == cur->key.target_class &&
203 (specified & cur->datum.specified)) 208 (specified & cur->key.specified))
204 return cur; 209 return cur;
205 210
206 if (node->key.source_type < cur->key.source_type) 211 if (node->key.source_type < cur->key.source_type)
@@ -278,75 +283,126 @@ void avtab_hash_eval(struct avtab *h, char *tag)
278 max_chain_len); 283 max_chain_len);
279} 284}
280 285
281int avtab_read_item(void *fp, struct avtab_datum *avdatum, struct avtab_key *avkey) 286static uint16_t spec_order[] = {
287 AVTAB_ALLOWED,
288 AVTAB_AUDITDENY,
289 AVTAB_AUDITALLOW,
290 AVTAB_TRANSITION,
291 AVTAB_CHANGE,
292 AVTAB_MEMBER
293};
294
295int avtab_read_item(void *fp, u32 vers, struct avtab *a,
296 int (*insertf)(struct avtab *a, struct avtab_key *k,
297 struct avtab_datum *d, void *p),
298 void *p)
282{ 299{
283 u32 buf[7]; 300 u16 buf16[4], enabled;
284 u32 items, items2; 301 u32 buf32[7], items, items2, val;
285 int rc; 302 struct avtab_key key;
303 struct avtab_datum datum;
304 int i, rc;
305
306 memset(&key, 0, sizeof(struct avt