@@ -87,28 +87,31 @@ static int cond_evaluate_expr(struct policydb *p, struct cond_expr *expr)
87
87
*/
88
88
void evaluate_cond_node (struct policydb * p , struct cond_node * node )
89
89
{
90
+ struct avtab_node * avnode ;
90
91
int new_state ;
91
- struct cond_av_list * cur ;
92
+ u32 i ;
92
93
93
94
new_state = cond_evaluate_expr (p , node -> expr );
94
95
if (new_state != node -> cur_state ) {
95
96
node -> cur_state = new_state ;
96
97
if (new_state == -1 )
97
98
pr_err ("SELinux: expression result was undefined - disabling all rules.\n" );
98
99
/* turn the rules on or off */
99
- for (cur = node -> true_list ; cur ; cur = cur -> next ) {
100
+ for (i = 0 ; i < node -> true_list .len ; i ++ ) {
101
+ avnode = node -> true_list .nodes [i ];
100
102
if (new_state <= 0 )
101
- cur -> node -> key .specified &= ~AVTAB_ENABLED ;
103
+ avnode -> key .specified &= ~AVTAB_ENABLED ;
102
104
else
103
- cur -> node -> key .specified |= AVTAB_ENABLED ;
105
+ avnode -> key .specified |= AVTAB_ENABLED ;
104
106
}
105
107
106
- for (cur = node -> false_list ; cur ; cur = cur -> next ) {
108
+ for (i = 0 ; i < node -> false_list .len ; i ++ ) {
109
+ avnode = node -> false_list .nodes [i ];
107
110
/* -1 or 1 */
108
111
if (new_state )
109
- cur -> node -> key .specified &= ~AVTAB_ENABLED ;
112
+ avnode -> key .specified &= ~AVTAB_ENABLED ;
110
113
else
111
- cur -> node -> key .specified |= AVTAB_ENABLED ;
114
+ avnode -> key .specified |= AVTAB_ENABLED ;
112
115
}
113
116
}
114
117
}
@@ -128,16 +131,6 @@ int cond_policydb_init(struct policydb *p)
128
131
return 0 ;
129
132
}
130
133
131
- static void cond_av_list_destroy (struct cond_av_list * list )
132
- {
133
- struct cond_av_list * cur , * next ;
134
- for (cur = list ; cur ; cur = next ) {
135
- next = cur -> next ;
136
- /* the avtab_ptr_t node is destroy by the avtab */
137
- kfree (cur );
138
- }
139
- }
140
-
141
134
static void cond_node_destroy (struct cond_node * node )
142
135
{
143
136
struct cond_expr * cur_expr , * next_expr ;
@@ -146,8 +139,9 @@ static void cond_node_destroy(struct cond_node *node)
146
139
next_expr = cur_expr -> next ;
147
140
kfree (cur_expr );
148
141
}
149
- cond_av_list_destroy (node -> true_list );
150
- cond_av_list_destroy (node -> false_list );
142
+ /* the avtab_ptr_t nodes are destroyed by the avtab */
143
+ kfree (node -> true_list .nodes );
144
+ kfree (node -> false_list .nodes );
151
145
}
152
146
153
147
static void cond_list_destroy (struct policydb * p )
@@ -255,19 +249,18 @@ int cond_read_bool(struct policydb *p, struct hashtab *h, void *fp)
255
249
256
250
struct cond_insertf_data {
257
251
struct policydb * p ;
252
+ struct avtab_node * * dst ;
258
253
struct cond_av_list * other ;
259
- struct cond_av_list * head ;
260
- struct cond_av_list * tail ;
261
254
};
262
255
263
256
static int cond_insertf (struct avtab * a , struct avtab_key * k , struct avtab_datum * d , void * ptr )
264
257
{
265
258
struct cond_insertf_data * data = ptr ;
266
259
struct policydb * p = data -> p ;
267
- struct cond_av_list * other = data -> other , * list , * cur ;
260
+ struct cond_av_list * other = data -> other ;
268
261
struct avtab_node * node_ptr ;
269
- u8 found ;
270
- int rc = - EINVAL ;
262
+ u32 i ;
263
+ bool found ;
271
264
272
265
/*
273
266
* For type rules we have to make certain there aren't any
@@ -277,7 +270,7 @@ static int cond_insertf(struct avtab *a, struct avtab_key *k, struct avtab_datum
277
270
if (k -> specified & AVTAB_TYPE ) {
278
271
if (avtab_search (& p -> te_avtab , k )) {
279
272
pr_err ("SELinux: type rule already exists outside of a conditional.\n" );
280
- goto err ;
273
+ return - EINVAL ;
281
274
}
282
275
/*
283
276
* If we are reading the false list other will be a pointer to
@@ -292,64 +285,47 @@ static int cond_insertf(struct avtab *a, struct avtab_key *k, struct avtab_datum
292
285
if (node_ptr ) {
293
286
if (avtab_search_node_next (node_ptr , k -> specified )) {
294
287
pr_err ("SELinux: too many conflicting type rules.\n" );
295
- goto err ;
288
+ return - EINVAL ;
296
289
}
297
- found = 0 ;
298
- for (cur = other ; cur ; cur = cur -> next ) {
299
- if (cur -> node == node_ptr ) {
300
- found = 1 ;
290
+ found = false ;
291
+ for (i = 0 ; i < other -> len ; i ++ ) {
292
+ if (other -> nodes [ i ] == node_ptr ) {
293
+ found = true ;
301
294
break ;
302
295
}
303
296
}
304
297
if (!found ) {
305
298
pr_err ("SELinux: conflicting type rules.\n" );
306
- goto err ;
299
+ return - EINVAL ;
307
300
}
308
301
}
309
302
} else {
310
303
if (avtab_search (& p -> te_cond_avtab , k )) {
311
304
pr_err ("SELinux: conflicting type rules when adding type rule for true.\n" );
312
- goto err ;
305
+ return - EINVAL ;
313
306
}
314
307
}
315
308
}
316
309
317
310
node_ptr = avtab_insert_nonunique (& p -> te_cond_avtab , k , d );
318
311
if (!node_ptr ) {
319
312
pr_err ("SELinux: could not insert rule.\n" );
320
- rc = - ENOMEM ;
321
- goto err ;
322
- }
323
-
324
- list = kzalloc (sizeof (* list ), GFP_KERNEL );
325
- if (!list ) {
326
- rc = - ENOMEM ;
327
- goto err ;
313
+ return - ENOMEM ;
328
314
}
329
315
330
- list -> node = node_ptr ;
331
- if (!data -> head )
332
- data -> head = list ;
333
- else
334
- data -> tail -> next = list ;
335
- data -> tail = list ;
316
+ * data -> dst = node_ptr ;
336
317
return 0 ;
337
-
338
- err :
339
- cond_av_list_destroy (data -> head );
340
- data -> head = NULL ;
341
- return rc ;
342
318
}
343
319
344
- static int cond_read_av_list (struct policydb * p , void * fp , struct cond_av_list * * ret_list , struct cond_av_list * other )
320
+ static int cond_read_av_list (struct policydb * p , void * fp ,
321
+ struct cond_av_list * list ,
322
+ struct cond_av_list * other )
345
323
{
346
- int i , rc ;
324
+ int rc ;
347
325
__le32 buf [1 ];
348
- u32 len ;
326
+ u32 i , len ;
349
327
struct cond_insertf_data data ;
350
328
351
- * ret_list = NULL ;
352
-
353
329
rc = next_entry (buf , fp , sizeof (u32 ));
354
330
if (rc )
355
331
return rc ;
@@ -358,18 +334,24 @@ static int cond_read_av_list(struct policydb *p, void *fp, struct cond_av_list *
358
334
if (len == 0 )
359
335
return 0 ;
360
336
337
+ list -> nodes = kcalloc (len , sizeof (* list -> nodes ), GFP_KERNEL );
338
+ if (!list -> nodes )
339
+ return - ENOMEM ;
340
+
361
341
data .p = p ;
362
342
data .other = other ;
363
- data .head = NULL ;
364
- data .tail = NULL ;
365
343
for (i = 0 ; i < len ; i ++ ) {
344
+ data .dst = & list -> nodes [i ];
366
345
rc = avtab_read_item (& p -> te_cond_avtab , fp , p , cond_insertf ,
367
346
& data );
368
- if (rc )
347
+ if (rc ) {
348
+ kfree (list -> nodes );
349
+ list -> nodes = NULL ;
369
350
return rc ;
351
+ }
370
352
}
371
353
372
- * ret_list = data . head ;
354
+ list -> len = len ;
373
355
return 0 ;
374
356
}
375
357
@@ -432,7 +414,7 @@ static int cond_read_node(struct policydb *p, struct cond_node *node, void *fp)
432
414
rc = cond_read_av_list (p , fp , & node -> true_list , NULL );
433
415
if (rc )
434
416
goto err ;
435
- rc = cond_read_av_list (p , fp , & node -> false_list , node -> true_list );
417
+ rc = cond_read_av_list (p , fp , & node -> false_list , & node -> true_list );
436
418
if (rc )
437
419
goto err ;
438
420
return 0 ;
@@ -511,24 +493,16 @@ static int cond_write_av_list(struct policydb *p,
511
493
struct cond_av_list * list , struct policy_file * fp )
512
494
{
513
495
__le32 buf [1 ];
514
- struct cond_av_list * cur_list ;
515
- u32 len ;
496
+ u32 i ;
516
497
int rc ;
517
498
518
- len = 0 ;
519
- for (cur_list = list ; cur_list != NULL ; cur_list = cur_list -> next )
520
- len ++ ;
521
-
522
- buf [0 ] = cpu_to_le32 (len );
499
+ buf [0 ] = cpu_to_le32 (list -> len );
523
500
rc = put_entry (buf , sizeof (u32 ), 1 , fp );
524
501
if (rc )
525
502
return rc ;
526
503
527
- if (len == 0 )
528
- return 0 ;
529
-
530
- for (cur_list = list ; cur_list != NULL ; cur_list = cur_list -> next ) {
531
- rc = avtab_write_item (p , cur_list -> node , fp );
504
+ for (i = 0 ; i < list -> len ; i ++ ) {
505
+ rc = avtab_write_item (p , list -> nodes [i ], fp );
532
506
if (rc )
533
507
return rc ;
534
508
}
@@ -565,10 +539,10 @@ static int cond_write_node(struct policydb *p, struct cond_node *node,
565
539
return rc ;
566
540
}
567
541
568
- rc = cond_write_av_list (p , node -> true_list , fp );
542
+ rc = cond_write_av_list (p , & node -> true_list , fp );
569
543
if (rc )
570
544
return rc ;
571
- rc = cond_write_av_list (p , node -> false_list , fp );
545
+ rc = cond_write_av_list (p , & node -> false_list , fp );
572
546
if (rc )
573
547
return rc ;
574
548
0 commit comments