diff options
Diffstat (limited to 'security/smack')
| -rw-r--r-- | security/smack/smack.h | 8 | ||||
| -rw-r--r-- | security/smack/smack_lsm.c | 34 |
2 files changed, 38 insertions, 4 deletions
diff --git a/security/smack/smack.h b/security/smack/smack.h index 6c91156ae225..26e58f1804b1 100644 --- a/security/smack/smack.h +++ b/security/smack/smack.h | |||
| @@ -90,9 +90,15 @@ struct superblock_smack { | |||
| 90 | struct smack_known *smk_floor; | 90 | struct smack_known *smk_floor; |
| 91 | struct smack_known *smk_hat; | 91 | struct smack_known *smk_hat; |
| 92 | struct smack_known *smk_default; | 92 | struct smack_known *smk_default; |
| 93 | int smk_initialized; | 93 | int smk_flags; |
| 94 | }; | 94 | }; |
| 95 | 95 | ||
| 96 | /* | ||
| 97 | * Superblock flags | ||
| 98 | */ | ||
| 99 | #define SMK_SB_INITIALIZED 0x01 | ||
| 100 | #define SMK_SB_UNTRUSTED 0x02 | ||
| 101 | |||
| 96 | struct socket_smack { | 102 | struct socket_smack { |
| 97 | struct smack_known *smk_out; /* outbound label */ | 103 | struct smack_known *smk_out; /* outbound label */ |
| 98 | struct smack_known *smk_in; /* inbound label */ | 104 | struct smack_known *smk_in; /* inbound label */ |
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(); |
