diff options
author | Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> | 2009-12-02 07:09:48 -0500 |
---|---|---|
committer | James Morris <jmorris@namei.org> | 2009-12-07 22:58:05 -0500 |
commit | 937bf6133b21b16965f75223085f4314ae32b8eb (patch) | |
tree | 4a042bc9298ffddfaf4017a5796cae46e9594d2c /security/tomoyo/file.c | |
parent | 5d0901a3a0c39c97ca504f73d24030f63cfc9fa2 (diff) |
TOMOYO: Add rest of file operation restrictions.
LSM hooks for chmod()/chown()/chroot() are now ready.
This patch utilizes these hooks.
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'security/tomoyo/file.c')
-rw-r--r-- | security/tomoyo/file.c | 47 |
1 files changed, 35 insertions, 12 deletions
diff --git a/security/tomoyo/file.c b/security/tomoyo/file.c index 5ae3a571559f..2d10f98fc551 100644 --- a/security/tomoyo/file.c +++ b/security/tomoyo/file.c | |||
@@ -81,12 +81,20 @@ static const char *tomoyo_sp_keyword[TOMOYO_MAX_SINGLE_PATH_OPERATION] = { | |||
81 | [TOMOYO_TYPE_TRUNCATE_ACL] = "truncate", | 81 | [TOMOYO_TYPE_TRUNCATE_ACL] = "truncate", |
82 | [TOMOYO_TYPE_SYMLINK_ACL] = "symlink", | 82 | [TOMOYO_TYPE_SYMLINK_ACL] = "symlink", |
83 | [TOMOYO_TYPE_REWRITE_ACL] = "rewrite", | 83 | [TOMOYO_TYPE_REWRITE_ACL] = "rewrite", |
84 | [TOMOYO_TYPE_IOCTL_ACL] = "ioctl", | ||
85 | [TOMOYO_TYPE_CHMOD_ACL] = "chmod", | ||
86 | [TOMOYO_TYPE_CHOWN_ACL] = "chown", | ||
87 | [TOMOYO_TYPE_CHGRP_ACL] = "chgrp", | ||
88 | [TOMOYO_TYPE_CHROOT_ACL] = "chroot", | ||
89 | [TOMOYO_TYPE_MOUNT_ACL] = "mount", | ||
90 | [TOMOYO_TYPE_UMOUNT_ACL] = "unmount", | ||
84 | }; | 91 | }; |
85 | 92 | ||
86 | /* Keyword array for double path operations. */ | 93 | /* Keyword array for double path operations. */ |
87 | static const char *tomoyo_dp_keyword[TOMOYO_MAX_DOUBLE_PATH_OPERATION] = { | 94 | static const char *tomoyo_dp_keyword[TOMOYO_MAX_DOUBLE_PATH_OPERATION] = { |
88 | [TOMOYO_TYPE_LINK_ACL] = "link", | 95 | [TOMOYO_TYPE_LINK_ACL] = "link", |
89 | [TOMOYO_TYPE_RENAME_ACL] = "rename", | 96 | [TOMOYO_TYPE_RENAME_ACL] = "rename", |
97 | [TOMOYO_TYPE_PIVOT_ROOT_ACL] = "pivot_root", | ||
90 | }; | 98 | }; |
91 | 99 | ||
92 | /** | 100 | /** |
@@ -655,7 +663,7 @@ static int tomoyo_check_single_path_acl2(const struct tomoyo_domain_info * | |||
655 | domain, | 663 | domain, |
656 | const struct tomoyo_path_info * | 664 | const struct tomoyo_path_info * |
657 | filename, | 665 | filename, |
658 | const u16 perm, | 666 | const u32 perm, |
659 | const bool may_use_pattern) | 667 | const bool may_use_pattern) |
660 | { | 668 | { |
661 | struct tomoyo_acl_info *ptr; | 669 | struct tomoyo_acl_info *ptr; |
@@ -668,8 +676,13 @@ static int tomoyo_check_single_path_acl2(const struct tomoyo_domain_info * | |||
668 | continue; | 676 | continue; |
669 | acl = container_of(ptr, struct tomoyo_single_path_acl_record, | 677 | acl = container_of(ptr, struct tomoyo_single_path_acl_record, |
670 | head); | 678 | head); |
671 | if (!(acl->perm & perm)) | 679 | if (perm <= 0xFFFF) { |
672 | continue; | 680 | if (!(acl->perm & perm)) |
681 | continue; | ||
682 | } else { | ||
683 | if (!(acl->perm_high & (perm >> 16))) | ||
684 | continue; | ||
685 | } | ||
673 | if (may_use_pattern || !acl->filename->is_patterned) { | 686 | if (may_use_pattern || !acl->filename->is_patterned) { |
674 | if (!tomoyo_path_matches_pattern(filename, | 687 | if (!tomoyo_path_matches_pattern(filename, |
675 | acl->filename)) | 688 | acl->filename)) |
@@ -697,7 +710,7 @@ static int tomoyo_check_file_acl(const struct tomoyo_domain_info *domain, | |||
697 | const struct tomoyo_path_info *filename, | 710 | const struct tomoyo_path_info *filename, |
698 | const u8 operation) | 711 | const u8 operation) |
699 | { | 712 | { |
700 | u16 perm = 0; | 713 | u32 perm = 0; |
701 | 714 | ||
702 | if (!tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE)) | 715 | if (!tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE)) |
703 | return 0; | 716 | return 0; |
@@ -830,13 +843,13 @@ static int tomoyo_update_single_path_acl(const u8 type, const char *filename, | |||
830 | struct tomoyo_domain_info * | 843 | struct tomoyo_domain_info * |
831 | const domain, const bool is_delete) | 844 | const domain, const bool is_delete) |
832 | { | 845 | { |
833 | static const u16 rw_mask = | 846 | static const u32 rw_mask = |
834 | (1 << TOMOYO_TYPE_READ_ACL) | (1 << TOMOYO_TYPE_WRITE_ACL); | 847 | (1 << TOMOYO_TYPE_READ_ACL) | (1 << TOMOYO_TYPE_WRITE_ACL); |
835 | const struct tomoyo_path_info *saved_filename; | 848 | const struct tomoyo_path_info *saved_filename; |
836 | struct tomoyo_acl_info *ptr; | 849 | struct tomoyo_acl_info *ptr; |
837 | struct tomoyo_single_path_acl_record *acl; | 850 | struct tomoyo_single_path_acl_record *acl; |
838 | int error = -ENOMEM; | 851 | int error = -ENOMEM; |
839 | const u16 perm = 1 << type; | 852 | const u32 perm = 1 << type; |
840 | 853 | ||
841 | if (!domain) | 854 | if (!domain) |
842 | return -EINVAL; | 855 | return -EINVAL; |
@@ -858,7 +871,10 @@ static int tomoyo_update_single_path_acl(const u8 type, const char *filename, | |||
858 | /* Special case. Clear all bits if marked as deleted. */ | 871 | /* Special case. Clear all bits if marked as deleted. */ |
859 | if (ptr->type & TOMOYO_ACL_DELETED) | 872 | if (ptr->type & TOMOYO_ACL_DELETED) |
860 | acl->perm = 0; | 873 | acl->perm = 0; |
861 | acl->perm |= perm; | 874 | if (perm <= 0xFFFF) |
875 | acl->perm |= perm; | ||
876 | else | ||
877 | acl->perm_high |= (perm >> 16); | ||
862 | if ((acl->perm & rw_mask) == rw_mask) | 878 | if ((acl->perm & rw_mask) == rw_mask) |
863 | acl->perm |= 1 << TOMOYO_TYPE_READ_WRITE_ACL; | 879 | acl->perm |= 1 << TOMOYO_TYPE_READ_WRITE_ACL; |
864 | else if (acl->perm & (1 << TOMOYO_TYPE_READ_WRITE_ACL)) | 880 | else if (acl->perm & (1 << TOMOYO_TYPE_READ_WRITE_ACL)) |
@@ -871,7 +887,10 @@ static int tomoyo_update_single_path_acl(const u8 type, const char *filename, | |||
871 | acl = tomoyo_alloc_acl_element(TOMOYO_TYPE_SINGLE_PATH_ACL); | 887 | acl = tomoyo_alloc_acl_element(TOMOYO_TYPE_SINGLE_PATH_ACL); |
872 | if (!acl) | 888 | if (!acl) |
873 | goto out; | 889 | goto out; |
874 | acl->perm = perm; | 890 | if (perm <= 0xFFFF) |
891 | acl->perm = perm; | ||
892 | else | ||
893 | acl->perm_high = (perm >> 16); | ||
875 | if (perm == (1 << TOMOYO_TYPE_READ_WRITE_ACL)) | 894 | if (perm == (1 << TOMOYO_TYPE_READ_WRITE_ACL)) |
876 | acl->perm |= rw_mask; | 895 | acl->perm |= rw_mask; |
877 | acl->filename = saved_filename; | 896 | acl->filename = saved_filename; |
@@ -887,12 +906,15 @@ static int tomoyo_update_single_path_acl(const u8 type, const char *filename, | |||
887 | head); | 906 | head); |
888 | if (acl->filename != saved_filename) | 907 | if (acl->filename != saved_filename) |
889 | continue; | 908 | continue; |
890 | acl->perm &= ~perm; | 909 | if (perm <= 0xFFFF) |
910 | acl->perm &= ~perm; | ||
911 | else | ||
912 | acl->perm_high &= ~(perm >> 16); | ||
891 | if ((acl->perm & rw_mask) != rw_mask) | 913 | if ((acl->perm & rw_mask) != rw_mask) |
892 | acl->perm &= ~(1 << TOMOYO_TYPE_READ_WRITE_ACL); | 914 | acl->perm &= ~(1 << TOMOYO_TYPE_READ_WRITE_ACL); |
893 | else if (!(acl->perm & (1 << TOMOYO_TYPE_READ_WRITE_ACL))) | 915 | else if (!(acl->perm & (1 << TOMOYO_TYPE_READ_WRITE_ACL))) |
894 | acl->perm &= ~rw_mask; | 916 | acl->perm &= ~rw_mask; |
895 | if (!acl->perm) | 917 | if (!acl->perm && !acl->perm_high) |
896 | ptr->type |= TOMOYO_ACL_DELETED; | 918 | ptr->type |= TOMOYO_ACL_DELETED; |
897 | error = 0; | 919 | error = 0; |
898 | break; | 920 | break; |
@@ -1193,7 +1215,7 @@ int tomoyo_check_open_permission(struct tomoyo_domain_info *domain, | |||
1193 | } | 1215 | } |
1194 | 1216 | ||
1195 | /** | 1217 | /** |
1196 | * tomoyo_check_1path_perm - Check permission for "create", "unlink", "mkdir", "rmdir", "mkfifo", "mksock", "mkblock", "mkchar", "truncate" and "symlink". | 1218 | * tomoyo_check_1path_perm - Check permission for "create", "unlink", "mkdir", "rmdir", "mkfifo", "mksock", "mkblock", "mkchar", "truncate", "symlink", "ioctl", "chmod", "chown", "chgrp", "chroot", "mount" and "unmount". |
1197 | * | 1219 | * |
1198 | * @domain: Pointer to "struct tomoyo_domain_info". | 1220 | * @domain: Pointer to "struct tomoyo_domain_info". |
1199 | * @operation: Type of operation. | 1221 | * @operation: Type of operation. |
@@ -1217,6 +1239,7 @@ int tomoyo_check_1path_perm(struct tomoyo_domain_info *domain, | |||
1217 | switch (operation) { | 1239 | switch (operation) { |
1218 | case TOMOYO_TYPE_MKDIR_ACL: | 1240 | case TOMOYO_TYPE_MKDIR_ACL: |
1219 | case TOMOYO_TYPE_RMDIR_ACL: | 1241 | case TOMOYO_TYPE_RMDIR_ACL: |
1242 | case TOMOYO_TYPE_CHROOT_ACL: | ||
1220 | if (!buf->is_dir) { | 1243 | if (!buf->is_dir) { |
1221 | /* | 1244 | /* |
1222 | * tomoyo_get_path() reserves space for appending "/." | 1245 | * tomoyo_get_path() reserves space for appending "/." |
@@ -1270,7 +1293,7 @@ int tomoyo_check_rewrite_permission(struct tomoyo_domain_info *domain, | |||
1270 | } | 1293 | } |
1271 | 1294 | ||
1272 | /** | 1295 | /** |
1273 | * tomoyo_check_2path_perm - Check permission for "rename" and "link". | 1296 | * tomoyo_check_2path_perm - Check permission for "rename", "link" and "pivot_root". |
1274 | * | 1297 | * |
1275 | * @domain: Pointer to "struct tomoyo_domain_info". | 1298 | * @domain: Pointer to "struct tomoyo_domain_info". |
1276 | * @operation: Type of operation. | 1299 | * @operation: Type of operation. |