aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/ss/conditional.c
diff options
context:
space:
mode:
authorEric Paris <eparis@redhat.com>2010-10-13 17:50:25 -0400
committerJames Morris <jmorris@namei.org>2010-10-20 19:12:58 -0400
commitcee74f47a6baba0ac457e87687fdcf0abd599f0a (patch)
tree3d9fdb073050664e62d9cdb6c28112090cd138da /security/selinux/ss/conditional.c
parent00d85c83ac52e2c1a66397f1abc589f80c543425 (diff)
SELinux: allow userspace to read policy back out of the kernel
There is interest in being able to see what the actual policy is that was loaded into the kernel. The patch creates a new selinuxfs file /selinux/policy which can be read by userspace. The actual policy that is loaded into the kernel will be written back out to userspace. Signed-off-by: Eric Paris <eparis@redhat.com> Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'security/selinux/ss/conditional.c')
-rw-r--r--security/selinux/ss/conditional.c123
1 files changed, 123 insertions, 0 deletions
diff --git a/security/selinux/ss/conditional.c b/security/selinux/ss/conditional.c
index c91e150c3087..655fe1c6cc69 100644
--- a/security/selinux/ss/conditional.c
+++ b/security/selinux/ss/conditional.c
@@ -490,6 +490,129 @@ err:
490 return rc; 490 return rc;
491} 491}
492 492
493int cond_write_bool(void *vkey, void *datum, void *ptr)
494{
495 char *key = vkey;
496 struct cond_bool_datum *booldatum = datum;
497 struct policy_data *pd = ptr;
498 void *fp = pd->fp;
499 __le32 buf[3];
500 u32 len;
501 int rc;
502
503 len = strlen(key);
504 buf[0] = cpu_to_le32(booldatum->value);
505 buf[1] = cpu_to_le32(booldatum->state);
506 buf[2] = cpu_to_le32(len);
507 rc = put_entry(buf, sizeof(u32), 3, fp);
508 if (rc)
509 return rc;
510 rc = put_entry(key, 1, len, fp);
511 if (rc)
512 return rc;
513 return 0;
514}
515
516/*
517 * cond_write_cond_av_list doesn't write out the av_list nodes.
518 * Instead it writes out the key/value pairs from the avtab. This
519 * is necessary because there is no way to uniquely identifying rules
520 * in the avtab so it is not possible to associate individual rules
521 * in the avtab with a conditional without saving them as part of
522 * the conditional. This means that the avtab with the conditional
523 * rules will not be saved but will be rebuilt on policy load.
524 */
525static int cond_write_av_list(struct policydb *p,
526 struct cond_av_list *list, struct policy_file *fp)
527{
528 __le32 buf[1];
529 struct cond_av_list *cur_list;
530 u32 len;
531 int rc;
532
533 len = 0;
534 for (cur_list = list; cur_list != NULL; cur_list = cur_list->next)
535 len++;
536
537 buf[0] = cpu_to_le32(len);
538 rc = put_entry(buf, sizeof(u32), 1, fp);
539 if (rc)
540 return rc;
541
542 if (len == 0)
543 return 0;
544
545 for (cur_list = list; cur_list != NULL; cur_list = cur_list->next) {
546 rc = avtab_write_item(p, cur_list->node, fp);
547 if (rc)
548 return rc;
549 }
550
551 return 0;
552}
553
554int cond_write_node(struct policydb *p, struct cond_node *node,
555 struct policy_file *fp)
556{
557 struct cond_expr *cur_expr;
558 __le32 buf[2];
559 int rc;
560 u32 len = 0;
561
562 buf[0] = cpu_to_le32(node->cur_state);
563 rc = put_entry(buf, sizeof(u32), 1, fp);
564 if (rc)
565 return rc;
566
567 for (cur_expr = node->expr; cur_expr != NULL; cur_expr = cur_expr->next)
568 len++;
569
570 buf[0] = cpu_to_le32(len);
571 rc = put_entry(buf, sizeof(u32), 1, fp);
572 if (rc)
573 return rc;
574
575 for (cur_expr = node->expr; cur_expr != NULL; cur_expr = cur_expr->next) {
576 buf[0] = cpu_to_le32(cur_expr->expr_type);
577 buf[1] = cpu_to_le32(cur_expr->bool);
578 rc = put_entry(buf, sizeof(u32), 2, fp);
579 if (rc)
580 return rc;
581 }
582
583 rc = cond_write_av_list(p, node->true_list, fp);
584 if (rc)
585 return rc;
586 rc = cond_write_av_list(p, node->false_list, fp);
587 if (rc)
588 return rc;
589
590 return 0;
591}
592
593int cond_write_list(struct policydb *p, struct cond_node *list, void *fp)
594{
595 struct cond_node *cur;
596 u32 len;
597 __le32 buf[1];
598 int rc;
599
600 len = 0;
601 for (cur = list; cur != NULL; cur = cur->next)
602 len++;
603 buf[0] = cpu_to_le32(len);
604 rc = put_entry(buf, sizeof(u32), 1, fp);
605 if (rc)
606 return rc;
607
608 for (cur = list; cur != NULL; cur = cur->next) {
609 rc = cond_write_node(p, cur, fp);
610 if (rc)
611 return rc;
612 }
613
614 return 0;
615}
493/* Determine whether additional permissions are granted by the conditional 616/* Determine whether additional permissions are granted by the conditional
494 * av table, and if so, add them to the result 617 * av table, and if so, add them to the result
495 */ 618 */