@@ -184,6 +184,43 @@ static int roles_init(struct policydb *p)
184
184
return rc ;
185
185
}
186
186
187
+ static u32 filenametr_hash (struct hashtab * h , const void * k )
188
+ {
189
+ const struct filename_trans * ft = k ;
190
+ unsigned long hash ;
191
+ unsigned int byte_num ;
192
+ unsigned char focus ;
193
+
194
+ hash = ft -> stype ^ ft -> ttype ^ ft -> tclass ;
195
+
196
+ byte_num = 0 ;
197
+ while ((focus = ft -> name [byte_num ++ ]))
198
+ hash = partial_name_hash (focus , hash );
199
+ return hash & (h -> size - 1 );
200
+ }
201
+
202
+ static int filenametr_cmp (struct hashtab * h , const void * k1 , const void * k2 )
203
+ {
204
+ const struct filename_trans * ft1 = k1 ;
205
+ const struct filename_trans * ft2 = k2 ;
206
+ int v ;
207
+
208
+ v = ft1 -> stype - ft2 -> stype ;
209
+ if (v )
210
+ return v ;
211
+
212
+ v = ft1 -> ttype - ft2 -> ttype ;
213
+ if (v )
214
+ return v ;
215
+
216
+ v = ft1 -> tclass - ft2 -> tclass ;
217
+ if (v )
218
+ return v ;
219
+
220
+ return strcmp (ft1 -> name , ft2 -> name );
221
+
222
+ }
223
+
187
224
static u32 rangetr_hash (struct hashtab * h , const void * k )
188
225
{
189
226
const struct range_trans * key = k ;
@@ -236,6 +273,10 @@ static int policydb_init(struct policydb *p)
236
273
if (rc )
237
274
goto out ;
238
275
276
+ p -> filename_trans = hashtab_create (filenametr_hash , filenametr_cmp , (1 << 10 ));
277
+ if (!p -> filename_trans )
278
+ goto out ;
279
+
239
280
p -> range_tr = hashtab_create (rangetr_hash , rangetr_cmp , 256 );
240
281
if (!p -> range_tr )
241
282
goto out ;
@@ -246,6 +287,8 @@ static int policydb_init(struct policydb *p)
246
287
247
288
return 0 ;
248
289
out :
290
+ hashtab_destroy (p -> filename_trans );
291
+ hashtab_destroy (p -> range_tr );
249
292
for (i = 0 ; i < SYM_NUM ; i ++ )
250
293
hashtab_destroy (p -> symtab [i ].table );
251
294
return rc ;
@@ -675,6 +718,16 @@ static int (*destroy_f[SYM_NUM]) (void *key, void *datum, void *datap) =
675
718
cat_destroy ,
676
719
};
677
720
721
+ static int filenametr_destroy (void * key , void * datum , void * p )
722
+ {
723
+ struct filename_trans * ft = key ;
724
+ kfree (ft -> name );
725
+ kfree (key );
726
+ kfree (datum );
727
+ cond_resched ();
728
+ return 0 ;
729
+ }
730
+
678
731
static int range_tr_destroy (void * key , void * datum , void * p )
679
732
{
680
733
struct mls_range * rt = datum ;
@@ -709,7 +762,6 @@ void policydb_destroy(struct policydb *p)
709
762
int i ;
710
763
struct role_allow * ra , * lra = NULL ;
711
764
struct role_trans * tr , * ltr = NULL ;
712
- struct filename_trans * ft , * nft ;
713
765
714
766
for (i = 0 ; i < SYM_NUM ; i ++ ) {
715
767
cond_resched ();
@@ -773,6 +825,9 @@ void policydb_destroy(struct policydb *p)
773
825
}
774
826
kfree (lra );
775
827
828
+ hashtab_map (p -> filename_trans , filenametr_destroy , NULL );
829
+ hashtab_destroy (p -> filename_trans );
830
+
776
831
hashtab_map (p -> range_tr , range_tr_destroy , NULL );
777
832
hashtab_destroy (p -> range_tr );
778
833
@@ -788,14 +843,6 @@ void policydb_destroy(struct policydb *p)
788
843
flex_array_free (p -> type_attr_map_array );
789
844
}
790
845
791
- ft = p -> filename_trans ;
792
- while (ft ) {
793
- nft = ft -> next ;
794
- kfree (ft -> name );
795
- kfree (ft );
796
- ft = nft ;
797
- }
798
-
799
846
ebitmap_destroy (& p -> filename_trans_ttypes );
800
847
ebitmap_destroy (& p -> policycaps );
801
848
ebitmap_destroy (& p -> permissive_map );
@@ -1806,9 +1853,10 @@ static int range_read(struct policydb *p, void *fp)
1806
1853
1807
1854
static int filename_trans_read (struct policydb * p , void * fp )
1808
1855
{
1809
- struct filename_trans * ft , * last ;
1810
- u32 nel , len ;
1856
+ struct filename_trans * ft ;
1857
+ struct filename_trans_datum * otype ;
1811
1858
char * name ;
1859
+ u32 nel , len ;
1812
1860
__le32 buf [4 ];
1813
1861
int rc , i ;
1814
1862
@@ -1817,25 +1865,23 @@ static int filename_trans_read(struct policydb *p, void *fp)
1817
1865
1818
1866
rc = next_entry (buf , fp , sizeof (u32 ));
1819
1867
if (rc )
1820
- goto out ;
1868
+ return rc ;
1821
1869
nel = le32_to_cpu (buf [0 ]);
1822
1870
1823
- last = p -> filename_trans ;
1824
- while (last && last -> next )
1825
- last = last -> next ;
1826
-
1827
1871
for (i = 0 ; i < nel ; i ++ ) {
1872
+ ft = NULL ;
1873
+ otype = NULL ;
1874
+ name = NULL ;
1875
+
1828
1876
rc = - ENOMEM ;
1829
1877
ft = kzalloc (sizeof (* ft ), GFP_KERNEL );
1830
1878
if (!ft )
1831
1879
goto out ;
1832
1880
1833
- /* add it to the tail of the list */
1834
- if (!last )
1835
- p -> filename_trans = ft ;
1836
- else
1837
- last -> next = ft ;
1838
- last = ft ;
1881
+ rc = - ENOMEM ;
1882
+ otype = kmalloc (sizeof (* otype ), GFP_KERNEL );
1883
+ if (!otype )
1884
+ goto out ;
1839
1885
1840
1886
/* length of the path component string */
1841
1887
rc = next_entry (buf , fp , sizeof (u32 ));
@@ -1863,14 +1909,22 @@ static int filename_trans_read(struct policydb *p, void *fp)
1863
1909
ft -> stype = le32_to_cpu (buf [0 ]);
1864
1910
ft -> ttype = le32_to_cpu (buf [1 ]);
1865
1911
ft -> tclass = le32_to_cpu (buf [2 ]);
1866
- ft -> otype = le32_to_cpu (buf [3 ]);
1912
+
1913
+ otype -> otype = le32_to_cpu (buf [3 ]);
1867
1914
1868
1915
rc = ebitmap_set_bit (& p -> filename_trans_ttypes , ft -> ttype , 1 );
1869
1916
if (rc )
1870
1917
goto out ;
1918
+
1919
+ hashtab_insert (p -> filename_trans , ft , otype );
1871
1920
}
1872
- rc = 0 ;
1921
+ hash_eval (p -> filename_trans , "filenametr" );
1922
+ return 0 ;
1873
1923
out :
1924
+ kfree (ft );
1925
+ kfree (name );
1926
+ kfree (otype );
1927
+
1874
1928
return rc ;
1875
1929
}
1876
1930
@@ -3131,43 +3185,60 @@ static int range_write(struct policydb *p, void *fp)
3131
3185
return 0 ;
3132
3186
}
3133
3187
3134
- static int filename_trans_write ( struct policydb * p , void * fp )
3188
+ static int filename_write_helper ( void * key , void * data , void * ptr )
3135
3189
{
3136
- struct filename_trans * ft ;
3137
- u32 len , nel = 0 ;
3138
3190
__le32 buf [4 ];
3191
+ struct filename_trans * ft = key ;
3192
+ struct filename_trans_datum * otype = data ;
3193
+ void * fp = ptr ;
3139
3194
int rc ;
3195
+ u32 len ;
3140
3196
3141
- for (ft = p -> filename_trans ; ft ; ft = ft -> next )
3142
- nel ++ ;
3143
-
3144
- buf [0 ] = cpu_to_le32 (nel );
3197
+ len = strlen (ft -> name );
3198
+ buf [0 ] = cpu_to_le32 (len );
3145
3199
rc = put_entry (buf , sizeof (u32 ), 1 , fp );
3146
3200
if (rc )
3147
3201
return rc ;
3148
3202
3149
- for (ft = p -> filename_trans ; ft ; ft = ft -> next ) {
3150
- len = strlen (ft -> name );
3151
- buf [0 ] = cpu_to_le32 (len );
3152
- rc = put_entry (buf , sizeof (u32 ), 1 , fp );
3153
- if (rc )
3154
- return rc ;
3203
+ rc = put_entry (ft -> name , sizeof (char ), len , fp );
3204
+ if (rc )
3205
+ return rc ;
3155
3206
3156
- rc = put_entry (ft -> name , sizeof (char ), len , fp );
3157
- if (rc )
3158
- return rc ;
3207
+ buf [0 ] = ft -> stype ;
3208
+ buf [1 ] = ft -> ttype ;
3209
+ buf [2 ] = ft -> tclass ;
3210
+ buf [3 ] = otype -> otype ;
3159
3211
3160
- buf [0 ] = ft -> stype ;
3161
- buf [1 ] = ft -> ttype ;
3162
- buf [2 ] = ft -> tclass ;
3163
- buf [3 ] = ft -> otype ;
3212
+ rc = put_entry (buf , sizeof (u32 ), 4 , fp );
3213
+ if (rc )
3214
+ return rc ;
3164
3215
3165
- rc = put_entry (buf , sizeof (u32 ), 4 , fp );
3166
- if (rc )
3167
- return rc ;
3168
- }
3169
3216
return 0 ;
3170
3217
}
3218
+
3219
+ static int filename_trans_write (struct policydb * p , void * fp )
3220
+ {
3221
+ u32 nel ;
3222
+ __le32 buf [1 ];
3223
+ int rc ;
3224
+
3225
+ nel = 0 ;
3226
+ rc = hashtab_map (p -> filename_trans , hashtab_cnt , & nel );
3227
+ if (rc )
3228
+ return rc ;
3229
+
3230
+ buf [0 ] = cpu_to_le32 (nel );
3231
+ rc = put_entry (buf , sizeof (u32 ), 1 , fp );
3232
+ if (rc )
3233
+ return rc ;
3234
+
3235
+ rc = hashtab_map (p -> filename_trans , filename_write_helper , fp );
3236
+ if (rc )
3237
+ return rc ;
3238
+
3239
+ return 0 ;
3240
+ }
3241
+
3171
3242
/*
3172
3243
* Write the configuration data in a policy database
3173
3244
* structure to a policy database binary representation
0 commit comments