diff options
Diffstat (limited to 'security/tomoyo')
-rw-r--r-- | security/tomoyo/common.c | 260 |
1 files changed, 82 insertions, 178 deletions
diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c index 6c68981c0f5f..a3c3b5de3b75 100644 --- a/security/tomoyo/common.c +++ b/security/tomoyo/common.c | |||
@@ -746,221 +746,125 @@ static int tomoyo_write_domain_policy(struct tomoyo_io_buffer *head) | |||
746 | } | 746 | } |
747 | 747 | ||
748 | /** | 748 | /** |
749 | * tomoyo_print_path_acl - Print a single path ACL entry. | 749 | * tomoyo_fns - Find next set bit. |
750 | * | 750 | * |
751 | * @head: Pointer to "struct tomoyo_io_buffer". | 751 | * @perm: 8 bits value. |
752 | * @ptr: Pointer to "struct tomoyo_path_acl". | 752 | * @bit: First bit to find. |
753 | * | 753 | * |
754 | * Returns true on success, false otherwise. | 754 | * Returns next on-bit on success, 8 otherwise. |
755 | */ | 755 | */ |
756 | static bool tomoyo_print_path_acl(struct tomoyo_io_buffer *head, | 756 | static u8 tomoyo_fns(const u8 perm, u8 bit) |
757 | struct tomoyo_path_acl *ptr) | ||
758 | { | 757 | { |
759 | int pos; | 758 | for ( ; bit < 8; bit++) |
760 | u8 bit; | 759 | if (perm & (1 << bit)) |
761 | const u16 perm = ptr->perm; | 760 | break; |
762 | 761 | return bit; | |
763 | for (bit = head->read_bit; bit < TOMOYO_MAX_PATH_OPERATION; bit++) { | ||
764 | if (!(perm & (1 << bit))) | ||
765 | continue; | ||
766 | if (head->print_execute_only && bit != TOMOYO_TYPE_EXECUTE) | ||
767 | continue; | ||
768 | /* Print "read/write" instead of "read" and "write". */ | ||
769 | if ((bit == TOMOYO_TYPE_READ || bit == TOMOYO_TYPE_WRITE) | ||
770 | && (perm & (1 << TOMOYO_TYPE_READ_WRITE))) | ||
771 | continue; | ||
772 | pos = head->read_avail; | ||
773 | if (!tomoyo_io_printf(head, "allow_%s ", | ||
774 | tomoyo_path_keyword[bit]) || | ||
775 | !tomoyo_print_name_union(head, &ptr->name) || | ||
776 | !tomoyo_io_printf(head, "\n")) | ||
777 | goto out; | ||
778 | } | ||
779 | head->read_bit = 0; | ||
780 | return true; | ||
781 | out: | ||
782 | head->read_bit = bit; | ||
783 | head->read_avail = pos; | ||
784 | return false; | ||
785 | } | 762 | } |
786 | 763 | ||
787 | /** | 764 | /** |
788 | * tomoyo_print_path2_acl - Print a double path ACL entry. | 765 | * tomoyo_print_entry - Print an ACL entry. |
789 | * | 766 | * |
790 | * @head: Pointer to "struct tomoyo_io_buffer". | 767 | * @head: Pointer to "struct tomoyo_io_buffer". |
791 | * @ptr: Pointer to "struct tomoyo_path2_acl". | 768 | * @acl: Pointer to an ACL entry. |
792 | * | 769 | * |
793 | * Returns true on success, false otherwise. | 770 | * Returns true on success, false otherwise. |
794 | */ | 771 | */ |
795 | static bool tomoyo_print_path2_acl(struct tomoyo_io_buffer *head, | 772 | static bool tomoyo_print_entry(struct tomoyo_io_buffer *head, |
796 | struct tomoyo_path2_acl *ptr) | 773 | struct tomoyo_acl_info *acl) |
797 | { | 774 | { |
798 | int pos; | 775 | const u8 acl_type = acl->type; |
799 | const u8 perm = ptr->perm; | 776 | u8 bit = head->read_bit; |
800 | u8 bit; | 777 | int pos = head->read_avail; |
801 | 778 | ||
802 | for (bit = head->read_bit; bit < TOMOYO_MAX_PATH2_OPERATION; bit++) { | 779 | if (acl->is_deleted) |
803 | if (!(perm & (1 << bit))) | 780 | return true; |
804 | continue; | 781 | next: |
805 | pos = head->read_avail; | 782 | if (acl_type == TOMOYO_TYPE_PATH_ACL) { |
783 | struct tomoyo_path_acl *ptr = | ||
784 | container_of(acl, typeof(*ptr), head); | ||
785 | const u16 perm = ptr->perm; | ||
786 | for ( ; bit < TOMOYO_MAX_PATH_OPERATION; bit++) { | ||
787 | if (!(perm & (1 << bit))) | ||
788 | continue; | ||
789 | if (head->print_execute_only && | ||
790 | bit != TOMOYO_TYPE_EXECUTE) | ||
791 | continue; | ||
792 | /* Print "read/write" instead of "read" and "write". */ | ||
793 | if ((bit == TOMOYO_TYPE_READ || | ||
794 | bit == TOMOYO_TYPE_WRITE) | ||
795 | && (perm & (1 << TOMOYO_TYPE_READ_WRITE))) | ||
796 | continue; | ||
797 | break; | ||
798 | } | ||
799 | if (bit >= TOMOYO_MAX_PATH_OPERATION) | ||
800 | goto done; | ||
801 | if (!tomoyo_io_printf(head, "allow_%s ", | ||
802 | tomoyo_path_keyword[bit]) || | ||
803 | !tomoyo_print_name_union(head, &ptr->name)) | ||
804 | goto out; | ||
805 | } else if (head->print_execute_only) { | ||
806 | return true; | ||
807 | } else if (acl_type == TOMOYO_TYPE_PATH2_ACL) { | ||
808 | struct tomoyo_path2_acl *ptr = | ||
809 | container_of(acl, typeof(*ptr), head); | ||
810 | bit = tomoyo_fns(ptr->perm, bit); | ||
811 | if (bit >= TOMOYO_MAX_PATH2_OPERATION) | ||
812 | goto done; | ||
806 | if (!tomoyo_io_printf(head, "allow_%s ", | 813 | if (!tomoyo_io_printf(head, "allow_%s ", |
807 | tomoyo_path2_keyword[bit]) || | 814 | tomoyo_path2_keyword[bit]) || |
808 | !tomoyo_print_name_union(head, &ptr->name1) || | 815 | !tomoyo_print_name_union(head, &ptr->name1) || |
809 | !tomoyo_print_name_union(head, &ptr->name2) || | 816 | !tomoyo_print_name_union(head, &ptr->name2)) |
810 | !tomoyo_io_printf(head, "\n")) | ||
811 | goto out; | 817 | goto out; |
812 | } | 818 | } else if (acl_type == TOMOYO_TYPE_PATH_NUMBER_ACL) { |
813 | head->read_bit = 0; | 819 | struct tomoyo_path_number_acl *ptr = |
814 | return true; | 820 | container_of(acl, typeof(*ptr), head); |
815 | out: | 821 | bit = tomoyo_fns(ptr->perm, bit); |
816 | head->read_bit = bit; | 822 | if (bit >= TOMOYO_MAX_PATH_NUMBER_OPERATION) |
817 | head->read_avail = pos; | 823 | goto done; |
818 | return false; | ||
819 | } | ||
820 | |||
821 | /** | ||
822 | * tomoyo_print_path_number_acl - Print a path_number ACL entry. | ||
823 | * | ||
824 | * @head: Pointer to "struct tomoyo_io_buffer". | ||
825 | * @ptr: Pointer to "struct tomoyo_path_number_acl". | ||
826 | * | ||
827 | * Returns true on success, false otherwise. | ||
828 | */ | ||
829 | static bool tomoyo_print_path_number_acl(struct tomoyo_io_buffer *head, | ||
830 | struct tomoyo_path_number_acl *ptr) | ||
831 | { | ||
832 | int pos; | ||
833 | u8 bit; | ||
834 | const u8 perm = ptr->perm; | ||
835 | for (bit = head->read_bit; bit < TOMOYO_MAX_PATH_NUMBER_OPERATION; | ||
836 | bit++) { | ||
837 | if (!(perm & (1 << bit))) | ||
838 | continue; | ||
839 | pos = head->read_avail; | ||
840 | if (!tomoyo_io_printf(head, "allow_%s", | 824 | if (!tomoyo_io_printf(head, "allow_%s", |
841 | tomoyo_path_number_keyword[bit]) || | 825 | tomoyo_path_number_keyword[bit]) || |
842 | !tomoyo_print_name_union(head, &ptr->name) || | 826 | !tomoyo_print_name_union(head, &ptr->name) || |
843 | !tomoyo_print_number_union(head, &ptr->number) || | 827 | !tomoyo_print_number_union(head, &ptr->number)) |
844 | !tomoyo_io_printf(head, "\n")) | ||
845 | goto out; | 828 | goto out; |
846 | } | 829 | } else if (acl_type == TOMOYO_TYPE_MKDEV_ACL) { |
847 | head->read_bit = 0; | 830 | struct tomoyo_mkdev_acl *ptr = |
848 | return true; | 831 | container_of(acl, typeof(*ptr), head); |
849 | out: | 832 | bit = tomoyo_fns(ptr->perm, bit); |
850 | head->read_bit = bit; | 833 | if (bit >= TOMOYO_MAX_MKDEV_OPERATION) |
851 | head->read_avail = pos; | 834 | goto done; |
852 | return false; | ||
853 | } | ||
854 | |||
855 | /** | ||
856 | * tomoyo_print_mkdev_acl - Print a mkdev ACL entry. | ||
857 | * | ||
858 | * @head: Pointer to "struct tomoyo_io_buffer". | ||
859 | * @ptr: Pointer to "struct tomoyo_mkdev_acl". | ||
860 | * | ||
861 | * Returns true on success, false otherwise. | ||
862 | */ | ||
863 | static bool tomoyo_print_mkdev_acl(struct tomoyo_io_buffer *head, | ||
864 | struct tomoyo_mkdev_acl *ptr) | ||
865 | { | ||
866 | int pos; | ||
867 | u8 bit; | ||
868 | const u16 perm = ptr->perm; | ||
869 | for (bit = head->read_bit; bit < TOMOYO_MAX_MKDEV_OPERATION; | ||
870 | bit++) { | ||
871 | if (!(perm & (1 << bit))) | ||
872 | continue; | ||
873 | pos = head->read_avail; | ||
874 | if (!tomoyo_io_printf(head, "allow_%s", | 835 | if (!tomoyo_io_printf(head, "allow_%s", |
875 | tomoyo_mkdev_keyword[bit]) || | 836 | tomoyo_mkdev_keyword[bit]) || |
876 | !tomoyo_print_name_union(head, &ptr->name) || | 837 | !tomoyo_print_name_union(head, &ptr->name) || |
877 | !tomoyo_print_number_union(head, &ptr->mode) || | 838 | !tomoyo_print_number_union(head, &ptr->mode) || |
878 | !tomoyo_print_number_union(head, &ptr->major) || | 839 | !tomoyo_print_number_union(head, &ptr->major) || |
879 | !tomoyo_print_number_union(head, &ptr->minor) || | 840 | !tomoyo_print_number_union(head, &ptr->minor)) |
880 | !tomoyo_io_printf(head, "\n")) | 841 | goto out; |
842 | } else if (acl_type == TOMOYO_TYPE_MOUNT_ACL) { | ||
843 | struct tomoyo_mount_acl *ptr = | ||
844 | container_of(acl, typeof(*ptr), head); | ||
845 | if (!tomoyo_io_printf(head, TOMOYO_KEYWORD_ALLOW_MOUNT) || | ||
846 | !tomoyo_print_name_union(head, &ptr->dev_name) || | ||
847 | !tomoyo_print_name_union(head, &ptr->dir_name) || | ||
848 | !tomoyo_print_name_union(head, &ptr->fs_type) || | ||
849 | !tomoyo_print_number_union(head, &ptr->flags)) | ||
881 | goto out; | 850 | goto out; |
882 | } | 851 | } |
852 | if (!tomoyo_io_printf(head, "\n")) | ||
853 | goto out; | ||
854 | head->read_bit = bit; | ||
855 | if (acl_type != TOMOYO_TYPE_MOUNT_ACL) { | ||
856 | bit++; | ||
857 | goto next; | ||
858 | } | ||
859 | done: | ||
883 | head->read_bit = 0; | 860 | head->read_bit = 0; |
884 | return true; | 861 | return true; |
885 | out: | 862 | out: |
886 | head->read_bit = bit; | ||
887 | head->read_avail = pos; | 863 | head->read_avail = pos; |
888 | return false; | 864 | return false; |
889 | } | 865 | } |
890 | 866 | ||
891 | /** | 867 | /** |
892 | * tomoyo_print_mount_acl - Print a mount ACL entry. | ||
893 | * | ||
894 | * @head: Pointer to "struct tomoyo_io_buffer". | ||
895 | * @ptr: Pointer to "struct tomoyo_mount_acl". | ||
896 | * | ||
897 | * Returns true on success, false otherwise. | ||
898 | */ | ||
899 | static bool tomoyo_print_mount_acl(struct tomoyo_io_buffer *head, | ||
900 | struct tomoyo_mount_acl *ptr) | ||
901 | { | ||
902 | const int pos = head->read_avail; | ||
903 | if (!tomoyo_io_printf(head, TOMOYO_KEYWORD_ALLOW_MOUNT) || | ||
904 | !tomoyo_print_name_union(head, &ptr->dev_name) || | ||
905 | !tomoyo_print_name_union(head, &ptr->dir_name) || | ||
906 | !tomoyo_print_name_union(head, &ptr->fs_type) || | ||
907 | !tomoyo_print_number_union(head, &ptr->flags) || | ||
908 | !tomoyo_io_printf(head, "\n")) { | ||
909 | head->read_avail = pos; | ||
910 | return false; | ||
911 | } | ||
912 | return true; | ||
913 | } | ||
914 | |||
915 | /** | ||
916 | * tomoyo_print_entry - Print an ACL entry. | ||
917 | * | ||
918 | * @head: Pointer to "struct tomoyo_io_buffer". | ||
919 | * @ptr: Pointer to an ACL entry. | ||
920 | * | ||
921 | * Returns true on success, false otherwise. | ||
922 | */ | ||
923 | static bool tomoyo_print_entry(struct tomoyo_io_buffer *head, | ||
924 | struct tomoyo_acl_info *ptr) | ||
925 | { | ||
926 | const u8 acl_type = ptr->type; | ||
927 | |||
928 | if (ptr->is_deleted) | ||
929 | return true; | ||
930 | if (acl_type == TOMOYO_TYPE_PATH_ACL) { | ||
931 | struct tomoyo_path_acl *acl | ||
932 | = container_of(ptr, struct tomoyo_path_acl, head); | ||
933 | return tomoyo_print_path_acl(head, acl); | ||
934 | } | ||
935 | if (head->print_execute_only) | ||
936 | return true; | ||
937 | if (acl_type == TOMOYO_TYPE_PATH2_ACL) { | ||
938 | struct tomoyo_path2_acl *acl | ||
939 | = container_of(ptr, struct tomoyo_path2_acl, head); | ||
940 | return tomoyo_print_path2_acl(head, acl); | ||
941 | } | ||
942 | if (acl_type == TOMOYO_TYPE_PATH_NUMBER_ACL) { | ||
943 | struct tomoyo_path_number_acl *acl | ||
944 | = container_of(ptr, struct tomoyo_path_number_acl, | ||
945 | head); | ||
946 | return tomoyo_print_path_number_acl(head, acl); | ||
947 | } | ||
948 | if (acl_type == TOMOYO_TYPE_MKDEV_ACL) { | ||
949 | struct tomoyo_mkdev_acl *acl | ||
950 | = container_of(ptr, struct tomoyo_mkdev_acl, | ||
951 | head); | ||
952 | return tomoyo_print_mkdev_acl(head, acl); | ||
953 | } | ||
954 | if (acl_type == TOMOYO_TYPE_MOUNT_ACL) { | ||
955 | struct tomoyo_mount_acl *acl | ||
956 | = container_of(ptr, struct tomoyo_mount_acl, head); | ||
957 | return tomoyo_print_mount_acl(head, acl); | ||
958 | } | ||
959 | BUG(); /* This must not happen. */ | ||
960 | return false; | ||
961 | } | ||
962 | |||
963 | /** | ||
964 | * tomoyo_read_domain_policy - Read domain policy. | 868 | * tomoyo_read_domain_policy - Read domain policy. |
965 | * | 869 | * |
966 | * @head: Pointer to "struct tomoyo_io_buffer". | 870 | * @head: Pointer to "struct tomoyo_io_buffer". |