diff options
Diffstat (limited to 'security/smack/smack_access.c')
-rw-r--r-- | security/smack/smack_access.c | 52 |
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 | */ |
88 | int smk_access_entry(char *subject_label, char *object_label) | 89 | int 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) | |||
129 | int smk_access(char *subject_label, char *object_label, int request, | 129 | int 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 | */ |
213 | 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) |
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 | ||
233 | out_audit: | 249 | out_audit: |
234 | #ifdef CONFIG_AUDIT | 250 | #ifdef CONFIG_AUDIT |