diff options
| author | Casey Schaufler <casey@schaufler-ca.com> | 2010-12-02 09:43:39 -0500 |
|---|---|---|
| committer | Casey Schaufler <casey@schaufler-ca.com> | 2010-12-02 09:43:39 -0500 |
| commit | 676dac4b1bee0469d6932f698aeb77e8489f5861 (patch) | |
| tree | 196b4cb35cf8dfdff0698dc4368cfd00acc7391a /security | |
| parent | 93ae86e759299718c611bc543b9b1633bf32905a (diff) | |
This patch adds a new security attribute to Smack called
SMACK64EXEC. It defines label that is used while task is
running.
Exception: in smack_task_wait() child task is checked
for write access to parent task using label inherited
from the task that forked it.
Fixed issues from previous submit:
- SMACK64EXEC was not read when SMACK64 was not set.
- inode security blob was not updated after setting
SMACK64EXEC
- inode security blob was not updated when removing
SMACK64EXEC
Diffstat (limited to 'security')
| -rw-r--r-- | security/smack/smack.h | 30 | ||||
| -rw-r--r-- | security/smack/smack_access.c | 4 | ||||
| -rw-r--r-- | security/smack/smack_lsm.c | 192 | ||||
| -rw-r--r-- | security/smack/smackfs.c | 4 |
4 files changed, 176 insertions, 54 deletions
diff --git a/security/smack/smack.h b/security/smack/smack.h index 43ae747a5aa4..a2e2cdfab4ef 100644 --- a/security/smack/smack.h +++ b/security/smack/smack.h | |||
| @@ -51,10 +51,16 @@ struct socket_smack { | |||
| 51 | */ | 51 | */ |
| 52 | struct inode_smack { | 52 | struct inode_smack { |
| 53 | char *smk_inode; /* label of the fso */ | 53 | char *smk_inode; /* label of the fso */ |
| 54 | char *smk_task; /* label of the task */ | ||
| 54 | struct mutex smk_lock; /* initialization lock */ | 55 | struct mutex smk_lock; /* initialization lock */ |
| 55 | int smk_flags; /* smack inode flags */ | 56 | int smk_flags; /* smack inode flags */ |
| 56 | }; | 57 | }; |
| 57 | 58 | ||
| 59 | struct task_smack { | ||
| 60 | char *smk_task; /* label used for access control */ | ||
| 61 | char *smk_forked; /* label when forked */ | ||
| 62 | }; | ||
| 63 | |||
| 58 | #define SMK_INODE_INSTANT 0x01 /* inode is instantiated */ | 64 | #define SMK_INODE_INSTANT 0x01 /* inode is instantiated */ |
| 59 | 65 | ||
| 60 | /* | 66 | /* |
| @@ -243,6 +249,30 @@ static inline char *smk_of_inode(const struct inode *isp) | |||
| 243 | } | 249 | } |
| 244 | 250 | ||
| 245 | /* | 251 | /* |
| 252 | * Present a pointer to the smack label in an task blob. | ||
| 253 | */ | ||
| 254 | static inline char *smk_of_task(const struct task_smack *tsp) | ||
| 255 | { | ||
| 256 | return tsp->smk_task; | ||
| 257 | } | ||
| 258 | |||
| 259 | /* | ||
| 260 | * Present a pointer to the forked smack label in an task blob. | ||
| 261 | */ | ||
| 262 | static inline char *smk_of_forked(const struct task_smack *tsp) | ||
| 263 | { | ||
| 264 | return tsp->smk_forked; | ||
| 265 | } | ||
| 266 | |||
| 267 | /* | ||
| 268 | * Present a pointer to the smack label in the curren task blob. | ||
| 269 | */ | ||
| 270 | static inline char *smk_of_current(void) | ||
| 271 | { | ||
| 272 | return smk_of_task(current_security()); | ||
| 273 | } | ||
| 274 | |||
| 275 | /* | ||
| 246 | * logging functions | 276 | * logging functions |
| 247 | */ | 277 | */ |
| 248 | #define SMACK_AUDIT_DENIED 0x1 | 278 | #define SMACK_AUDIT_DENIED 0x1 |
diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c index f4fac64c4da8..42becbc1ce33 100644 --- a/security/smack/smack_access.c +++ b/security/smack/smack_access.c | |||
| @@ -185,7 +185,7 @@ out_audit: | |||
| 185 | int smk_curacc(char *obj_label, u32 mode, struct smk_audit_info *a) | 185 | int smk_curacc(char *obj_label, u32 mode, struct smk_audit_info *a) |
| 186 | { | 186 | { |
| 187 | int rc; | 187 | int rc; |
| 188 | char *sp = current_security(); | 188 | char *sp = smk_of_current(); |
| 189 | 189 | ||
| 190 | rc = smk_access(sp, obj_label, mode, NULL); | 190 | rc = smk_access(sp, obj_label, mode, NULL); |
| 191 | if (rc == 0) | 191 | if (rc == 0) |
| @@ -196,7 +196,7 @@ int smk_curacc(char *obj_label, u32 mode, struct smk_audit_info *a) | |||
| 196 | * only one that gets privilege and current does not | 196 | * only one that gets privilege and current does not |
| 197 | * have that label. | 197 | * have that label. |
| 198 | */ | 198 | */ |
| 199 | if (smack_onlycap != NULL && smack_onlycap != current->cred->security) | 199 | if (smack_onlycap != NULL && smack_onlycap != sp) |
| 200 | goto out_audit; | 200 | goto out_audit; |
| 201 | 201 | ||
| 202 | if (capable(CAP_MAC_OVERRIDE)) | 202 | if (capable(CAP_MAC_OVERRIDE)) |
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 04a98c361a65..7e19afe0e738 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c | |||
| @@ -43,7 +43,7 @@ | |||
| 43 | * Returns a pointer to the master list entry for the Smack label | 43 | * Returns a pointer to the master list entry for the Smack label |
| 44 | * or NULL if there was no label to fetch. | 44 | * or NULL if there was no label to fetch. |
| 45 | */ | 45 | */ |
| 46 | static char *smk_fetch(struct inode *ip, struct dentry *dp) | 46 | static char *smk_fetch(const char *name, struct inode *ip, struct dentry *dp) |
| 47 | { | 47 | { |
| 48 | int rc; | 48 | int rc; |
| 49 | char in[SMK_LABELLEN]; | 49 | char in[SMK_LABELLEN]; |
| @@ -51,7 +51,7 @@ static char *smk_fetch(struct inode *ip, struct dentry *dp) | |||
| 51 | if (ip->i_op->getxattr == NULL) | 51 | if (ip->i_op->getxattr == NULL) |
| 52 | return NULL; | 52 | return NULL; |
| 53 | 53 | ||
| 54 | rc = ip->i_op->getxattr(dp, XATTR_NAME_SMACK, in, SMK_LABELLEN); | 54 | rc = ip->i_op->getxattr(dp, name, in, SMK_LABELLEN); |
| 55 | if (rc < 0) | 55 | if (rc < 0) |
| 56 | return NULL; | 56 | return NULL; |
| 57 | 57 | ||
| @@ -103,8 +103,8 @@ static int smack_ptrace_access_check(struct task_struct *ctp, unsigned int mode) | |||
| 103 | if (rc != 0) | 103 | if (rc != 0) |
| 104 | return rc; | 104 | return rc; |
| 105 | 105 | ||
| 106 | sp = current_security(); | 106 | sp = smk_of_current(); |
| 107 | tsp = task_security(ctp); | 107 | tsp = smk_of_task(task_security(ctp)); |
| 108 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); | 108 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); |
| 109 | smk_ad_setfield_u_tsk(&ad, ctp); | 109 | smk_ad_setfield_u_tsk(&ad, ctp); |
| 110 | 110 | ||
| @@ -138,8 +138,8 @@ static int smack_ptrace_traceme(struct task_struct *ptp) | |||
| 138 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); | 138 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); |
| 139 | smk_ad_setfield_u_tsk(&ad, ptp); | 139 | smk_ad_setfield_u_tsk(&ad, ptp); |
| 140 | 140 | ||
| 141 | sp = current_security(); | 141 | sp = smk_of_current(); |
| 142 | tsp = task_security(ptp); | 142 | tsp = smk_of_task(task_security(ptp)); |
| 143 | /* we won't log here, because rc can be overriden */ | 143 | /* we won't log here, because rc can be overriden */ |
| 144 | rc = smk_access(tsp, sp, MAY_READWRITE, NULL); | 144 | rc = smk_access(tsp, sp, MAY_READWRITE, NULL); |
| 145 | if (rc != 0 && has_capability(ptp, CAP_MAC_OVERRIDE)) | 145 | if (rc != 0 && has_capability(ptp, CAP_MAC_OVERRIDE)) |
| @@ -160,7 +160,7 @@ static int smack_ptrace_traceme(struct task_struct *ptp) | |||
| 160 | static int smack_syslog(int typefrom_file) | 160 | static int smack_syslog(int typefrom_file) |
| 161 | { | 161 | { |
| 162 | int rc = 0; | 162 | int rc = 0; |
| 163 | char *sp = current_security(); | 163 | char *sp = smk_of_current(); |
| 164 | 164 | ||
| 165 | if (capable(CAP_MAC_OVERRIDE)) | 165 | if (capable(CAP_MAC_OVERRIDE)) |
| 166 | return 0; | 166 | return 0; |
| @@ -391,6 +391,40 @@ static int smack_sb_umount(struct vfsmount *mnt, int flags) | |||
| 391 | } | 391 | } |
| 392 | 392 | ||
| 393 | /* | 393 | /* |
| 394 | * BPRM hooks | ||
| 395 | */ | ||
| 396 | |||
| 397 | static int smack_bprm_set_creds(struct linux_binprm *bprm) | ||
| 398 | { | ||
| 399 | struct task_smack *tsp = bprm->cred->security; | ||
| 400 | struct inode_smack *isp; | ||
| 401 | struct dentry *dp; | ||
| 402 | int rc; | ||
| 403 | |||
| 404 | rc = cap_bprm_set_creds(bprm); | ||
| 405 | if (rc != 0) | ||
| 406 | return rc; | ||
| 407 | |||
| 408 | if (bprm->cred_prepared) | ||
| 409 | return 0; | ||
| 410 | |||
| 411 | if (bprm->file == NULL || bprm->file->f_dentry == NULL) | ||
| 412 | return 0; | ||
| 413 | |||
| 414 | dp = bprm->file->f_dentry; | ||
| 415 | |||
| 416 | if (dp->d_inode == NULL) | ||
| 417 | return 0; | ||
| 418 | |||
| 419 | isp = dp->d_inode->i_security; | ||
| 420 | |||
| 421 | if (isp->smk_task != NULL) | ||
| 422 | tsp->smk_task = isp->smk_task; | ||
| 423 | |||
| 424 | return 0; | ||
| 425 | } | ||
| 426 | |||
| 427 | /* | ||
| 394 | * Inode hooks | 428 | * Inode hooks |
| 395 | */ | 429 | */ |
| 396 | 430 | ||
| @@ -402,7 +436,7 @@ static int smack_sb_umount(struct vfsmount *mnt, int flags) | |||
| 402 | */ | 436 | */ |
| 403 | static int smack_inode_alloc_security(struct inode *inode) | 437 | static int smack_inode_alloc_security(struct inode *inode) |
| 404 | { | 438 | { |
| 405 | inode->i_security = new_inode_smack(current_security()); | 439 | inode->i_security = new_inode_smack(smk_of_current()); |
| 406 | if (inode->i_security == NULL) | 440 | if (inode->i_security == NULL) |
| 407 | return -ENOMEM; | 441 | return -ENOMEM; |
| 408 | return 0; | 442 | return 0; |
| @@ -664,7 +698,8 @@ static int smack_inode_setxattr(struct dentry *dentry, const char *name, | |||
| 664 | 698 | ||
| 665 | if (strcmp(name, XATTR_NAME_SMACK) == 0 || | 699 | if (strcmp(name, XATTR_NAME_SMACK) == 0 || |
| 666 | strcmp(name, XATTR_NAME_SMACKIPIN) == 0 || | 700 | strcmp(name, XATTR_NAME_SMACKIPIN) == 0 || |
| 667 | strcmp(name, XATTR_NAME_SMACKIPOUT) == 0) { | 701 | strcmp(name, XATTR_NAME_SMACKIPOUT) == 0 || |
| 702 | strcmp(name, XATTR_NAME_SMACKEXEC) == 0) { | ||
| 668 | if (!capable(CAP_MAC_ADMIN)) | 703 | if (!capable(CAP_MAC_ADMIN)) |
| 669 | rc = -EPERM; | 704 | rc = -EPERM; |
| 670 | /* | 705 | /* |
| @@ -704,9 +739,10 @@ static void smack_inode_post_setxattr(struct dentry *dentry, const char *name, | |||
| 704 | char *nsp; | 739 | char *nsp; |
| 705 | 740 | ||
| 706 | /* | 741 | /* |
| 707 | * Not SMACK | 742 | * Not SMACK or SMACKEXEC |
| 708 | */ | 743 | */ |
| 709 | if (strcmp(name, XATTR_NAME_SMACK)) | 744 | if (strcmp(name, XATTR_NAME_SMACK) && |
| 745 | strcmp(name, XATTR_NAME_SMACKEXEC)) | ||
| 710 | return; | 746 | return; |
| 711 | 747 | ||
| 712 | isp = dentry->d_inode->i_security; | 748 | isp = dentry->d_inode->i_security; |
| @@ -716,10 +752,18 @@ static void smack_inode_post_setxattr(struct dentry *dentry, const char *name, | |||
| 716 | * assignment. | 752 | * assignment. |
| 717 | */ | 753 | */ |
| 718 | nsp = smk_import(value, size); | 754 | nsp = smk_import(value, size); |
| 719 | if (nsp != NULL) | 755 | |
| 720 | isp->smk_inode = nsp; | 756 | if (strcmp(name, XATTR_NAME_SMACK) == 0) { |
| 721 | else | 757 | if (nsp != NULL) |
| 722 | isp->smk_inode = smack_known_invalid.smk_known; | 758 | isp->smk_inode = nsp; |
| 759 | else | ||
| 760 | isp->smk_inode = smack_known_invalid.smk_known; | ||
| 761 | } else { | ||
| 762 | if (nsp != NULL) | ||
| 763 | isp->smk_task = nsp; | ||
| 764 | else | ||
| 765 | isp->smk_task = smack_known_invalid.smk_known; | ||
| 766 | } | ||
| 723 | 767 | ||
| 724 | return; | 768 | return; |
| 725 | } | 769 | } |
| @@ -752,12 +796,14 @@ static int smack_inode_getxattr(struct dentry *dentry, const char *name) | |||
| 752 | */ | 796 | */ |
| 753 | static int smack_inode_removexattr(struct dentry *dentry, const char *name) | 797 | static int smack_inode_removexattr(struct dentry *dentry, const char *name) |
| 754 | { | 798 | { |
| 799 | struct inode_smack *isp; | ||
| 755 | struct smk_audit_info ad; | 800 | struct smk_audit_info ad; |
| 756 | int rc = 0; | 801 | int rc = 0; |
| 757 | 802 | ||
| 758 | if (strcmp(name, XATTR_NAME_SMACK) == 0 || | 803 | if (strcmp(name, XATTR_NAME_SMACK) == 0 || |
| 759 | strcmp(name, XATTR_NAME_SMACKIPIN) == 0 || | 804 | strcmp(name, XATTR_NAME_SMACKIPIN) == 0 || |
| 760 | strcmp(name, XATTR_NAME_SMACKIPOUT) == 0) { | 805 | strcmp(name, XATTR_NAME_SMACKIPOUT) == 0 || |
| 806 | strcmp(name, XATTR_NAME_SMACKEXEC) == 0) { | ||
| 761 | if (!capable(CAP_MAC_ADMIN)) | 807 | if (!capable(CAP_MAC_ADMIN)) |
| 762 | rc = -EPERM; | 808 | rc = -EPERM; |
| 763 | } else | 809 | } else |
| @@ -768,6 +814,11 @@ static int smack_inode_removexattr(struct dentry *dentry, const char *name) | |||
| 768 | if (rc == 0) | 814 | if (rc == 0) |
| 769 | rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad); | 815 | rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad); |
| 770 | 816 | ||
| 817 | if (rc == 0) { | ||
| 818 | isp = dentry->d_inode->i_security; | ||
| 819 | isp->smk_task = NULL; | ||
| 820 | } | ||
| 821 | |||
| 771 | return rc; | 822 | return rc; |
| 772 | } | 823 | } |
| 773 | 824 | ||
| @@ -895,7 +946,7 @@ static int smack_file_permission(struct file *file, int mask) | |||
| 895 | */ | 946 | */ |
| 896 | static int smack_file_alloc_security(struct file *file) | 947 | static int smack_file_alloc_security(struct file *file) |
| 897 | { | 948 | { |
| 898 | file->f_security = current_security(); | 949 | file->f_security = smk_of_current(); |
| 899 | return 0; | 950 | return 0; |
| 900 | } | 951 | } |
| 901 | 952 | ||
| @@ -1005,7 +1056,7 @@ static int smack_file_fcntl(struct file *file, unsigned int cmd, | |||
| 1005 | */ | 1056 | */ |
| 1006 | static int smack_file_set_fowner(struct file *file) | 1057 | static int smack_file_set_fowner(struct file *file) |
| 1007 | { | 1058 | { |
| 1008 | file->f_security = current_security(); | 1059 | file->f_security = smk_of_current(); |
| 1009 | return 0; | 1060 | return 0; |
| 1010 | } | 1061 | } |
| 1011 | 1062 | ||
| @@ -1025,7 +1076,7 @@ static int smack_file_send_sigiotask(struct task_struct *tsk, | |||
| 1025 | { | 1076 | { |
| 1026 | struct file *file; | 1077 | struct file *file; |
| 1027 | int rc; | 1078 | int rc; |
| 1028 | char *tsp = tsk->cred->security; | 1079 | char *tsp = smk_of_task(tsk->cred->security); |
| 1029 | struct smk_audit_info ad; | 1080 | struct smk_audit_info ad; |
| 1030 | 1081 | ||
| 1031 | /* | 1082 | /* |
| @@ -1082,7 +1133,9 @@ static int smack_file_receive(struct file *file) | |||
| 1082 | */ | 1133 | */ |
| 1083 | static int smack_cred_alloc_blank(struct cred *cred, gfp_t gfp) | 1134 | static int smack_cred_alloc_blank(struct cred *cred, gfp_t gfp) |
| 1084 | { | 1135 | { |
| 1085 | cred->security = NULL; | 1136 | cred->security = kzalloc(sizeof(struct task_smack), gfp); |
| 1137 | if (cred->security == NULL) | ||
| 1138 | return -ENOMEM; | ||
| 1086 | return 0; | 1139 | return 0; |
| 1087 | } | 1140 | } |
| 1088 | 1141 | ||
| @@ -1097,7 +1150,7 @@ static int smack_cred_alloc_blank(struct cred *cred, gfp_t gfp) | |||
| 1097 | */ | 1150 | */ |
| 1098 | static void smack_cred_free(struct cred *cred) | 1151 | static void smack_cred_free(struct cred *cred) |
| 1099 | { | 1152 | { |
| 1100 | cred->security = NULL; | 1153 | kfree(cred->security); |
| 1101 | } | 1154 | } |
| 1102 | 1155 | ||
| 1103 | /** | 1156 | /** |
| @@ -1111,7 +1164,16 @@ static void smack_cred_free(struct cred *cred) | |||
| 1111 | static int smack_cred_prepare(struct cred *new, const struct cred *old, | 1164 | static int smack_cred_prepare(struct cred *new, const struct cred *old, |
| 1112 | gfp_t gfp) | 1165 | gfp_t gfp) |
| 1113 | { | 1166 | { |
| 1114 | new->security = old->security; | 1167 | struct task_smack *old_tsp = old->security; |
| 1168 | struct task_smack *new_tsp; | ||
| 1169 | |||
| 1170 | new_tsp = kzalloc(sizeof(struct task_smack), gfp); | ||
| 1171 | if (new_tsp == NULL) | ||
| 1172 | return -ENOMEM; | ||
| 1173 | |||
| 1174 | new_tsp->smk_task = old_tsp->smk_task; | ||
| 1175 | new_tsp->smk_forked = old_tsp->smk_task; | ||
| 1176 | new->security = new_tsp; | ||
| 1115 | return 0; | 1177 | return 0; |
| 1116 | } | 1178 | } |
| 1117 | 1179 | ||
| @@ -1124,7 +1186,11 @@ static int smack_cred_prepare(struct cred *new, const struct cred *old, | |||
| 1124 | */ | 1186 | */ |
| 1125 | static void smack_cred_transfer(struct cred *new, const struct cred *old) | 1187 | static void smack_cred_transfer(struct cred *new, const struct cred *old) |
| 1126 | { | 1188 | { |
| 1127 | new->security = old->security; | 1189 | struct task_smack *old_tsp = old->security; |
| 1190 | struct task_smack *new_tsp = new->security; | ||
| 1191 | |||
| 1192 | new_tsp->smk_task = old_tsp->smk_task; | ||
| 1193 | new_tsp->smk_forked = old_tsp->smk_task; | ||
| 1128 | } | 1194 | } |
| 1129 | 1195 | ||
| 1130 | /** | 1196 | /** |
| @@ -1136,12 +1202,13 @@ static void smack_cred_transfer(struct cred *new, const struct cred *old) | |||
| 1136 | */ | 1202 | */ |
| 1137 | static int smack_kernel_act_as(struct cred *new, u32 secid) | 1203 | static int smack_kernel_act_as(struct cred *new, u32 secid) |
| 1138 | { | 1204 | { |
| 1205 | struct task_smack *new_tsp = new->security; | ||
| 1139 | char *smack = smack_from_secid(secid); | 1206 | char *smack = smack_from_secid(secid); |
| 1140 | 1207 | ||
| 1141 | if (smack == NULL) | 1208 | if (smack == NULL) |
| 1142 | return -EINVAL; | 1209 | return -EINVAL; |
| 1143 | 1210 | ||
| 1144 | new->security = smack; | 1211 | new_tsp->smk_task = smack; |
| 1145 | return 0; | 1212 | return 0; |
| 1146 | } | 1213 | } |
| 1147 | 1214 | ||
| @@ -1157,8 +1224,10 @@ static int smack_kernel_create_files_as(struct cred *new, | |||
| 1157 | struct inode *inode) | 1224 | struct inode *inode) |
| 1158 | { | 1225 | { |
| 1159 | struct inode_smack *isp = inode->i_security; | 1226 | struct inode_smack *isp = inode->i_security; |
| 1227 | struct task_smack *tsp = new->security; | ||
| 1160 | 1228 | ||
| 1161 | new->security = isp->smk_inode; | 1229 | tsp->smk_forked = isp->smk_inode; |
| 1230 | tsp->smk_task = isp->smk_inode; | ||
| 1162 | return 0; | 1231 | return 0; |
| 1163 | } | 1232 | } |
| 1164 | 1233 | ||
| @@ -1175,7 +1244,7 @@ static int smk_curacc_on_task(struct task_struct *p, int access) | |||
| 1175 | 1244 | ||
| 1176 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); | 1245 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); |
| 1177 | smk_ad_setfield_u_tsk(&ad, p); | 1246 | smk_ad_setfield_u_tsk(&ad, p); |
| 1178 | return smk_curacc(task_security(p), access, &ad); | 1247 | return smk_curacc(smk_of_task(task_security(p)), access, &ad); |
| 1179 | } | 1248 | } |
| 1180 | 1249 | ||
| 1181 | /** | 1250 | /** |
| @@ -1221,7 +1290,7 @@ static int smack_task_getsid(struct task_struct *p) | |||
| 1221 | */ | 1290 | */ |
| 1222 | static void smack_task_getsecid(struct task_struct *p, u32 *secid) | 1291 | static void smack_task_getsecid(struct task_struct *p, u32 *secid) |
| 1223 | { | 1292 | { |
| 1224 | *secid = smack_to_secid(task_security(p)); | 1293 | *secid = smack_to_secid(smk_of_task(task_security(p))); |
| 1225 | } | 1294 | } |
| 1226 | 1295 | ||
| 1227 | /** | 1296 | /** |
| @@ -1333,14 +1402,15 @@ static int smack_task_kill(struct task_struct *p, struct siginfo *info, | |||
| 1333 | * can write the receiver. | 1402 | * can write the receiver. |
| 1334 | */ | 1403 | */ |
| 1335 | if (secid == 0) | 1404 | if (secid == 0) |
| 1336 | return smk_curacc(task_security(p), MAY_WRITE, &ad); | 1405 | return smk_curacc(smk_of_task(task_security(p)), MAY_WRITE, |
| 1406 | &ad); | ||
| 1337 | /* | 1407 | /* |
| 1338 | * If the secid isn't 0 we're dealing with some USB IO | 1408 | * If the secid isn't 0 we're dealing with some USB IO |
| 1339 | * specific behavior. This is not clean. For one thing | 1409 | * specific behavior. This is not clean. For one thing |
| 1340 | * we can't take privilege into account. | 1410 | * we can't take privilege into account. |
| 1341 | */ | 1411 | */ |
| 1342 | return smk_access(smack_from_secid(secid), task_security(p), | 1412 | return smk_access(smack_from_secid(secid), |
| 1343 | MAY_WRITE, &ad); | 1413 | smk_of_task(task_security(p)), MAY_WRITE, &ad); |
| 1344 | } | 1414 | } |
| 1345 | 1415 | ||
| 1346 | /** | 1416 | /** |
| @@ -1352,12 +1422,12 @@ static int smack_task_kill(struct task_struct *p, struct siginfo *info, | |||
| 1352 | static int smack_task_wait(struct task_struct *p) | 1422 | static int smack_task_wait(struct task_struct *p) |
| 1353 | { | 1423 | { |
| 1354 | struct smk_audit_info ad; | 1424 | struct smk_audit_info ad; |
| 1355 | char *sp = current_security(); | 1425 | char *sp = smk_of_current(); |
| 1356 | char *tsp = task_security(p); | 1426 | char *tsp = smk_of_forked(task_security(p)); |
| 1357 | int rc; | 1427 | int rc; |
| 1358 | 1428 | ||
| 1359 | /* we don't log here, we can be overriden */ | 1429 | /* we don't log here, we can be overriden */ |
| 1360 | rc = smk_access(sp, tsp, MAY_WRITE, NULL); | 1430 | rc = smk_access(tsp, sp, MAY_WRITE, NULL); |
| 1361 | if (rc == 0) | 1431 | if (rc == 0) |
| 1362 | goto out_log; | 1432 | goto out_log; |
| 1363 | 1433 | ||
| @@ -1378,7 +1448,7 @@ static int smack_task_wait(struct task_struct *p) | |||
| 1378 | out_log: | 1448 | out_log: |
| 1379 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); | 1449 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); |
| 1380 | smk_ad_setfield_u_tsk(&ad, p); | 1450 | smk_ad_setfield_u_tsk(&ad, p); |
| 1381 | smack_log(sp, tsp, MAY_WRITE, rc, &ad); | 1451 | smack_log(tsp, sp, MAY_WRITE, rc, &ad); |
| 1382 | return rc; | 1452 | return rc; |
| 1383 | } | 1453 | } |
| 1384 | 1454 | ||
| @@ -1392,7 +1462,7 @@ static int smack_task_wait(struct task_struct *p) | |||
| 1392 | static void smack_task_to_inode(struct task_struct *p, struct inode *inode) | 1462 | static void smack_task_to_inode(struct task_struct *p, struct inode *inode) |
| 1393 | { | 1463 | { |
| 1394 | struct inode_smack *isp = inode->i_security; | 1464 | struct inode_smack *isp = inode->i_security; |
| 1395 | isp->smk_inode = task_security(p); | 1465 | isp->smk_inode = smk_of_task(task_security(p)); |
| 1396 | } | 1466 | } |
| 1397 | 1467 | ||
| 1398 | /* | 1468 | /* |
| @@ -1411,7 +1481,7 @@ static void smack_task_to_inode(struct task_struct *p, struct inode *inode) | |||
| 1411 | */ | 1481 | */ |
| 1412 | static int smack_sk_alloc_security(struct sock *sk, int family, gfp_t gfp_flags) | 1482 | static int smack_sk_alloc_security(struct sock *sk, int family, gfp_t gfp_flags) |
| 1413 | { | 1483 | { |
| 1414 | char *csp = current_security(); | 1484 | char *csp = smk_of_current(); |
| 1415 | struct socket_smack *ssp; | 1485 | struct socket_smack *ssp; |
| 1416 | 1486 | ||
| 1417 | ssp = kzalloc(sizeof(struct socket_smack), gfp_flags); | 1487 | ssp = kzalloc(sizeof(struct socket_smack), gfp_flags); |
| @@ -1752,7 +1822,7 @@ static int smack_flags_to_may(int flags) | |||
| 1752 | */ | 1822 | */ |
| 1753 | static int smack_msg_msg_alloc_security(struct msg_msg *msg) | 1823 | static int smack_msg_msg_alloc_security(struct msg_msg *msg) |
| 1754 | { | 1824 | { |
| 1755 | msg->security = current_security(); | 1825 | msg->security = smk_of_current(); |
| 1756 | return 0; | 1826 | return 0; |
| 1757 | } | 1827 | } |
| 1758 | 1828 | ||
| @@ -1788,7 +1858,7 @@ static int smack_shm_alloc_security(struct shmid_kernel *shp) | |||
| 1788 | { | 1858 | { |
| 1789 | struct kern_ipc_perm *isp = &shp->shm_perm; | 1859 | struct kern_ipc_perm *isp = &shp->shm_perm; |
| 1790 | 1860 | ||
| 1791 | isp->security = current_security(); | 1861 | isp->security = smk_of_current(); |
| 1792 | return 0; | 1862 | return 0; |
| 1793 | } | 1863 | } |
| 1794 | 1864 | ||
| @@ -1911,7 +1981,7 @@ static int smack_sem_alloc_security(struct sem_array *sma) | |||
| 1911 | { | 1981 | { |
| 1912 | struct kern_ipc_perm *isp = &sma->sem_perm; | 1982 | struct kern_ipc_perm *isp = &sma->sem_perm; |
| 1913 | 1983 | ||
| 1914 | isp->security = current_security(); | 1984 | isp->security = smk_of_current(); |
| 1915 | return 0; | 1985 | return 0; |
| 1916 | } | 1986 | } |
| 1917 | 1987 | ||
| @@ -2029,7 +2099,7 @@ static int smack_msg_queue_alloc_security(struct msg_queue *msq) | |||
| 2029 | { | 2099 | { |
| 2030 | struct kern_ipc_perm *kisp = &msq->q_perm; | 2100 | struct kern_ipc_perm *kisp = &msq->q_perm; |
| 2031 | 2101 | ||
| 2032 | kisp->security = current_security(); | 2102 | kisp->security = smk_of_current(); |
| 2033 | return 0; | 2103 | return 0; |
| 2034 | } | 2104 | } |
| 2035 | 2105 | ||
| @@ -2201,7 +2271,7 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) | |||
| 2201 | struct super_block *sbp; | 2271 | struct super_block *sbp; |
| 2202 | struct superblock_smack *sbsp; | 2272 | struct superblock_smack *sbsp; |
| 2203 | struct inode_smack *isp; | 2273 | struct inode_smack *isp; |
| 2204 | char *csp = current_security(); | 2274 | char *csp = smk_of_current(); |
| 2205 | char *fetched; | 2275 | char *fetched; |
| 2206 | char *final; | 2276 | char *final; |
| 2207 | struct dentry *dp; | 2277 | struct dentry *dp; |
| @@ -2321,9 +2391,12 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) | |||
| 2321 | * Get the dentry for xattr. | 2391 | * Get the dentry for xattr. |
| 2322 | */ | 2392 | */ |
| 2323 | dp = dget(opt_dentry); | 2393 | dp = dget(opt_dentry); |
| 2324 | fetched = smk_fetch(inode, dp); | 2394 | fetched = smk_fetch(XATTR_NAME_SMACK, inode, dp); |
| 2325 | if (fetched != NULL) | 2395 | if (fetched != NULL) |
| 2326 | final = fetched; | 2396 | final = fetched; |
| 2397 | isp->smk_task = smk_fetch(XATTR_NAME_SMACKEXEC, inode, | ||
| 2398 | dp); | ||
| 2399 | |||
| 2327 | dput(dp); | 2400 | dput(dp); |
| 2328 | break; | 2401 | break; |
| 2329 | } | 2402 | } |
| @@ -2358,7 +2431,7 @@ static int smack_getprocattr(struct task_struct *p, char *name, char **value) | |||
| 2358 | if (strcmp(name, "current") != 0) | 2431 | if (strcmp(name, "current") != 0) |
| 2359 | return -EINVAL; | 2432 | return -EINVAL; |
| 2360 | 2433 | ||
| 2361 | cp = kstrdup(task_security(p), GFP_KERNEL); | 2434 | cp = kstrdup(smk_of_task(task_security(p)), GFP_KERNEL); |
| 2362 | if (cp == NULL) | 2435 | if (cp == NULL) |
| 2363 | return -ENOMEM; | 2436 | return -ENOMEM; |
| 2364 | 2437 | ||
| @@ -2382,6 +2455,7 @@ static int smack_getprocattr(struct task_struct *p, char *name, char **value) | |||
| 2382 | static int smack_setprocattr(struct task_struct *p, char *name, | 2455 | static int smack_setprocattr(struct task_struct *p, char *name, |
| 2383 | void *value, size_t size) | 2456 | void *value, size_t size) |
| 2384 | { | 2457 | { |
| 2458 | struct task_smack *tsp; | ||
| 2385 | struct cred *new; | 2459 | struct cred *new; |
| 2386 | char *newsmack; | 2460 | char *newsmack; |
| 2387 | 2461 | ||
| @@ -2414,7 +2488,13 @@ static int smack_setprocattr(struct task_struct *p, char *name, | |||
| 2414 | new = prepare_creds(); | 2488 | new = prepare_creds(); |
| 2415 | if (new == NULL) | 2489 | if (new == NULL) |
| 2416 | return -ENOMEM; | 2490 | return -ENOMEM; |
| 2417 | new->security = newsmack; | 2491 | tsp = kzalloc(sizeof(struct task_smack), GFP_KERNEL); |
| 2492 | if (tsp == NULL) { | ||
| 2493 | kfree(new); | ||
| 2494 | return -ENOMEM; | ||
| 2495 | } | ||
| 2496 | tsp->smk_task = newsmack; | ||
| 2497 | new->security = tsp; | ||
| 2418 | commit_creds(new); | 2498 | commit_creds(new); |
| 2419 | return size; | 2499 | return size; |
| 2420 | } | 2500 | } |
| @@ -2715,7 +2795,7 @@ static void smack_sock_graft(struct sock *sk, struct socket *parent) | |||
| 2715 | return; | 2795 | return; |
| 2716 | 2796 | ||
| 2717 | ssp = sk->sk_security; | 2797 | ssp = sk->sk_security; |
| 2718 | ssp->smk_in = ssp->smk_out = current_security(); | 2798 | ssp->smk_in = ssp->smk_out = smk_of_current(); |
| 2719 | /* cssp->smk_packet is already set in smack_inet_csk_clone() */ | 2799 | /* cssp->smk_packet is already set in smack_inet_csk_clone() */ |
| 2720 | } | 2800 | } |
| 2721 | 2801 | ||
| @@ -2836,7 +2916,7 @@ static void smack_inet_csk_clone(struct sock *sk, | |||
| 2836 | static int smack_key_alloc(struct key *key, const struct cred *cred, | 2916 | static int smack_key_alloc(struct key *key, const struct cred *cred, |
| 2837 | unsigned long flags) | 2917 | unsigned long flags) |
| 2838 | { | 2918 | { |
| 2839 | key->security = cred->security; | 2919 | key->security = smk_of_task(cred->security); |
| 2840 | return 0; | 2920 | return 0; |
| 2841 | } | 2921 | } |
| 2842 | 2922 | ||
| @@ -2865,6 +2945,7 @@ static int smack_key_permission(key_ref_t key_ref, | |||
| 2865 | { | 2945 | { |
| 2866 | struct key *keyp; | 2946 | struct key *keyp; |
| 2867 | struct smk_audit_info ad; | 2947 | struct smk_audit_info ad; |
| 2948 | char *tsp = smk_of_task(cred->security); | ||
| 2868 | 2949 | ||
| 2869 | keyp = key_ref_to_ptr(key_ref); | 2950 | keyp = key_ref_to_ptr(key_ref); |
| 2870 | if (keyp == NULL) | 2951 | if (keyp == NULL) |
| @@ -2878,14 +2959,14 @@ static int smack_key_permission(key_ref_t key_ref, | |||
| 2878 | /* | 2959 | /* |
| 2879 | * This should not occur | 2960 | * This should not occur |
| 2880 | */ | 2961 | */ |
| 2881 | if (cred->security == NULL) | 2962 | if (tsp == NULL) |
| 2882 | return -EACCES; | 2963 | return -EACCES; |
| 2883 | #ifdef CONFIG_AUDIT | 2964 | #ifdef CONFIG_AUDIT |
| 2884 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_KEY); | 2965 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_KEY); |
| 2885 | ad.a.u.key_struct.key = keyp->serial; | 2966 | ad.a.u.key_struct.key = keyp->serial; |
| 2886 | ad.a.u.key_struct.key_desc = keyp->description; | 2967 | ad.a.u.key_struct.key_desc = keyp->description; |
| 2887 | #endif | 2968 | #endif |
| 2888 | return smk_access(cred->security, keyp->security, | 2969 | return smk_access(tsp, keyp->security, |
| 2889 | MAY_READWRITE, &ad); | 2970 | MAY_READWRITE, &ad); |
| 2890 | } | 2971 | } |
| 2891 | #endif /* CONFIG_KEYS */ | 2972 | #endif /* CONFIG_KEYS */ |
| @@ -3087,6 +3168,8 @@ struct security_operations smack_ops = { | |||
| 3087 | .sb_mount = smack_sb_mount, | 3168 | .sb_mount = smack_sb_mount, |
| 3088 | .sb_umount = smack_sb_umount, | 3169 | .sb_umount = smack_sb_umount, |
| 3089 | 3170 | ||
| 3171 | .bprm_set_creds = smack_bprm_set_creds, | ||
| 3172 | |||
| 3090 | .inode_alloc_security = smack_inode_alloc_security, | 3173 | .inode_alloc_security = smack_inode_alloc_security, |
| 3091 | .inode_free_security = smack_inode_free_security, | 3174 | .inode_free_security = smack_inode_free_security, |
| 3092 | .inode_init_security = smack_inode_init_security, | 3175 | .inode_init_security = smack_inode_init_security, |
| @@ -3223,9 +3306,16 @@ static __init void init_smack_know_list(void) | |||
| 3223 | static __init int smack_init(void) | 3306 | static __init int smack_init(void) |
| 3224 | { | 3307 | { |
| 3225 | struct cred *cred; | 3308 | struct cred *cred; |
| 3309 | struct task_smack *tsp; | ||
| 3226 | 3310 | ||
| 3227 | if (!security_module_enable(&smack_ops)) | 3311 | tsp = kzalloc(sizeof(struct task_smack), GFP_KERNEL); |
| 3312 | if (tsp == NULL) | ||
| 3313 | return -ENOMEM; | ||
| 3314 | |||
| 3315 | if (!security_module_enable(&smack_ops)) { | ||
| 3316 | kfree(tsp); | ||
| 3228 | return 0; | 3317 | return 0; |
| 3318 | } | ||
| 3229 | 3319 | ||
| 3230 | printk(KERN_INFO "Smack: Initializing.\n"); | 3320 | printk(KERN_INFO "Smack: Initializing.\n"); |
| 3231 | 3321 | ||
| @@ -3233,7 +3323,9 @@ static __init int smack_init(void) | |||
| 3233 | * Set the security state for the initial task. | 3323 | * Set the security state for the initial task. |
| 3234 | */ | 3324 | */ |
| 3235 | cred = (struct cred *) current->cred; | 3325 | cred = (struct cred *) current->cred; |
| 3236 | cred->security = &smack_known_floor.smk_known; | 3326 | tsp->smk_forked = smack_known_floor.smk_known; |
| 3327 | tsp->smk_task = smack_known_floor.smk_known; | ||
| 3328 | cred->security = tsp; | ||
| 3237 | 3329 | ||
| 3238 | /* initialize the smack_know_list */ | 3330 | /* initialize the smack_know_list */ |
| 3239 | init_smack_know_list(); | 3331 | init_smack_know_list(); |
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c index dc1fd6239f24..01a0be93d8d0 100644 --- a/security/smack/smackfs.c +++ b/security/smack/smackfs.c | |||
| @@ -121,7 +121,7 @@ static void smk_netlabel_audit_set(struct netlbl_audit *nap) | |||
| 121 | { | 121 | { |
| 122 | nap->loginuid = audit_get_loginuid(current); | 122 | nap->loginuid = audit_get_loginuid(current); |
| 123 | nap->sessionid = audit_get_sessionid(current); | 123 | nap->sessionid = audit_get_sessionid(current); |
| 124 | nap->secid = smack_to_secid(current_security()); | 124 | nap->secid = smack_to_secid(smk_of_current()); |
| 125 | } | 125 | } |
| 126 | 126 | ||
| 127 | /* | 127 | /* |
| @@ -1160,7 +1160,7 @@ static ssize_t smk_write_onlycap(struct file *file, const char __user *buf, | |||
| 1160 | size_t count, loff_t *ppos) | 1160 | size_t count, loff_t *ppos) |
| 1161 | { | 1161 | { |
| 1162 | char in[SMK_LABELLEN]; | 1162 | char in[SMK_LABELLEN]; |
| 1163 | char *sp = current->cred->security; | 1163 | char *sp = smk_of_task(current->cred->security); |
| 1164 | 1164 | ||
| 1165 | if (!capable(CAP_MAC_ADMIN)) | 1165 | if (!capable(CAP_MAC_ADMIN)) |
| 1166 | return -EPERM; | 1166 | return -EPERM; |
