@@ -352,6 +352,13 @@ static int range_tr_destroy(void *key, void *datum, void *p)
352
352
return 0 ;
353
353
}
354
354
355
+ static int role_tr_destroy (void * key , void * datum , void * p )
356
+ {
357
+ kfree (key );
358
+ kfree (datum );
359
+ return 0 ;
360
+ }
361
+
355
362
static void ocontext_destroy (struct ocontext * c , int i )
356
363
{
357
364
if (!c )
@@ -458,6 +465,30 @@ static int rangetr_cmp(struct hashtab *h, const void *k1, const void *k2)
458
465
return v ;
459
466
}
460
467
468
+ static u32 role_trans_hash (struct hashtab * h , const void * k )
469
+ {
470
+ const struct role_trans_key * key = k ;
471
+
472
+ return (key -> role + (key -> type << 3 ) + (key -> tclass << 5 )) &
473
+ (h -> size - 1 );
474
+ }
475
+
476
+ static int role_trans_cmp (struct hashtab * h , const void * k1 , const void * k2 )
477
+ {
478
+ const struct role_trans_key * key1 = k1 , * key2 = k2 ;
479
+ int v ;
480
+
481
+ v = key1 -> role - key2 -> role ;
482
+ if (v )
483
+ return v ;
484
+
485
+ v = key1 -> type - key2 -> type ;
486
+ if (v )
487
+ return v ;
488
+
489
+ return key1 -> tclass - key2 -> tclass ;
490
+ }
491
+
461
492
/*
462
493
* Initialize a policy database structure.
463
494
*/
@@ -728,7 +759,6 @@ void policydb_destroy(struct policydb *p)
728
759
struct genfs * g , * gtmp ;
729
760
int i ;
730
761
struct role_allow * ra , * lra = NULL ;
731
- struct role_trans * tr , * ltr = NULL ;
732
762
733
763
for (i = 0 ; i < SYM_NUM ; i ++ ) {
734
764
cond_resched ();
@@ -775,12 +805,8 @@ void policydb_destroy(struct policydb *p)
775
805
776
806
cond_policydb_destroy (p );
777
807
778
- for (tr = p -> role_tr ; tr ; tr = tr -> next ) {
779
- cond_resched ();
780
- kfree (ltr );
781
- ltr = tr ;
782
- }
783
- kfree (ltr );
808
+ hashtab_map (p -> role_tr , role_tr_destroy , NULL );
809
+ hashtab_destroy (p -> role_tr );
784
810
785
811
for (ra = p -> role_allow ; ra ; ra = ra -> next ) {
786
812
cond_resched ();
@@ -2251,7 +2277,8 @@ static int ocontext_read(struct policydb *p, struct policydb_compat_info *info,
2251
2277
int policydb_read (struct policydb * p , void * fp )
2252
2278
{
2253
2279
struct role_allow * ra , * lra ;
2254
- struct role_trans * tr , * ltr ;
2280
+ struct role_trans_key * rtk = NULL ;
2281
+ struct role_trans_datum * rtd = NULL ;
2255
2282
int i , j , rc ;
2256
2283
__le32 buf [4 ];
2257
2284
u32 len , nprim , nel ;
@@ -2416,39 +2443,50 @@ int policydb_read(struct policydb *p, void *fp)
2416
2443
if (rc )
2417
2444
goto bad ;
2418
2445
nel = le32_to_cpu (buf [0 ]);
2419
- ltr = NULL ;
2446
+
2447
+ p -> role_tr = hashtab_create (role_trans_hash , role_trans_cmp , nel );
2448
+ if (!p -> role_tr )
2449
+ goto bad ;
2420
2450
for (i = 0 ; i < nel ; i ++ ) {
2421
2451
rc = - ENOMEM ;
2422
- tr = kzalloc (sizeof (* tr ), GFP_KERNEL );
2423
- if (!tr )
2452
+ rtk = kmalloc (sizeof (* rtk ), GFP_KERNEL );
2453
+ if (!rtk )
2424
2454
goto bad ;
2425
- if (ltr )
2426
- ltr -> next = tr ;
2427
- else
2428
- p -> role_tr = tr ;
2455
+
2456
+ rc = - ENOMEM ;
2457
+ rtd = kmalloc (sizeof (* rtd ), GFP_KERNEL );
2458
+ if (!rtd )
2459
+ goto bad ;
2460
+
2429
2461
rc = next_entry (buf , fp , sizeof (u32 )* 3 );
2430
2462
if (rc )
2431
2463
goto bad ;
2432
2464
2433
2465
rc = - EINVAL ;
2434
- tr -> role = le32_to_cpu (buf [0 ]);
2435
- tr -> type = le32_to_cpu (buf [1 ]);
2436
- tr -> new_role = le32_to_cpu (buf [2 ]);
2466
+ rtk -> role = le32_to_cpu (buf [0 ]);
2467
+ rtk -> type = le32_to_cpu (buf [1 ]);
2468
+ rtd -> new_role = le32_to_cpu (buf [2 ]);
2437
2469
if (p -> policyvers >= POLICYDB_VERSION_ROLETRANS ) {
2438
2470
rc = next_entry (buf , fp , sizeof (u32 ));
2439
2471
if (rc )
2440
2472
goto bad ;
2441
- tr -> tclass = le32_to_cpu (buf [0 ]);
2473
+ rtk -> tclass = le32_to_cpu (buf [0 ]);
2442
2474
} else
2443
- tr -> tclass = p -> process_class ;
2475
+ rtk -> tclass = p -> process_class ;
2444
2476
2445
2477
rc = - EINVAL ;
2446
- if (!policydb_role_isvalid (p , tr -> role ) ||
2447
- !policydb_type_isvalid (p , tr -> type ) ||
2448
- !policydb_class_isvalid (p , tr -> tclass ) ||
2449
- !policydb_role_isvalid (p , tr -> new_role ))
2478
+ if (!policydb_role_isvalid (p , rtk -> role ) ||
2479
+ !policydb_type_isvalid (p , rtk -> type ) ||
2480
+ !policydb_class_isvalid (p , rtk -> tclass ) ||
2481
+ !policydb_role_isvalid (p , rtd -> new_role ))
2482
+ goto bad ;
2483
+
2484
+ rc = hashtab_insert (p -> role_tr , rtk , rtd );
2485
+ if (rc )
2450
2486
goto bad ;
2451
- ltr = tr ;
2487
+
2488
+ rtk = NULL ;
2489
+ rtd = NULL ;
2452
2490
}
2453
2491
2454
2492
rc = next_entry (buf , fp , sizeof (u32 ));
@@ -2536,6 +2574,8 @@ int policydb_read(struct policydb *p, void *fp)
2536
2574
out :
2537
2575
return rc ;
2538
2576
bad :
2577
+ kfree (rtk );
2578
+ kfree (rtd );
2539
2579
policydb_destroy (p );
2540
2580
goto out ;
2541
2581
}
@@ -2653,39 +2693,45 @@ static int cat_write(void *vkey, void *datum, void *ptr)
2653
2693
return 0 ;
2654
2694
}
2655
2695
2656
- static int role_trans_write ( struct policydb * p , void * fp )
2696
+ static int role_trans_write_one ( void * key , void * datum , void * ptr )
2657
2697
{
2658
- struct role_trans * r = p -> role_tr ;
2659
- struct role_trans * tr ;
2698
+ struct role_trans_key * rtk = key ;
2699
+ struct role_trans_datum * rtd = datum ;
2700
+ struct policy_data * pd = ptr ;
2701
+ void * fp = pd -> fp ;
2702
+ struct policydb * p = pd -> p ;
2660
2703
__le32 buf [3 ];
2661
- size_t nel ;
2662
2704
int rc ;
2663
2705
2664
- nel = 0 ;
2665
- for (tr = r ; tr ; tr = tr -> next )
2666
- nel ++ ;
2667
- buf [0 ] = cpu_to_le32 (nel );
2668
- rc = put_entry (buf , sizeof (u32 ), 1 , fp );
2706
+ buf [0 ] = cpu_to_le32 (rtk -> role );
2707
+ buf [1 ] = cpu_to_le32 (rtk -> type );
2708
+ buf [2 ] = cpu_to_le32 (rtd -> new_role );
2709
+ rc = put_entry (buf , sizeof (u32 ), 3 , fp );
2669
2710
if (rc )
2670
2711
return rc ;
2671
- for (tr = r ; tr ; tr = tr -> next ) {
2672
- buf [0 ] = cpu_to_le32 (tr -> role );
2673
- buf [1 ] = cpu_to_le32 (tr -> type );
2674
- buf [2 ] = cpu_to_le32 (tr -> new_role );
2675
- rc = put_entry (buf , sizeof (u32 ), 3 , fp );
2712
+ if (p -> policyvers >= POLICYDB_VERSION_ROLETRANS ) {
2713
+ buf [0 ] = cpu_to_le32 (rtk -> tclass );
2714
+ rc = put_entry (buf , sizeof (u32 ), 1 , fp );
2676
2715
if (rc )
2677
2716
return rc ;
2678
- if (p -> policyvers >= POLICYDB_VERSION_ROLETRANS ) {
2679
- buf [0 ] = cpu_to_le32 (tr -> tclass );
2680
- rc = put_entry (buf , sizeof (u32 ), 1 , fp );
2681
- if (rc )
2682
- return rc ;
2683
- }
2684
2717
}
2685
-
2686
2718
return 0 ;
2687
2719
}
2688
2720
2721
+ static int role_trans_write (struct policydb * p , void * fp )
2722
+ {
2723
+ struct policy_data pd = { .p = p , .fp = fp };
2724
+ __le32 buf [1 ];
2725
+ int rc ;
2726
+
2727
+ buf [0 ] = cpu_to_le32 (p -> role_tr -> nel );
2728
+ rc = put_entry (buf , sizeof (u32 ), 1 , fp );
2729
+ if (rc )
2730
+ return rc ;
2731
+
2732
+ return hashtab_map (p -> role_tr , role_trans_write_one , & pd );
2733
+ }
2734
+
2689
2735
static int role_allow_write (struct role_allow * r , void * fp )
2690
2736
{
2691
2737
struct role_allow * ra ;
0 commit comments