@@ -154,6 +154,11 @@ static struct policydb_compat_info policydb_compat[] = {
154
154
.sym_num = SYM_NUM ,
155
155
.ocon_num = OCON_NUM ,
156
156
},
157
+ {
158
+ .version = POLICYDB_VERSION_COMP_FTRANS ,
159
+ .sym_num = SYM_NUM ,
160
+ .ocon_num = OCON_NUM ,
161
+ },
157
162
};
158
163
159
164
static struct policydb_compat_info * policydb_lookup_compat (int version )
@@ -492,23 +497,16 @@ static int role_trans_cmp(struct hashtab *h, const void *k1, const void *k2)
492
497
/*
493
498
* Initialize a policy database structure.
494
499
*/
495
- static int policydb_init (struct policydb * p )
500
+ static void policydb_init (struct policydb * p )
496
501
{
497
502
memset (p , 0 , sizeof (* p ));
498
503
499
504
avtab_init (& p -> te_avtab );
500
505
cond_policydb_init (p );
501
506
502
- p -> filename_trans = hashtab_create (filenametr_hash , filenametr_cmp ,
503
- (1 << 11 ));
504
- if (!p -> filename_trans )
505
- return - ENOMEM ;
506
-
507
507
ebitmap_init (& p -> filename_trans_ttypes );
508
508
ebitmap_init (& p -> policycaps );
509
509
ebitmap_init (& p -> permissive_map );
510
-
511
- return 0 ;
512
510
}
513
511
514
512
/*
@@ -1862,7 +1860,7 @@ static int range_read(struct policydb *p, void *fp)
1862
1860
return rc ;
1863
1861
}
1864
1862
1865
- static int filename_trans_read_one (struct policydb * p , void * fp )
1863
+ static int filename_trans_read_helper_compat (struct policydb * p , void * fp )
1866
1864
{
1867
1865
struct filename_trans_key key , * ft = NULL ;
1868
1866
struct filename_trans_datum * last , * datum = NULL ;
@@ -1945,6 +1943,99 @@ static int filename_trans_read_one(struct policydb *p, void *fp)
1945
1943
return rc ;
1946
1944
}
1947
1945
1946
+ static int filename_trans_read_helper (struct policydb * p , void * fp )
1947
+ {
1948
+ struct filename_trans_key * ft = NULL ;
1949
+ struct filename_trans_datum * * dst , * datum , * first = NULL ;
1950
+ char * name = NULL ;
1951
+ u32 len , ttype , tclass , ndatum , i ;
1952
+ __le32 buf [3 ];
1953
+ int rc ;
1954
+
1955
+ /* length of the path component string */
1956
+ rc = next_entry (buf , fp , sizeof (u32 ));
1957
+ if (rc )
1958
+ return rc ;
1959
+ len = le32_to_cpu (buf [0 ]);
1960
+
1961
+ /* path component string */
1962
+ rc = str_read (& name , GFP_KERNEL , fp , len );
1963
+ if (rc )
1964
+ return rc ;
1965
+
1966
+ rc = next_entry (buf , fp , sizeof (u32 ) * 3 );
1967
+ if (rc )
1968
+ goto out ;
1969
+
1970
+ ttype = le32_to_cpu (buf [0 ]);
1971
+ tclass = le32_to_cpu (buf [1 ]);
1972
+
1973
+ ndatum = le32_to_cpu (buf [2 ]);
1974
+ if (ndatum == 0 ) {
1975
+ pr_err ("SELinux: Filename transition key with no datum\n" );
1976
+ rc = - ENOENT ;
1977
+ goto out ;
1978
+ }
1979
+
1980
+ dst = & first ;
1981
+ for (i = 0 ; i < ndatum ; i ++ ) {
1982
+ rc = - ENOMEM ;
1983
+ datum = kmalloc (sizeof (* datum ), GFP_KERNEL );
1984
+ if (!datum )
1985
+ goto out ;
1986
+
1987
+ * dst = datum ;
1988
+
1989
+ /* ebitmap_read() will at least init the bitmap */
1990
+ rc = ebitmap_read (& datum -> stypes , fp );
1991
+ if (rc )
1992
+ goto out ;
1993
+
1994
+ rc = next_entry (buf , fp , sizeof (u32 ));
1995
+ if (rc )
1996
+ goto out ;
1997
+
1998
+ datum -> otype = le32_to_cpu (buf [0 ]);
1999
+ datum -> next = NULL ;
2000
+
2001
+ dst = & datum -> next ;
2002
+ }
2003
+
2004
+ rc = - ENOMEM ;
2005
+ ft = kmalloc (sizeof (* ft ), GFP_KERNEL );
2006
+ if (!ft )
2007
+ goto out ;
2008
+
2009
+ ft -> ttype = ttype ;
2010
+ ft -> tclass = tclass ;
2011
+ ft -> name = name ;
2012
+
2013
+ rc = hashtab_insert (p -> filename_trans , ft , first );
2014
+ if (rc == - EEXIST )
2015
+ pr_err ("SELinux: Duplicate filename transition key\n" );
2016
+ if (rc )
2017
+ goto out ;
2018
+
2019
+ rc = ebitmap_set_bit (& p -> filename_trans_ttypes , ttype , 1 );
2020
+ if (rc )
2021
+ return rc ;
2022
+
2023
+ p -> filename_trans_count += ndatum ;
2024
+ return 0 ;
2025
+
2026
+ out :
2027
+ kfree (ft );
2028
+ kfree (name );
2029
+ while (first ) {
2030
+ datum = first ;
2031
+ first = first -> next ;
2032
+
2033
+ ebitmap_destroy (& datum -> stypes );
2034
+ kfree (datum );
2035
+ }
2036
+ return rc ;
2037
+ }
2038
+
1948
2039
static int filename_trans_read (struct policydb * p , void * fp )
1949
2040
{
1950
2041
u32 nel ;
@@ -1959,12 +2050,29 @@ static int filename_trans_read(struct policydb *p, void *fp)
1959
2050
return rc ;
1960
2051
nel = le32_to_cpu (buf [0 ]);
1961
2052
1962
- p -> filename_trans_count = nel ;
2053
+ if (p -> policyvers < POLICYDB_VERSION_COMP_FTRANS ) {
2054
+ p -> filename_trans_count = nel ;
2055
+ p -> filename_trans = hashtab_create (filenametr_hash ,
2056
+ filenametr_cmp , (1 << 11 ));
2057
+ if (!p -> filename_trans )
2058
+ return - ENOMEM ;
1963
2059
1964
- for (i = 0 ; i < nel ; i ++ ) {
1965
- rc = filename_trans_read_one (p , fp );
1966
- if (rc )
1967
- return rc ;
2060
+ for (i = 0 ; i < nel ; i ++ ) {
2061
+ rc = filename_trans_read_helper_compat (p , fp );
2062
+ if (rc )
2063
+ return rc ;
2064
+ }
2065
+ } else {
2066
+ p -> filename_trans = hashtab_create (filenametr_hash ,
2067
+ filenametr_cmp , nel );
2068
+ if (!p -> filename_trans )
2069
+ return - ENOMEM ;
2070
+
2071
+ for (i = 0 ; i < nel ; i ++ ) {
2072
+ rc = filename_trans_read_helper (p , fp );
2073
+ if (rc )
2074
+ return rc ;
2075
+ }
1968
2076
}
1969
2077
hash_eval (p -> filename_trans , "filenametr" );
1970
2078
return 0 ;
@@ -2281,9 +2389,7 @@ int policydb_read(struct policydb *p, void *fp)
2281
2389
char * policydb_str ;
2282
2390
struct policydb_compat_info * info ;
2283
2391
2284
- rc = policydb_init (p );
2285
- if (rc )
2286
- return rc ;
2392
+ policydb_init (p );
2287
2393
2288
2394
/* Read the magic number and string length. */
2289
2395
rc = next_entry (buf , fp , sizeof (u32 ) * 2 );
@@ -3367,7 +3473,7 @@ static int range_write(struct policydb *p, void *fp)
3367
3473
return 0 ;
3368
3474
}
3369
3475
3370
- static int filename_write_helper (void * key , void * data , void * ptr )
3476
+ static int filename_write_helper_compat (void * key , void * data , void * ptr )
3371
3477
{
3372
3478
struct filename_trans_key * ft = key ;
3373
3479
struct filename_trans_datum * datum = data ;
@@ -3404,26 +3510,82 @@ static int filename_write_helper(void *key, void *data, void *ptr)
3404
3510
return 0 ;
3405
3511
}
3406
3512
3407
- static int filename_trans_write ( struct policydb * p , void * fp )
3513
+ static int filename_write_helper ( void * key , void * data , void * ptr )
3408
3514
{
3409
- __le32 buf [1 ];
3515
+ struct filename_trans_key * ft = key ;
3516
+ struct filename_trans_datum * datum ;
3517
+ void * fp = ptr ;
3518
+ __le32 buf [3 ];
3410
3519
int rc ;
3520
+ u32 ndatum , len = strlen (ft -> name );
3411
3521
3412
- if (p -> policyvers < POLICYDB_VERSION_FILENAME_TRANS )
3413
- return 0 ;
3414
-
3415
- buf [0 ] = cpu_to_le32 (p -> filename_trans_count );
3522
+ buf [0 ] = cpu_to_le32 (len );
3416
3523
rc = put_entry (buf , sizeof (u32 ), 1 , fp );
3417
3524
if (rc )
3418
3525
return rc ;
3419
3526
3420
- rc = hashtab_map ( p -> filename_trans , filename_write_helper , fp );
3527
+ rc = put_entry ( ft -> name , sizeof ( char ), len , fp );
3421
3528
if (rc )
3422
3529
return rc ;
3423
3530
3531
+ ndatum = 0 ;
3532
+ datum = data ;
3533
+ do {
3534
+ ndatum ++ ;
3535
+ datum = datum -> next ;
3536
+ } while (unlikely (datum ));
3537
+
3538
+ buf [0 ] = cpu_to_le32 (ft -> ttype );
3539
+ buf [1 ] = cpu_to_le32 (ft -> tclass );
3540
+ buf [2 ] = cpu_to_le32 (ndatum );
3541
+ rc = put_entry (buf , sizeof (u32 ), 3 , fp );
3542
+ if (rc )
3543
+ return rc ;
3544
+
3545
+ datum = data ;
3546
+ do {
3547
+ rc = ebitmap_write (& datum -> stypes , fp );
3548
+ if (rc )
3549
+ return rc ;
3550
+
3551
+ buf [0 ] = cpu_to_le32 (datum -> otype );
3552
+ rc = put_entry (buf , sizeof (u32 ), 1 , fp );
3553
+ if (rc )
3554
+ return rc ;
3555
+
3556
+ datum = datum -> next ;
3557
+ } while (unlikely (datum ));
3558
+
3424
3559
return 0 ;
3425
3560
}
3426
3561
3562
+ static int filename_trans_write (struct policydb * p , void * fp )
3563
+ {
3564
+ __le32 buf [1 ];
3565
+ int rc ;
3566
+
3567
+ if (p -> policyvers < POLICYDB_VERSION_FILENAME_TRANS )
3568
+ return 0 ;
3569
+
3570
+ if (p -> policyvers < POLICYDB_VERSION_COMP_FTRANS ) {
3571
+ buf [0 ] = cpu_to_le32 (p -> filename_trans_count );
3572
+ rc = put_entry (buf , sizeof (u32 ), 1 , fp );
3573
+ if (rc )
3574
+ return rc ;
3575
+
3576
+ rc = hashtab_map (p -> filename_trans ,
3577
+ filename_write_helper_compat , fp );
3578
+ } else {
3579
+ buf [0 ] = cpu_to_le32 (p -> filename_trans -> nel );
3580
+ rc = put_entry (buf , sizeof (u32 ), 1 , fp );
3581
+ if (rc )
3582
+ return rc ;
3583
+
3584
+ rc = hashtab_map (p -> filename_trans , filename_write_helper , fp );
3585
+ }
3586
+ return rc ;
3587
+ }
3588
+
3427
3589
/*
3428
3590
* Write the configuration data in a policy database
3429
3591
* structure to a policy database binary representation
0 commit comments