aboutsummaryrefslogtreecommitdiffstats
path: root/security/smack/smack.h
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/smack/smack.h
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/smack/smack.h')
-rw-r--r--security/smack/smack.h108
1 files changed, 55 insertions, 53 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}