diff options
Diffstat (limited to 'security/selinux/ss/mls.c')
-rw-r--r-- | security/selinux/ss/mls.c | 176 |
1 files changed, 156 insertions, 20 deletions
diff --git a/security/selinux/ss/mls.c b/security/selinux/ss/mls.c index 7bc5b6440f70..119bd6078ba1 100644 --- a/security/selinux/ss/mls.c +++ b/security/selinux/ss/mls.c | |||
@@ -10,6 +10,13 @@ | |||
10 | * | 10 | * |
11 | * Copyright (C) 2004-2006 Trusted Computer Solutions, Inc. | 11 | * Copyright (C) 2004-2006 Trusted Computer Solutions, Inc. |
12 | */ | 12 | */ |
13 | /* | ||
14 | * Updated: Hewlett-Packard <paul.moore@hp.com> | ||
15 | * | ||
16 | * Added support to import/export the MLS label | ||
17 | * | ||
18 | * (c) Copyright Hewlett-Packard Development Company, L.P., 2006 | ||
19 | */ | ||
13 | 20 | ||
14 | #include <linux/kernel.h> | 21 | #include <linux/kernel.h> |
15 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
@@ -212,26 +219,6 @@ int mls_context_isvalid(struct policydb *p, struct context *c) | |||
212 | } | 219 | } |
213 | 220 | ||
214 | /* | 221 | /* |
215 | * Copies the MLS range from `src' into `dst'. | ||
216 | */ | ||
217 | static inline int mls_copy_context(struct context *dst, | ||
218 | struct context *src) | ||
219 | { | ||
220 | int l, rc = 0; | ||
221 | |||
222 | /* Copy the MLS range from the source context */ | ||
223 | for (l = 0; l < 2; l++) { | ||
224 | dst->range.level[l].sens = src->range.level[l].sens; | ||
225 | rc = ebitmap_cpy(&dst->range.level[l].cat, | ||
226 | &src->range.level[l].cat); | ||
227 | if (rc) | ||
228 | break; | ||
229 | } | ||
230 | |||
231 | return rc; | ||
232 | } | ||
233 | |||
234 | /* | ||
235 | * Set the MLS fields in the security context structure | 222 | * Set the MLS fields in the security context structure |
236 | * `context' based on the string representation in | 223 | * `context' based on the string representation in |
237 | * the string `*scontext'. Update `*scontext' to | 224 | * the string `*scontext'. Update `*scontext' to |
@@ -585,3 +572,152 @@ int mls_compute_sid(struct context *scontext, | |||
585 | return -EINVAL; | 572 | return -EINVAL; |
586 | } | 573 | } |
587 | 574 | ||
575 | /** | ||
576 | * mls_export_lvl - Export the MLS sensitivity levels | ||
577 | * @context: the security context | ||
578 | * @low: the low sensitivity level | ||
579 | * @high: the high sensitivity level | ||
580 | * | ||
581 | * Description: | ||
582 | * Given the security context copy the low MLS sensitivity level into lvl_low | ||
583 | * and the high sensitivity level in lvl_high. The MLS levels are only | ||
584 | * exported if the pointers are not NULL, if they are NULL then that level is | ||
585 | * not exported. | ||
586 | * | ||
587 | */ | ||
588 | void mls_export_lvl(const struct context *context, u32 *low, u32 *high) | ||
589 | { | ||
590 | if (!selinux_mls_enabled) | ||
591 | return; | ||
592 | |||
593 | if (low != NULL) | ||
594 | *low = context->range.level[0].sens - 1; | ||
595 | if (high != NULL) | ||
596 | *high = context->range.level[1].sens - 1; | ||
597 | } | ||
598 | |||
599 | /** | ||
600 | * mls_import_lvl - Import the MLS sensitivity levels | ||
601 | * @context: the security context | ||
602 | * @low: the low sensitivity level | ||
603 | * @high: the high sensitivity level | ||
604 | * | ||
605 | * Description: | ||
606 | * Given the security context and the two sensitivty levels, set the MLS levels | ||
607 | * in the context according the two given as parameters. Returns zero on | ||
608 | * success, negative values on failure. | ||
609 | * | ||
610 | */ | ||
611 | void mls_import_lvl(struct context *context, u32 low, u32 high) | ||
612 | { | ||
613 | if (!selinux_mls_enabled) | ||
614 | return; | ||
615 | |||
616 | context->range.level[0].sens = low + 1; | ||
617 | context->range.level[1].sens = high + 1; | ||
618 | } | ||
619 | |||
620 | /** | ||
621 | * mls_export_cat - Export the MLS categories | ||
622 | * @context: the security context | ||
623 | * @low: the low category | ||
624 | * @low_len: length of the cat_low bitmap in bytes | ||
625 | * @high: the high category | ||
626 | * @high_len: length of the cat_high bitmap in bytes | ||
627 | * | ||
628 | * Description: | ||
629 | * Given the security context export the low MLS category bitmap into cat_low | ||
630 | * and the high category bitmap into cat_high. The MLS categories are only | ||
631 | * exported if the pointers are not NULL, if they are NULL then that level is | ||
632 | * not exported. The caller is responsibile for freeing the memory when | ||
633 | * finished. Returns zero on success, negative values on failure. | ||
634 | * | ||
635 | */ | ||
636 | int mls_export_cat(const struct context *context, | ||
637 | unsigned char **low, | ||
638 | size_t *low_len, | ||
639 | unsigned char **high, | ||
640 | size_t *high_len) | ||
641 | { | ||
642 | int rc = -EPERM; | ||
643 | |||
644 | if (!selinux_mls_enabled) | ||
645 | return 0; | ||
646 | |||
647 | if (low != NULL) { | ||
648 | rc = ebitmap_export(&context->range.level[0].cat, | ||
649 | low, | ||
650 | low_len); | ||
651 | if (rc != 0) | ||
652 | goto export_cat_failure; | ||
653 | } | ||
654 | if (high != NULL) { | ||
655 | rc = ebitmap_export(&context->range.level[1].cat, | ||
656 | high, | ||
657 | high_len); | ||
658 | if (rc != 0) | ||
659 | goto export_cat_failure; | ||
660 | } | ||
661 | |||
662 | return 0; | ||
663 | |||
664 | export_cat_failure: | ||
665 | if (low != NULL) | ||
666 | kfree(*low); | ||
667 | if (high != NULL) | ||
668 | kfree(*high); | ||
669 | return rc; | ||
670 | } | ||
671 | |||
672 | /** | ||
673 | * mls_import_cat - Import the MLS categories | ||
674 | * @context: the security context | ||
675 | * @low: the low category | ||
676 | * @low_len: length of the cat_low bitmap in bytes | ||
677 | * @high: the high category | ||
678 | * @high_len: length of the cat_high bitmap in bytes | ||
679 | * | ||
680 | * Description: | ||
681 | * Given the security context and the two category bitmap strings import the | ||
682 | * categories into the security context. The MLS categories are only imported | ||
683 | * if the pointers are not NULL, if they are NULL they are skipped. Returns | ||
684 | * zero on success, negative values on failure. | ||
685 | * | ||
686 | */ | ||
687 | int mls_import_cat(struct context *context, | ||
688 | const unsigned char *low, | ||
689 | size_t low_len, | ||
690 | const unsigned char *high, | ||
691 | size_t high_len) | ||
692 | { | ||
693 | int rc = -EPERM; | ||
694 | |||
695 | if (!selinux_mls_enabled) | ||
696 | return 0; | ||
697 | |||
698 | if (low != NULL) { | ||
699 | rc = ebitmap_import(low, | ||
700 | low_len, | ||
701 | &context->range.level[0].cat); | ||
702 | if (rc != 0) | ||
703 | goto import_cat_failure; | ||
704 | } | ||
705 | if (high != NULL) { | ||
706 | if (high == low) | ||
707 | rc = ebitmap_cpy(&context->range.level[1].cat, | ||
708 | &context->range.level[0].cat); | ||
709 | else | ||
710 | rc = ebitmap_import(high, | ||
711 | high_len, | ||
712 | &context->range.level[1].cat); | ||
713 | if (rc != 0) | ||
714 | goto import_cat_failure; | ||
715 | } | ||
716 | |||
717 | return 0; | ||
718 | |||
719 | import_cat_failure: | ||
720 | ebitmap_destroy(&context->range.level[0].cat); | ||
721 | ebitmap_destroy(&context->range.level[1].cat); | ||
722 | return rc; | ||
723 | } | ||