aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCasey Schaufler <casey@schaufler-ca.com>2010-12-02 09:43:39 -0500
committerCasey Schaufler <casey@schaufler-ca.com>2010-12-02 09:43:39 -0500
commit676dac4b1bee0469d6932f698aeb77e8489f5861 (patch)
tree196b4cb35cf8dfdff0698dc4368cfd00acc7391a
parent93ae86e759299718c611bc543b9b1633bf32905a (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
-rw-r--r--include/linux/xattr.h2
-rw-r--r--security/smack/smack.h30
-rw-r--r--security/smack/smack_access.c4
-rw-r--r--security/smack/smack_lsm.c192
-rw-r--r--security/smack/smackfs.c4
5 files changed, 178 insertions, 54 deletions
diff --git a/include/linux/xattr.h b/include/linux/xattr.h
index f1e5bde4b35a..351c7901d74a 100644
--- a/include/linux/xattr.h
+++ b/include/linux/xattr.h
@@ -40,9 +40,11 @@
40#define XATTR_SMACK_SUFFIX "SMACK64" 40#define XATTR_SMACK_SUFFIX "SMACK64"
41#define XATTR_SMACK_IPIN "SMACK64IPIN" 41#define XATTR_SMACK_IPIN "SMACK64IPIN"
42#define XATTR_SMACK_IPOUT "SMACK64IPOUT" 42#define XATTR_SMACK_IPOUT "SMACK64IPOUT"
43#define XATTR_SMACK_EXEC "SMACK64EXEC"
43#define XATTR_NAME_SMACK XATTR_SECURITY_PREFIX XATTR_SMACK_SUFFIX 44#define XATTR_NAME_SMACK XATTR_SECURITY_PREFIX XATTR_SMACK_SUFFIX
44#define XATTR_NAME_SMACKIPIN XATTR_SECURITY_PREFIX XATTR_SMACK_IPIN 45#define XATTR_NAME_SMACKIPIN XATTR_SECURITY_PREFIX XATTR_SMACK_IPIN
45#define XATTR_NAME_SMACKIPOUT XATTR_SECURITY_PREFIX XATTR_SMACK_IPOUT 46#define XATTR_NAME_SMACKIPOUT XATTR_SECURITY_PREFIX XATTR_SMACK_IPOUT
47#define XATTR_NAME_SMACKEXEC XATTR_SECURITY_PREFIX XATTR_SMACK_EXEC
46 48
47#define XATTR_CAPS_SUFFIX "capability" 49#define XATTR_CAPS_SUFFIX "capability"
48#define XATTR_NAME_CAPS XATTR_SECURITY_PREFIX XATTR_CAPS_SUFFIX 50#define XATTR_NAME_CAPS XATTR_SECURITY_PREFIX XATTR_CAPS_SUFFIX
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 */
52struct inode_smack { 52struct 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
59struct 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 */
254static 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 */
262static 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 */
270static 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:
185int smk_curacc(char *obj_label, u32 mode, struct smk_audit_info *a) 185int 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 */
46static char *smk_fetch(struct inode *ip, struct dentry *dp) 46static 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)
160static int smack_syslog(int typefrom_file) 160static 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
397static 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 */
403static int smack_inode_alloc_security(struct inode *inode) 437static 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 */
753static int smack_inode_removexattr(struct dentry *dentry, const char *name) 797static 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 */
896static int smack_file_alloc_security(struct file *file) 947static 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 */
1006static int smack_file_set_fowner(struct file *file) 1057static 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 */
1083static int smack_cred_alloc_blank(struct cred *cred, gfp_t gfp) 1134static 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 */
1098static void smack_cred_free(struct cred *cred) 1151static 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)
1111static int smack_cred_prepare(struct cred *new, const struct cred *old, 1164static 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 */
1125static void smack_cred_transfer(struct cred *new, const struct cred *old) 1187static 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 */
1137static int smack_kernel_act_as(struct cred *new, u32 secid) 1203static 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 */
1222static void smack_task_getsecid(struct task_struct *p, u32 *secid) 1291static 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,
1352static int smack_task_wait(struct task_struct *p) 1422static 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)
1392static void smack_task_to_inode(struct task_struct *p, struct inode *inode) 1462static 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 */
1412static int smack_sk_alloc_security(struct sock *sk, int family, gfp_t gfp_flags) 1482static 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 */
1753static int smack_msg_msg_alloc_security(struct msg_msg *msg) 1823static 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)
2382static int smack_setprocattr(struct task_struct *p, char *name, 2455static 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,
2836static int smack_key_alloc(struct key *key, const struct cred *cred, 2916static 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)
3223static __init int smack_init(void) 3306static __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;