aboutsummaryrefslogtreecommitdiffstats
path: root/security/smack/smack_access.c
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2015-02-10 14:35:36 -0500
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2015-02-10 14:35:36 -0500
commit4ba24fef3eb3b142197135223b90ced2f319cd53 (patch)
treea20c125b27740ec7b4c761b11d801108e1b316b2 /security/smack/smack_access.c
parent47c1ffb2b6b630894e9a16442611c056ab21c057 (diff)
parent98a4a59ee31a12105a2b84f5b8b515ac2cb208ef (diff)
Merge branch 'next' into for-linus
Prepare first round of input updates for 3.20.
Diffstat (limited to 'security/smack/smack_access.c')
-rw-r--r--security/smack/smack_access.c131
1 files changed, 57 insertions, 74 deletions
diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c
index f97d0842e621..1158430f5bb9 100644
--- a/security/smack/smack_access.c
+++ b/security/smack/smack_access.c
@@ -94,7 +94,7 @@ int smk_access_entry(char *subject_label, char *object_label,
94 struct smack_rule *srp; 94 struct smack_rule *srp;
95 95
96 list_for_each_entry_rcu(srp, rule_list, list) { 96 list_for_each_entry_rcu(srp, rule_list, list) {
97 if (srp->smk_object == object_label && 97 if (srp->smk_object->smk_known == object_label &&
98 srp->smk_subject->smk_known == subject_label) { 98 srp->smk_subject->smk_known == subject_label) {
99 may = srp->smk_access; 99 may = srp->smk_access;
100 break; 100 break;
@@ -111,8 +111,8 @@ int smk_access_entry(char *subject_label, char *object_label,
111 111
112/** 112/**
113 * smk_access - determine if a subject has a specific access to an object 113 * smk_access - determine if a subject has a specific access to an object
114 * @subject_known: a pointer to the subject's Smack label entry 114 * @subject: a pointer to the subject's Smack label entry
115 * @object_label: a pointer to the object's Smack label 115 * @object: a pointer to the object's Smack label entry
116 * @request: the access requested, in "MAY" format 116 * @request: the access requested, in "MAY" format
117 * @a : a pointer to the audit data 117 * @a : a pointer to the audit data
118 * 118 *
@@ -122,8 +122,8 @@ int smk_access_entry(char *subject_label, char *object_label,
122 * 122 *
123 * Smack labels are shared on smack_list 123 * Smack labels are shared on smack_list
124 */ 124 */
125int smk_access(struct smack_known *subject_known, char *object_label, 125int smk_access(struct smack_known *subject, struct smack_known *object,
126 int request, struct smk_audit_info *a) 126 int request, struct smk_audit_info *a)
127{ 127{
128 int may = MAY_NOT; 128 int may = MAY_NOT;
129 int rc = 0; 129 int rc = 0;
@@ -133,7 +133,7 @@ int smk_access(struct smack_known *subject_known, char *object_label,
133 * 133 *
134 * A star subject can't access any object. 134 * A star subject can't access any object.
135 */ 135 */
136 if (subject_known == &smack_known_star) { 136 if (subject == &smack_known_star) {
137 rc = -EACCES; 137 rc = -EACCES;
138 goto out_audit; 138 goto out_audit;
139 } 139 }
@@ -142,28 +142,28 @@ int smk_access(struct smack_known *subject_known, char *object_label,
142 * Tasks cannot be assigned the internet label. 142 * Tasks cannot be assigned the internet label.
143 * An internet subject can access any object. 143 * An internet subject can access any object.
144 */ 144 */
145 if (object_label == smack_known_web.smk_known || 145 if (object == &smack_known_web || subject == &smack_known_web)
146 subject_known == &smack_known_web)
147 goto out_audit; 146 goto out_audit;
148 /* 147 /*
149 * A star object can be accessed by any subject. 148 * A star object can be accessed by any subject.
150 */ 149 */
151 if (object_label == smack_known_star.smk_known) 150 if (object == &smack_known_star)
152 goto out_audit; 151 goto out_audit;
153 /* 152 /*
154 * An object can be accessed in any way by a subject 153 * An object can be accessed in any way by a subject
155 * with the same label. 154 * with the same label.
156 */ 155 */
157 if (subject_known->smk_known == object_label) 156 if (subject->smk_known == object->smk_known)
158 goto out_audit; 157 goto out_audit;
159 /* 158 /*
160 * A hat subject can read any object. 159 * A hat subject can read or lock any object.
161 * A floor object can be read by any subject. 160 * A floor object can be read or locked by any subject.
162 */ 161 */
163 if ((request & MAY_ANYREAD) == request) { 162 if ((request & MAY_ANYREAD) == request ||
164 if (object_label == smack_known_floor.smk_known) 163 (request & MAY_LOCK) == request) {
164 if (object == &smack_known_floor)
165 goto out_audit; 165 goto out_audit;
166 if (subject_known == &smack_known_hat) 166 if (subject == &smack_known_hat)
167 goto out_audit; 167 goto out_audit;
168 } 168 }
169 /* 169 /*
@@ -174,27 +174,38 @@ int smk_access(struct smack_known *subject_known, char *object_label,
174 * indicates there is no entry for this pair. 174 * indicates there is no entry for this pair.
175 */ 175 */
176 rcu_read_lock(); 176 rcu_read_lock();
177 may = smk_access_entry(subject_known->smk_known, object_label, 177 may = smk_access_entry(subject->smk_known, object->smk_known,
178 &subject_known->smk_rules); 178 &subject->smk_rules);
179 rcu_read_unlock(); 179 rcu_read_unlock();
180 180
181 if (may > 0 && (request & may) == request) 181 if (may <= 0 || (request & may) != request) {
182 rc = -EACCES;
182 goto out_audit; 183 goto out_audit;
184 }
185#ifdef CONFIG_SECURITY_SMACK_BRINGUP
186 /*
187 * Return a positive value if using bringup mode.
188 * This allows the hooks to identify checks that
189 * succeed because of "b" rules.
190 */
191 if (may & MAY_BRINGUP)
192 rc = MAY_BRINGUP;
193#endif
183 194
184 rc = -EACCES;
185out_audit: 195out_audit:
186#ifdef CONFIG_AUDIT 196#ifdef CONFIG_AUDIT
187 if (a) 197 if (a)
188 smack_log(subject_known->smk_known, object_label, request, 198 smack_log(subject->smk_known, object->smk_known,
189 rc, a); 199 request, rc, a);
190#endif 200#endif
201
191 return rc; 202 return rc;
192} 203}
193 204
194/** 205/**
195 * smk_tskacc - determine if a task has a specific access to an object 206 * smk_tskacc - determine if a task has a specific access to an object
196 * @tsp: a pointer to the subject task 207 * @tsp: a pointer to the subject's task
197 * @obj_label: a pointer to the object's Smack label 208 * @obj_known: a pointer to the object's label entry
198 * @mode: the access requested, in "MAY" format 209 * @mode: the access requested, in "MAY" format
199 * @a : common audit data 210 * @a : common audit data
200 * 211 *
@@ -203,24 +214,25 @@ out_audit:
203 * non zero otherwise. It allows that the task may have the capability 214 * non zero otherwise. It allows that the task may have the capability
204 * to override the rules. 215 * to override the rules.
205 */ 216 */
206int smk_tskacc(struct task_smack *subject, char *obj_label, 217int smk_tskacc(struct task_smack *tsp, struct smack_known *obj_known,
207 u32 mode, struct smk_audit_info *a) 218 u32 mode, struct smk_audit_info *a)
208{ 219{
209 struct smack_known *skp = smk_of_task(subject); 220 struct smack_known *sbj_known = smk_of_task(tsp);
210 int may; 221 int may;
211 int rc; 222 int rc;
212 223
213 /* 224 /*
214 * Check the global rule list 225 * Check the global rule list
215 */ 226 */
216 rc = smk_access(skp, obj_label, mode, NULL); 227 rc = smk_access(sbj_known, obj_known, mode, NULL);
217 if (rc == 0) { 228 if (rc >= 0) {
218 /* 229 /*
219 * If there is an entry in the task's rule list 230 * If there is an entry in the task's rule list
220 * it can further restrict access. 231 * it can further restrict access.
221 */ 232 */
222 may = smk_access_entry(skp->smk_known, obj_label, 233 may = smk_access_entry(sbj_known->smk_known,
223 &subject->smk_rules); 234 obj_known->smk_known,
235 &tsp->smk_rules);
224 if (may < 0) 236 if (may < 0)
225 goto out_audit; 237 goto out_audit;
226 if ((mode & may) == mode) 238 if ((mode & may) == mode)
@@ -237,14 +249,15 @@ int smk_tskacc(struct task_smack *subject, char *obj_label,
237out_audit: 249out_audit:
238#ifdef CONFIG_AUDIT 250#ifdef CONFIG_AUDIT
239 if (a) 251 if (a)
240 smack_log(skp->smk_known, obj_label, mode, rc, a); 252 smack_log(sbj_known->smk_known, obj_known->smk_known,
253 mode, rc, a);
241#endif 254#endif
242 return rc; 255 return rc;
243} 256}
244 257
245/** 258/**
246 * smk_curacc - determine if current has a specific access to an object 259 * smk_curacc - determine if current has a specific access to an object
247 * @obj_label: a pointer to the object's Smack label 260 * @obj_known: a pointer to the object's Smack label entry
248 * @mode: the access requested, in "MAY" format 261 * @mode: the access requested, in "MAY" format
249 * @a : common audit data 262 * @a : common audit data
250 * 263 *
@@ -253,11 +266,12 @@ out_audit:
253 * non zero otherwise. It allows that current may have the capability 266 * non zero otherwise. It allows that current may have the capability
254 * to override the rules. 267 * to override the rules.
255 */ 268 */
256int smk_curacc(char *obj_label, u32 mode, struct smk_audit_info *a) 269int smk_curacc(struct smack_known *obj_known,
270 u32 mode, struct smk_audit_info *a)
257{ 271{
258 struct task_smack *tsp = current_security(); 272 struct task_smack *tsp = current_security();
259 273
260 return smk_tskacc(tsp, obj_label, mode, a); 274 return smk_tskacc(tsp, obj_known, mode, a);
261} 275}
262 276
263#ifdef CONFIG_AUDIT 277#ifdef CONFIG_AUDIT
@@ -328,6 +342,13 @@ void smack_log(char *subject_label, char *object_label, int request,
328 struct smack_audit_data *sad; 342 struct smack_audit_data *sad;
329 struct common_audit_data *a = &ad->a; 343 struct common_audit_data *a = &ad->a;
330 344
345#ifdef CONFIG_SECURITY_SMACK_BRINGUP
346 /*
347 * The result may be positive in bringup mode.
348 */
349 if (result > 0)
350 result = 0;
351#endif
331 /* check if we have to log the current event */ 352 /* check if we have to log the current event */
332 if (result != 0 && (log_policy & SMACK_AUDIT_DENIED) == 0) 353 if (result != 0 && (log_policy & SMACK_AUDIT_DENIED) == 0)
333 return; 354 return;
@@ -431,10 +452,9 @@ char *smk_parse_smack(const char *string, int len)
431 return NULL; 452 return NULL;
432 453
433 smack = kzalloc(i + 1, GFP_KERNEL); 454 smack = kzalloc(i + 1, GFP_KERNEL);
434 if (smack != NULL) { 455 if (smack != NULL)
435 strncpy(smack, string, i + 1); 456 strncpy(smack, string, i);
436 smack[i] = '\0'; 457
437 }
438 return smack; 458 return smack;
439} 459}
440 460
@@ -544,27 +564,6 @@ unlockout:
544} 564}
545 565
546/** 566/**
547 * smk_import - import a smack label
548 * @string: a text string that might be a Smack label
549 * @len: the maximum size, or zero if it is NULL terminated.
550 *
551 * Returns a pointer to the label in the label list that
552 * matches the passed string, adding it if necessary.
553 */
554char *smk_import(const char *string, int len)
555{
556 struct smack_known *skp;
557
558 /* labels cannot begin with a '-' */
559 if (string[0] == '-')
560 return NULL;
561 skp = smk_import_entry(string, len);
562 if (skp == NULL)
563 return NULL;
564 return skp->smk_known;
565}
566
567/**
568 * smack_from_secid - find the Smack label associated with a secid 567 * smack_from_secid - find the Smack label associated with a secid
569 * @secid: an integer that might be associated with a Smack label 568 * @secid: an integer that might be associated with a Smack label
570 * 569 *
@@ -590,19 +589,3 @@ struct smack_known *smack_from_secid(const u32 secid)
590 rcu_read_unlock(); 589 rcu_read_unlock();
591 return &smack_known_invalid; 590 return &smack_known_invalid;
592} 591}
593
594/**
595 * smack_to_secid - find the secid associated with a Smack label
596 * @smack: the Smack label
597 *
598 * Returns the appropriate secid if there is one,
599 * otherwise 0
600 */
601u32 smack_to_secid(const char *smack)
602{
603 struct smack_known *skp = smk_find_entry(smack);
604
605 if (skp == NULL)
606 return 0;
607 return skp->smk_secid;
608}