Skip to content

Commit 8794d78

Browse files
WOnder93pcmoore
authored andcommitted
selinux: convert cond_expr to array
Since it is fixed-size after allocation and we know the size beforehand, using a plain old array is simpler and more efficient. Signed-off-by: Ondrej Mosnacek <[email protected]> Reviewed-by: Stephen Smalley <[email protected]> Signed-off-by: Paul Moore <[email protected]>
1 parent 2b3a003 commit 8794d78

File tree

2 files changed

+33
-43
lines changed

2 files changed

+33
-43
lines changed

security/selinux/ss/conditional.c

Lines changed: 24 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -23,18 +23,19 @@
2323
*/
2424
static int cond_evaluate_expr(struct policydb *p, struct cond_expr *expr)
2525
{
26-
27-
struct cond_expr *cur;
26+
u32 i;
2827
int s[COND_EXPR_MAXDEPTH];
2928
int sp = -1;
3029

31-
for (cur = expr; cur; cur = cur->next) {
32-
switch (cur->expr_type) {
30+
for (i = 0; i < expr->len; i++) {
31+
struct cond_expr_node *node = &expr->nodes[i];
32+
33+
switch (node->expr_type) {
3334
case COND_BOOL:
3435
if (sp == (COND_EXPR_MAXDEPTH - 1))
3536
return -1;
3637
sp++;
37-
s[sp] = p->bool_val_to_struct[cur->bool - 1]->state;
38+
s[sp] = p->bool_val_to_struct[node->bool - 1]->state;
3839
break;
3940
case COND_NOT:
4041
if (sp < 0)
@@ -91,7 +92,7 @@ void evaluate_cond_node(struct policydb *p, struct cond_node *node)
9192
int new_state;
9293
u32 i;
9394

94-
new_state = cond_evaluate_expr(p, node->expr);
95+
new_state = cond_evaluate_expr(p, &node->expr);
9596
if (new_state != node->cur_state) {
9697
node->cur_state = new_state;
9798
if (new_state == -1)
@@ -133,12 +134,7 @@ int cond_policydb_init(struct policydb *p)
133134

134135
static void cond_node_destroy(struct cond_node *node)
135136
{
136-
struct cond_expr *cur_expr, *next_expr;
137-
138-
for (cur_expr = node->expr; cur_expr; cur_expr = next_expr) {
139-
next_expr = cur_expr->next;
140-
kfree(cur_expr);
141-
}
137+
kfree(node->expr.nodes);
142138
/* the avtab_ptr_t nodes are destroyed by the avtab */
143139
kfree(node->true_list.nodes);
144140
kfree(node->false_list.nodes);
@@ -355,7 +351,7 @@ static int cond_read_av_list(struct policydb *p, void *fp,
355351
return 0;
356352
}
357353

358-
static int expr_isvalid(struct policydb *p, struct cond_expr *expr)
354+
static int expr_node_isvalid(struct policydb *p, struct cond_expr_node *expr)
359355
{
360356
if (expr->expr_type <= 0 || expr->expr_type > COND_LAST) {
361357
pr_err("SELinux: conditional expressions uses unknown operator.\n");
@@ -372,43 +368,37 @@ static int expr_isvalid(struct policydb *p, struct cond_expr *expr)
372368
static int cond_read_node(struct policydb *p, struct cond_node *node, void *fp)
373369
{
374370
__le32 buf[2];
375-
u32 len, i;
371+
u32 i, len;
376372
int rc;
377-
struct cond_expr *expr = NULL, *last = NULL;
378373

379374
rc = next_entry(buf, fp, sizeof(u32) * 2);
380375
if (rc)
381-
goto err;
376+
return rc;
382377

383378
node->cur_state = le32_to_cpu(buf[0]);
384379

385380
/* expr */
386381
len = le32_to_cpu(buf[1]);
382+
node->expr.nodes = kcalloc(len, sizeof(*node->expr.nodes), GFP_KERNEL);
383+
if (!node->expr.nodes)
384+
return -ENOMEM;
385+
386+
node->expr.len = len;
387387

388388
for (i = 0; i < len; i++) {
389+
struct cond_expr_node *expr = &node->expr.nodes[i];
390+
389391
rc = next_entry(buf, fp, sizeof(u32) * 2);
390392
if (rc)
391393
goto err;
392394

393-
rc = -ENOMEM;
394-
expr = kzalloc(sizeof(*expr), GFP_KERNEL);
395-
if (!expr)
396-
goto err;
397-
398395
expr->expr_type = le32_to_cpu(buf[0]);
399396
expr->bool = le32_to_cpu(buf[1]);
400397

401-
if (!expr_isvalid(p, expr)) {
398+
if (!expr_node_isvalid(p, expr)) {
402399
rc = -EINVAL;
403-
kfree(expr);
404400
goto err;
405401
}
406-
407-
if (i == 0)
408-
node->expr = expr;
409-
else
410-
last->next = expr;
411-
last = expr;
412402
}
413403

414404
rc = cond_read_av_list(p, fp, &node->true_list, NULL);
@@ -513,27 +503,23 @@ static int cond_write_av_list(struct policydb *p,
513503
static int cond_write_node(struct policydb *p, struct cond_node *node,
514504
struct policy_file *fp)
515505
{
516-
struct cond_expr *cur_expr;
517506
__le32 buf[2];
518507
int rc;
519-
u32 len = 0;
508+
u32 i;
520509

521510
buf[0] = cpu_to_le32(node->cur_state);
522511
rc = put_entry(buf, sizeof(u32), 1, fp);
523512
if (rc)
524513
return rc;
525514

526-
for (cur_expr = node->expr; cur_expr != NULL; cur_expr = cur_expr->next)
527-
len++;
528-
529-
buf[0] = cpu_to_le32(len);
515+
buf[0] = cpu_to_le32(node->expr.len);
530516
rc = put_entry(buf, sizeof(u32), 1, fp);
531517
if (rc)
532518
return rc;
533519

534-
for (cur_expr = node->expr; cur_expr != NULL; cur_expr = cur_expr->next) {
535-
buf[0] = cpu_to_le32(cur_expr->expr_type);
536-
buf[1] = cpu_to_le32(cur_expr->bool);
520+
for (i = 0; i < node->expr.len; i++) {
521+
buf[0] = cpu_to_le32(node->expr.nodes[i].expr_type);
522+
buf[1] = cpu_to_le32(node->expr.nodes[i].bool);
537523
rc = put_entry(buf, sizeof(u32), 2, fp);
538524
if (rc)
539525
return rc;

security/selinux/ss/conditional.h

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
* A conditional expression is a list of operators and operands
2020
* in reverse polish notation.
2121
*/
22-
struct cond_expr {
22+
struct cond_expr_node {
2323
#define COND_BOOL 1 /* plain bool */
2424
#define COND_NOT 2 /* !bool */
2525
#define COND_OR 3 /* bool || bool */
@@ -28,9 +28,13 @@ struct cond_expr {
2828
#define COND_EQ 6 /* bool == bool */
2929
#define COND_NEQ 7 /* bool != bool */
3030
#define COND_LAST COND_NEQ
31-
__u32 expr_type;
32-
__u32 bool;
33-
struct cond_expr *next;
31+
u32 expr_type;
32+
u32 bool;
33+
};
34+
35+
struct cond_expr {
36+
struct cond_expr_node *nodes;
37+
u32 len;
3438
};
3539

3640
/*
@@ -52,7 +56,7 @@ struct cond_av_list {
5256
*/
5357
struct cond_node {
5458
int cur_state;
55-
struct cond_expr *expr;
59+
struct cond_expr expr;
5660
struct cond_av_list true_list;
5761
struct cond_av_list false_list;
5862
};

0 commit comments

Comments
 (0)