diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
commit | c71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch) | |
tree | ecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /security/smack/smack_access.c | |
parent | ea53c912f8a86a8567697115b6a0d8152beee5c8 (diff) | |
parent | 6a00f206debf8a5c8899055726ad127dbeeed098 (diff) |
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts:
litmus/sched_cedf.c
Diffstat (limited to 'security/smack/smack_access.c')
-rw-r--r-- | security/smack/smack_access.c | 90 |
1 files changed, 67 insertions, 23 deletions
diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c index f4fac64c4da8..9637e107f7ea 100644 --- a/security/smack/smack_access.c +++ b/security/smack/smack_access.c | |||
@@ -67,6 +67,46 @@ static u32 smack_next_secid = 10; | |||
67 | int log_policy = SMACK_AUDIT_DENIED; | 67 | int 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 | * @rule_list: the list of rules to search | ||
74 | * | ||
75 | * This function looks up the subject/object pair in the | ||
76 | * access rule list and returns the access mode. If no | ||
77 | * entry is found returns -ENOENT. | ||
78 | * | ||
79 | * NOTE: | ||
80 | * Even though Smack labels are usually shared on smack_list | ||
81 | * labels that come in off the network can't be imported | ||
82 | * and added to the list for locking reasons. | ||
83 | * | ||
84 | * Therefore, it is necessary to check the contents of the labels, | ||
85 | * not just the pointer values. Of course, in most cases the labels | ||
86 | * will be on the list, so checking the pointers may be a worthwhile | ||
87 | * optimization. | ||
88 | */ | ||
89 | int smk_access_entry(char *subject_label, char *object_label, | ||
90 | struct list_head *rule_list) | ||
91 | { | ||
92 | int may = -ENOENT; | ||
93 | struct smack_rule *srp; | ||
94 | |||
95 | list_for_each_entry_rcu(srp, rule_list, list) { | ||
96 | if (srp->smk_subject == subject_label || | ||
97 | strcmp(srp->smk_subject, subject_label) == 0) { | ||
98 | if (srp->smk_object == object_label || | ||
99 | strcmp(srp->smk_object, object_label) == 0) { | ||
100 | may = srp->smk_access; | ||
101 | break; | ||
102 | } | ||
103 | } | ||
104 | } | ||
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 |
@@ -89,8 +129,7 @@ int log_policy = SMACK_AUDIT_DENIED; | |||
89 | int smk_access(char *subject_label, char *object_label, int request, | 129 | 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 | int may = MAY_NOT; |
93 | struct smack_rule *srp; | ||
94 | int rc = 0; | 133 | int rc = 0; |
95 | 134 | ||
96 | /* | 135 | /* |
@@ -142,24 +181,14 @@ int smk_access(char *subject_label, char *object_label, int request, | |||
142 | * Beyond here an explicit relationship is required. | 181 | * Beyond here an explicit relationship is required. |
143 | * If the requested access is contained in the available | 182 | * If the requested access is contained in the available |
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. A negative response from smk_access_entry() |
185 | * indicates there is no entry for this pair. | ||
146 | */ | 186 | */ |
147 | rcu_read_lock(); | 187 | rcu_read_lock(); |
148 | list_for_each_entry_rcu(srp, &smack_rule_list, list) { | 188 | may = smk_access_entry(subject_label, object_label, &smack_rule_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(); | 189 | rcu_read_unlock(); |
159 | /* | 190 | |
160 | * This is a bit map operation. | 191 | if (may > 0 && (request & may) == request) |
161 | */ | ||
162 | if ((request & may) == request) | ||
163 | goto out_audit; | 192 | goto out_audit; |
164 | 193 | ||
165 | rc = -EACCES; | 194 | rc = -EACCES; |
@@ -184,23 +213,38 @@ out_audit: | |||
184 | */ | 213 | */ |
185 | int smk_curacc(char *obj_label, u32 mode, struct smk_audit_info *a) | 214 | int smk_curacc(char *obj_label, u32 mode, struct smk_audit_info *a) |
186 | { | 215 | { |
216 | struct task_smack *tsp = current_security(); | ||
217 | char *sp = smk_of_task(tsp); | ||
218 | int may; | ||
187 | int rc; | 219 | int rc; |
188 | char *sp = current_security(); | ||
189 | 220 | ||
221 | /* | ||
222 | * Check the global rule list | ||
223 | */ | ||
190 | rc = smk_access(sp, obj_label, mode, NULL); | 224 | rc = smk_access(sp, obj_label, mode, NULL); |
191 | if (rc == 0) | 225 | if (rc == 0) { |
192 | goto out_audit; | 226 | /* |
227 | * If there is an entry in the task's rule list | ||
228 | * it can further restrict access. | ||
229 | */ | ||
230 | may = smk_access_entry(sp, obj_label, &tsp->smk_rules); | ||
231 | if (may < 0) | ||
232 | goto out_audit; | ||
233 | if ((mode & may) == mode) | ||
234 | goto out_audit; | ||
235 | rc = -EACCES; | ||
236 | } | ||
193 | 237 | ||
194 | /* | 238 | /* |
195 | * Return if a specific label has been designated as the | 239 | * Return if a specific label has been designated as the |
196 | * only one that gets privilege and current does not | 240 | * only one that gets privilege and current does not |
197 | * have that label. | 241 | * have that label. |
198 | */ | 242 | */ |
199 | if (smack_onlycap != NULL && smack_onlycap != current->cred->security) | 243 | if (smack_onlycap != NULL && smack_onlycap != sp) |
200 | goto out_audit; | 244 | goto out_audit; |
201 | 245 | ||
202 | if (capable(CAP_MAC_OVERRIDE)) | 246 | if (capable(CAP_MAC_OVERRIDE)) |
203 | return 0; | 247 | rc = 0; |
204 | 248 | ||
205 | out_audit: | 249 | out_audit: |
206 | #ifdef CONFIG_AUDIT | 250 | #ifdef CONFIG_AUDIT |
@@ -387,7 +431,7 @@ char *smk_import(const char *string, int len) | |||
387 | * smack_from_secid - find the Smack label associated with a secid | 431 | * smack_from_secid - find the Smack label associated with a secid |
388 | * @secid: an integer that might be associated with a Smack label | 432 | * @secid: an integer that might be associated with a Smack label |
389 | * | 433 | * |
390 | * Returns a pointer to the appropraite Smack label if there is one, | 434 | * Returns a pointer to the appropriate Smack label if there is one, |
391 | * otherwise a pointer to the invalid Smack label. | 435 | * otherwise a pointer to the invalid Smack label. |
392 | */ | 436 | */ |
393 | char *smack_from_secid(const u32 secid) | 437 | char *smack_from_secid(const u32 secid) |