diff options
Diffstat (limited to 'security/smack/smack_lsm.c')
-rw-r--r-- | security/smack/smack_lsm.c | 34 |
1 files changed, 31 insertions, 3 deletions
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 6777295f4b2b..b75634dbf53b 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c | |||
@@ -549,7 +549,7 @@ static int smack_sb_alloc_security(struct super_block *sb) | |||
549 | sbsp->smk_floor = &smack_known_floor; | 549 | sbsp->smk_floor = &smack_known_floor; |
550 | sbsp->smk_hat = &smack_known_hat; | 550 | sbsp->smk_hat = &smack_known_hat; |
551 | /* | 551 | /* |
552 | * smk_initialized will be zero from kzalloc. | 552 | * SMK_SB_INITIALIZED will be zero from kzalloc. |
553 | */ | 553 | */ |
554 | sb->s_security = sbsp; | 554 | sb->s_security = sbsp; |
555 | 555 | ||
@@ -766,10 +766,10 @@ static int smack_set_mnt_opts(struct super_block *sb, | |||
766 | int num_opts = opts->num_mnt_opts; | 766 | int num_opts = opts->num_mnt_opts; |
767 | int transmute = 0; | 767 | int transmute = 0; |
768 | 768 | ||
769 | if (sp->smk_initialized) | 769 | if (sp->smk_flags & SMK_SB_INITIALIZED) |
770 | return 0; | 770 | return 0; |
771 | 771 | ||
772 | sp->smk_initialized = 1; | 772 | sp->smk_flags |= SMK_SB_INITIALIZED; |
773 | 773 | ||
774 | for (i = 0; i < num_opts; i++) { | 774 | for (i = 0; i < num_opts; i++) { |
775 | switch (opts->mnt_opts_flags[i]) { | 775 | switch (opts->mnt_opts_flags[i]) { |
@@ -821,6 +821,17 @@ static int smack_set_mnt_opts(struct super_block *sb, | |||
821 | skp = smk_of_current(); | 821 | skp = smk_of_current(); |
822 | sp->smk_root = skp; | 822 | sp->smk_root = skp; |
823 | sp->smk_default = skp; | 823 | sp->smk_default = skp; |
824 | /* | ||
825 | * For a handful of fs types with no user-controlled | ||
826 | * backing store it's okay to trust security labels | ||
827 | * in the filesystem. The rest are untrusted. | ||
828 | */ | ||
829 | if (sb->s_user_ns != &init_user_ns && | ||
830 | sb->s_magic != SYSFS_MAGIC && sb->s_magic != TMPFS_MAGIC && | ||
831 | sb->s_magic != RAMFS_MAGIC) { | ||
832 | transmute = 1; | ||
833 | sp->smk_flags |= SMK_SB_UNTRUSTED; | ||
834 | } | ||
824 | } | 835 | } |
825 | 836 | ||
826 | /* | 837 | /* |
@@ -908,6 +919,7 @@ static int smack_bprm_set_creds(struct linux_binprm *bprm) | |||
908 | struct inode *inode = file_inode(bprm->file); | 919 | struct inode *inode = file_inode(bprm->file); |
909 | struct task_smack *bsp = bprm->cred->security; | 920 | struct task_smack *bsp = bprm->cred->security; |
910 | struct inode_smack *isp; | 921 | struct inode_smack *isp; |
922 | struct superblock_smack *sbsp; | ||
911 | int rc; | 923 | int rc; |
912 | 924 | ||
913 | if (bprm->cred_prepared) | 925 | if (bprm->cred_prepared) |
@@ -917,6 +929,11 @@ static int smack_bprm_set_creds(struct linux_binprm *bprm) | |||
917 | if (isp->smk_task == NULL || isp->smk_task == bsp->smk_task) | 929 | if (isp->smk_task == NULL || isp->smk_task == bsp->smk_task) |
918 | return 0; | 930 | return 0; |
919 | 931 | ||
932 | sbsp = inode->i_sb->s_security; | ||
933 | if ((sbsp->smk_flags & SMK_SB_UNTRUSTED) && | ||
934 | isp->smk_task != sbsp->smk_root) | ||
935 | return 0; | ||
936 | |||
920 | if (bprm->unsafe & (LSM_UNSAFE_PTRACE | LSM_UNSAFE_PTRACE_CAP)) { | 937 | if (bprm->unsafe & (LSM_UNSAFE_PTRACE | LSM_UNSAFE_PTRACE_CAP)) { |
921 | struct task_struct *tracer; | 938 | struct task_struct *tracer; |
922 | rc = 0; | 939 | rc = 0; |
@@ -1203,6 +1220,7 @@ static int smack_inode_rename(struct inode *old_inode, | |||
1203 | */ | 1220 | */ |
1204 | static int smack_inode_permission(struct inode *inode, int mask) | 1221 | static int smack_inode_permission(struct inode *inode, int mask) |
1205 | { | 1222 | { |
1223 | struct superblock_smack *sbsp = inode->i_sb->s_security; | ||
1206 | struct smk_audit_info ad; | 1224 | struct smk_audit_info ad; |
1207 | int no_block = mask & MAY_NOT_BLOCK; | 1225 | int no_block = mask & MAY_NOT_BLOCK; |
1208 | int rc; | 1226 | int rc; |
@@ -1214,6 +1232,11 @@ static int smack_inode_permission(struct inode *inode, int mask) | |||
1214 | if (mask == 0) | 1232 | if (mask == 0) |
1215 | return 0; | 1233 | return 0; |
1216 | 1234 | ||
1235 | if (sbsp->smk_flags & SMK_SB_UNTRUSTED) { | ||
1236 | if (smk_of_inode(inode) != sbsp->smk_root) | ||
1237 | return -EACCES; | ||
1238 | } | ||
1239 | |||
1217 | /* May be droppable after audit */ | 1240 | /* May be droppable after audit */ |
1218 | if (no_block) | 1241 | if (no_block) |
1219 | return -ECHILD; | 1242 | return -ECHILD; |
@@ -1708,6 +1731,7 @@ static int smack_mmap_file(struct file *file, | |||
1708 | struct task_smack *tsp; | 1731 | struct task_smack *tsp; |
1709 | struct smack_known *okp; | 1732 | struct smack_known *okp; |
1710 | struct inode_smack *isp; | 1733 | struct inode_smack *isp; |
1734 | struct superblock_smack *sbsp; | ||
1711 | int may; | 1735 | int may; |
1712 | int mmay; | 1736 | int mmay; |
1713 | int tmay; | 1737 | int tmay; |
@@ -1719,6 +1743,10 @@ static int smack_mmap_file(struct file *file, | |||
1719 | isp = file_inode(file)->i_security; | 1743 | isp = file_inode(file)->i_security; |
1720 | if (isp->smk_mmap == NULL) | 1744 | if (isp->smk_mmap == NULL) |
1721 | return 0; | 1745 | return 0; |
1746 | sbsp = file_inode(file)->i_sb->s_security; | ||
1747 | if (sbsp->smk_flags & SMK_SB_UNTRUSTED && | ||
1748 | isp->smk_mmap != sbsp->smk_root) | ||
1749 | return -EACCES; | ||
1722 | mkp = isp->smk_mmap; | 1750 | mkp = isp->smk_mmap; |
1723 | 1751 | ||
1724 | tsp = current_security(); | 1752 | tsp = current_security(); |