hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/security/selinux/ss/policydb.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Implementation of the policy database.
34 *
....@@ -25,9 +26,6 @@
2526 * Copyright (C) 2007 Hewlett-Packard Development Company, L.P.
2627 * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc.
2728 * Copyright (C) 2003 - 2004 Tresys Technology, LLC
28
- * This program is free software; you can redistribute it and/or modify
29
- * it under the terms of the GNU General Public License as published by
30
- * the Free Software Foundation, version 2.
3129 */
3230
3331 #include <linux/kernel.h>
....@@ -36,7 +34,6 @@
3634 #include <linux/string.h>
3735 #include <linux/errno.h>
3836 #include <linux/audit.h>
39
-#include <linux/flex_array.h>
4037 #include "security.h"
4138
4239 #include "policydb.h"
....@@ -58,17 +55,6 @@
5855 "categories",
5956 };
6057 #endif
61
-
62
-static unsigned int symtab_sizes[SYM_NUM] = {
63
- 2,
64
- 32,
65
- 16,
66
- 512,
67
- 128,
68
- 16,
69
- 16,
70
- 16,
71
-};
7258
7359 struct policydb_compat_info {
7460 int version;
....@@ -163,6 +149,16 @@
163149 .sym_num = SYM_NUM,
164150 .ocon_num = OCON_NUM,
165151 },
152
+ {
153
+ .version = POLICYDB_VERSION_GLBLUB,
154
+ .sym_num = SYM_NUM,
155
+ .ocon_num = OCON_NUM,
156
+ },
157
+ {
158
+ .version = POLICYDB_VERSION_COMP_FTRANS,
159
+ .sym_num = SYM_NUM,
160
+ .ocon_num = OCON_NUM,
161
+ },
166162 };
167163
168164 static struct policydb_compat_info *policydb_lookup_compat(int version)
....@@ -177,437 +173,6 @@
177173 }
178174 }
179175 return info;
180
-}
181
-
182
-/*
183
- * Initialize the role table.
184
- */
185
-static int roles_init(struct policydb *p)
186
-{
187
- char *key = NULL;
188
- int rc;
189
- struct role_datum *role;
190
-
191
- role = kzalloc(sizeof(*role), GFP_KERNEL);
192
- if (!role)
193
- return -ENOMEM;
194
-
195
- rc = -EINVAL;
196
- role->value = ++p->p_roles.nprim;
197
- if (role->value != OBJECT_R_VAL)
198
- goto out;
199
-
200
- rc = -ENOMEM;
201
- key = kstrdup(OBJECT_R, GFP_KERNEL);
202
- if (!key)
203
- goto out;
204
-
205
- rc = hashtab_insert(p->p_roles.table, key, role);
206
- if (rc)
207
- goto out;
208
-
209
- return 0;
210
-out:
211
- kfree(key);
212
- kfree(role);
213
- return rc;
214
-}
215
-
216
-static u32 filenametr_hash(struct hashtab *h, const void *k)
217
-{
218
- const struct filename_trans *ft = k;
219
- unsigned long hash;
220
- unsigned int byte_num;
221
- unsigned char focus;
222
-
223
- hash = ft->stype ^ ft->ttype ^ ft->tclass;
224
-
225
- byte_num = 0;
226
- while ((focus = ft->name[byte_num++]))
227
- hash = partial_name_hash(focus, hash);
228
- return hash & (h->size - 1);
229
-}
230
-
231
-static int filenametr_cmp(struct hashtab *h, const void *k1, const void *k2)
232
-{
233
- const struct filename_trans *ft1 = k1;
234
- const struct filename_trans *ft2 = k2;
235
- int v;
236
-
237
- v = ft1->stype - ft2->stype;
238
- if (v)
239
- return v;
240
-
241
- v = ft1->ttype - ft2->ttype;
242
- if (v)
243
- return v;
244
-
245
- v = ft1->tclass - ft2->tclass;
246
- if (v)
247
- return v;
248
-
249
- return strcmp(ft1->name, ft2->name);
250
-
251
-}
252
-
253
-static u32 rangetr_hash(struct hashtab *h, const void *k)
254
-{
255
- const struct range_trans *key = k;
256
- return (key->source_type + (key->target_type << 3) +
257
- (key->target_class << 5)) & (h->size - 1);
258
-}
259
-
260
-static int rangetr_cmp(struct hashtab *h, const void *k1, const void *k2)
261
-{
262
- const struct range_trans *key1 = k1, *key2 = k2;
263
- int v;
264
-
265
- v = key1->source_type - key2->source_type;
266
- if (v)
267
- return v;
268
-
269
- v = key1->target_type - key2->target_type;
270
- if (v)
271
- return v;
272
-
273
- v = key1->target_class - key2->target_class;
274
-
275
- return v;
276
-}
277
-
278
-static int (*destroy_f[SYM_NUM]) (void *key, void *datum, void *datap);
279
-
280
-/*
281
- * Initialize a policy database structure.
282
- */
283
-static int policydb_init(struct policydb *p)
284
-{
285
- int i, rc;
286
-
287
- memset(p, 0, sizeof(*p));
288
-
289
- for (i = 0; i < SYM_NUM; i++) {
290
- rc = symtab_init(&p->symtab[i], symtab_sizes[i]);
291
- if (rc)
292
- goto out;
293
- }
294
-
295
- rc = avtab_init(&p->te_avtab);
296
- if (rc)
297
- goto out;
298
-
299
- rc = roles_init(p);
300
- if (rc)
301
- goto out;
302
-
303
- rc = cond_policydb_init(p);
304
- if (rc)
305
- goto out;
306
-
307
- p->filename_trans = hashtab_create(filenametr_hash, filenametr_cmp, (1 << 10));
308
- if (!p->filename_trans) {
309
- rc = -ENOMEM;
310
- goto out;
311
- }
312
-
313
- p->range_tr = hashtab_create(rangetr_hash, rangetr_cmp, 256);
314
- if (!p->range_tr) {
315
- rc = -ENOMEM;
316
- goto out;
317
- }
318
-
319
- ebitmap_init(&p->filename_trans_ttypes);
320
- ebitmap_init(&p->policycaps);
321
- ebitmap_init(&p->permissive_map);
322
-
323
- return 0;
324
-out:
325
- hashtab_destroy(p->filename_trans);
326
- hashtab_destroy(p->range_tr);
327
- for (i = 0; i < SYM_NUM; i++) {
328
- hashtab_map(p->symtab[i].table, destroy_f[i], NULL);
329
- hashtab_destroy(p->symtab[i].table);
330
- }
331
- return rc;
332
-}
333
-
334
-/*
335
- * The following *_index functions are used to
336
- * define the val_to_name and val_to_struct arrays
337
- * in a policy database structure. The val_to_name
338
- * arrays are used when converting security context
339
- * structures into string representations. The
340
- * val_to_struct arrays are used when the attributes
341
- * of a class, role, or user are needed.
342
- */
343
-
344
-static int common_index(void *key, void *datum, void *datap)
345
-{
346
- struct policydb *p;
347
- struct common_datum *comdatum;
348
- struct flex_array *fa;
349
-
350
- comdatum = datum;
351
- p = datap;
352
- if (!comdatum->value || comdatum->value > p->p_commons.nprim)
353
- return -EINVAL;
354
-
355
- fa = p->sym_val_to_name[SYM_COMMONS];
356
- if (flex_array_put_ptr(fa, comdatum->value - 1, key,
357
- GFP_KERNEL | __GFP_ZERO))
358
- BUG();
359
- return 0;
360
-}
361
-
362
-static int class_index(void *key, void *datum, void *datap)
363
-{
364
- struct policydb *p;
365
- struct class_datum *cladatum;
366
- struct flex_array *fa;
367
-
368
- cladatum = datum;
369
- p = datap;
370
- if (!cladatum->value || cladatum->value > p->p_classes.nprim)
371
- return -EINVAL;
372
- fa = p->sym_val_to_name[SYM_CLASSES];
373
- if (flex_array_put_ptr(fa, cladatum->value - 1, key,
374
- GFP_KERNEL | __GFP_ZERO))
375
- BUG();
376
- p->class_val_to_struct[cladatum->value - 1] = cladatum;
377
- return 0;
378
-}
379
-
380
-static int role_index(void *key, void *datum, void *datap)
381
-{
382
- struct policydb *p;
383
- struct role_datum *role;
384
- struct flex_array *fa;
385
-
386
- role = datum;
387
- p = datap;
388
- if (!role->value
389
- || role->value > p->p_roles.nprim
390
- || role->bounds > p->p_roles.nprim)
391
- return -EINVAL;
392
-
393
- fa = p->sym_val_to_name[SYM_ROLES];
394
- if (flex_array_put_ptr(fa, role->value - 1, key,
395
- GFP_KERNEL | __GFP_ZERO))
396
- BUG();
397
- p->role_val_to_struct[role->value - 1] = role;
398
- return 0;
399
-}
400
-
401
-static int type_index(void *key, void *datum, void *datap)
402
-{
403
- struct policydb *p;
404
- struct type_datum *typdatum;
405
- struct flex_array *fa;
406
-
407
- typdatum = datum;
408
- p = datap;
409
-
410
- if (typdatum->primary) {
411
- if (!typdatum->value
412
- || typdatum->value > p->p_types.nprim
413
- || typdatum->bounds > p->p_types.nprim)
414
- return -EINVAL;
415
- fa = p->sym_val_to_name[SYM_TYPES];
416
- if (flex_array_put_ptr(fa, typdatum->value - 1, key,
417
- GFP_KERNEL | __GFP_ZERO))
418
- BUG();
419
-
420
- fa = p->type_val_to_struct_array;
421
- if (flex_array_put_ptr(fa, typdatum->value - 1, typdatum,
422
- GFP_KERNEL | __GFP_ZERO))
423
- BUG();
424
- }
425
-
426
- return 0;
427
-}
428
-
429
-static int user_index(void *key, void *datum, void *datap)
430
-{
431
- struct policydb *p;
432
- struct user_datum *usrdatum;
433
- struct flex_array *fa;
434
-
435
- usrdatum = datum;
436
- p = datap;
437
- if (!usrdatum->value
438
- || usrdatum->value > p->p_users.nprim
439
- || usrdatum->bounds > p->p_users.nprim)
440
- return -EINVAL;
441
-
442
- fa = p->sym_val_to_name[SYM_USERS];
443
- if (flex_array_put_ptr(fa, usrdatum->value - 1, key,
444
- GFP_KERNEL | __GFP_ZERO))
445
- BUG();
446
- p->user_val_to_struct[usrdatum->value - 1] = usrdatum;
447
- return 0;
448
-}
449
-
450
-static int sens_index(void *key, void *datum, void *datap)
451
-{
452
- struct policydb *p;
453
- struct level_datum *levdatum;
454
- struct flex_array *fa;
455
-
456
- levdatum = datum;
457
- p = datap;
458
-
459
- if (!levdatum->isalias) {
460
- if (!levdatum->level->sens ||
461
- levdatum->level->sens > p->p_levels.nprim)
462
- return -EINVAL;
463
- fa = p->sym_val_to_name[SYM_LEVELS];
464
- if (flex_array_put_ptr(fa, levdatum->level->sens - 1, key,
465
- GFP_KERNEL | __GFP_ZERO))
466
- BUG();
467
- }
468
-
469
- return 0;
470
-}
471
-
472
-static int cat_index(void *key, void *datum, void *datap)
473
-{
474
- struct policydb *p;
475
- struct cat_datum *catdatum;
476
- struct flex_array *fa;
477
-
478
- catdatum = datum;
479
- p = datap;
480
-
481
- if (!catdatum->isalias) {
482
- if (!catdatum->value || catdatum->value > p->p_cats.nprim)
483
- return -EINVAL;
484
- fa = p->sym_val_to_name[SYM_CATS];
485
- if (flex_array_put_ptr(fa, catdatum->value - 1, key,
486
- GFP_KERNEL | __GFP_ZERO))
487
- BUG();
488
- }
489
-
490
- return 0;
491
-}
492
-
493
-static int (*index_f[SYM_NUM]) (void *key, void *datum, void *datap) =
494
-{
495
- common_index,
496
- class_index,
497
- role_index,
498
- type_index,
499
- user_index,
500
- cond_index_bool,
501
- sens_index,
502
- cat_index,
503
-};
504
-
505
-#ifdef DEBUG_HASHES
506
-static void hash_eval(struct hashtab *h, const char *hash_name)
507
-{
508
- struct hashtab_info info;
509
-
510
- hashtab_stat(h, &info);
511
- pr_debug("SELinux: %s: %d entries and %d/%d buckets used, "
512
- "longest chain length %d\n", hash_name, h->nel,
513
- info.slots_used, h->size, info.max_chain_len);
514
-}
515
-
516
-static void symtab_hash_eval(struct symtab *s)
517
-{
518
- int i;
519
-
520
- for (i = 0; i < SYM_NUM; i++)
521
- hash_eval(s[i].table, symtab_name[i]);
522
-}
523
-
524
-#else
525
-static inline void hash_eval(struct hashtab *h, char *hash_name)
526
-{
527
-}
528
-#endif
529
-
530
-/*
531
- * Define the other val_to_name and val_to_struct arrays
532
- * in a policy database structure.
533
- *
534
- * Caller must clean up on failure.
535
- */
536
-static int policydb_index(struct policydb *p)
537
-{
538
- int i, rc;
539
-
540
- if (p->mls_enabled)
541
- pr_debug("SELinux: %d users, %d roles, %d types, %d bools, %d sens, %d cats\n",
542
- p->p_users.nprim, p->p_roles.nprim, p->p_types.nprim,
543
- p->p_bools.nprim, p->p_levels.nprim, p->p_cats.nprim);
544
- else
545
- pr_debug("SELinux: %d users, %d roles, %d types, %d bools\n",
546
- p->p_users.nprim, p->p_roles.nprim, p->p_types.nprim,
547
- p->p_bools.nprim);
548
-
549
- pr_debug("SELinux: %d classes, %d rules\n",
550
- p->p_classes.nprim, p->te_avtab.nel);
551
-
552
-#ifdef DEBUG_HASHES
553
- avtab_hash_eval(&p->te_avtab, "rules");
554
- symtab_hash_eval(p->symtab);
555
-#endif
556
-
557
- p->class_val_to_struct = kcalloc(p->p_classes.nprim,
558
- sizeof(*p->class_val_to_struct),
559
- GFP_KERNEL);
560
- if (!p->class_val_to_struct)
561
- return -ENOMEM;
562
-
563
- p->role_val_to_struct = kcalloc(p->p_roles.nprim,
564
- sizeof(*p->role_val_to_struct),
565
- GFP_KERNEL);
566
- if (!p->role_val_to_struct)
567
- return -ENOMEM;
568
-
569
- p->user_val_to_struct = kcalloc(p->p_users.nprim,
570
- sizeof(*p->user_val_to_struct),
571
- GFP_KERNEL);
572
- if (!p->user_val_to_struct)
573
- return -ENOMEM;
574
-
575
- /* Yes, I want the sizeof the pointer, not the structure */
576
- p->type_val_to_struct_array = flex_array_alloc(sizeof(struct type_datum *),
577
- p->p_types.nprim,
578
- GFP_KERNEL | __GFP_ZERO);
579
- if (!p->type_val_to_struct_array)
580
- return -ENOMEM;
581
-
582
- rc = flex_array_prealloc(p->type_val_to_struct_array, 0,
583
- p->p_types.nprim, GFP_KERNEL | __GFP_ZERO);
584
- if (rc)
585
- goto out;
586
-
587
- rc = cond_init_bool_indexes(p);
588
- if (rc)
589
- goto out;
590
-
591
- for (i = 0; i < SYM_NUM; i++) {
592
- p->sym_val_to_name[i] = flex_array_alloc(sizeof(char *),
593
- p->symtab[i].nprim,
594
- GFP_KERNEL | __GFP_ZERO);
595
- if (!p->sym_val_to_name[i])
596
- return -ENOMEM;
597
-
598
- rc = flex_array_prealloc(p->sym_val_to_name[i],
599
- 0, p->symtab[i].nprim,
600
- GFP_KERNEL | __GFP_ZERO);
601
- if (rc)
602
- goto out;
603
-
604
- rc = hashtab_map(p->symtab[i].table, index_f[i], p);
605
- if (rc)
606
- goto out;
607
- }
608
- rc = 0;
609
-out:
610
- return rc;
611176 }
612177
613178 /*
....@@ -630,8 +195,8 @@
630195 kfree(key);
631196 if (datum) {
632197 comdatum = datum;
633
- hashtab_map(comdatum->permissions.table, perm_destroy, NULL);
634
- hashtab_destroy(comdatum->permissions.table);
198
+ hashtab_map(&comdatum->permissions.table, perm_destroy, NULL);
199
+ hashtab_destroy(&comdatum->permissions.table);
635200 }
636201 kfree(datum);
637202 return 0;
....@@ -659,8 +224,8 @@
659224 kfree(key);
660225 if (datum) {
661226 cladatum = datum;
662
- hashtab_map(cladatum->permissions.table, perm_destroy, NULL);
663
- hashtab_destroy(cladatum->permissions.table);
227
+ hashtab_map(&cladatum->permissions.table, perm_destroy, NULL);
228
+ hashtab_destroy(&cladatum->permissions.table);
664229 constraint = cladatum->constraints;
665230 while (constraint) {
666231 e = constraint->expr;
....@@ -765,10 +330,17 @@
765330
766331 static int filenametr_destroy(void *key, void *datum, void *p)
767332 {
768
- struct filename_trans *ft = key;
333
+ struct filename_trans_key *ft = key;
334
+ struct filename_trans_datum *next, *d = datum;
335
+
769336 kfree(ft->name);
770337 kfree(key);
771
- kfree(datum);
338
+ do {
339
+ ebitmap_destroy(&d->stypes);
340
+ next = d->next;
341
+ kfree(d);
342
+ d = next;
343
+ } while (unlikely(d));
772344 cond_resched();
773345 return 0;
774346 }
....@@ -776,11 +348,19 @@
776348 static int range_tr_destroy(void *key, void *datum, void *p)
777349 {
778350 struct mls_range *rt = datum;
351
+
779352 kfree(key);
780353 ebitmap_destroy(&rt->level[0].cat);
781354 ebitmap_destroy(&rt->level[1].cat);
782355 kfree(datum);
783356 cond_resched();
357
+ return 0;
358
+}
359
+
360
+static int role_tr_destroy(void *key, void *datum, void *p)
361
+{
362
+ kfree(key);
363
+ kfree(datum);
784364 return 0;
785365 }
786366
....@@ -798,6 +378,409 @@
798378 }
799379
800380 /*
381
+ * Initialize the role table.
382
+ */
383
+static int roles_init(struct policydb *p)
384
+{
385
+ char *key = NULL;
386
+ int rc;
387
+ struct role_datum *role;
388
+
389
+ role = kzalloc(sizeof(*role), GFP_KERNEL);
390
+ if (!role)
391
+ return -ENOMEM;
392
+
393
+ rc = -EINVAL;
394
+ role->value = ++p->p_roles.nprim;
395
+ if (role->value != OBJECT_R_VAL)
396
+ goto out;
397
+
398
+ rc = -ENOMEM;
399
+ key = kstrdup(OBJECT_R, GFP_KERNEL);
400
+ if (!key)
401
+ goto out;
402
+
403
+ rc = symtab_insert(&p->p_roles, key, role);
404
+ if (rc)
405
+ goto out;
406
+
407
+ return 0;
408
+out:
409
+ kfree(key);
410
+ kfree(role);
411
+ return rc;
412
+}
413
+
414
+static u32 filenametr_hash(const void *k)
415
+{
416
+ const struct filename_trans_key *ft = k;
417
+ unsigned long hash;
418
+ unsigned int byte_num;
419
+ unsigned char focus;
420
+
421
+ hash = ft->ttype ^ ft->tclass;
422
+
423
+ byte_num = 0;
424
+ while ((focus = ft->name[byte_num++]))
425
+ hash = partial_name_hash(focus, hash);
426
+ return hash;
427
+}
428
+
429
+static int filenametr_cmp(const void *k1, const void *k2)
430
+{
431
+ const struct filename_trans_key *ft1 = k1;
432
+ const struct filename_trans_key *ft2 = k2;
433
+ int v;
434
+
435
+ v = ft1->ttype - ft2->ttype;
436
+ if (v)
437
+ return v;
438
+
439
+ v = ft1->tclass - ft2->tclass;
440
+ if (v)
441
+ return v;
442
+
443
+ return strcmp(ft1->name, ft2->name);
444
+
445
+}
446
+
447
+static const struct hashtab_key_params filenametr_key_params = {
448
+ .hash = filenametr_hash,
449
+ .cmp = filenametr_cmp,
450
+};
451
+
452
+struct filename_trans_datum *policydb_filenametr_search(
453
+ struct policydb *p, struct filename_trans_key *key)
454
+{
455
+ return hashtab_search(&p->filename_trans, key, filenametr_key_params);
456
+}
457
+
458
+static u32 rangetr_hash(const void *k)
459
+{
460
+ const struct range_trans *key = k;
461
+
462
+ return key->source_type + (key->target_type << 3) +
463
+ (key->target_class << 5);
464
+}
465
+
466
+static int rangetr_cmp(const void *k1, const void *k2)
467
+{
468
+ const struct range_trans *key1 = k1, *key2 = k2;
469
+ int v;
470
+
471
+ v = key1->source_type - key2->source_type;
472
+ if (v)
473
+ return v;
474
+
475
+ v = key1->target_type - key2->target_type;
476
+ if (v)
477
+ return v;
478
+
479
+ v = key1->target_class - key2->target_class;
480
+
481
+ return v;
482
+}
483
+
484
+static const struct hashtab_key_params rangetr_key_params = {
485
+ .hash = rangetr_hash,
486
+ .cmp = rangetr_cmp,
487
+};
488
+
489
+struct mls_range *policydb_rangetr_search(struct policydb *p,
490
+ struct range_trans *key)
491
+{
492
+ return hashtab_search(&p->range_tr, key, rangetr_key_params);
493
+}
494
+
495
+static u32 role_trans_hash(const void *k)
496
+{
497
+ const struct role_trans_key *key = k;
498
+
499
+ return key->role + (key->type << 3) + (key->tclass << 5);
500
+}
501
+
502
+static int role_trans_cmp(const void *k1, const void *k2)
503
+{
504
+ const struct role_trans_key *key1 = k1, *key2 = k2;
505
+ int v;
506
+
507
+ v = key1->role - key2->role;
508
+ if (v)
509
+ return v;
510
+
511
+ v = key1->type - key2->type;
512
+ if (v)
513
+ return v;
514
+
515
+ return key1->tclass - key2->tclass;
516
+}
517
+
518
+static const struct hashtab_key_params roletr_key_params = {
519
+ .hash = role_trans_hash,
520
+ .cmp = role_trans_cmp,
521
+};
522
+
523
+struct role_trans_datum *policydb_roletr_search(struct policydb *p,
524
+ struct role_trans_key *key)
525
+{
526
+ return hashtab_search(&p->role_tr, key, roletr_key_params);
527
+}
528
+
529
+/*
530
+ * Initialize a policy database structure.
531
+ */
532
+static void policydb_init(struct policydb *p)
533
+{
534
+ memset(p, 0, sizeof(*p));
535
+
536
+ avtab_init(&p->te_avtab);
537
+ cond_policydb_init(p);
538
+
539
+ ebitmap_init(&p->filename_trans_ttypes);
540
+ ebitmap_init(&p->policycaps);
541
+ ebitmap_init(&p->permissive_map);
542
+}
543
+
544
+/*
545
+ * The following *_index functions are used to
546
+ * define the val_to_name and val_to_struct arrays
547
+ * in a policy database structure. The val_to_name
548
+ * arrays are used when converting security context
549
+ * structures into string representations. The
550
+ * val_to_struct arrays are used when the attributes
551
+ * of a class, role, or user are needed.
552
+ */
553
+
554
+static int common_index(void *key, void *datum, void *datap)
555
+{
556
+ struct policydb *p;
557
+ struct common_datum *comdatum;
558
+
559
+ comdatum = datum;
560
+ p = datap;
561
+ if (!comdatum->value || comdatum->value > p->p_commons.nprim)
562
+ return -EINVAL;
563
+
564
+ p->sym_val_to_name[SYM_COMMONS][comdatum->value - 1] = key;
565
+
566
+ return 0;
567
+}
568
+
569
+static int class_index(void *key, void *datum, void *datap)
570
+{
571
+ struct policydb *p;
572
+ struct class_datum *cladatum;
573
+
574
+ cladatum = datum;
575
+ p = datap;
576
+ if (!cladatum->value || cladatum->value > p->p_classes.nprim)
577
+ return -EINVAL;
578
+
579
+ p->sym_val_to_name[SYM_CLASSES][cladatum->value - 1] = key;
580
+ p->class_val_to_struct[cladatum->value - 1] = cladatum;
581
+ return 0;
582
+}
583
+
584
+static int role_index(void *key, void *datum, void *datap)
585
+{
586
+ struct policydb *p;
587
+ struct role_datum *role;
588
+
589
+ role = datum;
590
+ p = datap;
591
+ if (!role->value
592
+ || role->value > p->p_roles.nprim
593
+ || role->bounds > p->p_roles.nprim)
594
+ return -EINVAL;
595
+
596
+ p->sym_val_to_name[SYM_ROLES][role->value - 1] = key;
597
+ p->role_val_to_struct[role->value - 1] = role;
598
+ return 0;
599
+}
600
+
601
+static int type_index(void *key, void *datum, void *datap)
602
+{
603
+ struct policydb *p;
604
+ struct type_datum *typdatum;
605
+
606
+ typdatum = datum;
607
+ p = datap;
608
+
609
+ if (typdatum->primary) {
610
+ if (!typdatum->value
611
+ || typdatum->value > p->p_types.nprim
612
+ || typdatum->bounds > p->p_types.nprim)
613
+ return -EINVAL;
614
+ p->sym_val_to_name[SYM_TYPES][typdatum->value - 1] = key;
615
+ p->type_val_to_struct[typdatum->value - 1] = typdatum;
616
+ }
617
+
618
+ return 0;
619
+}
620
+
621
+static int user_index(void *key, void *datum, void *datap)
622
+{
623
+ struct policydb *p;
624
+ struct user_datum *usrdatum;
625
+
626
+ usrdatum = datum;
627
+ p = datap;
628
+ if (!usrdatum->value
629
+ || usrdatum->value > p->p_users.nprim
630
+ || usrdatum->bounds > p->p_users.nprim)
631
+ return -EINVAL;
632
+
633
+ p->sym_val_to_name[SYM_USERS][usrdatum->value - 1] = key;
634
+ p->user_val_to_struct[usrdatum->value - 1] = usrdatum;
635
+ return 0;
636
+}
637
+
638
+static int sens_index(void *key, void *datum, void *datap)
639
+{
640
+ struct policydb *p;
641
+ struct level_datum *levdatum;
642
+
643
+ levdatum = datum;
644
+ p = datap;
645
+
646
+ if (!levdatum->isalias) {
647
+ if (!levdatum->level->sens ||
648
+ levdatum->level->sens > p->p_levels.nprim)
649
+ return -EINVAL;
650
+
651
+ p->sym_val_to_name[SYM_LEVELS][levdatum->level->sens - 1] = key;
652
+ }
653
+
654
+ return 0;
655
+}
656
+
657
+static int cat_index(void *key, void *datum, void *datap)
658
+{
659
+ struct policydb *p;
660
+ struct cat_datum *catdatum;
661
+
662
+ catdatum = datum;
663
+ p = datap;
664
+
665
+ if (!catdatum->isalias) {
666
+ if (!catdatum->value || catdatum->value > p->p_cats.nprim)
667
+ return -EINVAL;
668
+
669
+ p->sym_val_to_name[SYM_CATS][catdatum->value - 1] = key;
670
+ }
671
+
672
+ return 0;
673
+}
674
+
675
+static int (*index_f[SYM_NUM]) (void *key, void *datum, void *datap) =
676
+{
677
+ common_index,
678
+ class_index,
679
+ role_index,
680
+ type_index,
681
+ user_index,
682
+ cond_index_bool,
683
+ sens_index,
684
+ cat_index,
685
+};
686
+
687
+#ifdef DEBUG_HASHES
688
+static void hash_eval(struct hashtab *h, const char *hash_name)
689
+{
690
+ struct hashtab_info info;
691
+
692
+ hashtab_stat(h, &info);
693
+ pr_debug("SELinux: %s: %d entries and %d/%d buckets used, longest chain length %d\n",
694
+ hash_name, h->nel, info.slots_used, h->size,
695
+ info.max_chain_len);
696
+}
697
+
698
+static void symtab_hash_eval(struct symtab *s)
699
+{
700
+ int i;
701
+
702
+ for (i = 0; i < SYM_NUM; i++)
703
+ hash_eval(&s[i].table, symtab_name[i]);
704
+}
705
+
706
+#else
707
+static inline void hash_eval(struct hashtab *h, char *hash_name)
708
+{
709
+}
710
+#endif
711
+
712
+/*
713
+ * Define the other val_to_name and val_to_struct arrays
714
+ * in a policy database structure.
715
+ *
716
+ * Caller must clean up on failure.
717
+ */
718
+static int policydb_index(struct policydb *p)
719
+{
720
+ int i, rc;
721
+
722
+ if (p->mls_enabled)
723
+ pr_debug("SELinux: %d users, %d roles, %d types, %d bools, %d sens, %d cats\n",
724
+ p->p_users.nprim, p->p_roles.nprim, p->p_types.nprim,
725
+ p->p_bools.nprim, p->p_levels.nprim, p->p_cats.nprim);
726
+ else
727
+ pr_debug("SELinux: %d users, %d roles, %d types, %d bools\n",
728
+ p->p_users.nprim, p->p_roles.nprim, p->p_types.nprim,
729
+ p->p_bools.nprim);
730
+
731
+ pr_debug("SELinux: %d classes, %d rules\n",
732
+ p->p_classes.nprim, p->te_avtab.nel);
733
+
734
+#ifdef DEBUG_HASHES
735
+ avtab_hash_eval(&p->te_avtab, "rules");
736
+ symtab_hash_eval(p->symtab);
737
+#endif
738
+
739
+ p->class_val_to_struct = kcalloc(p->p_classes.nprim,
740
+ sizeof(*p->class_val_to_struct),
741
+ GFP_KERNEL);
742
+ if (!p->class_val_to_struct)
743
+ return -ENOMEM;
744
+
745
+ p->role_val_to_struct = kcalloc(p->p_roles.nprim,
746
+ sizeof(*p->role_val_to_struct),
747
+ GFP_KERNEL);
748
+ if (!p->role_val_to_struct)
749
+ return -ENOMEM;
750
+
751
+ p->user_val_to_struct = kcalloc(p->p_users.nprim,
752
+ sizeof(*p->user_val_to_struct),
753
+ GFP_KERNEL);
754
+ if (!p->user_val_to_struct)
755
+ return -ENOMEM;
756
+
757
+ p->type_val_to_struct = kvcalloc(p->p_types.nprim,
758
+ sizeof(*p->type_val_to_struct),
759
+ GFP_KERNEL);
760
+ if (!p->type_val_to_struct)
761
+ return -ENOMEM;
762
+
763
+ rc = cond_init_bool_indexes(p);
764
+ if (rc)
765
+ goto out;
766
+
767
+ for (i = 0; i < SYM_NUM; i++) {
768
+ p->sym_val_to_name[i] = kvcalloc(p->symtab[i].nprim,
769
+ sizeof(char *),
770
+ GFP_KERNEL);
771
+ if (!p->sym_val_to_name[i])
772
+ return -ENOMEM;
773
+
774
+ rc = hashtab_map(&p->symtab[i].table, index_f[i], p);
775
+ if (rc)
776
+ goto out;
777
+ }
778
+ rc = 0;
779
+out:
780
+ return rc;
781
+}
782
+
783
+/*
801784 * Free any memory allocated by a policy database structure.
802785 */
803786 void policydb_destroy(struct policydb *p)
....@@ -806,24 +789,20 @@
806789 struct genfs *g, *gtmp;
807790 int i;
808791 struct role_allow *ra, *lra = NULL;
809
- struct role_trans *tr, *ltr = NULL;
810792
811793 for (i = 0; i < SYM_NUM; i++) {
812794 cond_resched();
813
- hashtab_map(p->symtab[i].table, destroy_f[i], NULL);
814
- hashtab_destroy(p->symtab[i].table);
795
+ hashtab_map(&p->symtab[i].table, destroy_f[i], NULL);
796
+ hashtab_destroy(&p->symtab[i].table);
815797 }
816798
817
- for (i = 0; i < SYM_NUM; i++) {
818
- if (p->sym_val_to_name[i])
819
- flex_array_free(p->sym_val_to_name[i]);
820
- }
799
+ for (i = 0; i < SYM_NUM; i++)
800
+ kvfree(p->sym_val_to_name[i]);
821801
822802 kfree(p->class_val_to_struct);
823803 kfree(p->role_val_to_struct);
824804 kfree(p->user_val_to_struct);
825
- if (p->type_val_to_struct_array)
826
- flex_array_free(p->type_val_to_struct_array);
805
+ kvfree(p->type_val_to_struct);
827806
828807 avtab_destroy(&p->te_avtab);
829808
....@@ -856,12 +835,8 @@
856835
857836 cond_policydb_destroy(p);
858837
859
- for (tr = p->role_tr; tr; tr = tr->next) {
860
- cond_resched();
861
- kfree(ltr);
862
- ltr = tr;
863
- }
864
- kfree(ltr);
838
+ hashtab_map(&p->role_tr, role_tr_destroy, NULL);
839
+ hashtab_destroy(&p->role_tr);
865840
866841 for (ra = p->role_allow; ra; ra = ra->next) {
867842 cond_resched();
....@@ -870,22 +845,16 @@
870845 }
871846 kfree(lra);
872847
873
- hashtab_map(p->filename_trans, filenametr_destroy, NULL);
874
- hashtab_destroy(p->filename_trans);
848
+ hashtab_map(&p->filename_trans, filenametr_destroy, NULL);
849
+ hashtab_destroy(&p->filename_trans);
875850
876
- hashtab_map(p->range_tr, range_tr_destroy, NULL);
877
- hashtab_destroy(p->range_tr);
851
+ hashtab_map(&p->range_tr, range_tr_destroy, NULL);
852
+ hashtab_destroy(&p->range_tr);
878853
879854 if (p->type_attr_map_array) {
880
- for (i = 0; i < p->p_types.nprim; i++) {
881
- struct ebitmap *e;
882
-
883
- e = flex_array_get(p->type_attr_map_array, i);
884
- if (!e)
885
- continue;
886
- ebitmap_destroy(e);
887
- }
888
- flex_array_free(p->type_attr_map_array);
855
+ for (i = 0; i < p->p_types.nprim; i++)
856
+ ebitmap_destroy(&p->type_attr_map_array[i]);
857
+ kvfree(p->type_attr_map_array);
889858 }
890859
891860 ebitmap_destroy(&p->filename_trans_ttypes);
....@@ -905,41 +874,33 @@
905874 rc = sidtab_init(s);
906875 if (rc) {
907876 pr_err("SELinux: out of memory on SID table init\n");
908
- goto out;
877
+ return rc;
909878 }
910879
911880 head = p->ocontexts[OCON_ISID];
912881 for (c = head; c; c = c->next) {
913
- rc = -EINVAL;
914
- if (!c->context[0].user) {
915
- pr_err("SELinux: SID %s was never defined.\n",
916
- c->u.name);
882
+ u32 sid = c->sid[0];
883
+ const char *name = security_get_initial_sid_context(sid);
884
+
885
+ if (sid == SECSID_NULL) {
886
+ pr_err("SELinux: SID 0 was assigned a context.\n");
917887 sidtab_destroy(s);
918
- goto out;
919
- }
920
- if (c->sid[0] == SECSID_NULL || c->sid[0] > SECINITSID_NUM) {
921
- pr_err("SELinux: Initial SID %s out of range.\n",
922
- c->u.name);
923
- sidtab_destroy(s);
924
- goto out;
925
- }
926
- rc = context_add_hash(p, &c->context[0]);
927
- if (rc) {
928
- sidtab_destroy(s);
929
- goto out;
888
+ return -EINVAL;
930889 }
931890
932
- rc = sidtab_set_initial(s, c->sid[0], &c->context[0]);
891
+ /* Ignore initial SIDs unused by this kernel. */
892
+ if (!name)
893
+ continue;
894
+
895
+ rc = sidtab_set_initial(s, sid, &c->context[0]);
933896 if (rc) {
934897 pr_err("SELinux: unable to load initial SID %s.\n",
935
- c->u.name);
898
+ name);
936899 sidtab_destroy(s);
937
- goto out;
900
+ return rc;
938901 }
939902 }
940
- rc = 0;
941
-out:
942
- return rc;
903
+ return 0;
943904 }
944905
945906 int policydb_class_isvalid(struct policydb *p, unsigned int class)
....@@ -1123,18 +1084,18 @@
11231084 if (!str)
11241085 return -ENOMEM;
11251086
1126
- /* it's expected the caller should free the str */
1127
- *strp = str;
1128
-
11291087 rc = next_entry(str, fp, len);
1130
- if (rc)
1088
+ if (rc) {
1089
+ kfree(str);
11311090 return rc;
1091
+ }
11321092
11331093 str[len] = '\0';
1094
+ *strp = str;
11341095 return 0;
11351096 }
11361097
1137
-static int perm_read(struct policydb *p, struct hashtab *h, void *fp)
1098
+static int perm_read(struct policydb *p, struct symtab *s, void *fp)
11381099 {
11391100 char *key = NULL;
11401101 struct perm_datum *perdatum;
....@@ -1157,7 +1118,7 @@
11571118 if (rc)
11581119 goto bad;
11591120
1160
- rc = hashtab_insert(h, key, perdatum);
1121
+ rc = symtab_insert(s, key, perdatum);
11611122 if (rc)
11621123 goto bad;
11631124
....@@ -1167,7 +1128,7 @@
11671128 return rc;
11681129 }
11691130
1170
-static int common_read(struct policydb *p, struct hashtab *h, void *fp)
1131
+static int common_read(struct policydb *p, struct symtab *s, void *fp)
11711132 {
11721133 char *key = NULL;
11731134 struct common_datum *comdatum;
....@@ -1185,24 +1146,24 @@
11851146
11861147 len = le32_to_cpu(buf[0]);
11871148 comdatum->value = le32_to_cpu(buf[1]);
1149
+ nel = le32_to_cpu(buf[3]);
11881150
1189
- rc = symtab_init(&comdatum->permissions, PERM_SYMTAB_SIZE);
1151
+ rc = symtab_init(&comdatum->permissions, nel);
11901152 if (rc)
11911153 goto bad;
11921154 comdatum->permissions.nprim = le32_to_cpu(buf[2]);
1193
- nel = le32_to_cpu(buf[3]);
11941155
11951156 rc = str_read(&key, GFP_KERNEL, fp, len);
11961157 if (rc)
11971158 goto bad;
11981159
11991160 for (i = 0; i < nel; i++) {
1200
- rc = perm_read(p, comdatum->permissions.table, fp);
1161
+ rc = perm_read(p, &comdatum->permissions, fp);
12011162 if (rc)
12021163 goto bad;
12031164 }
12041165
1205
- rc = hashtab_insert(h, key, comdatum);
1166
+ rc = symtab_insert(s, key, comdatum);
12061167 if (rc)
12071168 goto bad;
12081169 return 0;
....@@ -1307,10 +1268,9 @@
13071268 if (rc)
13081269 return rc;
13091270 if (p->policyvers >=
1310
- POLICYDB_VERSION_CONSTRAINT_NAMES) {
1311
- e->type_names = kzalloc(sizeof
1312
- (*e->type_names),
1313
- GFP_KERNEL);
1271
+ POLICYDB_VERSION_CONSTRAINT_NAMES) {
1272
+ e->type_names = kzalloc(sizeof
1273
+ (*e->type_names), GFP_KERNEL);
13141274 if (!e->type_names)
13151275 return -ENOMEM;
13161276 type_set_init(e->type_names);
....@@ -1332,7 +1292,7 @@
13321292 return 0;
13331293 }
13341294
1335
-static int class_read(struct policydb *p, struct hashtab *h, void *fp)
1295
+static int class_read(struct policydb *p, struct symtab *s, void *fp)
13361296 {
13371297 char *key = NULL;
13381298 struct class_datum *cladatum;
....@@ -1351,12 +1311,12 @@
13511311 len = le32_to_cpu(buf[0]);
13521312 len2 = le32_to_cpu(buf[1]);
13531313 cladatum->value = le32_to_cpu(buf[2]);
1314
+ nel = le32_to_cpu(buf[4]);
13541315
1355
- rc = symtab_init(&cladatum->permissions, PERM_SYMTAB_SIZE);
1316
+ rc = symtab_init(&cladatum->permissions, nel);
13561317 if (rc)
13571318 goto bad;
13581319 cladatum->permissions.nprim = le32_to_cpu(buf[3]);
1359
- nel = le32_to_cpu(buf[4]);
13601320
13611321 ncons = le32_to_cpu(buf[5]);
13621322
....@@ -1370,7 +1330,8 @@
13701330 goto bad;
13711331
13721332 rc = -EINVAL;
1373
- cladatum->comdatum = hashtab_search(p->p_commons.table, cladatum->comkey);
1333
+ cladatum->comdatum = symtab_search(&p->p_commons,
1334
+ cladatum->comkey);
13741335 if (!cladatum->comdatum) {
13751336 pr_err("SELinux: unknown common %s\n",
13761337 cladatum->comkey);
....@@ -1378,7 +1339,7 @@
13781339 }
13791340 }
13801341 for (i = 0; i < nel; i++) {
1381
- rc = perm_read(p, cladatum->permissions.table, fp);
1342
+ rc = perm_read(p, &cladatum->permissions, fp);
13821343 if (rc)
13831344 goto bad;
13841345 }
....@@ -1416,7 +1377,7 @@
14161377 cladatum->default_type = le32_to_cpu(buf[0]);
14171378 }
14181379
1419
- rc = hashtab_insert(h, key, cladatum);
1380
+ rc = symtab_insert(s, key, cladatum);
14201381 if (rc)
14211382 goto bad;
14221383
....@@ -1426,7 +1387,7 @@
14261387 return rc;
14271388 }
14281389
1429
-static int role_read(struct policydb *p, struct hashtab *h, void *fp)
1390
+static int role_read(struct policydb *p, struct symtab *s, void *fp)
14301391 {
14311392 char *key = NULL;
14321393 struct role_datum *role;
....@@ -1473,7 +1434,7 @@
14731434 goto bad;
14741435 }
14751436
1476
- rc = hashtab_insert(h, key, role);
1437
+ rc = symtab_insert(s, key, role);
14771438 if (rc)
14781439 goto bad;
14791440 return 0;
....@@ -1482,7 +1443,7 @@
14821443 return rc;
14831444 }
14841445
1485
-static int type_read(struct policydb *p, struct hashtab *h, void *fp)
1446
+static int type_read(struct policydb *p, struct symtab *s, void *fp)
14861447 {
14871448 char *key = NULL;
14881449 struct type_datum *typdatum;
....@@ -1520,7 +1481,7 @@
15201481 if (rc)
15211482 goto bad;
15221483
1523
- rc = hashtab_insert(h, key, typdatum);
1484
+ rc = symtab_insert(s, key, typdatum);
15241485 if (rc)
15251486 goto bad;
15261487 return 0;
....@@ -1556,7 +1517,7 @@
15561517 return 0;
15571518 }
15581519
1559
-static int user_read(struct policydb *p, struct hashtab *h, void *fp)
1520
+static int user_read(struct policydb *p, struct symtab *s, void *fp)
15601521 {
15611522 char *key = NULL;
15621523 struct user_datum *usrdatum;
....@@ -1597,7 +1558,7 @@
15971558 goto bad;
15981559 }
15991560
1600
- rc = hashtab_insert(h, key, usrdatum);
1561
+ rc = symtab_insert(s, key, usrdatum);
16011562 if (rc)
16021563 goto bad;
16031564 return 0;
....@@ -1606,7 +1567,7 @@
16061567 return rc;
16071568 }
16081569
1609
-static int sens_read(struct policydb *p, struct hashtab *h, void *fp)
1570
+static int sens_read(struct policydb *p, struct symtab *s, void *fp)
16101571 {
16111572 char *key = NULL;
16121573 struct level_datum *levdatum;
....@@ -1638,7 +1599,7 @@
16381599 if (rc)
16391600 goto bad;
16401601
1641
- rc = hashtab_insert(h, key, levdatum);
1602
+ rc = symtab_insert(s, key, levdatum);
16421603 if (rc)
16431604 goto bad;
16441605 return 0;
....@@ -1647,7 +1608,7 @@
16471608 return rc;
16481609 }
16491610
1650
-static int cat_read(struct policydb *p, struct hashtab *h, void *fp)
1611
+static int cat_read(struct policydb *p, struct symtab *s, void *fp)
16511612 {
16521613 char *key = NULL;
16531614 struct cat_datum *catdatum;
....@@ -1671,7 +1632,7 @@
16711632 if (rc)
16721633 goto bad;
16731634
1674
- rc = hashtab_insert(h, key, catdatum);
1635
+ rc = symtab_insert(s, key, catdatum);
16751636 if (rc)
16761637 goto bad;
16771638 return 0;
....@@ -1680,7 +1641,7 @@
16801641 return rc;
16811642 }
16821643
1683
-static int (*read_f[SYM_NUM]) (struct policydb *p, struct hashtab *h, void *fp) =
1644
+static int (*read_f[SYM_NUM]) (struct policydb *p, struct symtab *s, void *fp) =
16841645 {
16851646 common_read,
16861647 class_read,
....@@ -1779,8 +1740,7 @@
17791740 return -EINVAL;
17801741 }
17811742
1782
- upper = flex_array_get_ptr(p->type_val_to_struct_array,
1783
- upper->bounds - 1);
1743
+ upper = p->type_val_to_struct[upper->bounds - 1];
17841744 BUG_ON(!upper);
17851745
17861746 if (upper->attribute) {
....@@ -1802,18 +1762,15 @@
18021762 if (p->policyvers < POLICYDB_VERSION_BOUNDARY)
18031763 return 0;
18041764
1805
- rc = hashtab_map(p->p_users.table,
1806
- user_bounds_sanity_check, p);
1765
+ rc = hashtab_map(&p->p_users.table, user_bounds_sanity_check, p);
18071766 if (rc)
18081767 return rc;
18091768
1810
- rc = hashtab_map(p->p_roles.table,
1811
- role_bounds_sanity_check, p);
1769
+ rc = hashtab_map(&p->p_roles.table, role_bounds_sanity_check, p);
18121770 if (rc)
18131771 return rc;
18141772
1815
- rc = hashtab_map(p->p_types.table,
1816
- type_bounds_sanity_check, p);
1773
+ rc = hashtab_map(&p->p_types.table, type_bounds_sanity_check, p);
18171774 if (rc)
18181775 return rc;
18191776
....@@ -1824,7 +1781,7 @@
18241781 {
18251782 struct class_datum *cladatum;
18261783
1827
- cladatum = hashtab_search(p->p_classes.table, name);
1784
+ cladatum = symtab_search(&p->p_classes, name);
18281785 if (!cladatum)
18291786 return 0;
18301787
....@@ -1843,11 +1800,9 @@
18431800 cladatum = p->class_val_to_struct[tclass-1];
18441801 comdatum = cladatum->comdatum;
18451802 if (comdatum)
1846
- perdatum = hashtab_search(comdatum->permissions.table,
1847
- name);
1803
+ perdatum = symtab_search(&comdatum->permissions, name);
18481804 if (!perdatum)
1849
- perdatum = hashtab_search(cladatum->permissions.table,
1850
- name);
1805
+ perdatum = symtab_search(&cladatum->permissions, name);
18511806 if (!perdatum)
18521807 return 0;
18531808
....@@ -1870,6 +1825,11 @@
18701825 return rc;
18711826
18721827 nel = le32_to_cpu(buf[0]);
1828
+
1829
+ rc = hashtab_init(&p->range_tr, nel);
1830
+ if (rc)
1831
+ return rc;
1832
+
18731833 for (i = 0; i < nel; i++) {
18741834 rc = -ENOMEM;
18751835 rt = kzalloc(sizeof(*rt), GFP_KERNEL);
....@@ -1911,14 +1871,14 @@
19111871 goto out;
19121872 }
19131873
1914
- rc = hashtab_insert(p->range_tr, rt, r);
1874
+ rc = hashtab_insert(&p->range_tr, rt, r, rangetr_key_params);
19151875 if (rc)
19161876 goto out;
19171877
19181878 rt = NULL;
19191879 r = NULL;
19201880 }
1921
- hash_eval(p->range_tr, "rangetr");
1881
+ hash_eval(&p->range_tr, "rangetr");
19221882 rc = 0;
19231883 out:
19241884 kfree(rt);
....@@ -1926,13 +1886,183 @@
19261886 return rc;
19271887 }
19281888
1889
+static int filename_trans_read_helper_compat(struct policydb *p, void *fp)
1890
+{
1891
+ struct filename_trans_key key, *ft = NULL;
1892
+ struct filename_trans_datum *last, *datum = NULL;
1893
+ char *name = NULL;
1894
+ u32 len, stype, otype;
1895
+ __le32 buf[4];
1896
+ int rc;
1897
+
1898
+ /* length of the path component string */
1899
+ rc = next_entry(buf, fp, sizeof(u32));
1900
+ if (rc)
1901
+ return rc;
1902
+ len = le32_to_cpu(buf[0]);
1903
+
1904
+ /* path component string */
1905
+ rc = str_read(&name, GFP_KERNEL, fp, len);
1906
+ if (rc)
1907
+ return rc;
1908
+
1909
+ rc = next_entry(buf, fp, sizeof(u32) * 4);
1910
+ if (rc)
1911
+ goto out;
1912
+
1913
+ stype = le32_to_cpu(buf[0]);
1914
+ key.ttype = le32_to_cpu(buf[1]);
1915
+ key.tclass = le32_to_cpu(buf[2]);
1916
+ key.name = name;
1917
+
1918
+ otype = le32_to_cpu(buf[3]);
1919
+
1920
+ last = NULL;
1921
+ datum = policydb_filenametr_search(p, &key);
1922
+ while (datum) {
1923
+ if (unlikely(ebitmap_get_bit(&datum->stypes, stype - 1))) {
1924
+ /* conflicting/duplicate rules are ignored */
1925
+ datum = NULL;
1926
+ goto out;
1927
+ }
1928
+ if (likely(datum->otype == otype))
1929
+ break;
1930
+ last = datum;
1931
+ datum = datum->next;
1932
+ }
1933
+ if (!datum) {
1934
+ rc = -ENOMEM;
1935
+ datum = kmalloc(sizeof(*datum), GFP_KERNEL);
1936
+ if (!datum)
1937
+ goto out;
1938
+
1939
+ ebitmap_init(&datum->stypes);
1940
+ datum->otype = otype;
1941
+ datum->next = NULL;
1942
+
1943
+ if (unlikely(last)) {
1944
+ last->next = datum;
1945
+ } else {
1946
+ rc = -ENOMEM;
1947
+ ft = kmemdup(&key, sizeof(key), GFP_KERNEL);
1948
+ if (!ft)
1949
+ goto out;
1950
+
1951
+ rc = hashtab_insert(&p->filename_trans, ft, datum,
1952
+ filenametr_key_params);
1953
+ if (rc)
1954
+ goto out;
1955
+ name = NULL;
1956
+
1957
+ rc = ebitmap_set_bit(&p->filename_trans_ttypes,
1958
+ key.ttype, 1);
1959
+ if (rc)
1960
+ return rc;
1961
+ }
1962
+ }
1963
+ kfree(name);
1964
+ return ebitmap_set_bit(&datum->stypes, stype - 1, 1);
1965
+
1966
+out:
1967
+ kfree(ft);
1968
+ kfree(name);
1969
+ kfree(datum);
1970
+ return rc;
1971
+}
1972
+
1973
+static int filename_trans_read_helper(struct policydb *p, void *fp)
1974
+{
1975
+ struct filename_trans_key *ft = NULL;
1976
+ struct filename_trans_datum **dst, *datum, *first = NULL;
1977
+ char *name = NULL;
1978
+ u32 len, ttype, tclass, ndatum, i;
1979
+ __le32 buf[3];
1980
+ int rc;
1981
+
1982
+ /* length of the path component string */
1983
+ rc = next_entry(buf, fp, sizeof(u32));
1984
+ if (rc)
1985
+ return rc;
1986
+ len = le32_to_cpu(buf[0]);
1987
+
1988
+ /* path component string */
1989
+ rc = str_read(&name, GFP_KERNEL, fp, len);
1990
+ if (rc)
1991
+ return rc;
1992
+
1993
+ rc = next_entry(buf, fp, sizeof(u32) * 3);
1994
+ if (rc)
1995
+ goto out;
1996
+
1997
+ ttype = le32_to_cpu(buf[0]);
1998
+ tclass = le32_to_cpu(buf[1]);
1999
+
2000
+ ndatum = le32_to_cpu(buf[2]);
2001
+ if (ndatum == 0) {
2002
+ pr_err("SELinux: Filename transition key with no datum\n");
2003
+ rc = -ENOENT;
2004
+ goto out;
2005
+ }
2006
+
2007
+ dst = &first;
2008
+ for (i = 0; i < ndatum; i++) {
2009
+ rc = -ENOMEM;
2010
+ datum = kmalloc(sizeof(*datum), GFP_KERNEL);
2011
+ if (!datum)
2012
+ goto out;
2013
+
2014
+ datum->next = NULL;
2015
+ *dst = datum;
2016
+
2017
+ /* ebitmap_read() will at least init the bitmap */
2018
+ rc = ebitmap_read(&datum->stypes, fp);
2019
+ if (rc)
2020
+ goto out;
2021
+
2022
+ rc = next_entry(buf, fp, sizeof(u32));
2023
+ if (rc)
2024
+ goto out;
2025
+
2026
+ datum->otype = le32_to_cpu(buf[0]);
2027
+
2028
+ dst = &datum->next;
2029
+ }
2030
+
2031
+ rc = -ENOMEM;
2032
+ ft = kmalloc(sizeof(*ft), GFP_KERNEL);
2033
+ if (!ft)
2034
+ goto out;
2035
+
2036
+ ft->ttype = ttype;
2037
+ ft->tclass = tclass;
2038
+ ft->name = name;
2039
+
2040
+ rc = hashtab_insert(&p->filename_trans, ft, first,
2041
+ filenametr_key_params);
2042
+ if (rc == -EEXIST)
2043
+ pr_err("SELinux: Duplicate filename transition key\n");
2044
+ if (rc)
2045
+ goto out;
2046
+
2047
+ return ebitmap_set_bit(&p->filename_trans_ttypes, ttype, 1);
2048
+
2049
+out:
2050
+ kfree(ft);
2051
+ kfree(name);
2052
+ while (first) {
2053
+ datum = first;
2054
+ first = first->next;
2055
+
2056
+ ebitmap_destroy(&datum->stypes);
2057
+ kfree(datum);
2058
+ }
2059
+ return rc;
2060
+}
2061
+
19292062 static int filename_trans_read(struct policydb *p, void *fp)
19302063 {
1931
- struct filename_trans *ft;
1932
- struct filename_trans_datum *otype;
1933
- char *name;
1934
- u32 nel, len;
1935
- __le32 buf[4];
2064
+ u32 nel;
2065
+ __le32 buf[1];
19362066 int rc, i;
19372067
19382068 if (p->policyvers < POLICYDB_VERSION_FILENAME_TRANS)
....@@ -1943,69 +2073,31 @@
19432073 return rc;
19442074 nel = le32_to_cpu(buf[0]);
19452075
1946
- for (i = 0; i < nel; i++) {
1947
- otype = NULL;
1948
- name = NULL;
2076
+ if (p->policyvers < POLICYDB_VERSION_COMP_FTRANS) {
2077
+ p->compat_filename_trans_count = nel;
19492078
1950
- rc = -ENOMEM;
1951
- ft = kzalloc(sizeof(*ft), GFP_KERNEL);
1952
- if (!ft)
1953
- goto out;
1954
-
1955
- rc = -ENOMEM;
1956
- otype = kmalloc(sizeof(*otype), GFP_KERNEL);
1957
- if (!otype)
1958
- goto out;
1959
-
1960
- /* length of the path component string */
1961
- rc = next_entry(buf, fp, sizeof(u32));
2079
+ rc = hashtab_init(&p->filename_trans, (1 << 11));
19622080 if (rc)
1963
- goto out;
1964
- len = le32_to_cpu(buf[0]);
2081
+ return rc;
19652082
1966
- /* path component string */
1967
- rc = str_read(&name, GFP_KERNEL, fp, len);
2083
+ for (i = 0; i < nel; i++) {
2084
+ rc = filename_trans_read_helper_compat(p, fp);
2085
+ if (rc)
2086
+ return rc;
2087
+ }
2088
+ } else {
2089
+ rc = hashtab_init(&p->filename_trans, nel);
19682090 if (rc)
1969
- goto out;
2091
+ return rc;
19702092
1971
- ft->name = name;
1972
-
1973
- rc = next_entry(buf, fp, sizeof(u32) * 4);
1974
- if (rc)
1975
- goto out;
1976
-
1977
- ft->stype = le32_to_cpu(buf[0]);
1978
- ft->ttype = le32_to_cpu(buf[1]);
1979
- ft->tclass = le32_to_cpu(buf[2]);
1980
-
1981
- otype->otype = le32_to_cpu(buf[3]);
1982
-
1983
- rc = ebitmap_set_bit(&p->filename_trans_ttypes, ft->ttype, 1);
1984
- if (rc)
1985
- goto out;
1986
-
1987
- rc = hashtab_insert(p->filename_trans, ft, otype);
1988
- if (rc) {
1989
- /*
1990
- * Do not return -EEXIST to the caller, or the system
1991
- * will not boot.
1992
- */
1993
- if (rc != -EEXIST)
1994
- goto out;
1995
- /* But free memory to avoid memory leak. */
1996
- kfree(ft);
1997
- kfree(name);
1998
- kfree(otype);
2093
+ for (i = 0; i < nel; i++) {
2094
+ rc = filename_trans_read_helper(p, fp);
2095
+ if (rc)
2096
+ return rc;
19992097 }
20002098 }
2001
- hash_eval(p->filename_trans, "filenametr");
2099
+ hash_eval(&p->filename_trans, "filenametr");
20022100 return 0;
2003
-out:
2004
- kfree(ft);
2005
- kfree(name);
2006
- kfree(otype);
2007
-
2008
- return rc;
20092101 }
20102102
20112103 static int genfs_read(struct policydb *p, void *fp)
....@@ -2310,17 +2402,16 @@
23102402 int policydb_read(struct policydb *p, void *fp)
23112403 {
23122404 struct role_allow *ra, *lra;
2313
- struct role_trans *tr, *ltr;
2405
+ struct role_trans_key *rtk = NULL;
2406
+ struct role_trans_datum *rtd = NULL;
23142407 int i, j, rc;
23152408 __le32 buf[4];
2316
- u32 len, nprim, nel;
2409
+ u32 len, nprim, nel, perm;
23172410
23182411 char *policydb_str;
23192412 struct policydb_compat_info *info;
23202413
2321
- rc = policydb_init(p);
2322
- if (rc)
2323
- return rc;
2414
+ policydb_init(p);
23242415
23252416 /* Read the magic number and string length. */
23262417 rc = next_entry(buf, fp, sizeof(u32) * 2);
....@@ -2444,8 +2535,19 @@
24442535 goto bad;
24452536 nprim = le32_to_cpu(buf[0]);
24462537 nel = le32_to_cpu(buf[1]);
2538
+
2539
+ rc = symtab_init(&p->symtab[i], nel);
2540
+ if (rc)
2541
+ goto out;
2542
+
2543
+ if (i == SYM_ROLES) {
2544
+ rc = roles_init(p);
2545
+ if (rc)
2546
+ goto out;
2547
+ }
2548
+
24472549 for (j = 0; j < nel; j++) {
2448
- rc = read_f[i](p, p->symtab[i].table, fp);
2550
+ rc = read_f[i](p, &p->symtab[i], fp);
24492551 if (rc)
24502552 goto bad;
24512553 }
....@@ -2455,8 +2557,10 @@
24552557
24562558 rc = -EINVAL;
24572559 p->process_class = string_to_security_class(p, "process");
2458
- if (!p->process_class)
2560
+ if (!p->process_class) {
2561
+ pr_err("SELinux: process class is required, not defined in policy\n");
24592562 goto bad;
2563
+ }
24602564
24612565 rc = avtab_read(&p->te_avtab, fp, p);
24622566 if (rc)
....@@ -2472,39 +2576,50 @@
24722576 if (rc)
24732577 goto bad;
24742578 nel = le32_to_cpu(buf[0]);
2475
- ltr = NULL;
2579
+
2580
+ rc = hashtab_init(&p->role_tr, nel);
2581
+ if (rc)
2582
+ goto bad;
24762583 for (i = 0; i < nel; i++) {
24772584 rc = -ENOMEM;
2478
- tr = kzalloc(sizeof(*tr), GFP_KERNEL);
2479
- if (!tr)
2585
+ rtk = kmalloc(sizeof(*rtk), GFP_KERNEL);
2586
+ if (!rtk)
24802587 goto bad;
2481
- if (ltr)
2482
- ltr->next = tr;
2483
- else
2484
- p->role_tr = tr;
2588
+
2589
+ rc = -ENOMEM;
2590
+ rtd = kmalloc(sizeof(*rtd), GFP_KERNEL);
2591
+ if (!rtd)
2592
+ goto bad;
2593
+
24852594 rc = next_entry(buf, fp, sizeof(u32)*3);
24862595 if (rc)
24872596 goto bad;
24882597
24892598 rc = -EINVAL;
2490
- tr->role = le32_to_cpu(buf[0]);
2491
- tr->type = le32_to_cpu(buf[1]);
2492
- tr->new_role = le32_to_cpu(buf[2]);
2599
+ rtk->role = le32_to_cpu(buf[0]);
2600
+ rtk->type = le32_to_cpu(buf[1]);
2601
+ rtd->new_role = le32_to_cpu(buf[2]);
24932602 if (p->policyvers >= POLICYDB_VERSION_ROLETRANS) {
24942603 rc = next_entry(buf, fp, sizeof(u32));
24952604 if (rc)
24962605 goto bad;
2497
- tr->tclass = le32_to_cpu(buf[0]);
2606
+ rtk->tclass = le32_to_cpu(buf[0]);
24982607 } else
2499
- tr->tclass = p->process_class;
2608
+ rtk->tclass = p->process_class;
25002609
25012610 rc = -EINVAL;
2502
- if (!policydb_role_isvalid(p, tr->role) ||
2503
- !policydb_type_isvalid(p, tr->type) ||
2504
- !policydb_class_isvalid(p, tr->tclass) ||
2505
- !policydb_role_isvalid(p, tr->new_role))
2611
+ if (!policydb_role_isvalid(p, rtk->role) ||
2612
+ !policydb_type_isvalid(p, rtk->type) ||
2613
+ !policydb_class_isvalid(p, rtk->tclass) ||
2614
+ !policydb_role_isvalid(p, rtd->new_role))
25062615 goto bad;
2507
- ltr = tr;
2616
+
2617
+ rc = hashtab_insert(&p->role_tr, rtk, rtd, roletr_key_params);
2618
+ if (rc)
2619
+ goto bad;
2620
+
2621
+ rtk = NULL;
2622
+ rtd = NULL;
25082623 }
25092624
25102625 rc = next_entry(buf, fp, sizeof(u32));
....@@ -2543,10 +2658,18 @@
25432658 goto bad;
25442659
25452660 rc = -EINVAL;
2546
- p->process_trans_perms = string_to_av_perm(p, p->process_class, "transition");
2547
- p->process_trans_perms |= string_to_av_perm(p, p->process_class, "dyntransition");
2548
- if (!p->process_trans_perms)
2661
+ perm = string_to_av_perm(p, p->process_class, "transition");
2662
+ if (!perm) {
2663
+ pr_err("SELinux: process transition permission is required, not defined in policy\n");
25492664 goto bad;
2665
+ }
2666
+ p->process_trans_perms = perm;
2667
+ perm = string_to_av_perm(p, p->process_class, "dyntransition");
2668
+ if (!perm) {
2669
+ pr_err("SELinux: process dyntransition permission is required, not defined in policy\n");
2670
+ goto bad;
2671
+ }
2672
+ p->process_trans_perms |= perm;
25502673
25512674 rc = ocontext_read(p, info, fp);
25522675 if (rc)
....@@ -2561,23 +2684,19 @@
25612684 goto bad;
25622685
25632686 rc = -ENOMEM;
2564
- p->type_attr_map_array = flex_array_alloc(sizeof(struct ebitmap),
2565
- p->p_types.nprim,
2566
- GFP_KERNEL | __GFP_ZERO);
2687
+ p->type_attr_map_array = kvcalloc(p->p_types.nprim,
2688
+ sizeof(*p->type_attr_map_array),
2689
+ GFP_KERNEL);
25672690 if (!p->type_attr_map_array)
25682691 goto bad;
25692692
2570
- /* preallocate so we don't have to worry about the put ever failing */
2571
- rc = flex_array_prealloc(p->type_attr_map_array, 0, p->p_types.nprim,
2572
- GFP_KERNEL | __GFP_ZERO);
2573
- if (rc)
2574
- goto bad;
2693
+ /* just in case ebitmap_init() becomes more than just a memset(0): */
2694
+ for (i = 0; i < p->p_types.nprim; i++)
2695
+ ebitmap_init(&p->type_attr_map_array[i]);
25752696
25762697 for (i = 0; i < p->p_types.nprim; i++) {
2577
- struct ebitmap *e = flex_array_get(p->type_attr_map_array, i);
2698
+ struct ebitmap *e = &p->type_attr_map_array[i];
25782699
2579
- BUG_ON(!e);
2580
- ebitmap_init(e);
25812700 if (p->policyvers >= POLICYDB_VERSION_AVTAB) {
25822701 rc = ebitmap_read(e, fp);
25832702 if (rc)
....@@ -2597,6 +2716,8 @@
25972716 out:
25982717 return rc;
25992718 bad:
2719
+ kfree(rtk);
2720
+ kfree(rtd);
26002721 policydb_destroy(p);
26012722 goto out;
26022723 }
....@@ -2714,43 +2835,49 @@
27142835 return 0;
27152836 }
27162837
2717
-static int role_trans_write(struct policydb *p, void *fp)
2838
+static int role_trans_write_one(void *key, void *datum, void *ptr)
27182839 {
2719
- struct role_trans *r = p->role_tr;
2720
- struct role_trans *tr;
2721
- u32 buf[3];
2722
- size_t nel;
2840
+ struct role_trans_key *rtk = key;
2841
+ struct role_trans_datum *rtd = datum;
2842
+ struct policy_data *pd = ptr;
2843
+ void *fp = pd->fp;
2844
+ struct policydb *p = pd->p;
2845
+ __le32 buf[3];
27232846 int rc;
27242847
2725
- nel = 0;
2726
- for (tr = r; tr; tr = tr->next)
2727
- nel++;
2728
- buf[0] = cpu_to_le32(nel);
2848
+ buf[0] = cpu_to_le32(rtk->role);
2849
+ buf[1] = cpu_to_le32(rtk->type);
2850
+ buf[2] = cpu_to_le32(rtd->new_role);
2851
+ rc = put_entry(buf, sizeof(u32), 3, fp);
2852
+ if (rc)
2853
+ return rc;
2854
+ if (p->policyvers >= POLICYDB_VERSION_ROLETRANS) {
2855
+ buf[0] = cpu_to_le32(rtk->tclass);
2856
+ rc = put_entry(buf, sizeof(u32), 1, fp);
2857
+ if (rc)
2858
+ return rc;
2859
+ }
2860
+ return 0;
2861
+}
2862
+
2863
+static int role_trans_write(struct policydb *p, void *fp)
2864
+{
2865
+ struct policy_data pd = { .p = p, .fp = fp };
2866
+ __le32 buf[1];
2867
+ int rc;
2868
+
2869
+ buf[0] = cpu_to_le32(p->role_tr.nel);
27292870 rc = put_entry(buf, sizeof(u32), 1, fp);
27302871 if (rc)
27312872 return rc;
2732
- for (tr = r; tr; tr = tr->next) {
2733
- buf[0] = cpu_to_le32(tr->role);
2734
- buf[1] = cpu_to_le32(tr->type);
2735
- buf[2] = cpu_to_le32(tr->new_role);
2736
- rc = put_entry(buf, sizeof(u32), 3, fp);
2737
- if (rc)
2738
- return rc;
2739
- if (p->policyvers >= POLICYDB_VERSION_ROLETRANS) {
2740
- buf[0] = cpu_to_le32(tr->tclass);
2741
- rc = put_entry(buf, sizeof(u32), 1, fp);
2742
- if (rc)
2743
- return rc;
2744
- }
2745
- }
27462873
2747
- return 0;
2874
+ return hashtab_map(&p->role_tr, role_trans_write_one, &pd);
27482875 }
27492876
27502877 static int role_allow_write(struct role_allow *r, void *fp)
27512878 {
27522879 struct role_allow *ra;
2753
- u32 buf[2];
2880
+ __le32 buf[2];
27542881 size_t nel;
27552882 int rc;
27562883
....@@ -2838,7 +2965,7 @@
28382965 buf[0] = cpu_to_le32(len);
28392966 buf[1] = cpu_to_le32(comdatum->value);
28402967 buf[2] = cpu_to_le32(comdatum->permissions.nprim);
2841
- buf[3] = cpu_to_le32(comdatum->permissions.table->nel);
2968
+ buf[3] = cpu_to_le32(comdatum->permissions.table.nel);
28422969 rc = put_entry(buf, sizeof(u32), 4, fp);
28432970 if (rc)
28442971 return rc;
....@@ -2847,7 +2974,7 @@
28472974 if (rc)
28482975 return rc;
28492976
2850
- rc = hashtab_map(comdatum->permissions.table, perm_write, fp);
2977
+ rc = hashtab_map(&comdatum->permissions.table, perm_write, fp);
28512978 if (rc)
28522979 return rc;
28532980
....@@ -2946,10 +3073,7 @@
29463073 buf[1] = cpu_to_le32(len2);
29473074 buf[2] = cpu_to_le32(cladatum->value);
29483075 buf[3] = cpu_to_le32(cladatum->permissions.nprim);
2949
- if (cladatum->permissions.table)
2950
- buf[4] = cpu_to_le32(cladatum->permissions.table->nel);
2951
- else
2952
- buf[4] = 0;
3076
+ buf[4] = cpu_to_le32(cladatum->permissions.table.nel);
29533077 buf[5] = cpu_to_le32(ncons);
29543078 rc = put_entry(buf, sizeof(u32), 6, fp);
29553079 if (rc)
....@@ -2965,7 +3089,7 @@
29653089 return rc;
29663090 }
29673091
2968
- rc = hashtab_map(cladatum->permissions.table, perm_write, fp);
3092
+ rc = hashtab_map(&cladatum->permissions.table, perm_write, fp);
29693093 if (rc)
29703094 return rc;
29713095
....@@ -3323,14 +3447,6 @@
33233447 return 0;
33243448 }
33253449
3326
-static int hashtab_cnt(void *key, void *data, void *ptr)
3327
-{
3328
- int *cnt = ptr;
3329
- *cnt = *cnt + 1;
3330
-
3331
- return 0;
3332
-}
3333
-
33343450 static int range_write_helper(void *key, void *data, void *ptr)
33353451 {
33363452 __le32 buf[2];
....@@ -3362,41 +3478,71 @@
33623478 static int range_write(struct policydb *p, void *fp)
33633479 {
33643480 __le32 buf[1];
3365
- int rc, nel;
3481
+ int rc;
33663482 struct policy_data pd;
33673483
33683484 pd.p = p;
33693485 pd.fp = fp;
33703486
3371
- /* count the number of entries in the hashtab */
3372
- nel = 0;
3373
- rc = hashtab_map(p->range_tr, hashtab_cnt, &nel);
3374
- if (rc)
3375
- return rc;
3376
-
3377
- buf[0] = cpu_to_le32(nel);
3487
+ buf[0] = cpu_to_le32(p->range_tr.nel);
33783488 rc = put_entry(buf, sizeof(u32), 1, fp);
33793489 if (rc)
33803490 return rc;
33813491
33823492 /* actually write all of the entries */
3383
- rc = hashtab_map(p->range_tr, range_write_helper, &pd);
3493
+ rc = hashtab_map(&p->range_tr, range_write_helper, &pd);
33843494 if (rc)
33853495 return rc;
33863496
33873497 return 0;
33883498 }
33893499
3500
+static int filename_write_helper_compat(void *key, void *data, void *ptr)
3501
+{
3502
+ struct filename_trans_key *ft = key;
3503
+ struct filename_trans_datum *datum = data;
3504
+ struct ebitmap_node *node;
3505
+ void *fp = ptr;
3506
+ __le32 buf[4];
3507
+ int rc;
3508
+ u32 bit, len = strlen(ft->name);
3509
+
3510
+ do {
3511
+ ebitmap_for_each_positive_bit(&datum->stypes, node, bit) {
3512
+ buf[0] = cpu_to_le32(len);
3513
+ rc = put_entry(buf, sizeof(u32), 1, fp);
3514
+ if (rc)
3515
+ return rc;
3516
+
3517
+ rc = put_entry(ft->name, sizeof(char), len, fp);
3518
+ if (rc)
3519
+ return rc;
3520
+
3521
+ buf[0] = cpu_to_le32(bit + 1);
3522
+ buf[1] = cpu_to_le32(ft->ttype);
3523
+ buf[2] = cpu_to_le32(ft->tclass);
3524
+ buf[3] = cpu_to_le32(datum->otype);
3525
+
3526
+ rc = put_entry(buf, sizeof(u32), 4, fp);
3527
+ if (rc)
3528
+ return rc;
3529
+ }
3530
+
3531
+ datum = datum->next;
3532
+ } while (unlikely(datum));
3533
+
3534
+ return 0;
3535
+}
3536
+
33903537 static int filename_write_helper(void *key, void *data, void *ptr)
33913538 {
3392
- __le32 buf[4];
3393
- struct filename_trans *ft = key;
3394
- struct filename_trans_datum *otype = data;
3539
+ struct filename_trans_key *ft = key;
3540
+ struct filename_trans_datum *datum;
33953541 void *fp = ptr;
3542
+ __le32 buf[3];
33963543 int rc;
3397
- u32 len;
3544
+ u32 ndatum, len = strlen(ft->name);
33983545
3399
- len = strlen(ft->name);
34003546 buf[0] = cpu_to_le32(len);
34013547 rc = put_entry(buf, sizeof(u32), 1, fp);
34023548 if (rc)
....@@ -3406,42 +3552,62 @@
34063552 if (rc)
34073553 return rc;
34083554
3409
- buf[0] = cpu_to_le32(ft->stype);
3410
- buf[1] = cpu_to_le32(ft->ttype);
3411
- buf[2] = cpu_to_le32(ft->tclass);
3412
- buf[3] = cpu_to_le32(otype->otype);
3555
+ ndatum = 0;
3556
+ datum = data;
3557
+ do {
3558
+ ndatum++;
3559
+ datum = datum->next;
3560
+ } while (unlikely(datum));
34133561
3414
- rc = put_entry(buf, sizeof(u32), 4, fp);
3562
+ buf[0] = cpu_to_le32(ft->ttype);
3563
+ buf[1] = cpu_to_le32(ft->tclass);
3564
+ buf[2] = cpu_to_le32(ndatum);
3565
+ rc = put_entry(buf, sizeof(u32), 3, fp);
34153566 if (rc)
34163567 return rc;
3568
+
3569
+ datum = data;
3570
+ do {
3571
+ rc = ebitmap_write(&datum->stypes, fp);
3572
+ if (rc)
3573
+ return rc;
3574
+
3575
+ buf[0] = cpu_to_le32(datum->otype);
3576
+ rc = put_entry(buf, sizeof(u32), 1, fp);
3577
+ if (rc)
3578
+ return rc;
3579
+
3580
+ datum = datum->next;
3581
+ } while (unlikely(datum));
34173582
34183583 return 0;
34193584 }
34203585
34213586 static int filename_trans_write(struct policydb *p, void *fp)
34223587 {
3423
- u32 nel;
34243588 __le32 buf[1];
34253589 int rc;
34263590
34273591 if (p->policyvers < POLICYDB_VERSION_FILENAME_TRANS)
34283592 return 0;
34293593
3430
- nel = 0;
3431
- rc = hashtab_map(p->filename_trans, hashtab_cnt, &nel);
3432
- if (rc)
3433
- return rc;
3594
+ if (p->policyvers < POLICYDB_VERSION_COMP_FTRANS) {
3595
+ buf[0] = cpu_to_le32(p->compat_filename_trans_count);
3596
+ rc = put_entry(buf, sizeof(u32), 1, fp);
3597
+ if (rc)
3598
+ return rc;
34343599
3435
- buf[0] = cpu_to_le32(nel);
3436
- rc = put_entry(buf, sizeof(u32), 1, fp);
3437
- if (rc)
3438
- return rc;
3600
+ rc = hashtab_map(&p->filename_trans,
3601
+ filename_write_helper_compat, fp);
3602
+ } else {
3603
+ buf[0] = cpu_to_le32(p->filename_trans.nel);
3604
+ rc = put_entry(buf, sizeof(u32), 1, fp);
3605
+ if (rc)
3606
+ return rc;
34393607
3440
- rc = hashtab_map(p->filename_trans, filename_write_helper, fp);
3441
- if (rc)
3442
- return rc;
3443
-
3444
- return 0;
3608
+ rc = hashtab_map(&p->filename_trans, filename_write_helper, fp);
3609
+ }
3610
+ return rc;
34453611 }
34463612
34473613 /*
....@@ -3528,12 +3694,12 @@
35283694 pd.p = p;
35293695
35303696 buf[0] = cpu_to_le32(p->symtab[i].nprim);
3531
- buf[1] = cpu_to_le32(p->symtab[i].table->nel);
3697
+ buf[1] = cpu_to_le32(p->symtab[i].table.nel);
35323698
35333699 rc = put_entry(buf, sizeof(u32), 2, fp);
35343700 if (rc)
35353701 return rc;
3536
- rc = hashtab_map(p->symtab[i].table, write_f[i], &pd);
3702
+ rc = hashtab_map(&p->symtab[i].table, write_f[i], &pd);
35373703 if (rc)
35383704 return rc;
35393705 }
....@@ -3542,7 +3708,7 @@
35423708 if (rc)
35433709 return rc;
35443710
3545
- rc = cond_write_list(p, p->cond_list, fp);
3711
+ rc = cond_write_list(p, fp);
35463712 if (rc)
35473713 return rc;
35483714
....@@ -3571,9 +3737,8 @@
35713737 return rc;
35723738
35733739 for (i = 0; i < p->p_types.nprim; i++) {
3574
- struct ebitmap *e = flex_array_get(p->type_attr_map_array, i);
3740
+ struct ebitmap *e = &p->type_attr_map_array[i];
35753741
3576
- BUG_ON(!e);
35773742 rc = ebitmap_write(e, fp);
35783743 if (rc)
35793744 return rc;