mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-01 22:54:01 +00:00
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 <omosnace@redhat.com> Reviewed-by: Stephen Smalley <sds@tycho.nsa.gov> Signed-off-by: Paul Moore <paul@paul-moore.com>
This commit is contained in:
parent
2b3a003e15
commit
8794d78390
2 changed files with 33 additions and 43 deletions
|
@ -23,18 +23,19 @@
|
||||||
*/
|
*/
|
||||||
static int cond_evaluate_expr(struct policydb *p, struct cond_expr *expr)
|
static int cond_evaluate_expr(struct policydb *p, struct cond_expr *expr)
|
||||||
{
|
{
|
||||||
|
u32 i;
|
||||||
struct cond_expr *cur;
|
|
||||||
int s[COND_EXPR_MAXDEPTH];
|
int s[COND_EXPR_MAXDEPTH];
|
||||||
int sp = -1;
|
int sp = -1;
|
||||||
|
|
||||||
for (cur = expr; cur; cur = cur->next) {
|
for (i = 0; i < expr->len; i++) {
|
||||||
switch (cur->expr_type) {
|
struct cond_expr_node *node = &expr->nodes[i];
|
||||||
|
|
||||||
|
switch (node->expr_type) {
|
||||||
case COND_BOOL:
|
case COND_BOOL:
|
||||||
if (sp == (COND_EXPR_MAXDEPTH - 1))
|
if (sp == (COND_EXPR_MAXDEPTH - 1))
|
||||||
return -1;
|
return -1;
|
||||||
sp++;
|
sp++;
|
||||||
s[sp] = p->bool_val_to_struct[cur->bool - 1]->state;
|
s[sp] = p->bool_val_to_struct[node->bool - 1]->state;
|
||||||
break;
|
break;
|
||||||
case COND_NOT:
|
case COND_NOT:
|
||||||
if (sp < 0)
|
if (sp < 0)
|
||||||
|
@ -91,7 +92,7 @@ void evaluate_cond_node(struct policydb *p, struct cond_node *node)
|
||||||
int new_state;
|
int new_state;
|
||||||
u32 i;
|
u32 i;
|
||||||
|
|
||||||
new_state = cond_evaluate_expr(p, node->expr);
|
new_state = cond_evaluate_expr(p, &node->expr);
|
||||||
if (new_state != node->cur_state) {
|
if (new_state != node->cur_state) {
|
||||||
node->cur_state = new_state;
|
node->cur_state = new_state;
|
||||||
if (new_state == -1)
|
if (new_state == -1)
|
||||||
|
@ -133,12 +134,7 @@ int cond_policydb_init(struct policydb *p)
|
||||||
|
|
||||||
static void cond_node_destroy(struct cond_node *node)
|
static void cond_node_destroy(struct cond_node *node)
|
||||||
{
|
{
|
||||||
struct cond_expr *cur_expr, *next_expr;
|
kfree(node->expr.nodes);
|
||||||
|
|
||||||
for (cur_expr = node->expr; cur_expr; cur_expr = next_expr) {
|
|
||||||
next_expr = cur_expr->next;
|
|
||||||
kfree(cur_expr);
|
|
||||||
}
|
|
||||||
/* the avtab_ptr_t nodes are destroyed by the avtab */
|
/* the avtab_ptr_t nodes are destroyed by the avtab */
|
||||||
kfree(node->true_list.nodes);
|
kfree(node->true_list.nodes);
|
||||||
kfree(node->false_list.nodes);
|
kfree(node->false_list.nodes);
|
||||||
|
@ -355,7 +351,7 @@ static int cond_read_av_list(struct policydb *p, void *fp,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int expr_isvalid(struct policydb *p, struct cond_expr *expr)
|
static int expr_node_isvalid(struct policydb *p, struct cond_expr_node *expr)
|
||||||
{
|
{
|
||||||
if (expr->expr_type <= 0 || expr->expr_type > COND_LAST) {
|
if (expr->expr_type <= 0 || expr->expr_type > COND_LAST) {
|
||||||
pr_err("SELinux: conditional expressions uses unknown operator.\n");
|
pr_err("SELinux: conditional expressions uses unknown operator.\n");
|
||||||
|
@ -372,43 +368,37 @@ static int expr_isvalid(struct policydb *p, struct cond_expr *expr)
|
||||||
static int cond_read_node(struct policydb *p, struct cond_node *node, void *fp)
|
static int cond_read_node(struct policydb *p, struct cond_node *node, void *fp)
|
||||||
{
|
{
|
||||||
__le32 buf[2];
|
__le32 buf[2];
|
||||||
u32 len, i;
|
u32 i, len;
|
||||||
int rc;
|
int rc;
|
||||||
struct cond_expr *expr = NULL, *last = NULL;
|
|
||||||
|
|
||||||
rc = next_entry(buf, fp, sizeof(u32) * 2);
|
rc = next_entry(buf, fp, sizeof(u32) * 2);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto err;
|
return rc;
|
||||||
|
|
||||||
node->cur_state = le32_to_cpu(buf[0]);
|
node->cur_state = le32_to_cpu(buf[0]);
|
||||||
|
|
||||||
/* expr */
|
/* expr */
|
||||||
len = le32_to_cpu(buf[1]);
|
len = le32_to_cpu(buf[1]);
|
||||||
|
node->expr.nodes = kcalloc(len, sizeof(*node->expr.nodes), GFP_KERNEL);
|
||||||
|
if (!node->expr.nodes)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
node->expr.len = len;
|
||||||
|
|
||||||
for (i = 0; i < len; i++) {
|
for (i = 0; i < len; i++) {
|
||||||
|
struct cond_expr_node *expr = &node->expr.nodes[i];
|
||||||
|
|
||||||
rc = next_entry(buf, fp, sizeof(u32) * 2);
|
rc = next_entry(buf, fp, sizeof(u32) * 2);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
rc = -ENOMEM;
|
|
||||||
expr = kzalloc(sizeof(*expr), GFP_KERNEL);
|
|
||||||
if (!expr)
|
|
||||||
goto err;
|
|
||||||
|
|
||||||
expr->expr_type = le32_to_cpu(buf[0]);
|
expr->expr_type = le32_to_cpu(buf[0]);
|
||||||
expr->bool = le32_to_cpu(buf[1]);
|
expr->bool = le32_to_cpu(buf[1]);
|
||||||
|
|
||||||
if (!expr_isvalid(p, expr)) {
|
if (!expr_node_isvalid(p, expr)) {
|
||||||
rc = -EINVAL;
|
rc = -EINVAL;
|
||||||
kfree(expr);
|
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i == 0)
|
|
||||||
node->expr = expr;
|
|
||||||
else
|
|
||||||
last->next = expr;
|
|
||||||
last = expr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = cond_read_av_list(p, fp, &node->true_list, NULL);
|
rc = cond_read_av_list(p, fp, &node->true_list, NULL);
|
||||||
|
@ -513,27 +503,23 @@ static int cond_write_av_list(struct policydb *p,
|
||||||
static int cond_write_node(struct policydb *p, struct cond_node *node,
|
static int cond_write_node(struct policydb *p, struct cond_node *node,
|
||||||
struct policy_file *fp)
|
struct policy_file *fp)
|
||||||
{
|
{
|
||||||
struct cond_expr *cur_expr;
|
|
||||||
__le32 buf[2];
|
__le32 buf[2];
|
||||||
int rc;
|
int rc;
|
||||||
u32 len = 0;
|
u32 i;
|
||||||
|
|
||||||
buf[0] = cpu_to_le32(node->cur_state);
|
buf[0] = cpu_to_le32(node->cur_state);
|
||||||
rc = put_entry(buf, sizeof(u32), 1, fp);
|
rc = put_entry(buf, sizeof(u32), 1, fp);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
for (cur_expr = node->expr; cur_expr != NULL; cur_expr = cur_expr->next)
|
buf[0] = cpu_to_le32(node->expr.len);
|
||||||
len++;
|
|
||||||
|
|
||||||
buf[0] = cpu_to_le32(len);
|
|
||||||
rc = put_entry(buf, sizeof(u32), 1, fp);
|
rc = put_entry(buf, sizeof(u32), 1, fp);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
for (cur_expr = node->expr; cur_expr != NULL; cur_expr = cur_expr->next) {
|
for (i = 0; i < node->expr.len; i++) {
|
||||||
buf[0] = cpu_to_le32(cur_expr->expr_type);
|
buf[0] = cpu_to_le32(node->expr.nodes[i].expr_type);
|
||||||
buf[1] = cpu_to_le32(cur_expr->bool);
|
buf[1] = cpu_to_le32(node->expr.nodes[i].bool);
|
||||||
rc = put_entry(buf, sizeof(u32), 2, fp);
|
rc = put_entry(buf, sizeof(u32), 2, fp);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
* A conditional expression is a list of operators and operands
|
* A conditional expression is a list of operators and operands
|
||||||
* in reverse polish notation.
|
* in reverse polish notation.
|
||||||
*/
|
*/
|
||||||
struct cond_expr {
|
struct cond_expr_node {
|
||||||
#define COND_BOOL 1 /* plain bool */
|
#define COND_BOOL 1 /* plain bool */
|
||||||
#define COND_NOT 2 /* !bool */
|
#define COND_NOT 2 /* !bool */
|
||||||
#define COND_OR 3 /* bool || bool */
|
#define COND_OR 3 /* bool || bool */
|
||||||
|
@ -28,9 +28,13 @@ struct cond_expr {
|
||||||
#define COND_EQ 6 /* bool == bool */
|
#define COND_EQ 6 /* bool == bool */
|
||||||
#define COND_NEQ 7 /* bool != bool */
|
#define COND_NEQ 7 /* bool != bool */
|
||||||
#define COND_LAST COND_NEQ
|
#define COND_LAST COND_NEQ
|
||||||
__u32 expr_type;
|
u32 expr_type;
|
||||||
__u32 bool;
|
u32 bool;
|
||||||
struct cond_expr *next;
|
};
|
||||||
|
|
||||||
|
struct cond_expr {
|
||||||
|
struct cond_expr_node *nodes;
|
||||||
|
u32 len;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -52,7 +56,7 @@ struct cond_av_list {
|
||||||
*/
|
*/
|
||||||
struct cond_node {
|
struct cond_node {
|
||||||
int cur_state;
|
int cur_state;
|
||||||
struct cond_expr *expr;
|
struct cond_expr expr;
|
||||||
struct cond_av_list true_list;
|
struct cond_av_list true_list;
|
||||||
struct cond_av_list false_list;
|
struct cond_av_list false_list;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue