aboutsummaryrefslogtreecommitdiffstats
path: root/security/smack
diff options
context:
space:
mode:
Diffstat (limited to 'security/smack')
-rw-r--r--security/smack/smack.h45
-rw-r--r--security/smack/smack_access.c58
-rw-r--r--security/smack/smack_lsm.c354
-rw-r--r--security/smack/smackfs.c41
4 files changed, 368 insertions, 130 deletions
diff --git a/security/smack/smack.h b/security/smack/smack.h
index 43ae747a5aa4..129c4eb8ffb1 100644
--- a/security/smack/smack.h
+++ b/security/smack/smack.h
@@ -51,11 +51,18 @@ 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 */
65#define SMK_INODE_TRANSMUTE 0x02 /* directory is transmuting */
59 66
60/* 67/*
61 * A label access rule. 68 * A label access rule.
@@ -161,6 +168,10 @@ struct smack_known {
161#define SMACK_CIPSO_MAXCATNUM 239 /* CIPSO 2.2 standard */ 168#define SMACK_CIPSO_MAXCATNUM 239 /* CIPSO 2.2 standard */
162 169
163/* 170/*
171 * Flag for transmute access
172 */
173#define MAY_TRANSMUTE 64
174/*
164 * Just to make the common cases easier to deal with 175 * Just to make the common cases easier to deal with
165 */ 176 */
166#define MAY_ANY (MAY_READ | MAY_WRITE | MAY_APPEND | MAY_EXEC) 177#define MAY_ANY (MAY_READ | MAY_WRITE | MAY_APPEND | MAY_EXEC)
@@ -191,6 +202,7 @@ struct inode_smack *new_inode_smack(char *);
191/* 202/*
192 * These functions are in smack_access.c 203 * These functions are in smack_access.c
193 */ 204 */
205int smk_access_entry(char *, char *);
194int smk_access(char *, char *, int, struct smk_audit_info *); 206int smk_access(char *, char *, int, struct smk_audit_info *);
195int smk_curacc(char *, u32, struct smk_audit_info *); 207int smk_curacc(char *, u32, struct smk_audit_info *);
196int smack_to_cipso(const char *, struct smack_cipso *); 208int smack_to_cipso(const char *, struct smack_cipso *);
@@ -234,6 +246,15 @@ static inline void smack_catset_bit(int cat, char *catsetp)
234} 246}
235 247
236/* 248/*
249 * Is the directory transmuting?
250 */
251static inline int smk_inode_transmutable(const struct inode *isp)
252{
253 struct inode_smack *sip = isp->i_security;
254 return (sip->smk_flags & SMK_INODE_TRANSMUTE) != 0;
255}
256
257/*
237 * Present a pointer to the smack label in an inode blob. 258 * Present a pointer to the smack label in an inode blob.
238 */ 259 */
239static inline char *smk_of_inode(const struct inode *isp) 260static inline char *smk_of_inode(const struct inode *isp)
@@ -243,6 +264,30 @@ static inline char *smk_of_inode(const struct inode *isp)
243} 264}
244 265
245/* 266/*
267 * Present a pointer to the smack label in an task blob.
268 */
269static inline char *smk_of_task(const struct task_smack *tsp)
270{
271 return tsp->smk_task;
272}
273
274/*
275 * Present a pointer to the forked smack label in an task blob.
276 */
277static inline char *smk_of_forked(const struct task_smack *tsp)
278{
279 return tsp->smk_forked;
280}
281
282/*
283 * Present a pointer to the smack label in the current task blob.
284 */
285static inline char *smk_of_current(void)
286{
287 return smk_of_task(current_security());
288}
289
290/*
246 * logging functions 291 * logging functions
247 */ 292 */
248#define SMACK_AUDIT_DENIED 0x1 293#define SMACK_AUDIT_DENIED 0x1
diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c
index f4fac64c4da8..7ba8478f599e 100644
--- a/security/smack/smack_access.c
+++ b/security/smack/smack_access.c
@@ -67,6 +67,46 @@ static u32 smack_next_secid = 10;
67int log_policy = SMACK_AUDIT_DENIED; 67int log_policy = SMACK_AUDIT_DENIED;
68 68
69/** 69/**
70 * smk_access_entry - look up matching access rule
71 * @subject_label: a pointer to the subject's Smack label
72 * @object_label: a pointer to the object's Smack label
73 *
74 * This function looks up the subject/object pair in the
75 * access rule list and returns pointer to the matching rule if found,
76 * NULL otherwise.
77 *
78 * NOTE:
79 * Even though Smack labels are usually shared on smack_list
80 * labels that come in off the network can't be imported
81 * and added to the list for locking reasons.
82 *
83 * Therefore, it is necessary to check the contents of the labels,
84 * not just the pointer values. Of course, in most cases the labels
85 * will be on the list, so checking the pointers may be a worthwhile
86 * optimization.
87 */
88int smk_access_entry(char *subject_label, char *object_label)
89{
90 u32 may = MAY_NOT;
91 struct smack_rule *srp;
92
93 rcu_read_lock();
94 list_for_each_entry_rcu(srp, &smack_rule_list, list) {
95 if (srp->smk_subject == subject_label ||
96 strcmp(srp->smk_subject, subject_label) == 0) {
97 if (srp->smk_object == object_label ||
98 strcmp(srp->smk_object, object_label) == 0) {
99 may = srp->smk_access;
100 break;
101 }
102 }
103 }
104 rcu_read_unlock();
105
106 return may;
107}
108
109/**
70 * smk_access - determine if a subject has a specific access to an object 110 * smk_access - determine if a subject has a specific access to an object
71 * @subject_label: a pointer to the subject's Smack label 111 * @subject_label: a pointer to the subject's Smack label
72 * @object_label: a pointer to the object's Smack label 112 * @object_label: a pointer to the object's Smack label
@@ -90,7 +130,6 @@ int smk_access(char *subject_label, char *object_label, int request,
90 struct smk_audit_info *a) 130 struct smk_audit_info *a)
91{ 131{
92 u32 may = MAY_NOT; 132 u32 may = MAY_NOT;
93 struct smack_rule *srp;
94 int rc = 0; 133 int rc = 0;
95 134
96 /* 135 /*
@@ -144,18 +183,7 @@ int smk_access(char *subject_label, char *object_label, int request,
144 * access (e.g. read is included in readwrite) it's 183 * access (e.g. read is included in readwrite) it's
145 * good. 184 * good.
146 */ 185 */
147 rcu_read_lock(); 186 may = smk_access_entry(subject_label, object_label);
148 list_for_each_entry_rcu(srp, &smack_rule_list, list) {
149 if (srp->smk_subject == subject_label ||
150 strcmp(srp->smk_subject, subject_label) == 0) {
151 if (srp->smk_object == object_label ||
152 strcmp(srp->smk_object, object_label) == 0) {
153 may = srp->smk_access;
154 break;
155 }
156 }
157 }
158 rcu_read_unlock();
159 /* 187 /*
160 * This is a bit map operation. 188 * This is a bit map operation.
161 */ 189 */
@@ -185,7 +213,7 @@ out_audit:
185int smk_curacc(char *obj_label, u32 mode, struct smk_audit_info *a) 213int smk_curacc(char *obj_label, u32 mode, struct smk_audit_info *a)
186{ 214{
187 int rc; 215 int rc;
188 char *sp = current_security(); 216 char *sp = smk_of_current();
189 217
190 rc = smk_access(sp, obj_label, mode, NULL); 218 rc = smk_access(sp, obj_label, mode, NULL);
191 if (rc == 0) 219 if (rc == 0)
@@ -196,7 +224,7 @@ int smk_curacc(char *obj_label, u32 mode, struct smk_audit_info *a)
196 * only one that gets privilege and current does not 224 * only one that gets privilege and current does not
197 * have that label. 225 * have that label.
198 */ 226 */
199 if (smack_onlycap != NULL && smack_onlycap != current->cred->security) 227 if (smack_onlycap != NULL && smack_onlycap != sp)
200 goto out_audit; 228 goto out_audit;
201 229
202 if (capable(CAP_MAC_OVERRIDE)) 230 if (capable(CAP_MAC_OVERRIDE))
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index ccb71a044a1a..533bf3255d7f 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -3,12 +3,14 @@
3 * 3 *
4 * This file contains the smack hook function implementations. 4 * This file contains the smack hook function implementations.
5 * 5 *
6 * Author: 6 * Authors:
7 * Casey Schaufler <casey@schaufler-ca.com> 7 * Casey Schaufler <casey@schaufler-ca.com>
8 * Jarkko Sakkinen <ext-jarkko.2.sakkinen@nokia.com>
8 * 9 *
9 * Copyright (C) 2007 Casey Schaufler <casey@schaufler-ca.com> 10 * Copyright (C) 2007 Casey Schaufler <casey@schaufler-ca.com>
10 * Copyright (C) 2009 Hewlett-Packard Development Company, L.P. 11 * Copyright (C) 2009 Hewlett-Packard Development Company, L.P.
11 * Paul Moore <paul.moore@hp.com> 12 * Paul Moore <paul.moore@hp.com>
13 * Copyright (C) 2010 Nokia Corporation
12 * 14 *
13 * This program is free software; you can redistribute it and/or modify 15 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2, 16 * it under the terms of the GNU General Public License version 2,
@@ -35,6 +37,9 @@
35 37
36#define task_security(task) (task_cred_xxx((task), security)) 38#define task_security(task) (task_cred_xxx((task), security))
37 39
40#define TRANS_TRUE "TRUE"
41#define TRANS_TRUE_SIZE 4
42
38/** 43/**
39 * smk_fetch - Fetch the smack label from a file. 44 * smk_fetch - Fetch the smack label from a file.
40 * @ip: a pointer to the inode 45 * @ip: a pointer to the inode
@@ -43,7 +48,7 @@
43 * Returns a pointer to the master list entry for the Smack label 48 * Returns a pointer to the master list entry for the Smack label
44 * or NULL if there was no label to fetch. 49 * or NULL if there was no label to fetch.
45 */ 50 */
46static char *smk_fetch(struct inode *ip, struct dentry *dp) 51static char *smk_fetch(const char *name, struct inode *ip, struct dentry *dp)
47{ 52{
48 int rc; 53 int rc;
49 char in[SMK_LABELLEN]; 54 char in[SMK_LABELLEN];
@@ -51,7 +56,7 @@ static char *smk_fetch(struct inode *ip, struct dentry *dp)
51 if (ip->i_op->getxattr == NULL) 56 if (ip->i_op->getxattr == NULL)
52 return NULL; 57 return NULL;
53 58
54 rc = ip->i_op->getxattr(dp, XATTR_NAME_SMACK, in, SMK_LABELLEN); 59 rc = ip->i_op->getxattr(dp, name, in, SMK_LABELLEN);
55 if (rc < 0) 60 if (rc < 0)
56 return NULL; 61 return NULL;
57 62
@@ -103,8 +108,8 @@ static int smack_ptrace_access_check(struct task_struct *ctp, unsigned int mode)
103 if (rc != 0) 108 if (rc != 0)
104 return rc; 109 return rc;
105 110
106 sp = current_security(); 111 sp = smk_of_current();
107 tsp = task_security(ctp); 112 tsp = smk_of_task(task_security(ctp));
108 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); 113 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
109 smk_ad_setfield_u_tsk(&ad, ctp); 114 smk_ad_setfield_u_tsk(&ad, ctp);
110 115
@@ -138,8 +143,8 @@ static int smack_ptrace_traceme(struct task_struct *ptp)
138 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); 143 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
139 smk_ad_setfield_u_tsk(&ad, ptp); 144 smk_ad_setfield_u_tsk(&ad, ptp);
140 145
141 sp = current_security(); 146 sp = smk_of_current();
142 tsp = task_security(ptp); 147 tsp = smk_of_task(task_security(ptp));
143 /* we won't log here, because rc can be overriden */ 148 /* we won't log here, because rc can be overriden */
144 rc = smk_access(tsp, sp, MAY_READWRITE, NULL); 149 rc = smk_access(tsp, sp, MAY_READWRITE, NULL);
145 if (rc != 0 && has_capability(ptp, CAP_MAC_OVERRIDE)) 150 if (rc != 0 && has_capability(ptp, CAP_MAC_OVERRIDE))
@@ -160,7 +165,7 @@ static int smack_ptrace_traceme(struct task_struct *ptp)
160static int smack_syslog(int typefrom_file) 165static int smack_syslog(int typefrom_file)
161{ 166{
162 int rc = 0; 167 int rc = 0;
163 char *sp = current_security(); 168 char *sp = smk_of_current();
164 169
165 if (capable(CAP_MAC_OVERRIDE)) 170 if (capable(CAP_MAC_OVERRIDE))
166 return 0; 171 return 0;
@@ -391,6 +396,40 @@ static int smack_sb_umount(struct vfsmount *mnt, int flags)
391} 396}
392 397
393/* 398/*
399 * BPRM hooks
400 */
401
402static int smack_bprm_set_creds(struct linux_binprm *bprm)
403{
404 struct task_smack *tsp = bprm->cred->security;
405 struct inode_smack *isp;
406 struct dentry *dp;
407 int rc;
408
409 rc = cap_bprm_set_creds(bprm);
410 if (rc != 0)
411 return rc;
412
413 if (bprm->cred_prepared)
414 return 0;
415
416 if (bprm->file == NULL || bprm->file->f_dentry == NULL)
417 return 0;
418
419 dp = bprm->file->f_dentry;
420
421 if (dp->d_inode == NULL)
422 return 0;
423
424 isp = dp->d_inode->i_security;
425
426 if (isp->smk_task != NULL)
427 tsp->smk_task = isp->smk_task;
428
429 return 0;
430}
431
432/*
394 * Inode hooks 433 * Inode hooks
395 */ 434 */
396 435
@@ -402,7 +441,7 @@ static int smack_sb_umount(struct vfsmount *mnt, int flags)
402 */ 441 */
403static int smack_inode_alloc_security(struct inode *inode) 442static int smack_inode_alloc_security(struct inode *inode)
404{ 443{
405 inode->i_security = new_inode_smack(current_security()); 444 inode->i_security = new_inode_smack(smk_of_current());
406 if (inode->i_security == NULL) 445 if (inode->i_security == NULL)
407 return -ENOMEM; 446 return -ENOMEM;
408 return 0; 447 return 0;
@@ -434,6 +473,8 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir,
434 char **name, void **value, size_t *len) 473 char **name, void **value, size_t *len)
435{ 474{
436 char *isp = smk_of_inode(inode); 475 char *isp = smk_of_inode(inode);
476 char *dsp = smk_of_inode(dir);
477 u32 may;
437 478
438 if (name) { 479 if (name) {
439 *name = kstrdup(XATTR_SMACK_SUFFIX, GFP_KERNEL); 480 *name = kstrdup(XATTR_SMACK_SUFFIX, GFP_KERNEL);
@@ -442,6 +483,16 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir,
442 } 483 }
443 484
444 if (value) { 485 if (value) {
486 may = smk_access_entry(smk_of_current(), dsp);
487
488 /*
489 * If the access rule allows transmutation and
490 * the directory requests transmutation then
491 * by all means transmute.
492 */
493 if (((may & MAY_TRANSMUTE) != 0) && smk_inode_transmutable(dir))
494 isp = dsp;
495
445 *value = kstrdup(isp, GFP_KERNEL); 496 *value = kstrdup(isp, GFP_KERNEL);
446 if (*value == NULL) 497 if (*value == NULL)
447 return -ENOMEM; 498 return -ENOMEM;
@@ -664,7 +715,8 @@ static int smack_inode_setxattr(struct dentry *dentry, const char *name,
664 715
665 if (strcmp(name, XATTR_NAME_SMACK) == 0 || 716 if (strcmp(name, XATTR_NAME_SMACK) == 0 ||
666 strcmp(name, XATTR_NAME_SMACKIPIN) == 0 || 717 strcmp(name, XATTR_NAME_SMACKIPIN) == 0 ||
667 strcmp(name, XATTR_NAME_SMACKIPOUT) == 0) { 718 strcmp(name, XATTR_NAME_SMACKIPOUT) == 0 ||
719 strcmp(name, XATTR_NAME_SMACKEXEC) == 0) {
668 if (!capable(CAP_MAC_ADMIN)) 720 if (!capable(CAP_MAC_ADMIN))
669 rc = -EPERM; 721 rc = -EPERM;
670 /* 722 /*
@@ -674,6 +726,12 @@ static int smack_inode_setxattr(struct dentry *dentry, const char *name,
674 if (size == 0 || size >= SMK_LABELLEN || 726 if (size == 0 || size >= SMK_LABELLEN ||
675 smk_import(value, size) == NULL) 727 smk_import(value, size) == NULL)
676 rc = -EINVAL; 728 rc = -EINVAL;
729 } else if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) {
730 if (!capable(CAP_MAC_ADMIN))
731 rc = -EPERM;
732 if (size != TRANS_TRUE_SIZE ||
733 strncmp(value, TRANS_TRUE, TRANS_TRUE_SIZE) != 0)
734 rc = -EINVAL;
677 } else 735 } else
678 rc = cap_inode_setxattr(dentry, name, value, size, flags); 736 rc = cap_inode_setxattr(dentry, name, value, size, flags);
679 737
@@ -700,26 +758,23 @@ static int smack_inode_setxattr(struct dentry *dentry, const char *name,
700static void smack_inode_post_setxattr(struct dentry *dentry, const char *name, 758static void smack_inode_post_setxattr(struct dentry *dentry, const char *name,
701 const void *value, size_t size, int flags) 759 const void *value, size_t size, int flags)
702{ 760{
703 struct inode_smack *isp;
704 char *nsp; 761 char *nsp;
762 struct inode_smack *isp = dentry->d_inode->i_security;
705 763
706 /* 764 if (strcmp(name, XATTR_NAME_SMACK) == 0) {
707 * Not SMACK 765 nsp = smk_import(value, size);
708 */ 766 if (nsp != NULL)
709 if (strcmp(name, XATTR_NAME_SMACK)) 767 isp->smk_inode = nsp;
710 return; 768 else
711 769 isp->smk_inode = smack_known_invalid.smk_known;
712 isp = dentry->d_inode->i_security; 770 } else if (strcmp(name, XATTR_NAME_SMACKEXEC) == 0) {
713 771 nsp = smk_import(value, size);
714 /* 772 if (nsp != NULL)
715 * No locking is done here. This is a pointer 773 isp->smk_task = nsp;
716 * assignment. 774 else
717 */ 775 isp->smk_task = smack_known_invalid.smk_known;
718 nsp = smk_import(value, size); 776 } else if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0)
719 if (nsp != NULL) 777 isp->smk_flags |= SMK_INODE_TRANSMUTE;
720 isp->smk_inode = nsp;
721 else
722 isp->smk_inode = smack_known_invalid.smk_known;
723 778
724 return; 779 return;
725} 780}
@@ -752,12 +807,15 @@ static int smack_inode_getxattr(struct dentry *dentry, const char *name)
752 */ 807 */
753static int smack_inode_removexattr(struct dentry *dentry, const char *name) 808static int smack_inode_removexattr(struct dentry *dentry, const char *name)
754{ 809{
810 struct inode_smack *isp;
755 struct smk_audit_info ad; 811 struct smk_audit_info ad;
756 int rc = 0; 812 int rc = 0;
757 813
758 if (strcmp(name, XATTR_NAME_SMACK) == 0 || 814 if (strcmp(name, XATTR_NAME_SMACK) == 0 ||
759 strcmp(name, XATTR_NAME_SMACKIPIN) == 0 || 815 strcmp(name, XATTR_NAME_SMACKIPIN) == 0 ||
760 strcmp(name, XATTR_NAME_SMACKIPOUT) == 0) { 816 strcmp(name, XATTR_NAME_SMACKIPOUT) == 0 ||
817 strcmp(name, XATTR_NAME_SMACKEXEC) == 0 ||
818 strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) {
761 if (!capable(CAP_MAC_ADMIN)) 819 if (!capable(CAP_MAC_ADMIN))
762 rc = -EPERM; 820 rc = -EPERM;
763 } else 821 } else
@@ -768,6 +826,11 @@ static int smack_inode_removexattr(struct dentry *dentry, const char *name)
768 if (rc == 0) 826 if (rc == 0)
769 rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad); 827 rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad);
770 828
829 if (rc == 0) {
830 isp = dentry->d_inode->i_security;
831 isp->smk_task = NULL;
832 }
833
771 return rc; 834 return rc;
772} 835}
773 836
@@ -895,7 +958,7 @@ static int smack_file_permission(struct file *file, int mask)
895 */ 958 */
896static int smack_file_alloc_security(struct file *file) 959static int smack_file_alloc_security(struct file *file)
897{ 960{
898 file->f_security = current_security(); 961 file->f_security = smk_of_current();
899 return 0; 962 return 0;
900} 963}
901 964
@@ -1005,7 +1068,7 @@ static int smack_file_fcntl(struct file *file, unsigned int cmd,
1005 */ 1068 */
1006static int smack_file_set_fowner(struct file *file) 1069static int smack_file_set_fowner(struct file *file)
1007{ 1070{
1008 file->f_security = current_security(); 1071 file->f_security = smk_of_current();
1009 return 0; 1072 return 0;
1010} 1073}
1011 1074
@@ -1025,7 +1088,7 @@ static int smack_file_send_sigiotask(struct task_struct *tsk,
1025{ 1088{
1026 struct file *file; 1089 struct file *file;
1027 int rc; 1090 int rc;
1028 char *tsp = tsk->cred->security; 1091 char *tsp = smk_of_task(tsk->cred->security);
1029 struct smk_audit_info ad; 1092 struct smk_audit_info ad;
1030 1093
1031 /* 1094 /*
@@ -1082,7 +1145,9 @@ static int smack_file_receive(struct file *file)
1082 */ 1145 */
1083static int smack_cred_alloc_blank(struct cred *cred, gfp_t gfp) 1146static int smack_cred_alloc_blank(struct cred *cred, gfp_t gfp)
1084{ 1147{
1085 cred->security = NULL; 1148 cred->security = kzalloc(sizeof(struct task_smack), gfp);
1149 if (cred->security == NULL)
1150 return -ENOMEM;
1086 return 0; 1151 return 0;
1087} 1152}
1088 1153
@@ -1097,7 +1162,7 @@ static int smack_cred_alloc_blank(struct cred *cred, gfp_t gfp)
1097 */ 1162 */
1098static void smack_cred_free(struct cred *cred) 1163static void smack_cred_free(struct cred *cred)
1099{ 1164{
1100 cred->security = NULL; 1165 kfree(cred->security);
1101} 1166}
1102 1167
1103/** 1168/**
@@ -1111,7 +1176,16 @@ static void smack_cred_free(struct cred *cred)
1111static int smack_cred_prepare(struct cred *new, const struct cred *old, 1176static int smack_cred_prepare(struct cred *new, const struct cred *old,
1112 gfp_t gfp) 1177 gfp_t gfp)
1113{ 1178{
1114 new->security = old->security; 1179 struct task_smack *old_tsp = old->security;
1180 struct task_smack *new_tsp;
1181
1182 new_tsp = kzalloc(sizeof(struct task_smack), gfp);
1183 if (new_tsp == NULL)
1184 return -ENOMEM;
1185
1186 new_tsp->smk_task = old_tsp->smk_task;
1187 new_tsp->smk_forked = old_tsp->smk_task;
1188 new->security = new_tsp;
1115 return 0; 1189 return 0;
1116} 1190}
1117 1191
@@ -1124,7 +1198,11 @@ static int smack_cred_prepare(struct cred *new, const struct cred *old,
1124 */ 1198 */
1125static void smack_cred_transfer(struct cred *new, const struct cred *old) 1199static void smack_cred_transfer(struct cred *new, const struct cred *old)
1126{ 1200{
1127 new->security = old->security; 1201 struct task_smack *old_tsp = old->security;
1202 struct task_smack *new_tsp = new->security;
1203
1204 new_tsp->smk_task = old_tsp->smk_task;
1205 new_tsp->smk_forked = old_tsp->smk_task;
1128} 1206}
1129 1207
1130/** 1208/**
@@ -1136,12 +1214,13 @@ static void smack_cred_transfer(struct cred *new, const struct cred *old)
1136 */ 1214 */
1137static int smack_kernel_act_as(struct cred *new, u32 secid) 1215static int smack_kernel_act_as(struct cred *new, u32 secid)
1138{ 1216{
1217 struct task_smack *new_tsp = new->security;
1139 char *smack = smack_from_secid(secid); 1218 char *smack = smack_from_secid(secid);
1140 1219
1141 if (smack == NULL) 1220 if (smack == NULL)
1142 return -EINVAL; 1221 return -EINVAL;
1143 1222
1144 new->security = smack; 1223 new_tsp->smk_task = smack;
1145 return 0; 1224 return 0;
1146} 1225}
1147 1226
@@ -1157,8 +1236,10 @@ static int smack_kernel_create_files_as(struct cred *new,
1157 struct inode *inode) 1236 struct inode *inode)
1158{ 1237{
1159 struct inode_smack *isp = inode->i_security; 1238 struct inode_smack *isp = inode->i_security;
1239 struct task_smack *tsp = new->security;
1160 1240
1161 new->security = isp->smk_inode; 1241 tsp->smk_forked = isp->smk_inode;
1242 tsp->smk_task = isp->smk_inode;
1162 return 0; 1243 return 0;
1163} 1244}
1164 1245
@@ -1175,7 +1256,7 @@ static int smk_curacc_on_task(struct task_struct *p, int access)
1175 1256
1176 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); 1257 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
1177 smk_ad_setfield_u_tsk(&ad, p); 1258 smk_ad_setfield_u_tsk(&ad, p);
1178 return smk_curacc(task_security(p), access, &ad); 1259 return smk_curacc(smk_of_task(task_security(p)), access, &ad);
1179} 1260}
1180 1261
1181/** 1262/**
@@ -1221,7 +1302,7 @@ static int smack_task_getsid(struct task_struct *p)
1221 */ 1302 */
1222static void smack_task_getsecid(struct task_struct *p, u32 *secid) 1303static void smack_task_getsecid(struct task_struct *p, u32 *secid)
1223{ 1304{
1224 *secid = smack_to_secid(task_security(p)); 1305 *secid = smack_to_secid(smk_of_task(task_security(p)));
1225} 1306}
1226 1307
1227/** 1308/**
@@ -1333,14 +1414,15 @@ static int smack_task_kill(struct task_struct *p, struct siginfo *info,
1333 * can write the receiver. 1414 * can write the receiver.
1334 */ 1415 */
1335 if (secid == 0) 1416 if (secid == 0)
1336 return smk_curacc(task_security(p), MAY_WRITE, &ad); 1417 return smk_curacc(smk_of_task(task_security(p)), MAY_WRITE,
1418 &ad);
1337 /* 1419 /*
1338 * If the secid isn't 0 we're dealing with some USB IO 1420 * If the secid isn't 0 we're dealing with some USB IO
1339 * specific behavior. This is not clean. For one thing 1421 * specific behavior. This is not clean. For one thing
1340 * we can't take privilege into account. 1422 * we can't take privilege into account.
1341 */ 1423 */
1342 return smk_access(smack_from_secid(secid), task_security(p), 1424 return smk_access(smack_from_secid(secid),
1343 MAY_WRITE, &ad); 1425 smk_of_task(task_security(p)), MAY_WRITE, &ad);
1344} 1426}
1345 1427
1346/** 1428/**
@@ -1352,12 +1434,12 @@ static int smack_task_kill(struct task_struct *p, struct siginfo *info,
1352static int smack_task_wait(struct task_struct *p) 1434static int smack_task_wait(struct task_struct *p)
1353{ 1435{
1354 struct smk_audit_info ad; 1436 struct smk_audit_info ad;
1355 char *sp = current_security(); 1437 char *sp = smk_of_current();
1356 char *tsp = task_security(p); 1438 char *tsp = smk_of_forked(task_security(p));
1357 int rc; 1439 int rc;
1358 1440
1359 /* we don't log here, we can be overriden */ 1441 /* we don't log here, we can be overriden */
1360 rc = smk_access(sp, tsp, MAY_WRITE, NULL); 1442 rc = smk_access(tsp, sp, MAY_WRITE, NULL);
1361 if (rc == 0) 1443 if (rc == 0)
1362 goto out_log; 1444 goto out_log;
1363 1445
@@ -1378,7 +1460,7 @@ static int smack_task_wait(struct task_struct *p)
1378 out_log: 1460 out_log:
1379 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); 1461 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
1380 smk_ad_setfield_u_tsk(&ad, p); 1462 smk_ad_setfield_u_tsk(&ad, p);
1381 smack_log(sp, tsp, MAY_WRITE, rc, &ad); 1463 smack_log(tsp, sp, MAY_WRITE, rc, &ad);
1382 return rc; 1464 return rc;
1383} 1465}
1384 1466
@@ -1392,7 +1474,7 @@ static int smack_task_wait(struct task_struct *p)
1392static void smack_task_to_inode(struct task_struct *p, struct inode *inode) 1474static void smack_task_to_inode(struct task_struct *p, struct inode *inode)
1393{ 1475{
1394 struct inode_smack *isp = inode->i_security; 1476 struct inode_smack *isp = inode->i_security;
1395 isp->smk_inode = task_security(p); 1477 isp->smk_inode = smk_of_task(task_security(p));
1396} 1478}
1397 1479
1398/* 1480/*
@@ -1411,7 +1493,7 @@ static void smack_task_to_inode(struct task_struct *p, struct inode *inode)
1411 */ 1493 */
1412static int smack_sk_alloc_security(struct sock *sk, int family, gfp_t gfp_flags) 1494static int smack_sk_alloc_security(struct sock *sk, int family, gfp_t gfp_flags)
1413{ 1495{
1414 char *csp = current_security(); 1496 char *csp = smk_of_current();
1415 struct socket_smack *ssp; 1497 struct socket_smack *ssp;
1416 1498
1417 ssp = kzalloc(sizeof(struct socket_smack), gfp_flags); 1499 ssp = kzalloc(sizeof(struct socket_smack), gfp_flags);
@@ -1667,10 +1749,13 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name,
1667 ssp->smk_in = sp; 1749 ssp->smk_in = sp;
1668 else if (strcmp(name, XATTR_SMACK_IPOUT) == 0) { 1750 else if (strcmp(name, XATTR_SMACK_IPOUT) == 0) {
1669 ssp->smk_out = sp; 1751 ssp->smk_out = sp;
1670 rc = smack_netlabel(sock->sk, SMACK_CIPSO_SOCKET); 1752 if (sock->sk->sk_family != PF_UNIX) {
1671 if (rc != 0) 1753 rc = smack_netlabel(sock->sk, SMACK_CIPSO_SOCKET);
1672 printk(KERN_WARNING "Smack: \"%s\" netlbl error %d.\n", 1754 if (rc != 0)
1673 __func__, -rc); 1755 printk(KERN_WARNING
1756 "Smack: \"%s\" netlbl error %d.\n",
1757 __func__, -rc);
1758 }
1674 } else 1759 } else
1675 return -EOPNOTSUPP; 1760 return -EOPNOTSUPP;
1676 1761
@@ -1749,7 +1834,7 @@ static int smack_flags_to_may(int flags)
1749 */ 1834 */
1750static int smack_msg_msg_alloc_security(struct msg_msg *msg) 1835static int smack_msg_msg_alloc_security(struct msg_msg *msg)
1751{ 1836{
1752 msg->security = current_security(); 1837 msg->security = smk_of_current();
1753 return 0; 1838 return 0;
1754} 1839}
1755 1840
@@ -1785,7 +1870,7 @@ static int smack_shm_alloc_security(struct shmid_kernel *shp)
1785{ 1870{
1786 struct kern_ipc_perm *isp = &shp->shm_perm; 1871 struct kern_ipc_perm *isp = &shp->shm_perm;
1787 1872
1788 isp->security = current_security(); 1873 isp->security = smk_of_current();
1789 return 0; 1874 return 0;
1790} 1875}
1791 1876
@@ -1908,7 +1993,7 @@ static int smack_sem_alloc_security(struct sem_array *sma)
1908{ 1993{
1909 struct kern_ipc_perm *isp = &sma->sem_perm; 1994 struct kern_ipc_perm *isp = &sma->sem_perm;
1910 1995
1911 isp->security = current_security(); 1996 isp->security = smk_of_current();
1912 return 0; 1997 return 0;
1913} 1998}
1914 1999
@@ -2026,7 +2111,7 @@ static int smack_msg_queue_alloc_security(struct msg_queue *msq)
2026{ 2111{
2027 struct kern_ipc_perm *kisp = &msq->q_perm; 2112 struct kern_ipc_perm *kisp = &msq->q_perm;
2028 2113
2029 kisp->security = current_security(); 2114 kisp->security = smk_of_current();
2030 return 0; 2115 return 0;
2031} 2116}
2032 2117
@@ -2198,9 +2283,11 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
2198 struct super_block *sbp; 2283 struct super_block *sbp;
2199 struct superblock_smack *sbsp; 2284 struct superblock_smack *sbsp;
2200 struct inode_smack *isp; 2285 struct inode_smack *isp;
2201 char *csp = current_security(); 2286 char *csp = smk_of_current();
2202 char *fetched; 2287 char *fetched;
2203 char *final; 2288 char *final;
2289 char trattr[TRANS_TRUE_SIZE];
2290 int transflag = 0;
2204 struct dentry *dp; 2291 struct dentry *dp;
2205 2292
2206 if (inode == NULL) 2293 if (inode == NULL)
@@ -2267,9 +2354,10 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
2267 break; 2354 break;
2268 case SOCKFS_MAGIC: 2355 case SOCKFS_MAGIC:
2269 /* 2356 /*
2270 * Casey says sockets get the smack of the task. 2357 * Socket access is controlled by the socket
2358 * structures associated with the task involved.
2271 */ 2359 */
2272 final = csp; 2360 final = smack_known_star.smk_known;
2273 break; 2361 break;
2274 case PROC_SUPER_MAGIC: 2362 case PROC_SUPER_MAGIC:
2275 /* 2363 /*
@@ -2296,7 +2384,16 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
2296 /* 2384 /*
2297 * This isn't an understood special case. 2385 * This isn't an understood special case.
2298 * Get the value from the xattr. 2386 * Get the value from the xattr.
2299 * 2387 */
2388
2389 /*
2390 * UNIX domain sockets use lower level socket data.
2391 */
2392 if (S_ISSOCK(inode->i_mode)) {
2393 final = smack_known_star.smk_known;
2394 break;
2395 }
2396 /*
2300 * No xattr support means, alas, no SMACK label. 2397 * No xattr support means, alas, no SMACK label.
2301 * Use the aforeapplied default. 2398 * Use the aforeapplied default.
2302 * It would be curious if the label of the task 2399 * It would be curious if the label of the task
@@ -2308,9 +2405,21 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
2308 * Get the dentry for xattr. 2405 * Get the dentry for xattr.
2309 */ 2406 */
2310 dp = dget(opt_dentry); 2407 dp = dget(opt_dentry);
2311 fetched = smk_fetch(inode, dp); 2408 fetched = smk_fetch(XATTR_NAME_SMACK, inode, dp);
2312 if (fetched != NULL) 2409 if (fetched != NULL) {
2313 final = fetched; 2410 final = fetched;
2411 if (S_ISDIR(inode->i_mode)) {
2412 trattr[0] = '\0';
2413 inode->i_op->getxattr(dp,
2414 XATTR_NAME_SMACKTRANSMUTE,
2415 trattr, TRANS_TRUE_SIZE);
2416 if (strncmp(trattr, TRANS_TRUE,
2417 TRANS_TRUE_SIZE) == 0)
2418 transflag = SMK_INODE_TRANSMUTE;
2419 }
2420 }
2421 isp->smk_task = smk_fetch(XATTR_NAME_SMACKEXEC, inode, dp);
2422
2314 dput(dp); 2423 dput(dp);
2315 break; 2424 break;
2316 } 2425 }
@@ -2320,7 +2429,7 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
2320 else 2429 else
2321 isp->smk_inode = final; 2430 isp->smk_inode = final;
2322 2431
2323 isp->smk_flags |= SMK_INODE_INSTANT; 2432 isp->smk_flags |= (SMK_INODE_INSTANT | transflag);
2324 2433
2325unlockandout: 2434unlockandout:
2326 mutex_unlock(&isp->smk_lock); 2435 mutex_unlock(&isp->smk_lock);
@@ -2345,7 +2454,7 @@ static int smack_getprocattr(struct task_struct *p, char *name, char **value)
2345 if (strcmp(name, "current") != 0) 2454 if (strcmp(name, "current") != 0)
2346 return -EINVAL; 2455 return -EINVAL;
2347 2456
2348 cp = kstrdup(task_security(p), GFP_KERNEL); 2457 cp = kstrdup(smk_of_task(task_security(p)), GFP_KERNEL);
2349 if (cp == NULL) 2458 if (cp == NULL)
2350 return -ENOMEM; 2459 return -ENOMEM;
2351 2460
@@ -2369,6 +2478,8 @@ static int smack_getprocattr(struct task_struct *p, char *name, char **value)
2369static int smack_setprocattr(struct task_struct *p, char *name, 2478static int smack_setprocattr(struct task_struct *p, char *name,
2370 void *value, size_t size) 2479 void *value, size_t size)
2371{ 2480{
2481 struct task_smack *tsp;
2482 struct task_smack *oldtsp;
2372 struct cred *new; 2483 struct cred *new;
2373 char *newsmack; 2484 char *newsmack;
2374 2485
@@ -2398,10 +2509,18 @@ static int smack_setprocattr(struct task_struct *p, char *name,
2398 if (newsmack == smack_known_web.smk_known) 2509 if (newsmack == smack_known_web.smk_known)
2399 return -EPERM; 2510 return -EPERM;
2400 2511
2512 oldtsp = p->cred->security;
2401 new = prepare_creds(); 2513 new = prepare_creds();
2402 if (new == NULL) 2514 if (new == NULL)
2403 return -ENOMEM; 2515 return -ENOMEM;
2404 new->security = newsmack; 2516 tsp = kzalloc(sizeof(struct task_smack), GFP_KERNEL);
2517 if (tsp == NULL) {
2518 kfree(new);
2519 return -ENOMEM;
2520 }
2521 tsp->smk_task = newsmack;
2522 tsp->smk_forked = oldtsp->smk_forked;
2523 new->security = tsp;
2405 commit_creds(new); 2524 commit_creds(new);
2406 return size; 2525 return size;
2407} 2526}
@@ -2418,14 +2537,18 @@ static int smack_setprocattr(struct task_struct *p, char *name,
2418static int smack_unix_stream_connect(struct sock *sock, 2537static int smack_unix_stream_connect(struct sock *sock,
2419 struct sock *other, struct sock *newsk) 2538 struct sock *other, struct sock *newsk)
2420{ 2539{
2421 struct inode *sp = SOCK_INODE(sock->sk_socket); 2540 struct socket_smack *ssp = sock->sk_security;
2422 struct inode *op = SOCK_INODE(other->sk_socket); 2541 struct socket_smack *osp = other->sk_security;
2423 struct smk_audit_info ad; 2542 struct smk_audit_info ad;
2543 int rc = 0;
2424 2544
2425 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET); 2545 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET);
2426 smk_ad_setfield_u_net_sk(&ad, other); 2546 smk_ad_setfield_u_net_sk(&ad, other);
2427 return smk_access(smk_of_inode(sp), smk_of_inode(op), 2547
2428 MAY_READWRITE, &ad); 2548 if (!capable(CAP_MAC_OVERRIDE))
2549 rc = smk_access(ssp->smk_out, osp->smk_in, MAY_WRITE, &ad);
2550
2551 return rc;
2429} 2552}
2430 2553
2431/** 2554/**
@@ -2438,13 +2561,18 @@ static int smack_unix_stream_connect(struct sock *sock,
2438 */ 2561 */
2439static int smack_unix_may_send(struct socket *sock, struct socket *other) 2562static int smack_unix_may_send(struct socket *sock, struct socket *other)
2440{ 2563{
2441 struct inode *sp = SOCK_INODE(sock); 2564 struct socket_smack *ssp = sock->sk->sk_security;
2442 struct inode *op = SOCK_INODE(other); 2565 struct socket_smack *osp = other->sk->sk_security;
2443 struct smk_audit_info ad; 2566 struct smk_audit_info ad;
2567 int rc = 0;
2444 2568
2445 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET); 2569 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET);
2446 smk_ad_setfield_u_net_sk(&ad, other->sk); 2570 smk_ad_setfield_u_net_sk(&ad, other->sk);
2447 return smk_access(smk_of_inode(sp), smk_of_inode(op), MAY_WRITE, &ad); 2571
2572 if (!capable(CAP_MAC_OVERRIDE))
2573 rc = smk_access(ssp->smk_out, osp->smk_in, MAY_WRITE, &ad);
2574
2575 return rc;
2448} 2576}
2449 2577
2450/** 2578/**
@@ -2629,7 +2757,7 @@ static int smack_socket_getpeersec_stream(struct socket *sock,
2629 2757
2630/** 2758/**
2631 * smack_socket_getpeersec_dgram - pull in packet label 2759 * smack_socket_getpeersec_dgram - pull in packet label
2632 * @sock: the socket 2760 * @sock: the peer socket
2633 * @skb: packet data 2761 * @skb: packet data
2634 * @secid: pointer to where to put the secid of the packet 2762 * @secid: pointer to where to put the secid of the packet
2635 * 2763 *
@@ -2640,41 +2768,39 @@ static int smack_socket_getpeersec_dgram(struct socket *sock,
2640 2768
2641{ 2769{
2642 struct netlbl_lsm_secattr secattr; 2770 struct netlbl_lsm_secattr secattr;
2643 struct sock *sk; 2771 struct socket_smack *sp;
2644 char smack[SMK_LABELLEN]; 2772 char smack[SMK_LABELLEN];
2645 int family = PF_INET; 2773 int family = PF_UNSPEC;
2646 u32 s; 2774 u32 s = 0; /* 0 is the invalid secid */
2647 int rc; 2775 int rc;
2648 2776
2649 /* 2777 if (skb != NULL) {
2650 * Only works for families with packets. 2778 if (skb->protocol == htons(ETH_P_IP))
2651 */ 2779 family = PF_INET;
2652 if (sock != NULL) { 2780 else if (skb->protocol == htons(ETH_P_IPV6))
2653 sk = sock->sk; 2781 family = PF_INET6;
2654 if (sk->sk_family != PF_INET && sk->sk_family != PF_INET6)
2655 return 0;
2656 family = sk->sk_family;
2657 } 2782 }
2658 /* 2783 if (family == PF_UNSPEC && sock != NULL)
2659 * Translate what netlabel gave us. 2784 family = sock->sk->sk_family;
2660 */
2661 netlbl_secattr_init(&secattr);
2662 rc = netlbl_skbuff_getattr(skb, family, &secattr);
2663 if (rc == 0)
2664 smack_from_secattr(&secattr, smack);
2665 netlbl_secattr_destroy(&secattr);
2666 2785
2667 /* 2786 if (family == PF_UNIX) {
2668 * Give up if we couldn't get anything 2787 sp = sock->sk->sk_security;
2669 */ 2788 s = smack_to_secid(sp->smk_out);
2670 if (rc != 0) 2789 } else if (family == PF_INET || family == PF_INET6) {
2671 return rc; 2790 /*
2672 2791 * Translate what netlabel gave us.
2673 s = smack_to_secid(smack); 2792 */
2793 netlbl_secattr_init(&secattr);
2794 rc = netlbl_skbuff_getattr(skb, family, &secattr);
2795 if (rc == 0) {
2796 smack_from_secattr(&secattr, smack);
2797 s = smack_to_secid(smack);
2798 }
2799 netlbl_secattr_destroy(&secattr);
2800 }
2801 *secid = s;
2674 if (s == 0) 2802 if (s == 0)
2675 return -EINVAL; 2803 return -EINVAL;
2676
2677 *secid = s;
2678 return 0; 2804 return 0;
2679} 2805}
2680 2806
@@ -2695,7 +2821,7 @@ static void smack_sock_graft(struct sock *sk, struct socket *parent)
2695 return; 2821 return;
2696 2822
2697 ssp = sk->sk_security; 2823 ssp = sk->sk_security;
2698 ssp->smk_in = ssp->smk_out = current_security(); 2824 ssp->smk_in = ssp->smk_out = smk_of_current();
2699 /* cssp->smk_packet is already set in smack_inet_csk_clone() */ 2825 /* cssp->smk_packet is already set in smack_inet_csk_clone() */
2700} 2826}
2701 2827
@@ -2816,7 +2942,7 @@ static void smack_inet_csk_clone(struct sock *sk,
2816static int smack_key_alloc(struct key *key, const struct cred *cred, 2942static int smack_key_alloc(struct key *key, const struct cred *cred,
2817 unsigned long flags) 2943 unsigned long flags)
2818{ 2944{
2819 key->security = cred->security; 2945 key->security = smk_of_task(cred->security);
2820 return 0; 2946 return 0;
2821} 2947}
2822 2948
@@ -2845,6 +2971,7 @@ static int smack_key_permission(key_ref_t key_ref,
2845{ 2971{
2846 struct key *keyp; 2972 struct key *keyp;
2847 struct smk_audit_info ad; 2973 struct smk_audit_info ad;
2974 char *tsp = smk_of_task(cred->security);
2848 2975
2849 keyp = key_ref_to_ptr(key_ref); 2976 keyp = key_ref_to_ptr(key_ref);
2850 if (keyp == NULL) 2977 if (keyp == NULL)
@@ -2858,14 +2985,14 @@ static int smack_key_permission(key_ref_t key_ref,
2858 /* 2985 /*
2859 * This should not occur 2986 * This should not occur
2860 */ 2987 */
2861 if (cred->security == NULL) 2988 if (tsp == NULL)
2862 return -EACCES; 2989 return -EACCES;
2863#ifdef CONFIG_AUDIT 2990#ifdef CONFIG_AUDIT
2864 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_KEY); 2991 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_KEY);
2865 ad.a.u.key_struct.key = keyp->serial; 2992 ad.a.u.key_struct.key = keyp->serial;
2866 ad.a.u.key_struct.key_desc = keyp->description; 2993 ad.a.u.key_struct.key_desc = keyp->description;
2867#endif 2994#endif
2868 return smk_access(cred->security, keyp->security, 2995 return smk_access(tsp, keyp->security,
2869 MAY_READWRITE, &ad); 2996 MAY_READWRITE, &ad);
2870} 2997}
2871#endif /* CONFIG_KEYS */ 2998#endif /* CONFIG_KEYS */
@@ -3067,6 +3194,8 @@ struct security_operations smack_ops = {
3067 .sb_mount = smack_sb_mount, 3194 .sb_mount = smack_sb_mount,
3068 .sb_umount = smack_sb_umount, 3195 .sb_umount = smack_sb_umount,
3069 3196
3197 .bprm_set_creds = smack_bprm_set_creds,
3198
3070 .inode_alloc_security = smack_inode_alloc_security, 3199 .inode_alloc_security = smack_inode_alloc_security,
3071 .inode_free_security = smack_inode_free_security, 3200 .inode_free_security = smack_inode_free_security,
3072 .inode_init_security = smack_inode_init_security, 3201 .inode_init_security = smack_inode_init_security,
@@ -3203,9 +3332,16 @@ static __init void init_smack_know_list(void)
3203static __init int smack_init(void) 3332static __init int smack_init(void)
3204{ 3333{
3205 struct cred *cred; 3334 struct cred *cred;
3335 struct task_smack *tsp;
3206 3336
3207 if (!security_module_enable(&smack_ops)) 3337 tsp = kzalloc(sizeof(struct task_smack), GFP_KERNEL);
3338 if (tsp == NULL)
3339 return -ENOMEM;
3340
3341 if (!security_module_enable(&smack_ops)) {
3342 kfree(tsp);
3208 return 0; 3343 return 0;
3344 }
3209 3345
3210 printk(KERN_INFO "Smack: Initializing.\n"); 3346 printk(KERN_INFO "Smack: Initializing.\n");
3211 3347
@@ -3213,7 +3349,9 @@ static __init int smack_init(void)
3213 * Set the security state for the initial task. 3349 * Set the security state for the initial task.
3214 */ 3350 */
3215 cred = (struct cred *) current->cred; 3351 cred = (struct cred *) current->cred;
3216 cred->security = &smack_known_floor.smk_known; 3352 tsp->smk_forked = smack_known_floor.smk_known;
3353 tsp->smk_task = smack_known_floor.smk_known;
3354 cred->security = tsp;
3217 3355
3218 /* initialize the smack_know_list */ 3356 /* initialize the smack_know_list */
3219 init_smack_know_list(); 3357 init_smack_know_list();
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
index dc1fd6239f24..362d5eda948b 100644
--- a/security/smack/smackfs.c
+++ b/security/smack/smackfs.c
@@ -109,9 +109,12 @@ const char *smack_cipso_option = SMACK_CIPSO_OPTION;
109 * SMK_ACCESSLEN: Maximum length for a rule access field 109 * SMK_ACCESSLEN: Maximum length for a rule access field
110 * SMK_LOADLEN: Smack rule length 110 * SMK_LOADLEN: Smack rule length
111 */ 111 */
112#define SMK_ACCESS "rwxa" 112#define SMK_OACCESS "rwxa"
113#define SMK_ACCESSLEN (sizeof(SMK_ACCESS) - 1) 113#define SMK_ACCESS "rwxat"
114#define SMK_LOADLEN (SMK_LABELLEN + SMK_LABELLEN + SMK_ACCESSLEN) 114#define SMK_OACCESSLEN (sizeof(SMK_OACCESS) - 1)
115#define SMK_ACCESSLEN (sizeof(SMK_ACCESS) - 1)
116#define SMK_OLOADLEN (SMK_LABELLEN + SMK_LABELLEN + SMK_OACCESSLEN)
117#define SMK_LOADLEN (SMK_LABELLEN + SMK_LABELLEN + SMK_ACCESSLEN)
115 118
116/** 119/**
117 * smk_netlabel_audit_set - fill a netlbl_audit struct 120 * smk_netlabel_audit_set - fill a netlbl_audit struct
@@ -121,7 +124,7 @@ static void smk_netlabel_audit_set(struct netlbl_audit *nap)
121{ 124{
122 nap->loginuid = audit_get_loginuid(current); 125 nap->loginuid = audit_get_loginuid(current);
123 nap->sessionid = audit_get_sessionid(current); 126 nap->sessionid = audit_get_sessionid(current);
124 nap->secid = smack_to_secid(current_security()); 127 nap->secid = smack_to_secid(smk_of_current());
125} 128}
126 129
127/* 130/*
@@ -175,6 +178,8 @@ static int load_seq_show(struct seq_file *s, void *v)
175 seq_putc(s, 'x'); 178 seq_putc(s, 'x');
176 if (srp->smk_access & MAY_APPEND) 179 if (srp->smk_access & MAY_APPEND)
177 seq_putc(s, 'a'); 180 seq_putc(s, 'a');
181 if (srp->smk_access & MAY_TRANSMUTE)
182 seq_putc(s, 't');
178 if (srp->smk_access == 0) 183 if (srp->smk_access == 0)
179 seq_putc(s, '-'); 184 seq_putc(s, '-');
180 185
@@ -273,10 +278,15 @@ static ssize_t smk_write_load(struct file *file, const char __user *buf,
273 if (!capable(CAP_MAC_ADMIN)) 278 if (!capable(CAP_MAC_ADMIN))
274 return -EPERM; 279 return -EPERM;
275 280
276 if (*ppos != 0 || count != SMK_LOADLEN) 281 if (*ppos != 0)
282 return -EINVAL;
283 /*
284 * Minor hack for backward compatability
285 */
286 if (count < (SMK_OLOADLEN) || count > SMK_LOADLEN)
277 return -EINVAL; 287 return -EINVAL;
278 288
279 data = kzalloc(count, GFP_KERNEL); 289 data = kzalloc(SMK_LOADLEN, GFP_KERNEL);
280 if (data == NULL) 290 if (data == NULL)
281 return -ENOMEM; 291 return -ENOMEM;
282 292
@@ -285,6 +295,12 @@ static ssize_t smk_write_load(struct file *file, const char __user *buf,
285 goto out; 295 goto out;
286 } 296 }
287 297
298 /*
299 * More on the minor hack for backward compatability
300 */
301 if (count == (SMK_OLOADLEN))
302 data[SMK_OLOADLEN] = '-';
303
288 rule = kzalloc(sizeof(*rule), GFP_KERNEL); 304 rule = kzalloc(sizeof(*rule), GFP_KERNEL);
289 if (rule == NULL) { 305 if (rule == NULL) {
290 rc = -ENOMEM; 306 rc = -ENOMEM;
@@ -345,6 +361,17 @@ static ssize_t smk_write_load(struct file *file, const char __user *buf,
345 goto out_free_rule; 361 goto out_free_rule;
346 } 362 }
347 363
364 switch (data[SMK_LABELLEN + SMK_LABELLEN + 4]) {
365 case '-':
366 break;
367 case 't':
368 case 'T':
369 rule->smk_access |= MAY_TRANSMUTE;
370 break;
371 default:
372 goto out_free_rule;
373 }
374
348 rc = smk_set_access(rule); 375 rc = smk_set_access(rule);
349 376
350 if (!rc) 377 if (!rc)
@@ -1160,7 +1187,7 @@ static ssize_t smk_write_onlycap(struct file *file, const char __user *buf,
1160 size_t count, loff_t *ppos) 1187 size_t count, loff_t *ppos)
1161{ 1188{
1162 char in[SMK_LABELLEN]; 1189 char in[SMK_LABELLEN];
1163 char *sp = current->cred->security; 1190 char *sp = smk_of_task(current->cred->security);
1164 1191
1165 if (!capable(CAP_MAC_ADMIN)) 1192 if (!capable(CAP_MAC_ADMIN))
1166 return -EPERM; 1193 return -EPERM;