diff options
author | Dan Carpenter <error27@gmail.com> | 2010-06-12 14:53:46 -0400 |
---|---|---|
committer | James Morris <jmorris@namei.org> | 2010-08-02 01:35:02 -0400 |
commit | fc5c126e4733e6fb3080d3d822ca63226e74fc84 (patch) | |
tree | 3320c22b66107c984ac0cf07c365420df42a4977 /security/selinux/ss/conditional.c | |
parent | 9d623b17a740d5a85c12108cdc71c64fb15484fc (diff) |
selinux: fix error codes in cond_read_node()
Originally cond_read_node() returned -1 (-EPERM) on errors which was
incorrect. Now it either propagates the error codes from lower level
functions next_entry() or cond_read_av_list() or it returns -ENOMEM or
-EINVAL.
next_entry() returns -EINVAL.
cond_read_av_list() returns -EINVAL or -ENOMEM.
Signed-off-by: Dan Carpenter <error27@gmail.com>
Acked-by: Stephen D. Smalley <sds@tycho.nsa.gov>
Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'security/selinux/ss/conditional.c')
-rw-r--r-- | security/selinux/ss/conditional.c | 20 |
1 files changed, 12 insertions, 8 deletions
diff --git a/security/selinux/ss/conditional.c b/security/selinux/ss/conditional.c index aac40c7ff28c..a2b3b298e604 100644 --- a/security/selinux/ss/conditional.c +++ b/security/selinux/ss/conditional.c | |||
@@ -392,24 +392,25 @@ static int cond_read_node(struct policydb *p, struct cond_node *node, void *fp) | |||
392 | struct cond_expr *expr = NULL, *last = NULL; | 392 | struct cond_expr *expr = NULL, *last = NULL; |
393 | 393 | ||
394 | rc = next_entry(buf, fp, sizeof(u32)); | 394 | rc = next_entry(buf, fp, sizeof(u32)); |
395 | if (rc < 0) | 395 | if (rc) |
396 | return -1; | 396 | return rc; |
397 | 397 | ||
398 | node->cur_state = le32_to_cpu(buf[0]); | 398 | node->cur_state = le32_to_cpu(buf[0]); |
399 | 399 | ||
400 | len = 0; | 400 | len = 0; |
401 | rc = next_entry(buf, fp, sizeof(u32)); | 401 | rc = next_entry(buf, fp, sizeof(u32)); |
402 | if (rc < 0) | 402 | if (rc) |
403 | return -1; | 403 | return rc; |
404 | 404 | ||
405 | /* expr */ | 405 | /* expr */ |
406 | len = le32_to_cpu(buf[0]); | 406 | len = le32_to_cpu(buf[0]); |
407 | 407 | ||
408 | for (i = 0; i < len; i++) { | 408 | for (i = 0; i < len; i++) { |
409 | rc = next_entry(buf, fp, sizeof(u32) * 2); | 409 | rc = next_entry(buf, fp, sizeof(u32) * 2); |
410 | if (rc < 0) | 410 | if (rc) |
411 | goto err; | 411 | goto err; |
412 | 412 | ||
413 | rc = -ENOMEM; | ||
413 | expr = kzalloc(sizeof(struct cond_expr), GFP_KERNEL); | 414 | expr = kzalloc(sizeof(struct cond_expr), GFP_KERNEL); |
414 | if (!expr) | 415 | if (!expr) |
415 | goto err; | 416 | goto err; |
@@ -418,6 +419,7 @@ static int cond_read_node(struct policydb *p, struct cond_node *node, void *fp) | |||
418 | expr->bool = le32_to_cpu(buf[1]); | 419 | expr->bool = le32_to_cpu(buf[1]); |
419 | 420 | ||
420 | if (!expr_isvalid(p, expr)) { | 421 | if (!expr_isvalid(p, expr)) { |
422 | rc = -EINVAL; | ||
421 | kfree(expr); | 423 | kfree(expr); |
422 | goto err; | 424 | goto err; |
423 | } | 425 | } |
@@ -429,14 +431,16 @@ static int cond_read_node(struct policydb *p, struct cond_node *node, void *fp) | |||
429 | last = expr; | 431 | last = expr; |
430 | } | 432 | } |
431 | 433 | ||
432 | if (cond_read_av_list(p, fp, &node->true_list, NULL) != 0) | 434 | rc = cond_read_av_list(p, fp, &node->true_list, NULL); |
435 | if (rc) | ||
433 | goto err; | 436 | goto err; |
434 | if (cond_read_av_list(p, fp, &node->false_list, node->true_list) != 0) | 437 | rc = cond_read_av_list(p, fp, &node->false_list, node->true_list); |
438 | if (rc) | ||
435 | goto err; | 439 | goto err; |
436 | return 0; | 440 | return 0; |
437 | err: | 441 | err: |
438 | cond_node_destroy(node); | 442 | cond_node_destroy(node); |
439 | return -1; | 443 | return rc; |
440 | } | 444 | } |
441 | 445 | ||
442 | int cond_read_list(struct policydb *p, void *fp) | 446 | int cond_read_list(struct policydb *p, void *fp) |