aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorCasey Schaufler <casey@schaufler-ca.com>2013-05-22 21:43:03 -0400
committerCasey Schaufler <casey@schaufler-ca.com>2013-05-28 13:08:32 -0400
commit2f823ff8bec03a1e6f9e11fd0c4d54e4c7d09532 (patch)
tree8ba448a6cc7b5cdc4d173390721eda3f83a3e012 /security
parentc673944347edfd4362b10eea11ac384a582b1cf5 (diff)
Smack: Improve access check performance
Each Smack label that the kernel has seen is added to a list of labels. The list of access rules for a given subject label hangs off of the label list entry for the label. This patch changes the structures that contain subject labels to point at the label list entry rather that the label itself. Doing so removes a label list lookup in smk_access() that was accounting for the largest single chunk of Smack overhead. Targeted for git://git.gitorious.org/smack-next/kernel.git Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
Diffstat (limited to 'security')
-rw-r--r--security/smack/smack.h108
-rw-r--r--security/smack/smack_access.c41
-rw-r--r--security/smack/smack_lsm.c331
-rw-r--r--security/smack/smackfs.c51
4 files changed, 282 insertions, 249 deletions
diff --git a/security/smack/smack.h b/security/smack/smack.h
index bb28e099abfe..159f25bfcf45 100644
--- a/security/smack/smack.h
+++ b/security/smack/smack.h
@@ -29,6 +29,38 @@
29#define SMK_LONGLABEL 256 29#define SMK_LONGLABEL 256
30 30
31/* 31/*
32 * This is the repository for labels seen so that it is
33 * not necessary to keep allocating tiny chuncks of memory
34 * and so that they can be shared.
35 *
36 * Labels are never modified in place. Anytime a label
37 * is imported (e.g. xattrset on a file) the list is checked
38 * for it and it is added if it doesn't exist. The address
39 * is passed out in either case. Entries are added, but
40 * never deleted.
41 *
42 * Since labels are hanging around anyway it doesn't
43 * hurt to maintain a secid for those awkward situations
44 * where kernel components that ought to use LSM independent
45 * interfaces don't. The secid should go away when all of
46 * these components have been repaired.
47 *
48 * The cipso value associated with the label gets stored here, too.
49 *
50 * Keep the access rules for this subject label here so that
51 * the entire set of rules does not need to be examined every
52 * time.
53 */
54struct smack_known {
55 struct list_head list;
56 char *smk_known;
57 u32 smk_secid;
58 struct netlbl_lsm_secattr smk_netlabel; /* on wire labels */
59 struct list_head smk_rules; /* access rules */
60 struct mutex smk_rules_lock; /* lock for rules */
61};
62
63/*
32 * Maximum number of bytes for the levels in a CIPSO IP option. 64 * Maximum number of bytes for the levels in a CIPSO IP option.
33 * Why 23? CIPSO is constrained to 30, so a 32 byte buffer is 65 * Why 23? CIPSO is constrained to 30, so a 32 byte buffer is
34 * bigger than can be used, and 24 is the next lower multiple 66 * bigger than can be used, and 24 is the next lower multiple
@@ -46,25 +78,25 @@ struct superblock_smack {
46}; 78};
47 79
48struct socket_smack { 80struct socket_smack {
49 char *smk_out; /* outbound label */ 81 struct smack_known *smk_out; /* outbound label */
50 char *smk_in; /* inbound label */ 82 char *smk_in; /* inbound label */
51 char *smk_packet; /* TCP peer label */ 83 char *smk_packet; /* TCP peer label */
52}; 84};
53 85
54/* 86/*
55 * Inode smack data 87 * Inode smack data
56 */ 88 */
57struct inode_smack { 89struct inode_smack {
58 char *smk_inode; /* label of the fso */ 90 char *smk_inode; /* label of the fso */
59 char *smk_task; /* label of the task */ 91 struct smack_known *smk_task; /* label of the task */
60 char *smk_mmap; /* label of the mmap domain */ 92 struct smack_known *smk_mmap; /* label of the mmap domain */
61 struct mutex smk_lock; /* initialization lock */ 93 struct mutex smk_lock; /* initialization lock */
62 int smk_flags; /* smack inode flags */ 94 int smk_flags; /* smack inode flags */
63}; 95};
64 96
65struct task_smack { 97struct task_smack {
66 char *smk_task; /* label for access control */ 98 struct smack_known *smk_task; /* label for access control */
67 char *smk_forked; /* label when forked */ 99 struct smack_known *smk_forked; /* label when forked */
68 struct list_head smk_rules; /* per task access rules */ 100 struct list_head smk_rules; /* per task access rules */
69 struct mutex smk_rules_lock; /* lock for the rules */ 101 struct mutex smk_rules_lock; /* lock for the rules */
70}; 102};
@@ -78,7 +110,7 @@ struct task_smack {
78 */ 110 */
79struct smack_rule { 111struct smack_rule {
80 struct list_head list; 112 struct list_head list;
81 char *smk_subject; 113 struct smack_known *smk_subject;
82 char *smk_object; 114 char *smk_object;
83 int smk_access; 115 int smk_access;
84}; 116};
@@ -101,39 +133,7 @@ struct smk_port_label {
101 struct sock *smk_sock; /* socket initialized on */ 133 struct sock *smk_sock; /* socket initialized on */
102 unsigned short smk_port; /* the port number */ 134 unsigned short smk_port; /* the port number */
103 char *smk_in; /* incoming label */ 135 char *smk_in; /* incoming label */
104 char *smk_out; /* outgoing label */ 136 struct smack_known *smk_out; /* outgoing label */
105};
106
107/*
108 * This is the repository for labels seen so that it is
109 * not necessary to keep allocating tiny chuncks of memory
110 * and so that they can be shared.
111 *
112 * Labels are never modified in place. Anytime a label
113 * is imported (e.g. xattrset on a file) the list is checked
114 * for it and it is added if it doesn't exist. The address
115 * is passed out in either case. Entries are added, but
116 * never deleted.
117 *
118 * Since labels are hanging around anyway it doesn't
119 * hurt to maintain a secid for those awkward situations
120 * where kernel components that ought to use LSM independent
121 * interfaces don't. The secid should go away when all of
122 * these components have been repaired.
123 *
124 * The cipso value associated with the label gets stored here, too.
125 *
126 * Keep the access rules for this subject label here so that
127 * the entire set of rules does not need to be examined every
128 * time.
129 */
130struct smack_known {
131 struct list_head list;
132 char *smk_known;
133 u32 smk_secid;
134 struct netlbl_lsm_secattr smk_netlabel; /* on wire labels */
135 struct list_head smk_rules; /* access rules */
136 struct mutex smk_rules_lock; /* lock for rules */
137}; 137};
138 138
139/* 139/*
@@ -214,9 +214,9 @@ struct inode_smack *new_inode_smack(char *);
214 * These functions are in smack_access.c 214 * These functions are in smack_access.c
215 */ 215 */
216int smk_access_entry(char *, char *, struct list_head *); 216int smk_access_entry(char *, char *, struct list_head *);
217int smk_access(char *, char *, int, struct smk_audit_info *); 217int smk_access(struct smack_known *, char *, int, struct smk_audit_info *);
218int smk_curacc(char *, u32, struct smk_audit_info *); 218int smk_curacc(char *, u32, struct smk_audit_info *);
219char *smack_from_secid(const u32); 219struct smack_known *smack_from_secid(const u32);
220char *smk_parse_smack(const char *string, int len); 220char *smk_parse_smack(const char *string, int len);
221int smk_netlbl_mls(int, char *, struct netlbl_lsm_secattr *, int); 221int smk_netlbl_mls(int, char *, struct netlbl_lsm_secattr *, int);
222char *smk_import(const char *, int); 222char *smk_import(const char *, int);
@@ -229,7 +229,7 @@ u32 smack_to_secid(const char *);
229 */ 229 */
230extern int smack_cipso_direct; 230extern int smack_cipso_direct;
231extern int smack_cipso_mapped; 231extern int smack_cipso_mapped;
232extern char *smack_net_ambient; 232extern struct smack_known *smack_net_ambient;
233extern char *smack_onlycap; 233extern char *smack_onlycap;
234extern const char *smack_cipso_option; 234extern const char *smack_cipso_option;
235 235
@@ -265,17 +265,17 @@ static inline char *smk_of_inode(const struct inode *isp)
265} 265}
266 266
267/* 267/*
268 * Present a pointer to the smack label in an task blob. 268 * Present a pointer to the smack label entry in an task blob.
269 */ 269 */
270static inline char *smk_of_task(const struct task_smack *tsp) 270static inline struct smack_known *smk_of_task(const struct task_smack *tsp)
271{ 271{
272 return tsp->smk_task; 272 return tsp->smk_task;
273} 273}
274 274
275/* 275/*
276 * Present a pointer to the forked smack label in an task blob. 276 * Present a pointer to the forked smack label entry in an task blob.
277 */ 277 */
278static inline char *smk_of_forked(const struct task_smack *tsp) 278static inline struct smack_known *smk_of_forked(const struct task_smack *tsp)
279{ 279{
280 return tsp->smk_forked; 280 return tsp->smk_forked;
281} 281}
@@ -283,7 +283,7 @@ static inline char *smk_of_forked(const struct task_smack *tsp)
283/* 283/*
284 * Present a pointer to the smack label in the current task blob. 284 * Present a pointer to the smack label in the current task blob.
285 */ 285 */
286static inline char *smk_of_current(void) 286static inline struct smack_known *smk_of_current(void)
287{ 287{
288 return smk_of_task(current_security()); 288 return smk_of_task(current_security());
289} 289}
@@ -294,9 +294,11 @@ static inline char *smk_of_current(void)
294 */ 294 */
295static inline int smack_privileged(int cap) 295static inline int smack_privileged(int cap)
296{ 296{
297 struct smack_known *skp = smk_of_current();
298
297 if (!capable(cap)) 299 if (!capable(cap))
298 return 0; 300 return 0;
299 if (smack_onlycap == NULL || smack_onlycap == smk_of_current()) 301 if (smack_onlycap == NULL || smack_onlycap == skp->smk_known)
300 return 1; 302 return 1;
301 return 0; 303 return 0;
302} 304}
diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c
index 2e397a88d410..53f2327a592f 100644
--- a/security/smack/smack_access.c
+++ b/security/smack/smack_access.c
@@ -93,7 +93,7 @@ int smk_access_entry(char *subject_label, char *object_label,
93 93
94 list_for_each_entry_rcu(srp, rule_list, list) { 94 list_for_each_entry_rcu(srp, rule_list, list) {
95 if (srp->smk_object == object_label && 95 if (srp->smk_object == object_label &&
96 srp->smk_subject == subject_label) { 96 srp->smk_subject->smk_known == subject_label) {
97 may = srp->smk_access; 97 may = srp->smk_access;
98 break; 98 break;
99 } 99 }
@@ -104,7 +104,7 @@ int smk_access_entry(char *subject_label, char *object_label,
104 104
105/** 105/**
106 * smk_access - determine if a subject has a specific access to an object 106 * smk_access - determine if a subject has a specific access to an object
107 * @subject_label: a pointer to the subject's Smack label 107 * @subject_known: a pointer to the subject's Smack label entry
108 * @object_label: a pointer to the object's Smack label 108 * @object_label: a pointer to the object's Smack label
109 * @request: the access requested, in "MAY" format 109 * @request: the access requested, in "MAY" format
110 * @a : a pointer to the audit data 110 * @a : a pointer to the audit data
@@ -115,10 +115,9 @@ int smk_access_entry(char *subject_label, char *object_label,
115 * 115 *
116 * Smack labels are shared on smack_list 116 * Smack labels are shared on smack_list
117 */ 117 */
118int smk_access(char *subject_label, char *object_label, int request, 118int smk_access(struct smack_known *subject_known, char *object_label,
119 struct smk_audit_info *a) 119 int request, struct smk_audit_info *a)
120{ 120{
121 struct smack_known *skp;
122 int may = MAY_NOT; 121 int may = MAY_NOT;
123 int rc = 0; 122 int rc = 0;
124 123
@@ -127,7 +126,7 @@ int smk_access(char *subject_label, char *object_label, int request,
127 * 126 *
128 * A star subject can't access any object. 127 * A star subject can't access any object.
129 */ 128 */
130 if (subject_label == smack_known_star.smk_known) { 129 if (subject_known == &smack_known_star) {
131 rc = -EACCES; 130 rc = -EACCES;
132 goto out_audit; 131 goto out_audit;
133 } 132 }
@@ -137,7 +136,7 @@ int smk_access(char *subject_label, char *object_label, int request,
137 * An internet subject can access any object. 136 * An internet subject can access any object.
138 */ 137 */
139 if (object_label == smack_known_web.smk_known || 138 if (object_label == smack_known_web.smk_known ||
140 subject_label == smack_known_web.smk_known) 139 subject_known == &smack_known_web)
141 goto out_audit; 140 goto out_audit;
142 /* 141 /*
143 * A star object can be accessed by any subject. 142 * A star object can be accessed by any subject.
@@ -148,7 +147,7 @@ int smk_access(char *subject_label, char *object_label, int request,
148 * An object can be accessed in any way by a subject 147 * An object can be accessed in any way by a subject
149 * with the same label. 148 * with the same label.
150 */ 149 */
151 if (subject_label == object_label) 150 if (subject_known->smk_known == object_label)
152 goto out_audit; 151 goto out_audit;
153 /* 152 /*
154 * A hat subject can read any object. 153 * A hat subject can read any object.
@@ -157,7 +156,7 @@ int smk_access(char *subject_label, char *object_label, int request,
157 if ((request & MAY_ANYREAD) == request) { 156 if ((request & MAY_ANYREAD) == request) {
158 if (object_label == smack_known_floor.smk_known) 157 if (object_label == smack_known_floor.smk_known)
159 goto out_audit; 158 goto out_audit;
160 if (subject_label == smack_known_hat.smk_known) 159 if (subject_known == &smack_known_hat)
161 goto out_audit; 160 goto out_audit;
162 } 161 }
163 /* 162 /*
@@ -167,9 +166,9 @@ int smk_access(char *subject_label, char *object_label, int request,
167 * good. A negative response from smk_access_entry() 166 * good. A negative response from smk_access_entry()
168 * indicates there is no entry for this pair. 167 * indicates there is no entry for this pair.
169 */ 168 */
170 skp = smk_find_entry(subject_label);
171 rcu_read_lock(); 169 rcu_read_lock();
172 may = smk_access_entry(subject_label, object_label, &skp->smk_rules); 170 may = smk_access_entry(subject_known->smk_known, object_label,
171 &subject_known->smk_rules);
173 rcu_read_unlock(); 172 rcu_read_unlock();
174 173
175 if (may > 0 && (request & may) == request) 174 if (may > 0 && (request & may) == request)
@@ -179,7 +178,8 @@ int smk_access(char *subject_label, char *object_label, int request,
179out_audit: 178out_audit:
180#ifdef CONFIG_AUDIT 179#ifdef CONFIG_AUDIT
181 if (a) 180 if (a)
182 smack_log(subject_label, object_label, request, rc, a); 181 smack_log(subject_known->smk_known, object_label, request,
182 rc, a);
183#endif 183#endif
184 return rc; 184 return rc;
185} 185}
@@ -198,20 +198,21 @@ out_audit:
198int smk_curacc(char *obj_label, u32 mode, struct smk_audit_info *a) 198int smk_curacc(char *obj_label, u32 mode, struct smk_audit_info *a)
199{ 199{
200 struct task_smack *tsp = current_security(); 200 struct task_smack *tsp = current_security();
201 char *sp = smk_of_task(tsp); 201 struct smack_known *skp = smk_of_task(tsp);
202 int may; 202 int may;
203 int rc; 203 int rc;
204 204
205 /* 205 /*
206 * Check the global rule list 206 * Check the global rule list
207 */ 207 */
208 rc = smk_access(sp, obj_label, mode, NULL); 208 rc = smk_access(skp, obj_label, mode, NULL);
209 if (rc == 0) { 209 if (rc == 0) {
210 /* 210 /*
211 * If there is an entry in the task's rule list 211 * If there is an entry in the task's rule list
212 * it can further restrict access. 212 * it can further restrict access.
213 */ 213 */
214 may = smk_access_entry(sp, obj_label, &tsp->smk_rules); 214 may = smk_access_entry(skp->smk_known, obj_label,
215 &tsp->smk_rules);
215 if (may < 0) 216 if (may < 0)
216 goto out_audit; 217 goto out_audit;
217 if ((mode & may) == mode) 218 if ((mode & may) == mode)
@@ -228,7 +229,7 @@ int smk_curacc(char *obj_label, u32 mode, struct smk_audit_info *a)
228out_audit: 229out_audit:
229#ifdef CONFIG_AUDIT 230#ifdef CONFIG_AUDIT
230 if (a) 231 if (a)
231 smack_log(sp, obj_label, mode, rc, a); 232 smack_log(skp->smk_known, obj_label, mode, rc, a);
232#endif 233#endif
233 return rc; 234 return rc;
234} 235}
@@ -513,10 +514,10 @@ char *smk_import(const char *string, int len)
513 * smack_from_secid - find the Smack label associated with a secid 514 * smack_from_secid - find the Smack label associated with a secid
514 * @secid: an integer that might be associated with a Smack label 515 * @secid: an integer that might be associated with a Smack label
515 * 516 *
516 * Returns a pointer to the appropriate Smack label if there is one, 517 * Returns a pointer to the appropriate Smack label entry if there is one,
517 * otherwise a pointer to the invalid Smack label. 518 * otherwise a pointer to the invalid Smack label.
518 */ 519 */
519char *smack_from_secid(const u32 secid) 520struct smack_known *smack_from_secid(const u32 secid)
520{ 521{
521 struct smack_known *skp; 522 struct smack_known *skp;
522 523
@@ -524,7 +525,7 @@ char *smack_from_secid(const u32 secid)
524 list_for_each_entry_rcu(skp, &smack_known_list, list) { 525 list_for_each_entry_rcu(skp, &smack_known_list, list) {
525 if (skp->smk_secid == secid) { 526 if (skp->smk_secid == secid) {
526 rcu_read_unlock(); 527 rcu_read_unlock();
527 return skp->smk_known; 528 return skp;
528 } 529 }
529 } 530 }
530 531
@@ -533,7 +534,7 @@ char *smack_from_secid(const u32 secid)
533 * of a secid that is not on the list. 534 * of a secid that is not on the list.
534 */ 535 */
535 rcu_read_unlock(); 536 rcu_read_unlock();
536 return smack_known_invalid.smk_known; 537 return &smack_known_invalid;
537} 538}
538 539
539/** 540/**
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 609e89de3c24..3669d9f9824e 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -62,11 +62,12 @@ LIST_HEAD(smk_ipv6_port_list);
62 * Returns a pointer to the master list entry for the Smack label 62 * Returns a pointer to the master list entry for the Smack label
63 * or NULL if there was no label to fetch. 63 * or NULL if there was no label to fetch.
64 */ 64 */
65static char *smk_fetch(const char *name, struct inode *ip, struct dentry *dp) 65static struct smack_known *smk_fetch(const char *name, struct inode *ip,
66 struct dentry *dp)
66{ 67{
67 int rc; 68 int rc;
68 char *buffer; 69 char *buffer;
69 char *result = NULL; 70 struct smack_known *skp = NULL;
70 71
71 if (ip->i_op->getxattr == NULL) 72 if (ip->i_op->getxattr == NULL)
72 return NULL; 73 return NULL;
@@ -77,11 +78,11 @@ static char *smk_fetch(const char *name, struct inode *ip, struct dentry *dp)
77 78
78 rc = ip->i_op->getxattr(dp, name, buffer, SMK_LONGLABEL); 79 rc = ip->i_op->getxattr(dp, name, buffer, SMK_LONGLABEL);
79 if (rc > 0) 80 if (rc > 0)
80 result = smk_import(buffer, rc); 81 skp = smk_import_entry(buffer, rc);
81 82
82 kfree(buffer); 83 kfree(buffer);
83 84
84 return result; 85 return skp;
85} 86}
86 87
87/** 88/**
@@ -111,7 +112,8 @@ struct inode_smack *new_inode_smack(char *smack)
111 * 112 *
112 * Returns the new blob or NULL if there's no memory available 113 * Returns the new blob or NULL if there's no memory available
113 */ 114 */
114static struct task_smack *new_task_smack(char *task, char *forked, gfp_t gfp) 115static struct task_smack *new_task_smack(struct smack_known *task,
116 struct smack_known *forked, gfp_t gfp)
115{ 117{
116 struct task_smack *tsp; 118 struct task_smack *tsp;
117 119
@@ -173,17 +175,17 @@ static int smack_ptrace_access_check(struct task_struct *ctp, unsigned int mode)
173{ 175{
174 int rc; 176 int rc;
175 struct smk_audit_info ad; 177 struct smk_audit_info ad;
176 char *tsp; 178 struct smack_known *skp;
177 179
178 rc = cap_ptrace_access_check(ctp, mode); 180 rc = cap_ptrace_access_check(ctp, mode);
179 if (rc != 0) 181 if (rc != 0)
180 return rc; 182 return rc;
181 183
182 tsp = smk_of_task(task_security(ctp)); 184 skp = smk_of_task(task_security(ctp));
183 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); 185 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
184 smk_ad_setfield_u_tsk(&ad, ctp); 186 smk_ad_setfield_u_tsk(&ad, ctp);
185 187
186 rc = smk_curacc(tsp, MAY_READWRITE, &ad); 188 rc = smk_curacc(skp->smk_known, MAY_READWRITE, &ad);
187 return rc; 189 return rc;
188} 190}
189 191
@@ -199,17 +201,17 @@ static int smack_ptrace_traceme(struct task_struct *ptp)
199{ 201{
200 int rc; 202 int rc;
201 struct smk_audit_info ad; 203 struct smk_audit_info ad;
202 char *tsp; 204 struct smack_known *skp;
203 205
204 rc = cap_ptrace_traceme(ptp); 206 rc = cap_ptrace_traceme(ptp);
205 if (rc != 0) 207 if (rc != 0)
206 return rc; 208 return rc;
207 209
208 tsp = smk_of_task(task_security(ptp)); 210 skp = smk_of_task(task_security(ptp));
209 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); 211 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
210 smk_ad_setfield_u_tsk(&ad, ptp); 212 smk_ad_setfield_u_tsk(&ad, ptp);
211 213
212 rc = smk_curacc(tsp, MAY_READWRITE, &ad); 214 rc = smk_curacc(skp->smk_known, MAY_READWRITE, &ad);
213 return rc; 215 return rc;
214} 216}
215 217
@@ -224,12 +226,12 @@ static int smack_ptrace_traceme(struct task_struct *ptp)
224static int smack_syslog(int typefrom_file) 226static int smack_syslog(int typefrom_file)
225{ 227{
226 int rc = 0; 228 int rc = 0;
227 char *sp = smk_of_current(); 229 struct smack_known *skp = smk_of_current();
228 230
229 if (smack_privileged(CAP_MAC_OVERRIDE)) 231 if (smack_privileged(CAP_MAC_OVERRIDE))
230 return 0; 232 return 0;
231 233
232 if (sp != smack_known_floor.smk_known) 234 if (skp != &smack_known_floor)
233 rc = -EACCES; 235 rc = -EACCES;
234 236
235 return rc; 237 return rc;
@@ -533,7 +535,9 @@ static int smack_bprm_secureexec(struct linux_binprm *bprm)
533 */ 535 */
534static int smack_inode_alloc_security(struct inode *inode) 536static int smack_inode_alloc_security(struct inode *inode)
535{ 537{
536 inode->i_security = new_inode_smack(smk_of_current()); 538 struct smack_known *skp = smk_of_current();
539
540 inode->i_security = new_inode_smack(skp->smk_known);
537 if (inode->i_security == NULL) 541 if (inode->i_security == NULL)
538 return -ENOMEM; 542 return -ENOMEM;
539 return 0; 543 return 0;
@@ -566,9 +570,8 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir,
566 const struct qstr *qstr, char **name, 570 const struct qstr *qstr, char **name,
567 void **value, size_t *len) 571 void **value, size_t *len)
568{ 572{
569 struct smack_known *skp;
570 struct inode_smack *issp = inode->i_security; 573 struct inode_smack *issp = inode->i_security;
571 char *csp = smk_of_current(); 574 struct smack_known *skp = smk_of_current();
572 char *isp = smk_of_inode(inode); 575 char *isp = smk_of_inode(inode);
573 char *dsp = smk_of_inode(dir); 576 char *dsp = smk_of_inode(dir);
574 int may; 577 int may;
@@ -580,9 +583,8 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir,
580 } 583 }
581 584
582 if (value) { 585 if (value) {
583 skp = smk_find_entry(csp);
584 rcu_read_lock(); 586 rcu_read_lock();
585 may = smk_access_entry(csp, dsp, &skp->smk_rules); 587 may = smk_access_entry(skp->smk_known, dsp, &skp->smk_rules);
586 rcu_read_unlock(); 588 rcu_read_unlock();
587 589
588 /* 590 /*
@@ -871,29 +873,31 @@ static int smack_inode_setxattr(struct dentry *dentry, const char *name,
871static void smack_inode_post_setxattr(struct dentry *dentry, const char *name, 873static void smack_inode_post_setxattr(struct dentry *dentry, const char *name,
872 const void *value, size_t size, int flags) 874 const void *value, size_t size, int flags)
873{ 875{
874 char *nsp; 876 struct smack_known *skp;
875 struct inode_smack *isp = dentry->d_inode->i_security; 877 struct inode_smack *isp = dentry->d_inode->i_security;
876 878
879 if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) {
880 isp->smk_flags |= SMK_INODE_TRANSMUTE;
881 return;
882 }
883
884 skp = smk_import_entry(value, size);
877 if (strcmp(name, XATTR_NAME_SMACK) == 0) { 885 if (strcmp(name, XATTR_NAME_SMACK) == 0) {
878 nsp = smk_import(value, size); 886 if (skp != NULL)
879 if (nsp != NULL) 887 isp->smk_inode = skp->smk_known;
880 isp->smk_inode = nsp;
881 else 888 else
882 isp->smk_inode = smack_known_invalid.smk_known; 889 isp->smk_inode = smack_known_invalid.smk_known;
883 } else if (strcmp(name, XATTR_NAME_SMACKEXEC) == 0) { 890 } else if (strcmp(name, XATTR_NAME_SMACKEXEC) == 0) {
884 nsp = smk_import(value, size); 891 if (skp != NULL)
885 if (nsp != NULL) 892 isp->smk_task = skp;
886 isp->smk_task = nsp;
887 else 893 else
888 isp->smk_task = smack_known_invalid.smk_known; 894 isp->smk_task = &smack_known_invalid;
889 } else if (strcmp(name, XATTR_NAME_SMACKMMAP) == 0) { 895 } else if (strcmp(name, XATTR_NAME_SMACKMMAP) == 0) {
890 nsp = smk_import(value, size); 896 if (skp != NULL)
891 if (nsp != NULL) 897 isp->smk_mmap = skp;
892 isp->smk_mmap = nsp;
893 else 898 else
894 isp->smk_mmap = smack_known_invalid.smk_known; 899 isp->smk_mmap = &smack_known_invalid;
895 } else if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) 900 }
896 isp->smk_flags |= SMK_INODE_TRANSMUTE;
897 901
898 return; 902 return;
899} 903}
@@ -999,7 +1003,7 @@ static int smack_inode_getsecurity(const struct inode *inode,
999 if (strcmp(name, XATTR_SMACK_IPIN) == 0) 1003 if (strcmp(name, XATTR_SMACK_IPIN) == 0)
1000 isp = ssp->smk_in; 1004 isp = ssp->smk_in;
1001 else if (strcmp(name, XATTR_SMACK_IPOUT) == 0) 1005 else if (strcmp(name, XATTR_SMACK_IPOUT) == 0)
1002 isp = ssp->smk_out; 1006 isp = ssp->smk_out->smk_known;
1003 else 1007 else
1004 return -EOPNOTSUPP; 1008 return -EOPNOTSUPP;
1005 1009
@@ -1079,7 +1083,9 @@ static int smack_file_permission(struct file *file, int mask)
1079 */ 1083 */
1080static int smack_file_alloc_security(struct file *file) 1084static int smack_file_alloc_security(struct file *file)
1081{ 1085{
1082 file->f_security = smk_of_current(); 1086 struct smack_known *skp = smk_of_current();
1087
1088 file->f_security = skp->smk_known;
1083 return 0; 1089 return 0;
1084} 1090}
1085 1091
@@ -1190,10 +1196,9 @@ static int smack_mmap_file(struct file *file,
1190 unsigned long flags) 1196 unsigned long flags)
1191{ 1197{
1192 struct smack_known *skp; 1198 struct smack_known *skp;
1199 struct smack_known *mkp;
1193 struct smack_rule *srp; 1200 struct smack_rule *srp;
1194 struct task_smack *tsp; 1201 struct task_smack *tsp;
1195 char *sp;
1196 char *msmack;
1197 char *osmack; 1202 char *osmack;
1198 struct inode_smack *isp; 1203 struct inode_smack *isp;
1199 int may; 1204 int may;
@@ -1207,11 +1212,10 @@ static int smack_mmap_file(struct file *file,
1207 isp = file_inode(file)->i_security; 1212 isp = file_inode(file)->i_security;
1208 if (isp->smk_mmap == NULL) 1213 if (isp->smk_mmap == NULL)
1209 return 0; 1214 return 0;
1210 msmack = isp->smk_mmap; 1215 mkp = isp->smk_mmap;
1211 1216
1212 tsp = current_security(); 1217 tsp = current_security();
1213 sp = smk_of_current(); 1218 skp = smk_of_current();
1214 skp = smk_find_entry(sp);
1215 rc = 0; 1219 rc = 0;
1216 1220
1217 rcu_read_lock(); 1221 rcu_read_lock();
@@ -1225,13 +1229,13 @@ static int smack_mmap_file(struct file *file,
1225 /* 1229 /*
1226 * Matching labels always allows access. 1230 * Matching labels always allows access.
1227 */ 1231 */
1228 if (msmack == osmack) 1232 if (mkp->smk_known == osmack)
1229 continue; 1233 continue;
1230 /* 1234 /*
1231 * If there is a matching local rule take 1235 * If there is a matching local rule take
1232 * that into account as well. 1236 * that into account as well.
1233 */ 1237 */
1234 may = smk_access_entry(srp->smk_subject, osmack, 1238 may = smk_access_entry(srp->smk_subject->smk_known, osmack,
1235 &tsp->smk_rules); 1239 &tsp->smk_rules);
1236 if (may == -ENOENT) 1240 if (may == -ENOENT)
1237 may = srp->smk_access; 1241 may = srp->smk_access;
@@ -1249,8 +1253,8 @@ static int smack_mmap_file(struct file *file,
1249 * If there isn't one a SMACK64MMAP subject 1253 * If there isn't one a SMACK64MMAP subject
1250 * can't have as much access as current. 1254 * can't have as much access as current.
1251 */ 1255 */
1252 skp = smk_find_entry(msmack); 1256 mmay = smk_access_entry(mkp->smk_known, osmack,
1253 mmay = smk_access_entry(msmack, osmack, &skp->smk_rules); 1257 &mkp->smk_rules);
1254 if (mmay == -ENOENT) { 1258 if (mmay == -ENOENT) {
1255 rc = -EACCES; 1259 rc = -EACCES;
1256 break; 1260 break;
@@ -1259,7 +1263,8 @@ static int smack_mmap_file(struct file *file,
1259 * If there is a local entry it modifies the 1263 * If there is a local entry it modifies the
1260 * potential access, too. 1264 * potential access, too.
1261 */ 1265 */
1262 tmay = smk_access_entry(msmack, osmack, &tsp->smk_rules); 1266 tmay = smk_access_entry(mkp->smk_known, osmack,
1267 &tsp->smk_rules);
1263 if (tmay != -ENOENT) 1268 if (tmay != -ENOENT)
1264 mmay &= tmay; 1269 mmay &= tmay;
1265 1270
@@ -1288,7 +1293,9 @@ static int smack_mmap_file(struct file *file,
1288 */ 1293 */
1289static int smack_file_set_fowner(struct file *file) 1294static int smack_file_set_fowner(struct file *file)
1290{ 1295{
1291 file->f_security = smk_of_current(); 1296 struct smack_known *skp = smk_of_current();
1297
1298 file->f_security = skp->smk_known;
1292 return 0; 1299 return 0;
1293} 1300}
1294 1301
@@ -1306,9 +1313,10 @@ static int smack_file_set_fowner(struct file *file)
1306static int smack_file_send_sigiotask(struct task_struct *tsk, 1313static int smack_file_send_sigiotask(struct task_struct *tsk,
1307 struct fown_struct *fown, int signum) 1314 struct fown_struct *fown, int signum)
1308{ 1315{
1316 struct smack_known *skp;
1317 struct smack_known *tkp = smk_of_task(tsk->cred->security);
1309 struct file *file; 1318 struct file *file;
1310 int rc; 1319 int rc;
1311 char *tsp = smk_of_task(tsk->cred->security);
1312 struct smk_audit_info ad; 1320 struct smk_audit_info ad;
1313 1321
1314 /* 1322 /*
@@ -1317,13 +1325,14 @@ static int smack_file_send_sigiotask(struct task_struct *tsk,
1317 file = container_of(fown, struct file, f_owner); 1325 file = container_of(fown, struct file, f_owner);
1318 1326
1319 /* we don't log here as rc can be overriden */ 1327 /* we don't log here as rc can be overriden */
1320 rc = smk_access(file->f_security, tsp, MAY_WRITE, NULL); 1328 skp = smk_find_entry(file->f_security);
1329 rc = smk_access(skp, tkp->smk_known, MAY_WRITE, NULL);
1321 if (rc != 0 && has_capability(tsk, CAP_MAC_OVERRIDE)) 1330 if (rc != 0 && has_capability(tsk, CAP_MAC_OVERRIDE))
1322 rc = 0; 1331 rc = 0;
1323 1332
1324 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); 1333 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
1325 smk_ad_setfield_u_tsk(&ad, tsk); 1334 smk_ad_setfield_u_tsk(&ad, tsk);
1326 smack_log(file->f_security, tsp, MAY_WRITE, rc, &ad); 1335 smack_log(file->f_security, tkp->smk_known, MAY_WRITE, rc, &ad);
1327 return rc; 1336 return rc;
1328} 1337}
1329 1338
@@ -1478,12 +1487,12 @@ static void smack_cred_transfer(struct cred *new, const struct cred *old)
1478static int smack_kernel_act_as(struct cred *new, u32 secid) 1487static int smack_kernel_act_as(struct cred *new, u32 secid)
1479{ 1488{
1480 struct task_smack *new_tsp = new->security; 1489 struct task_smack *new_tsp = new->security;
1481 char *smack = smack_from_secid(secid); 1490 struct smack_known *skp = smack_from_secid(secid);
1482 1491
1483 if (smack == NULL) 1492 if (skp == NULL)
1484 return -EINVAL; 1493 return -EINVAL;
1485 1494
1486 new_tsp->smk_task = smack; 1495 new_tsp->smk_task = skp;
1487 return 0; 1496 return 0;
1488} 1497}
1489 1498
@@ -1501,8 +1510,8 @@ static int smack_kernel_create_files_as(struct cred *new,
1501 struct inode_smack *isp = inode->i_security; 1510 struct inode_smack *isp = inode->i_security;
1502 struct task_smack *tsp = new->security; 1511 struct task_smack *tsp = new->security;
1503 1512
1504 tsp->smk_forked = isp->smk_inode; 1513 tsp->smk_forked = smk_find_entry(isp->smk_inode);
1505 tsp->smk_task = isp->smk_inode; 1514 tsp->smk_task = tsp->smk_forked;
1506 return 0; 1515 return 0;
1507} 1516}
1508 1517
@@ -1518,10 +1527,11 @@ static int smk_curacc_on_task(struct task_struct *p, int access,
1518 const char *caller) 1527 const char *caller)
1519{ 1528{
1520 struct smk_audit_info ad; 1529 struct smk_audit_info ad;
1530 struct smack_known *skp = smk_of_task(task_security(p));
1521 1531
1522 smk_ad_init(&ad, caller, LSM_AUDIT_DATA_TASK); 1532 smk_ad_init(&ad, caller, LSM_AUDIT_DATA_TASK);
1523 smk_ad_setfield_u_tsk(&ad, p); 1533 smk_ad_setfield_u_tsk(&ad, p);
1524 return smk_curacc(smk_of_task(task_security(p)), access, &ad); 1534 return smk_curacc(skp->smk_known, access, &ad);
1525} 1535}
1526 1536
1527/** 1537/**
@@ -1567,7 +1577,9 @@ static int smack_task_getsid(struct task_struct *p)
1567 */ 1577 */
1568static void smack_task_getsecid(struct task_struct *p, u32 *secid) 1578static void smack_task_getsecid(struct task_struct *p, u32 *secid)
1569{ 1579{
1570 *secid = smack_to_secid(smk_of_task(task_security(p))); 1580 struct smack_known *skp = smk_of_task(task_security(p));
1581
1582 *secid = skp->smk_secid;
1571} 1583}
1572 1584
1573/** 1585/**
@@ -1671,6 +1683,8 @@ static int smack_task_kill(struct task_struct *p, struct siginfo *info,
1671 int sig, u32 secid) 1683 int sig, u32 secid)
1672{ 1684{
1673 struct smk_audit_info ad; 1685 struct smk_audit_info ad;
1686 struct smack_known *skp;
1687 struct smack_known *tkp = smk_of_task(task_security(p));
1674 1688
1675 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); 1689 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
1676 smk_ad_setfield_u_tsk(&ad, p); 1690 smk_ad_setfield_u_tsk(&ad, p);
@@ -1679,15 +1693,14 @@ static int smack_task_kill(struct task_struct *p, struct siginfo *info,
1679 * can write the receiver. 1693 * can write the receiver.
1680 */ 1694 */
1681 if (secid == 0) 1695 if (secid == 0)
1682 return smk_curacc(smk_of_task(task_security(p)), MAY_WRITE, 1696 return smk_curacc(tkp->smk_known, MAY_WRITE, &ad);
1683 &ad);
1684 /* 1697 /*
1685 * If the secid isn't 0 we're dealing with some USB IO 1698 * If the secid isn't 0 we're dealing with some USB IO
1686 * specific behavior. This is not clean. For one thing 1699 * specific behavior. This is not clean. For one thing
1687 * we can't take privilege into account. 1700 * we can't take privilege into account.
1688 */ 1701 */
1689 return smk_access(smack_from_secid(secid), 1702 skp = smack_from_secid(secid);
1690 smk_of_task(task_security(p)), MAY_WRITE, &ad); 1703 return smk_access(skp, tkp->smk_known, MAY_WRITE, &ad);
1691} 1704}
1692 1705
1693/** 1706/**
@@ -1719,7 +1732,9 @@ static int smack_task_wait(struct task_struct *p)
1719static void smack_task_to_inode(struct task_struct *p, struct inode *inode) 1732static void smack_task_to_inode(struct task_struct *p, struct inode *inode)
1720{ 1733{
1721 struct inode_smack *isp = inode->i_security; 1734 struct inode_smack *isp = inode->i_security;
1722 isp->smk_inode = smk_of_task(task_security(p)); 1735 struct smack_known *skp = smk_of_task(task_security(p));
1736
1737 isp->smk_inode = skp->smk_known;
1723} 1738}
1724 1739
1725/* 1740/*
@@ -1738,15 +1753,15 @@ static void smack_task_to_inode(struct task_struct *p, struct inode *inode)
1738 */ 1753 */
1739static int smack_sk_alloc_security(struct sock *sk, int family, gfp_t gfp_flags) 1754static int smack_sk_alloc_security(struct sock *sk, int family, gfp_t gfp_flags)
1740{ 1755{
1741 char *csp = smk_of_current(); 1756 struct smack_known *skp = smk_of_current();
1742 struct socket_smack *ssp; 1757 struct socket_smack *ssp;
1743 1758
1744 ssp = kzalloc(sizeof(struct socket_smack), gfp_flags); 1759 ssp = kzalloc(sizeof(struct socket_smack), gfp_flags);
1745 if (ssp == NULL) 1760 if (ssp == NULL)
1746 return -ENOMEM; 1761 return -ENOMEM;
1747 1762
1748 ssp->smk_in = csp; 1763 ssp->smk_in = skp->smk_known;
1749 ssp->smk_out = csp; 1764 ssp->smk_out = skp;
1750 ssp->smk_packet = NULL; 1765 ssp->smk_packet = NULL;
1751 1766
1752 sk->sk_security = ssp; 1767 sk->sk_security = ssp;
@@ -1833,7 +1848,7 @@ static int smack_netlabel(struct sock *sk, int labeled)
1833 labeled == SMACK_UNLABELED_SOCKET) 1848 labeled == SMACK_UNLABELED_SOCKET)
1834 netlbl_sock_delattr(sk); 1849 netlbl_sock_delattr(sk);
1835 else { 1850 else {
1836 skp = smk_find_entry(ssp->smk_out); 1851 skp = ssp->smk_out;
1837 rc = netlbl_sock_setattr(sk, sk->sk_family, &skp->smk_netlabel); 1852 rc = netlbl_sock_setattr(sk, sk->sk_family, &skp->smk_netlabel);
1838 } 1853 }
1839 1854
@@ -1856,6 +1871,7 @@ static int smack_netlabel(struct sock *sk, int labeled)
1856 */ 1871 */
1857static int smack_netlabel_send(struct sock *sk, struct sockaddr_in *sap) 1872static int smack_netlabel_send(struct sock *sk, struct sockaddr_in *sap)
1858{ 1873{
1874 struct smack_known *skp;
1859 int rc; 1875 int rc;
1860 int sk_lbl; 1876 int sk_lbl;
1861 char *hostsp; 1877 char *hostsp;
@@ -1874,7 +1890,8 @@ static int smack_netlabel_send(struct sock *sk, struct sockaddr_in *sap)
1874 ad.a.u.net->v4info.daddr = sap->sin_addr.s_addr; 1890 ad.a.u.net->v4info.daddr = sap->sin_addr.s_addr;
1875#endif 1891#endif
1876 sk_lbl = SMACK_UNLABELED_SOCKET; 1892 sk_lbl = SMACK_UNLABELED_SOCKET;
1877 rc = smk_access(ssp->smk_out, hostsp, MAY_WRITE, &ad); 1893 skp = ssp->smk_out;
1894 rc = smk_access(skp, hostsp, MAY_WRITE, &ad);
1878 } else { 1895 } else {
1879 sk_lbl = SMACK_CIPSO_SOCKET; 1896 sk_lbl = SMACK_CIPSO_SOCKET;
1880 rc = 0; 1897 rc = 0;
@@ -1974,8 +1991,8 @@ static int smk_ipv6_port_check(struct sock *sk, struct sockaddr *address,
1974 struct sockaddr_in6 *addr6; 1991 struct sockaddr_in6 *addr6;
1975 struct smk_port_label *spp; 1992 struct smk_port_label *spp;
1976 struct socket_smack *ssp = sk->sk_security; 1993 struct socket_smack *ssp = sk->sk_security;
1994 struct smack_known *skp;
1977 unsigned short port = 0; 1995 unsigned short port = 0;
1978 char *subject;
1979 char *object; 1996 char *object;
1980 struct smk_audit_info ad; 1997 struct smk_audit_info ad;
1981#ifdef CONFIG_AUDIT 1998#ifdef CONFIG_AUDIT
@@ -1983,11 +2000,11 @@ static int smk_ipv6_port_check(struct sock *sk, struct sockaddr *address,
1983#endif 2000#endif
1984 2001
1985 if (act == SMK_RECEIVING) { 2002 if (act == SMK_RECEIVING) {
1986 subject = smack_net_ambient; 2003 skp = smack_net_ambient;
1987 object = ssp->smk_in; 2004 object = ssp->smk_in;
1988 } else { 2005 } else {
1989 subject = ssp->smk_out; 2006 skp = ssp->smk_out;
1990 object = smack_net_ambient; 2007 object = smack_net_ambient->smk_known;
1991 } 2008 }
1992 2009
1993 /* 2010 /*
@@ -2008,7 +2025,7 @@ static int smk_ipv6_port_check(struct sock *sk, struct sockaddr *address,
2008 * It's local so the send check has to have passed. 2025 * It's local so the send check has to have passed.
2009 */ 2026 */
2010 if (act == SMK_RECEIVING) { 2027 if (act == SMK_RECEIVING) {
2011 subject = smack_known_web.smk_known; 2028 skp = &smack_known_web;
2012 goto auditout; 2029 goto auditout;
2013 } 2030 }
2014 2031
@@ -2017,7 +2034,7 @@ static int smk_ipv6_port_check(struct sock *sk, struct sockaddr *address,
2017 continue; 2034 continue;
2018 object = spp->smk_in; 2035 object = spp->smk_in;
2019 if (act == SMK_CONNECTING) 2036 if (act == SMK_CONNECTING)
2020 ssp->smk_packet = spp->smk_out; 2037 ssp->smk_packet = spp->smk_out->smk_known;
2021 break; 2038 break;
2022 } 2039 }
2023 2040
@@ -2032,7 +2049,7 @@ auditout:
2032 else 2049 else
2033 ad.a.u.net->v6info.daddr = addr6->sin6_addr; 2050 ad.a.u.net->v6info.daddr = addr6->sin6_addr;
2034#endif 2051#endif
2035 return smk_access(subject, object, MAY_WRITE, &ad); 2052 return smk_access(skp, object, MAY_WRITE, &ad);
2036} 2053}
2037 2054
2038/** 2055/**
@@ -2050,7 +2067,7 @@ auditout:
2050static int smack_inode_setsecurity(struct inode *inode, const char *name, 2067static int smack_inode_setsecurity(struct inode *inode, const char *name,
2051 const void *value, size_t size, int flags) 2068 const void *value, size_t size, int flags)
2052{ 2069{
2053 char *sp; 2070 struct smack_known *skp;
2054 struct inode_smack *nsp = inode->i_security; 2071 struct inode_smack *nsp = inode->i_security;
2055 struct socket_smack *ssp; 2072 struct socket_smack *ssp;
2056 struct socket *sock; 2073 struct socket *sock;
@@ -2059,12 +2076,12 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name,
2059 if (value == NULL || size > SMK_LONGLABEL || size == 0) 2076 if (value == NULL || size > SMK_LONGLABEL || size == 0)
2060 return -EACCES; 2077 return -EACCES;
2061 2078
2062 sp = smk_import(value, size); 2079 skp = smk_import_entry(value, size);
2063 if (sp == NULL) 2080 if (skp == NULL)
2064 return -EINVAL; 2081 return -EINVAL;
2065 2082
2066 if (strcmp(name, XATTR_SMACK_SUFFIX) == 0) { 2083 if (strcmp(name, XATTR_SMACK_SUFFIX) == 0) {
2067 nsp->smk_inode = sp; 2084 nsp->smk_inode = skp->smk_known;
2068 nsp->smk_flags |= SMK_INODE_INSTANT; 2085 nsp->smk_flags |= SMK_INODE_INSTANT;
2069 return 0; 2086 return 0;
2070 } 2087 }
@@ -2081,9 +2098,9 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name,
2081 ssp = sock->sk->sk_security; 2098 ssp = sock->sk->sk_security;
2082 2099
2083 if (strcmp(name, XATTR_SMACK_IPIN) == 0) 2100 if (strcmp(name, XATTR_SMACK_IPIN) == 0)
2084 ssp->smk_in = sp; 2101 ssp->smk_in = skp->smk_known;
2085 else if (strcmp(name, XATTR_SMACK_IPOUT) == 0) { 2102 else if (strcmp(name, XATTR_SMACK_IPOUT) == 0) {
2086 ssp->smk_out = sp; 2103 ssp->smk_out = skp;
2087 if (sock->sk->sk_family == PF_INET) { 2104 if (sock->sk->sk_family == PF_INET) {
2088 rc = smack_netlabel(sock->sk, SMACK_CIPSO_SOCKET); 2105 rc = smack_netlabel(sock->sk, SMACK_CIPSO_SOCKET);
2089 if (rc != 0) 2106 if (rc != 0)
@@ -2203,7 +2220,9 @@ static int smack_flags_to_may(int flags)
2203 */ 2220 */
2204static int smack_msg_msg_alloc_security(struct msg_msg *msg) 2221static int smack_msg_msg_alloc_security(struct msg_msg *msg)
2205{ 2222{
2206 msg->security = smk_of_current(); 2223 struct smack_known *skp = smk_of_current();
2224
2225 msg->security = skp->smk_known;
2207 return 0; 2226 return 0;
2208} 2227}
2209 2228
@@ -2238,8 +2257,9 @@ static char *smack_of_shm(struct shmid_kernel *shp)
2238static int smack_shm_alloc_security(struct shmid_kernel *shp) 2257static int smack_shm_alloc_security(struct shmid_kernel *shp)
2239{ 2258{
2240 struct kern_ipc_perm *isp = &shp->shm_perm; 2259 struct kern_ipc_perm *isp = &shp->shm_perm;
2260 struct smack_known *skp = smk_of_current();
2241 2261
2242 isp->security = smk_of_current(); 2262 isp->security = skp->smk_known;
2243 return 0; 2263 return 0;
2244} 2264}
2245 2265
@@ -2361,8 +2381,9 @@ static char *smack_of_sem(struct sem_array *sma)
2361static int smack_sem_alloc_security(struct sem_array *sma) 2381static int smack_sem_alloc_security(struct sem_array *sma)
2362{ 2382{
2363 struct kern_ipc_perm *isp = &sma->sem_perm; 2383 struct kern_ipc_perm *isp = &sma->sem_perm;
2384 struct smack_known *skp = smk_of_current();
2364 2385
2365 isp->security = smk_of_current(); 2386 isp->security = skp->smk_known;
2366 return 0; 2387 return 0;
2367} 2388}
2368 2389
@@ -2479,8 +2500,9 @@ static int smack_sem_semop(struct sem_array *sma, struct sembuf *sops,
2479static int smack_msg_queue_alloc_security(struct msg_queue *msq) 2500static int smack_msg_queue_alloc_security(struct msg_queue *msq)
2480{ 2501{
2481 struct kern_ipc_perm *kisp = &msq->q_perm; 2502 struct kern_ipc_perm *kisp = &msq->q_perm;
2503 struct smack_known *skp = smk_of_current();
2482 2504
2483 kisp->security = smk_of_current(); 2505 kisp->security = skp->smk_known;
2484 return 0; 2506 return 0;
2485} 2507}
2486 2508
@@ -2652,8 +2674,8 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
2652 struct super_block *sbp; 2674 struct super_block *sbp;
2653 struct superblock_smack *sbsp; 2675 struct superblock_smack *sbsp;
2654 struct inode_smack *isp; 2676 struct inode_smack *isp;
2655 char *csp = smk_of_current(); 2677 struct smack_known *skp;
2656 char *fetched; 2678 struct smack_known *ckp = smk_of_current();
2657 char *final; 2679 char *final;
2658 char trattr[TRANS_TRUE_SIZE]; 2680 char trattr[TRANS_TRUE_SIZE];
2659 int transflag = 0; 2681 int transflag = 0;
@@ -2720,7 +2742,7 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
2720 * Programs that change smack have to treat the 2742 * Programs that change smack have to treat the
2721 * pty with respect. 2743 * pty with respect.
2722 */ 2744 */
2723 final = csp; 2745 final = ckp->smk_known;
2724 break; 2746 break;
2725 case SOCKFS_MAGIC: 2747 case SOCKFS_MAGIC:
2726 /* 2748 /*
@@ -2775,9 +2797,9 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
2775 * Get the dentry for xattr. 2797 * Get the dentry for xattr.
2776 */ 2798 */
2777 dp = dget(opt_dentry); 2799 dp = dget(opt_dentry);
2778 fetched = smk_fetch(XATTR_NAME_SMACK, inode, dp); 2800 skp = smk_fetch(XATTR_NAME_SMACK, inode, dp);
2779 if (fetched != NULL) 2801 if (skp != NULL)
2780 final = fetched; 2802 final = skp->smk_known;
2781 2803
2782 /* 2804 /*
2783 * Transmuting directory 2805 * Transmuting directory
@@ -2817,7 +2839,7 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
2817 } 2839 }
2818 2840
2819 if (final == NULL) 2841 if (final == NULL)
2820 isp->smk_inode = csp; 2842 isp->smk_inode = ckp->smk_known;
2821 else 2843 else
2822 isp->smk_inode = final; 2844 isp->smk_inode = final;
2823 2845
@@ -2840,13 +2862,14 @@ unlockandout:
2840 */ 2862 */
2841static int smack_getprocattr(struct task_struct *p, char *name, char **value) 2863static int smack_getprocattr(struct task_struct *p, char *name, char **value)
2842{ 2864{
2865 struct smack_known *skp = smk_of_task(task_security(p));
2843 char *cp; 2866 char *cp;
2844 int slen; 2867 int slen;
2845 2868
2846 if (strcmp(name, "current") != 0) 2869 if (strcmp(name, "current") != 0)
2847 return -EINVAL; 2870 return -EINVAL;
2848 2871
2849 cp = kstrdup(smk_of_task(task_security(p)), GFP_KERNEL); 2872 cp = kstrdup(skp->smk_known, GFP_KERNEL);
2850 if (cp == NULL) 2873 if (cp == NULL)
2851 return -ENOMEM; 2874 return -ENOMEM;
2852 2875
@@ -2872,7 +2895,7 @@ static int smack_setprocattr(struct task_struct *p, char *name,
2872{ 2895{
2873 struct task_smack *tsp; 2896 struct task_smack *tsp;
2874 struct cred *new; 2897 struct cred *new;
2875 char *newsmack; 2898 struct smack_known *skp;
2876 2899
2877 /* 2900 /*
2878 * Changing another process' Smack value is too dangerous 2901 * Changing another process' Smack value is too dangerous
@@ -2890,14 +2913,14 @@ static int smack_setprocattr(struct task_struct *p, char *name,
2890 if (strcmp(name, "current") != 0) 2913 if (strcmp(name, "current") != 0)
2891 return -EINVAL; 2914 return -EINVAL;
2892 2915
2893 newsmack = smk_import(value, size); 2916 skp = smk_import_entry(value, size);
2894 if (newsmack == NULL) 2917 if (skp == NULL)
2895 return -EINVAL; 2918 return -EINVAL;
2896 2919
2897 /* 2920 /*
2898 * No process is ever allowed the web ("@") label. 2921 * No process is ever allowed the web ("@") label.
2899 */ 2922 */
2900 if (newsmack == smack_known_web.smk_known) 2923 if (skp == &smack_known_web)
2901 return -EPERM; 2924 return -EPERM;
2902 2925
2903 new = prepare_creds(); 2926 new = prepare_creds();
@@ -2905,7 +2928,7 @@ static int smack_setprocattr(struct task_struct *p, char *name,
2905 return -ENOMEM; 2928 return -ENOMEM;
2906 2929
2907 tsp = new->security; 2930 tsp = new->security;
2908 tsp->smk_task = newsmack; 2931 tsp->smk_task = skp;
2909 2932
2910 commit_creds(new); 2933 commit_creds(new);
2911 return size; 2934 return size;
@@ -2923,6 +2946,7 @@ static int smack_setprocattr(struct task_struct *p, char *name,
2923static int smack_unix_stream_connect(struct sock *sock, 2946static int smack_unix_stream_connect(struct sock *sock,
2924 struct sock *other, struct sock *newsk) 2947 struct sock *other, struct sock *newsk)
2925{ 2948{
2949 struct smack_known *skp;
2926 struct socket_smack *ssp = sock->sk_security; 2950 struct socket_smack *ssp = sock->sk_security;
2927 struct socket_smack *osp = other->sk_security; 2951 struct socket_smack *osp = other->sk_security;
2928 struct socket_smack *nsp = newsk->sk_security; 2952 struct socket_smack *nsp = newsk->sk_security;
@@ -2936,15 +2960,17 @@ static int smack_unix_stream_connect(struct sock *sock,
2936 smk_ad_setfield_u_net_sk(&ad, other); 2960 smk_ad_setfield_u_net_sk(&ad, other);
2937#endif 2961#endif
2938 2962
2939 if (!smack_privileged(CAP_MAC_OVERRIDE)) 2963 if (!smack_privileged(CAP_MAC_OVERRIDE)) {
2940 rc = smk_access(ssp->smk_out, osp->smk_in, MAY_WRITE, &ad); 2964 skp = ssp->smk_out;
2965 rc = smk_access(skp, osp->smk_in, MAY_WRITE, &ad);
2966 }
2941 2967
2942 /* 2968 /*
2943 * Cross reference the peer labels for SO_PEERSEC. 2969 * Cross reference the peer labels for SO_PEERSEC.
2944 */ 2970 */
2945 if (rc == 0) { 2971 if (rc == 0) {
2946 nsp->smk_packet = ssp->smk_out; 2972 nsp->smk_packet = ssp->smk_out->smk_known;
2947 ssp->smk_packet = osp->smk_out; 2973 ssp->smk_packet = osp->smk_out->smk_known;
2948 } 2974 }
2949 2975
2950 return rc; 2976 return rc;
@@ -2962,8 +2988,8 @@ static int smack_unix_may_send(struct socket *sock, struct socket *other)
2962{ 2988{
2963 struct socket_smack *ssp = sock->sk->sk_security; 2989 struct socket_smack *ssp = sock->sk->sk_security;
2964 struct socket_smack *osp = other->sk->sk_security; 2990 struct socket_smack *osp = other->sk->sk_security;
2991 struct smack_known *skp;
2965 struct smk_audit_info ad; 2992 struct smk_audit_info ad;
2966 int rc = 0;
2967 2993
2968#ifdef CONFIG_AUDIT 2994#ifdef CONFIG_AUDIT
2969 struct lsm_network_audit net; 2995 struct lsm_network_audit net;
@@ -2972,10 +2998,11 @@ static int smack_unix_may_send(struct socket *sock, struct socket *other)
2972 smk_ad_setfield_u_net_sk(&ad, other->sk); 2998 smk_ad_setfield_u_net_sk(&ad, other->sk);
2973#endif 2999#endif
2974 3000
2975 if (!smack_privileged(CAP_MAC_OVERRIDE)) 3001 if (smack_privileged(CAP_MAC_OVERRIDE))
2976 rc = smk_access(ssp->smk_out, osp->smk_in, MAY_WRITE, &ad); 3002 return 0;
2977 3003
2978 return rc; 3004 skp = ssp->smk_out;
3005 return smk_access(skp, osp->smk_in, MAY_WRITE, &ad);
2979} 3006}
2980 3007
2981/** 3008/**
@@ -3017,13 +3044,12 @@ static int smack_socket_sendmsg(struct socket *sock, struct msghdr *msg,
3017 * @sap: netlabel secattr 3044 * @sap: netlabel secattr
3018 * @ssp: socket security information 3045 * @ssp: socket security information
3019 * 3046 *
3020 * Returns a pointer to a Smack label found on the label list. 3047 * Returns a pointer to a Smack label entry found on the label list.
3021 */ 3048 */
3022static char *smack_from_secattr(struct netlbl_lsm_secattr *sap, 3049static struct smack_known *smack_from_secattr(struct netlbl_lsm_secattr *sap,
3023 struct socket_smack *ssp) 3050 struct socket_smack *ssp)
3024{ 3051{
3025 struct smack_known *kp; 3052 struct smack_known *skp;
3026 char *sp;
3027 int found = 0; 3053 int found = 0;
3028 3054
3029 if ((sap->flags & NETLBL_SECATTR_MLS_LVL) != 0) { 3055 if ((sap->flags & NETLBL_SECATTR_MLS_LVL) != 0) {
@@ -3038,11 +3064,11 @@ static char *smack_from_secattr(struct netlbl_lsm_secattr *sap,
3038 * ambient value. 3064 * ambient value.
3039 */ 3065 */
3040 rcu_read_lock(); 3066 rcu_read_lock();
3041 list_for_each_entry(kp, &smack_known_list, list) { 3067 list_for_each_entry(skp, &smack_known_list, list) {
3042 if (sap->attr.mls.lvl != kp->smk_netlabel.attr.mls.lvl) 3068 if (sap->attr.mls.lvl != skp->smk_netlabel.attr.mls.lvl)
3043 continue; 3069 continue;
3044 if (memcmp(sap->attr.mls.cat, 3070 if (memcmp(sap->attr.mls.cat,
3045 kp->smk_netlabel.attr.mls.cat, 3071 skp->smk_netlabel.attr.mls.cat,
3046 SMK_CIPSOLEN) != 0) 3072 SMK_CIPSOLEN) != 0)
3047 continue; 3073 continue;
3048 found = 1; 3074 found = 1;
@@ -3051,17 +3077,17 @@ static char *smack_from_secattr(struct netlbl_lsm_secattr *sap,
3051 rcu_read_unlock(); 3077 rcu_read_unlock();
3052 3078
3053 if (found) 3079 if (found)
3054 return kp->smk_known; 3080 return skp;
3055 3081
3056 if (ssp != NULL && ssp->smk_in == smack_known_star.smk_known) 3082 if (ssp != NULL && ssp->smk_in == smack_known_star.smk_known)
3057 return smack_known_web.smk_known; 3083 return &smack_known_web;
3058 return smack_known_star.smk_known; 3084 return &smack_known_star;
3059 } 3085 }
3060 if ((sap->flags & NETLBL_SECATTR_SECID) != 0) { 3086 if ((sap->flags & NETLBL_SECATTR_SECID) != 0) {
3061 /* 3087 /*
3062 * Looks like a fallback, which gives us a secid. 3088 * Looks like a fallback, which gives us a secid.
3063 */ 3089 */
3064 sp = smack_from_secid(sap->attr.secid); 3090 skp = smack_from_secid(sap->attr.secid);
3065 /* 3091 /*
3066 * This has got to be a bug because it is 3092 * This has got to be a bug because it is
3067 * impossible to specify a fallback without 3093 * impossible to specify a fallback without
@@ -3069,8 +3095,8 @@ static char *smack_from_secattr(struct netlbl_lsm_secattr *sap,
3069 * it has a secid, and the only way to get a 3095 * it has a secid, and the only way to get a
3070 * secid is from a fallback. 3096 * secid is from a fallback.
3071 */ 3097 */
3072 BUG_ON(sp == NULL); 3098 BUG_ON(skp == NULL);
3073 return sp; 3099 return skp;
3074 } 3100 }
3075 /* 3101 /*
3076 * Without guidance regarding the smack value 3102 * Without guidance regarding the smack value
@@ -3139,8 +3165,8 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
3139{ 3165{
3140 struct netlbl_lsm_secattr secattr; 3166 struct netlbl_lsm_secattr secattr;
3141 struct socket_smack *ssp = sk->sk_security; 3167 struct socket_smack *ssp = sk->sk_security;
3168 struct smack_known *skp;
3142 struct sockaddr sadd; 3169 struct sockaddr sadd;
3143 char *csp;
3144 int rc = 0; 3170 int rc = 0;
3145 struct smk_audit_info ad; 3171 struct smk_audit_info ad;
3146#ifdef CONFIG_AUDIT 3172#ifdef CONFIG_AUDIT
@@ -3155,9 +3181,9 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
3155 3181
3156 rc = netlbl_skbuff_getattr(skb, sk->sk_family, &secattr); 3182 rc = netlbl_skbuff_getattr(skb, sk->sk_family, &secattr);
3157 if (rc == 0) 3183 if (rc == 0)
3158 csp = smack_from_secattr(&secattr, ssp); 3184 skp = smack_from_secattr(&secattr, ssp);
3159 else 3185 else
3160 csp = smack_net_ambient; 3186 skp = smack_net_ambient;
3161 3187
3162 netlbl_secattr_destroy(&secattr); 3188 netlbl_secattr_destroy(&secattr);
3163 3189
@@ -3173,7 +3199,7 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
3173 * This is the simplist possible security model 3199 * This is the simplist possible security model
3174 * for networking. 3200 * for networking.
3175 */ 3201 */
3176 rc = smk_access(csp, ssp->smk_in, MAY_WRITE, &ad); 3202 rc = smk_access(skp, ssp->smk_in, MAY_WRITE, &ad);
3177 if (rc != 0) 3203 if (rc != 0)
3178 netlbl_skbuff_err(skb, rc, 0); 3204 netlbl_skbuff_err(skb, rc, 0);
3179 break; 3205 break;
@@ -3238,7 +3264,7 @@ static int smack_socket_getpeersec_dgram(struct socket *sock,
3238{ 3264{
3239 struct netlbl_lsm_secattr secattr; 3265 struct netlbl_lsm_secattr secattr;
3240 struct socket_smack *ssp = NULL; 3266 struct socket_smack *ssp = NULL;
3241 char *sp; 3267 struct smack_known *skp;
3242 int family = PF_UNSPEC; 3268 int family = PF_UNSPEC;
3243 u32 s = 0; /* 0 is the invalid secid */ 3269 u32 s = 0; /* 0 is the invalid secid */
3244 int rc; 3270 int rc;
@@ -3254,7 +3280,7 @@ static int smack_socket_getpeersec_dgram(struct socket *sock,
3254 3280
3255 if (family == PF_UNIX) { 3281 if (family == PF_UNIX) {
3256 ssp = sock->sk->sk_security; 3282 ssp = sock->sk->sk_security;
3257 s = smack_to_secid(ssp->smk_out); 3283 s = ssp->smk_out->smk_secid;
3258 } else if (family == PF_INET || family == PF_INET6) { 3284 } else if (family == PF_INET || family == PF_INET6) {
3259 /* 3285 /*
3260 * Translate what netlabel gave us. 3286 * Translate what netlabel gave us.
@@ -3264,8 +3290,8 @@ static int smack_socket_getpeersec_dgram(struct socket *sock,
3264 netlbl_secattr_init(&secattr); 3290 netlbl_secattr_init(&secattr);
3265 rc = netlbl_skbuff_getattr(skb, family, &secattr); 3291 rc = netlbl_skbuff_getattr(skb, family, &secattr);
3266 if (rc == 0) { 3292 if (rc == 0) {
3267 sp = smack_from_secattr(&secattr, ssp); 3293 skp = smack_from_secattr(&secattr, ssp);
3268 s = smack_to_secid(sp); 3294 s = skp->smk_secid;
3269 } 3295 }
3270 netlbl_secattr_destroy(&secattr); 3296 netlbl_secattr_destroy(&secattr);
3271 } 3297 }
@@ -3286,13 +3312,15 @@ static int smack_socket_getpeersec_dgram(struct socket *sock,
3286static void smack_sock_graft(struct sock *sk, struct socket *parent) 3312static void smack_sock_graft(struct sock *sk, struct socket *parent)
3287{ 3313{
3288 struct socket_smack *ssp; 3314 struct socket_smack *ssp;
3315 struct smack_known *skp = smk_of_current();
3289 3316
3290 if (sk == NULL || 3317 if (sk == NULL ||
3291 (sk->sk_family != PF_INET && sk->sk_family != PF_INET6)) 3318 (sk->sk_family != PF_INET && sk->sk_family != PF_INET6))
3292 return; 3319 return;
3293 3320
3294 ssp = sk->sk_security; 3321 ssp = sk->sk_security;
3295 ssp->smk_in = ssp->smk_out = smk_of_current(); 3322 ssp->smk_in = skp->smk_known;
3323 ssp->smk_out = skp;
3296 /* cssp->smk_packet is already set in smack_inet_csk_clone() */ 3324 /* cssp->smk_packet is already set in smack_inet_csk_clone() */
3297} 3325}
3298 3326
@@ -3314,7 +3342,6 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
3314 struct netlbl_lsm_secattr secattr; 3342 struct netlbl_lsm_secattr secattr;
3315 struct sockaddr_in addr; 3343 struct sockaddr_in addr;
3316 struct iphdr *hdr; 3344 struct iphdr *hdr;
3317 char *sp;
3318 char *hsp; 3345 char *hsp;
3319 int rc; 3346 int rc;
3320 struct smk_audit_info ad; 3347 struct smk_audit_info ad;
@@ -3337,9 +3364,9 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
3337 netlbl_secattr_init(&secattr); 3364 netlbl_secattr_init(&secattr);
3338 rc = netlbl_skbuff_getattr(skb, family, &secattr); 3365 rc = netlbl_skbuff_getattr(skb, family, &secattr);
3339 if (rc == 0) 3366 if (rc == 0)
3340 sp = smack_from_secattr(&secattr, ssp); 3367 skp = smack_from_secattr(&secattr, ssp);
3341 else 3368 else
3342 sp = smack_known_huh.smk_known; 3369 skp = &smack_known_huh;
3343 netlbl_secattr_destroy(&secattr); 3370 netlbl_secattr_destroy(&secattr);
3344 3371
3345#ifdef CONFIG_AUDIT 3372#ifdef CONFIG_AUDIT
@@ -3352,7 +3379,7 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
3352 * Receiving a packet requires that the other end be able to write 3379 * Receiving a packet requires that the other end be able to write
3353 * here. Read access is not required. 3380 * here. Read access is not required.
3354 */ 3381 */
3355 rc = smk_access(sp, ssp->smk_in, MAY_WRITE, &ad); 3382 rc = smk_access(skp, ssp->smk_in, MAY_WRITE, &ad);
3356 if (rc != 0) 3383 if (rc != 0)
3357 return rc; 3384 return rc;
3358 3385
@@ -3360,7 +3387,7 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
3360 * Save the peer's label in the request_sock so we can later setup 3387 * Save the peer's label in the request_sock so we can later setup
3361 * smk_packet in the child socket so that SO_PEERCRED can report it. 3388 * smk_packet in the child socket so that SO_PEERCRED can report it.
3362 */ 3389 */
3363 req->peer_secid = smack_to_secid(sp); 3390 req->peer_secid = skp->smk_secid;
3364 3391
3365 /* 3392 /*
3366 * We need to decide if we want to label the incoming connection here 3393 * We need to decide if we want to label the incoming connection here
@@ -3373,10 +3400,9 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
3373 hsp = smack_host_label(&addr); 3400 hsp = smack_host_label(&addr);
3374 rcu_read_unlock(); 3401 rcu_read_unlock();
3375 3402
3376 if (hsp == NULL) { 3403 if (hsp == NULL)
3377 skp = smk_find_entry(sp);
3378 rc = netlbl_req_setattr(req, &skp->smk_netlabel); 3404 rc = netlbl_req_setattr(req, &skp->smk_netlabel);
3379 } else 3405 else
3380 netlbl_req_delattr(req); 3406 netlbl_req_delattr(req);
3381 3407
3382 return rc; 3408 return rc;
@@ -3393,10 +3419,12 @@ static void smack_inet_csk_clone(struct sock *sk,
3393 const struct request_sock *req) 3419 const struct request_sock *req)
3394{ 3420{
3395 struct socket_smack *ssp = sk->sk_security; 3421 struct socket_smack *ssp = sk->sk_security;
3422 struct smack_known *skp;
3396 3423
3397 if (req->peer_secid != 0) 3424 if (req->peer_secid != 0) {
3398 ssp->smk_packet = smack_from_secid(req->peer_secid); 3425 skp = smack_from_secid(req->peer_secid);
3399 else 3426 ssp->smk_packet = skp->smk_known;
3427 } else
3400 ssp->smk_packet = NULL; 3428 ssp->smk_packet = NULL;
3401} 3429}
3402 3430
@@ -3422,7 +3450,9 @@ static void smack_inet_csk_clone(struct sock *sk,
3422static int smack_key_alloc(struct key *key, const struct cred *cred, 3450static int smack_key_alloc(struct key *key, const struct cred *cred,
3423 unsigned long flags) 3451 unsigned long flags)
3424{ 3452{
3425 key->security = smk_of_task(cred->security); 3453 struct smack_known *skp = smk_of_task(cred->security);
3454
3455 key->security = skp->smk_known;
3426 return 0; 3456 return 0;
3427} 3457}
3428 3458
@@ -3451,7 +3481,7 @@ static int smack_key_permission(key_ref_t key_ref,
3451{ 3481{
3452 struct key *keyp; 3482 struct key *keyp;
3453 struct smk_audit_info ad; 3483 struct smk_audit_info ad;
3454 char *tsp = smk_of_task(cred->security); 3484 struct smack_known *tkp = smk_of_task(cred->security);
3455 3485
3456 keyp = key_ref_to_ptr(key_ref); 3486 keyp = key_ref_to_ptr(key_ref);
3457 if (keyp == NULL) 3487 if (keyp == NULL)
@@ -3465,15 +3495,14 @@ static int smack_key_permission(key_ref_t key_ref,
3465 /* 3495 /*
3466 * This should not occur 3496 * This should not occur
3467 */ 3497 */
3468 if (tsp == NULL) 3498 if (tkp == NULL)
3469 return -EACCES; 3499 return -EACCES;
3470#ifdef CONFIG_AUDIT 3500#ifdef CONFIG_AUDIT
3471 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_KEY); 3501 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_KEY);
3472 ad.a.u.key_struct.key = keyp->serial; 3502 ad.a.u.key_struct.key = keyp->serial;
3473 ad.a.u.key_struct.key_desc = keyp->description; 3503 ad.a.u.key_struct.key_desc = keyp->description;
3474#endif 3504#endif
3475 return smk_access(tsp, keyp->security, 3505 return smk_access(tkp, keyp->security, MAY_READWRITE, &ad);
3476 MAY_READWRITE, &ad);
3477} 3506}
3478#endif /* CONFIG_KEYS */ 3507#endif /* CONFIG_KEYS */
3479 3508
@@ -3555,7 +3584,7 @@ static int smack_audit_rule_known(struct audit_krule *krule)
3555static int smack_audit_rule_match(u32 secid, u32 field, u32 op, void *vrule, 3584static int smack_audit_rule_match(u32 secid, u32 field, u32 op, void *vrule,
3556 struct audit_context *actx) 3585 struct audit_context *actx)
3557{ 3586{
3558 char *smack; 3587 struct smack_known *skp;
3559 char *rule = vrule; 3588 char *rule = vrule;
3560 3589
3561 if (!rule) { 3590 if (!rule) {
@@ -3567,7 +3596,7 @@ static int smack_audit_rule_match(u32 secid, u32 field, u32 op, void *vrule,
3567 if (field != AUDIT_SUBJ_USER && field != AUDIT_OBJ_USER) 3596 if (field != AUDIT_SUBJ_USER && field != AUDIT_OBJ_USER)
3568 return 0; 3597 return 0;
3569 3598
3570 smack = smack_from_secid(secid); 3599 skp = smack_from_secid(secid);
3571 3600
3572 /* 3601 /*
3573 * No need to do string comparisons. If a match occurs, 3602 * No need to do string comparisons. If a match occurs,
@@ -3575,9 +3604,9 @@ static int smack_audit_rule_match(u32 secid, u32 field, u32 op, void *vrule,
3575 * label. 3604 * label.
3576 */ 3605 */
3577 if (op == Audit_equal) 3606 if (op == Audit_equal)
3578 return (rule == smack); 3607 return (rule == skp->smk_known);
3579 if (op == Audit_not_equal) 3608 if (op == Audit_not_equal)
3580 return (rule != smack); 3609 return (rule != skp->smk_known);
3581 3610
3582 return 0; 3611 return 0;
3583} 3612}
@@ -3605,11 +3634,11 @@ static void smack_audit_rule_free(void *vrule)
3605 */ 3634 */
3606static int smack_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) 3635static int smack_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
3607{ 3636{
3608 char *sp = smack_from_secid(secid); 3637 struct smack_known *skp = smack_from_secid(secid);
3609 3638
3610 if (secdata) 3639 if (secdata)
3611 *secdata = sp; 3640 *secdata = skp->smk_known;
3612 *seclen = strlen(sp); 3641 *seclen = strlen(skp->smk_known);
3613 return 0; 3642 return 0;
3614} 3643}
3615 3644
@@ -3845,8 +3874,8 @@ static __init int smack_init(void)
3845 if (!security_module_enable(&smack_ops)) 3874 if (!security_module_enable(&smack_ops))
3846 return 0; 3875 return 0;
3847 3876
3848 tsp = new_task_smack(smack_known_floor.smk_known, 3877 tsp = new_task_smack(&smack_known_floor, &smack_known_floor,
3849 smack_known_floor.smk_known, GFP_KERNEL); 3878 GFP_KERNEL);
3850 if (tsp == NULL) 3879 if (tsp == NULL)
3851 return -ENOMEM; 3880 return -ENOMEM;
3852 3881
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
index 53a08b85bda4..3c79cba5fa4a 100644
--- a/security/smack/smackfs.c
+++ b/security/smack/smackfs.c
@@ -66,7 +66,7 @@ static DEFINE_MUTEX(smk_netlbladdr_lock);
66 * If it isn't somehow marked, use this. 66 * If it isn't somehow marked, use this.
67 * It can be reset via smackfs/ambient 67 * It can be reset via smackfs/ambient
68 */ 68 */
69char *smack_net_ambient; 69struct smack_known *smack_net_ambient;
70 70
71/* 71/*
72 * This is the level in a CIPSO header that indicates a 72 * This is the level in a CIPSO header that indicates a
@@ -112,7 +112,7 @@ struct smack_master_list {
112LIST_HEAD(smack_rule_list); 112LIST_HEAD(smack_rule_list);
113 113
114struct smack_parsed_rule { 114struct smack_parsed_rule {
115 char *smk_subject; 115 struct smack_known *smk_subject;
116 char *smk_object; 116 char *smk_object;
117 int smk_access1; 117 int smk_access1;
118 int smk_access2; 118 int smk_access2;
@@ -163,9 +163,11 @@ static inline void smack_catset_bit(unsigned int cat, char *catsetp)
163 */ 163 */
164static void smk_netlabel_audit_set(struct netlbl_audit *nap) 164static void smk_netlabel_audit_set(struct netlbl_audit *nap)
165{ 165{
166 struct smack_known *skp = smk_of_current();
167
166 nap->loginuid = audit_get_loginuid(current); 168 nap->loginuid = audit_get_loginuid(current);
167 nap->sessionid = audit_get_sessionid(current); 169 nap->sessionid = audit_get_sessionid(current);
168 nap->secid = smack_to_secid(smk_of_current()); 170 nap->secid = skp->smk_secid;
169} 171}
170 172
171/* 173/*
@@ -306,7 +308,7 @@ static int smk_fill_rule(const char *subject, const char *object,
306 struct smack_known *skp; 308 struct smack_known *skp;
307 309
308 if (import) { 310 if (import) {
309 rule->smk_subject = smk_import(subject, len); 311 rule->smk_subject = smk_import_entry(subject, len);
310 if (rule->smk_subject == NULL) 312 if (rule->smk_subject == NULL)
311 return -1; 313 return -1;
312 314
@@ -321,7 +323,7 @@ static int smk_fill_rule(const char *subject, const char *object,
321 kfree(cp); 323 kfree(cp);
322 if (skp == NULL) 324 if (skp == NULL)
323 return -1; 325 return -1;
324 rule->smk_subject = skp->smk_known; 326 rule->smk_subject = skp;
325 327
326 cp = smk_parse_smack(object, len); 328 cp = smk_parse_smack(object, len);
327 if (cp == NULL) 329 if (cp == NULL)
@@ -445,7 +447,6 @@ static ssize_t smk_write_rules_list(struct file *file, const char __user *buf,
445 struct list_head *rule_list, 447 struct list_head *rule_list,
446 struct mutex *rule_lock, int format) 448 struct mutex *rule_lock, int format)
447{ 449{
448 struct smack_known *skp;
449 struct smack_parsed_rule *rule; 450 struct smack_parsed_rule *rule;
450 char *data; 451 char *data;
451 int datalen; 452 int datalen;
@@ -505,12 +506,10 @@ static ssize_t smk_write_rules_list(struct file *file, const char __user *buf,
505 goto out_free_rule; 506 goto out_free_rule;
506 } 507 }
507 508
508
509 if (rule_list == NULL) { 509 if (rule_list == NULL) {
510 load = 1; 510 load = 1;
511 skp = smk_find_entry(rule->smk_subject); 511 rule_list = &rule->smk_subject->smk_rules;
512 rule_list = &skp->smk_rules; 512 rule_lock = &rule->smk_subject->smk_rules_lock;
513 rule_lock = &skp->smk_rules_lock;
514 } 513 }
515 514
516 rc = smk_set_access(rule, rule_list, rule_lock, load); 515 rc = smk_set_access(rule, rule_list, rule_lock, load);
@@ -579,13 +578,14 @@ static void smk_rule_show(struct seq_file *s, struct smack_rule *srp, int max)
579 * because you should expect to be able to write 578 * because you should expect to be able to write
580 * anything you read back. 579 * anything you read back.
581 */ 580 */
582 if (strlen(srp->smk_subject) >= max || strlen(srp->smk_object) >= max) 581 if (strlen(srp->smk_subject->smk_known) >= max ||
582 strlen(srp->smk_object) >= max)
583 return; 583 return;
584 584
585 if (srp->smk_access == 0) 585 if (srp->smk_access == 0)
586 return; 586 return;
587 587
588 seq_printf(s, "%s %s", srp->smk_subject, srp->smk_object); 588 seq_printf(s, "%s %s", srp->smk_subject->smk_known, srp->smk_object);
589 589
590 seq_putc(s, ' '); 590 seq_putc(s, ' ');
591 591
@@ -738,9 +738,9 @@ static void smk_unlbl_ambient(char *oldambient)
738 __func__, __LINE__, rc); 738 __func__, __LINE__, rc);
739 } 739 }
740 if (smack_net_ambient == NULL) 740 if (smack_net_ambient == NULL)
741 smack_net_ambient = smack_known_floor.smk_known; 741 smack_net_ambient = &smack_known_floor;
742 742
743 rc = netlbl_cfg_unlbl_map_add(smack_net_ambient, PF_INET, 743 rc = netlbl_cfg_unlbl_map_add(smack_net_ambient->smk_known, PF_INET,
744 NULL, NULL, &nai); 744 NULL, NULL, &nai);
745 if (rc != 0) 745 if (rc != 0)
746 printk(KERN_WARNING "%s:%d add rc = %d\n", 746 printk(KERN_WARNING "%s:%d add rc = %d\n",
@@ -1535,11 +1535,12 @@ static ssize_t smk_read_ambient(struct file *filp, char __user *buf,
1535 */ 1535 */
1536 mutex_lock(&smack_ambient_lock); 1536 mutex_lock(&smack_ambient_lock);
1537 1537
1538 asize = strlen(smack_net_ambient) + 1; 1538 asize = strlen(smack_net_ambient->smk_known) + 1;
1539 1539
1540 if (cn >= asize) 1540 if (cn >= asize)
1541 rc = simple_read_from_buffer(buf, cn, ppos, 1541 rc = simple_read_from_buffer(buf, cn, ppos,
1542 smack_net_ambient, asize); 1542 smack_net_ambient->smk_known,
1543 asize);
1543 else 1544 else
1544 rc = -EINVAL; 1545 rc = -EINVAL;
1545 1546
@@ -1560,8 +1561,8 @@ static ssize_t smk_read_ambient(struct file *filp, char __user *buf,
1560static ssize_t smk_write_ambient(struct file *file, const char __user *buf, 1561static ssize_t smk_write_ambient(struct file *file, const char __user *buf,
1561 size_t count, loff_t *ppos) 1562 size_t count, loff_t *ppos)
1562{ 1563{
1564 struct smack_known *skp;
1563 char *oldambient; 1565 char *oldambient;
1564 char *smack = NULL;
1565 char *data; 1566 char *data;
1566 int rc = count; 1567 int rc = count;
1567 1568
@@ -1577,16 +1578,16 @@ static ssize_t smk_write_ambient(struct file *file, const char __user *buf,
1577 goto out; 1578 goto out;
1578 } 1579 }
1579 1580
1580 smack = smk_import(data, count); 1581 skp = smk_import_entry(data, count);
1581 if (smack == NULL) { 1582 if (skp == NULL) {
1582 rc = -EINVAL; 1583 rc = -EINVAL;
1583 goto out; 1584 goto out;
1584 } 1585 }
1585 1586
1586 mutex_lock(&smack_ambient_lock); 1587 mutex_lock(&smack_ambient_lock);
1587 1588
1588 oldambient = smack_net_ambient; 1589 oldambient = smack_net_ambient->smk_known;
1589 smack_net_ambient = smack; 1590 smack_net_ambient = skp;
1590 smk_unlbl_ambient(oldambient); 1591 smk_unlbl_ambient(oldambient);
1591 1592
1592 mutex_unlock(&smack_ambient_lock); 1593 mutex_unlock(&smack_ambient_lock);
@@ -1645,7 +1646,7 @@ static ssize_t smk_write_onlycap(struct file *file, const char __user *buf,
1645 size_t count, loff_t *ppos) 1646 size_t count, loff_t *ppos)
1646{ 1647{
1647 char *data; 1648 char *data;
1648 char *sp = smk_of_task(current->cred->security); 1649 struct smack_known *skp = smk_of_task(current->cred->security);
1649 int rc = count; 1650 int rc = count;
1650 1651
1651 if (!smack_privileged(CAP_MAC_ADMIN)) 1652 if (!smack_privileged(CAP_MAC_ADMIN))
@@ -1656,7 +1657,7 @@ static ssize_t smk_write_onlycap(struct file *file, const char __user *buf,
1656 * explicitly for clarity. The smk_access() implementation 1657 * explicitly for clarity. The smk_access() implementation
1657 * would use smk_access(smack_onlycap, MAY_WRITE) 1658 * would use smk_access(smack_onlycap, MAY_WRITE)
1658 */ 1659 */
1659 if (smack_onlycap != NULL && smack_onlycap != sp) 1660 if (smack_onlycap != NULL && smack_onlycap != skp->smk_known)
1660 return -EPERM; 1661 return -EPERM;
1661 1662
1662 data = kzalloc(count, GFP_KERNEL); 1663 data = kzalloc(count, GFP_KERNEL);
@@ -1866,8 +1867,8 @@ static ssize_t smk_user_access(struct file *file, const char __user *buf,
1866 if (res) 1867 if (res)
1867 return -EINVAL; 1868 return -EINVAL;
1868 1869
1869 res = smk_access(rule.smk_subject, rule.smk_object, rule.smk_access1, 1870 res = smk_access(rule.smk_subject, rule.smk_object,
1870 NULL); 1871 rule.smk_access1, NULL);
1871 data[0] = res == 0 ? '1' : '0'; 1872 data[0] = res == 0 ? '1' : '0';
1872 data[1] = '\0'; 1873 data[1] = '\0';
1873 1874