aboutsummaryrefslogtreecommitdiffstats
path: root/security/smack/smack_access.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/smack/smack_access.c')
-rw-r--r--security/smack/smack_access.c52
1 files changed, 34 insertions, 18 deletions
diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c
index 7ba8478f599e..86453db4333d 100644
--- a/security/smack/smack_access.c
+++ b/security/smack/smack_access.c
@@ -70,10 +70,11 @@ int log_policy = SMACK_AUDIT_DENIED;
70 * smk_access_entry - look up matching access rule 70 * smk_access_entry - look up matching access rule
71 * @subject_label: a pointer to the subject's Smack label 71 * @subject_label: a pointer to the subject's Smack label
72 * @object_label: a pointer to the object's Smack label 72 * @object_label: a pointer to the object's Smack label
73 * @rule_list: the list of rules to search
73 * 74 *
74 * This function looks up the subject/object pair in the 75 * This function looks up the subject/object pair in the
75 * access rule list and returns pointer to the matching rule if found, 76 * access rule list and returns the access mode. If no
76 * NULL otherwise. 77 * entry is found returns -ENOENT.
77 * 78 *
78 * NOTE: 79 * NOTE:
79 * Even though Smack labels are usually shared on smack_list 80 * Even though Smack labels are usually shared on smack_list
@@ -85,13 +86,13 @@ int log_policy = SMACK_AUDIT_DENIED;
85 * will be on the list, so checking the pointers may be a worthwhile 86 * will be on the list, so checking the pointers may be a worthwhile
86 * optimization. 87 * optimization.
87 */ 88 */
88int smk_access_entry(char *subject_label, char *object_label) 89int smk_access_entry(char *subject_label, char *object_label,
90 struct list_head *rule_list)
89{ 91{
90 u32 may = MAY_NOT; 92 int may = -ENOENT;
91 struct smack_rule *srp; 93 struct smack_rule *srp;
92 94
93 rcu_read_lock(); 95 list_for_each_entry_rcu(srp, rule_list, list) {
94 list_for_each_entry_rcu(srp, &smack_rule_list, list) {
95 if (srp->smk_subject == subject_label || 96 if (srp->smk_subject == subject_label ||
96 strcmp(srp->smk_subject, subject_label) == 0) { 97 strcmp(srp->smk_subject, subject_label) == 0) {
97 if (srp->smk_object == object_label || 98 if (srp->smk_object == object_label ||
@@ -101,7 +102,6 @@ int smk_access_entry(char *subject_label, char *object_label)
101 } 102 }
102 } 103 }
103 } 104 }
104 rcu_read_unlock();
105 105
106 return may; 106 return may;
107} 107}
@@ -129,7 +129,7 @@ int smk_access_entry(char *subject_label, char *object_label)
129int smk_access(char *subject_label, char *object_label, int request, 129int smk_access(char *subject_label, char *object_label, int request,
130 struct smk_audit_info *a) 130 struct smk_audit_info *a)
131{ 131{
132 u32 may = MAY_NOT; 132 int may = MAY_NOT;
133 int rc = 0; 133 int rc = 0;
134 134
135 /* 135 /*
@@ -181,13 +181,14 @@ int smk_access(char *subject_label, char *object_label, int request,
181 * Beyond here an explicit relationship is required. 181 * Beyond here an explicit relationship is required.
182 * If the requested access is contained in the available 182 * If the requested access is contained in the available
183 * access (e.g. read is included in readwrite) it's 183 * access (e.g. read is included in readwrite) it's
184 * good. 184 * good. A negative response from smk_access_entry()
185 */ 185 * indicates there is no entry for this pair.
186 may = smk_access_entry(subject_label, object_label);
187 /*
188 * This is a bit map operation.
189 */ 186 */
190 if ((request & may) == request) 187 rcu_read_lock();
188 may = smk_access_entry(subject_label, object_label, &smack_rule_list);
189 rcu_read_unlock();
190
191 if (may > 0 && (request & may) == request)
191 goto out_audit; 192 goto out_audit;
192 193
193 rc = -EACCES; 194 rc = -EACCES;
@@ -212,12 +213,27 @@ out_audit:
212 */ 213 */
213int smk_curacc(char *obj_label, u32 mode, struct smk_audit_info *a) 214int smk_curacc(char *obj_label, u32 mode, struct smk_audit_info *a)
214{ 215{
216 struct task_smack *tsp = current_security();
217 char *sp = smk_of_task(tsp);
218 int may;
215 int rc; 219 int rc;
216 char *sp = smk_of_current();
217 220
221 /*
222 * Check the global rule list
223 */
218 rc = smk_access(sp, obj_label, mode, NULL); 224 rc = smk_access(sp, obj_label, mode, NULL);
219 if (rc == 0) 225 if (rc == 0) {
220 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 }
221 237
222 /* 238 /*
223 * Return if a specific label has been designated as the 239 * Return if a specific label has been designated as the
@@ -228,7 +244,7 @@ int smk_curacc(char *obj_label, u32 mode, struct smk_audit_info *a)
228 goto out_audit; 244 goto out_audit;
229 245
230 if (capable(CAP_MAC_OVERRIDE)) 246 if (capable(CAP_MAC_OVERRIDE))
231 return 0; 247 rc = 0;
232 248
233out_audit: 249out_audit:
234#ifdef CONFIG_AUDIT 250#ifdef CONFIG_AUDIT