Blame view

security/smack/smack_access.c 13.7 KB
e114e4737   Casey Schaufler   Smack: Simplified...
1
2
3
4
5
6
7
8
9
10
11
12
13
  /*
   * Copyright (C) 2007 Casey Schaufler <casey@schaufler-ca.com>
   *
   *      This program is free software; you can redistribute it and/or modify
   *      it under the terms of the GNU General Public License as published by
   *      the Free Software Foundation, version 2.
   *
   * Author:
   *      Casey Schaufler <casey@schaufler-ca.com>
   *
   */
  
  #include <linux/types.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
14
  #include <linux/slab.h>
e114e4737   Casey Schaufler   Smack: Simplified...
15
16
17
  #include <linux/fs.h>
  #include <linux/sched.h>
  #include "smack.h"
e114e4737   Casey Schaufler   Smack: Simplified...
18
  struct smack_known smack_known_huh = {
e114e4737   Casey Schaufler   Smack: Simplified...
19
20
21
22
23
24
  	.smk_known	= "?",
  	.smk_secid	= 2,
  	.smk_cipso	= NULL,
  };
  
  struct smack_known smack_known_hat = {
e114e4737   Casey Schaufler   Smack: Simplified...
25
26
27
28
29
30
  	.smk_known	= "^",
  	.smk_secid	= 3,
  	.smk_cipso	= NULL,
  };
  
  struct smack_known smack_known_star = {
e114e4737   Casey Schaufler   Smack: Simplified...
31
32
33
34
35
36
  	.smk_known	= "*",
  	.smk_secid	= 4,
  	.smk_cipso	= NULL,
  };
  
  struct smack_known smack_known_floor = {
e114e4737   Casey Schaufler   Smack: Simplified...
37
38
39
40
41
42
  	.smk_known	= "_",
  	.smk_secid	= 5,
  	.smk_cipso	= NULL,
  };
  
  struct smack_known smack_known_invalid = {
e114e4737   Casey Schaufler   Smack: Simplified...
43
44
45
46
  	.smk_known	= "",
  	.smk_secid	= 6,
  	.smk_cipso	= NULL,
  };
6d3dc07cb   Casey Schaufler   smack: Add suppor...
47
  struct smack_known smack_known_web = {
6d3dc07cb   Casey Schaufler   smack: Add suppor...
48
49
50
51
  	.smk_known	= "@",
  	.smk_secid	= 7,
  	.smk_cipso	= NULL,
  };
7198e2eeb   Etienne Basset   smack: convert sm...
52
  LIST_HEAD(smack_known_list);
e114e4737   Casey Schaufler   Smack: Simplified...
53
54
55
56
57
58
  
  /*
   * The initial value needs to be bigger than any of the
   * known values above.
   */
  static u32 smack_next_secid = 10;
ecfcc53fe   Etienne Basset   smack: implement ...
59
60
61
62
63
  /*
   * what events do we log
   * can be overwritten at run-time by /smack/logging
   */
  int log_policy = SMACK_AUDIT_DENIED;
e114e4737   Casey Schaufler   Smack: Simplified...
64
  /**
5c6d1125f   Jarkko Sakkinen   Smack: Transmute ...
65
66
67
   * smk_access_entry - look up matching access rule
   * @subject_label: a pointer to the subject's Smack label
   * @object_label: a pointer to the object's Smack label
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
68
   * @rule_list: the list of rules to search
5c6d1125f   Jarkko Sakkinen   Smack: Transmute ...
69
70
   *
   * This function looks up the subject/object pair in the
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
71
72
   * access rule list and returns the access mode. If no
   * entry is found returns -ENOENT.
5c6d1125f   Jarkko Sakkinen   Smack: Transmute ...
73
74
   *
   * NOTE:
5c6d1125f   Jarkko Sakkinen   Smack: Transmute ...
75
   *
272cd7a8c   Casey Schaufler   Smack: Rule list ...
76
77
78
79
80
81
82
83
84
85
86
87
   * Earlier versions of this function allowed for labels that
   * were not on the label list. This was done to allow for
   * labels to come over the network that had never been seen
   * before on this host. Unless the receiving socket has the
   * star label this will always result in a failure check. The
   * star labeled socket case is now handled in the networking
   * hooks so there is no case where the label is not on the
   * label list. Checking to see if the address of two labels
   * is the same is now a reliable test.
   *
   * Do the object check first because that is more
   * likely to differ.
5c6d1125f   Jarkko Sakkinen   Smack: Transmute ...
88
   */
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
89
90
  int smk_access_entry(char *subject_label, char *object_label,
  			struct list_head *rule_list)
5c6d1125f   Jarkko Sakkinen   Smack: Transmute ...
91
  {
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
92
  	int may = -ENOENT;
5c6d1125f   Jarkko Sakkinen   Smack: Transmute ...
93
  	struct smack_rule *srp;
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
94
  	list_for_each_entry_rcu(srp, rule_list, list) {
272cd7a8c   Casey Schaufler   Smack: Rule list ...
95
96
97
98
  		if (srp->smk_object == object_label &&
  		    srp->smk_subject == subject_label) {
  			may = srp->smk_access;
  			break;
5c6d1125f   Jarkko Sakkinen   Smack: Transmute ...
99
100
  		}
  	}
5c6d1125f   Jarkko Sakkinen   Smack: Transmute ...
101
102
103
104
105
  
  	return may;
  }
  
  /**
e114e4737   Casey Schaufler   Smack: Simplified...
106
107
108
109
   * smk_access - determine if a subject has a specific access to an object
   * @subject_label: a pointer to the subject's Smack label
   * @object_label: a pointer to the object's Smack label
   * @request: the access requested, in "MAY" format
ecfcc53fe   Etienne Basset   smack: implement ...
110
   * @a : a pointer to the audit data
e114e4737   Casey Schaufler   Smack: Simplified...
111
112
113
114
115
   *
   * This function looks up the subject/object pair in the
   * access rule list and returns 0 if the access is permitted,
   * non zero otherwise.
   *
272cd7a8c   Casey Schaufler   Smack: Rule list ...
116
   * Smack labels are shared on smack_list
e114e4737   Casey Schaufler   Smack: Simplified...
117
   */
ecfcc53fe   Etienne Basset   smack: implement ...
118
119
  int smk_access(char *subject_label, char *object_label, int request,
  	       struct smk_audit_info *a)
e114e4737   Casey Schaufler   Smack: Simplified...
120
  {
272cd7a8c   Casey Schaufler   Smack: Rule list ...
121
  	struct smack_known *skp;
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
122
  	int may = MAY_NOT;
ecfcc53fe   Etienne Basset   smack: implement ...
123
  	int rc = 0;
e114e4737   Casey Schaufler   Smack: Simplified...
124
125
126
127
128
129
  
  	/*
  	 * Hardcoded comparisons.
  	 *
  	 * A star subject can't access any object.
  	 */
272cd7a8c   Casey Schaufler   Smack: Rule list ...
130
  	if (subject_label == smack_known_star.smk_known) {
ecfcc53fe   Etienne Basset   smack: implement ...
131
132
133
  		rc = -EACCES;
  		goto out_audit;
  	}
e114e4737   Casey Schaufler   Smack: Simplified...
134
  	/*
6d3dc07cb   Casey Schaufler   smack: Add suppor...
135
136
137
138
139
  	 * An internet object can be accessed by any subject.
  	 * Tasks cannot be assigned the internet label.
  	 * An internet subject can access any object.
  	 */
  	if (object_label == smack_known_web.smk_known ||
272cd7a8c   Casey Schaufler   Smack: Rule list ...
140
  	    subject_label == smack_known_web.smk_known)
ecfcc53fe   Etienne Basset   smack: implement ...
141
  		goto out_audit;
6d3dc07cb   Casey Schaufler   smack: Add suppor...
142
  	/*
e114e4737   Casey Schaufler   Smack: Simplified...
143
144
  	 * A star object can be accessed by any subject.
  	 */
272cd7a8c   Casey Schaufler   Smack: Rule list ...
145
  	if (object_label == smack_known_star.smk_known)
ecfcc53fe   Etienne Basset   smack: implement ...
146
  		goto out_audit;
e114e4737   Casey Schaufler   Smack: Simplified...
147
148
149
150
  	/*
  	 * An object can be accessed in any way by a subject
  	 * with the same label.
  	 */
272cd7a8c   Casey Schaufler   Smack: Rule list ...
151
  	if (subject_label == object_label)
ecfcc53fe   Etienne Basset   smack: implement ...
152
  		goto out_audit;
e114e4737   Casey Schaufler   Smack: Simplified...
153
154
155
156
157
  	/*
  	 * A hat subject can read any object.
  	 * A floor object can be read by any subject.
  	 */
  	if ((request & MAY_ANYREAD) == request) {
272cd7a8c   Casey Schaufler   Smack: Rule list ...
158
  		if (object_label == smack_known_floor.smk_known)
ecfcc53fe   Etienne Basset   smack: implement ...
159
  			goto out_audit;
272cd7a8c   Casey Schaufler   Smack: Rule list ...
160
  		if (subject_label == smack_known_hat.smk_known)
ecfcc53fe   Etienne Basset   smack: implement ...
161
  			goto out_audit;
e114e4737   Casey Schaufler   Smack: Simplified...
162
163
164
165
166
  	}
  	/*
  	 * Beyond here an explicit relationship is required.
  	 * If the requested access is contained in the available
  	 * access (e.g. read is included in readwrite) it's
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
167
168
  	 * good. A negative response from smk_access_entry()
  	 * indicates there is no entry for this pair.
e114e4737   Casey Schaufler   Smack: Simplified...
169
  	 */
272cd7a8c   Casey Schaufler   Smack: Rule list ...
170
  	skp = smk_find_entry(subject_label);
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
171
  	rcu_read_lock();
272cd7a8c   Casey Schaufler   Smack: Rule list ...
172
  	may = smk_access_entry(subject_label, object_label, &skp->smk_rules);
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
173
174
175
  	rcu_read_unlock();
  
  	if (may > 0 && (request & may) == request)
ecfcc53fe   Etienne Basset   smack: implement ...
176
  		goto out_audit;
e114e4737   Casey Schaufler   Smack: Simplified...
177

ecfcc53fe   Etienne Basset   smack: implement ...
178
179
180
181
182
183
184
  	rc = -EACCES;
  out_audit:
  #ifdef CONFIG_AUDIT
  	if (a)
  		smack_log(subject_label, object_label, request, rc, a);
  #endif
  	return rc;
e114e4737   Casey Schaufler   Smack: Simplified...
185
186
187
188
  }
  
  /**
   * smk_curacc - determine if current has a specific access to an object
251a2a958   Randy Dunlap   smack: fix lots o...
189
190
   * @obj_label: a pointer to the object's Smack label
   * @mode: the access requested, in "MAY" format
ecfcc53fe   Etienne Basset   smack: implement ...
191
   * @a : common audit data
e114e4737   Casey Schaufler   Smack: Simplified...
192
193
194
   *
   * This function checks the current subject label/object label pair
   * in the access rule list and returns 0 if the access is permitted,
154462353   Casey Schaufler   smack: limit priv...
195
   * non zero otherwise. It allows that current may have the capability
e114e4737   Casey Schaufler   Smack: Simplified...
196
197
   * to override the rules.
   */
ecfcc53fe   Etienne Basset   smack: implement ...
198
  int smk_curacc(char *obj_label, u32 mode, struct smk_audit_info *a)
e114e4737   Casey Schaufler   Smack: Simplified...
199
  {
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
200
201
202
  	struct task_smack *tsp = current_security();
  	char *sp = smk_of_task(tsp);
  	int may;
e114e4737   Casey Schaufler   Smack: Simplified...
203
  	int rc;
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
204
205
206
  	/*
  	 * Check the global rule list
  	 */
ecfcc53fe   Etienne Basset   smack: implement ...
207
  	rc = smk_access(sp, obj_label, mode, NULL);
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
208
209
210
211
212
213
214
215
216
217
218
219
  	if (rc == 0) {
  		/*
  		 * If there is an entry in the task's rule list
  		 * it can further restrict access.
  		 */
  		may = smk_access_entry(sp, obj_label, &tsp->smk_rules);
  		if (may < 0)
  			goto out_audit;
  		if ((mode & may) == mode)
  			goto out_audit;
  		rc = -EACCES;
  	}
e114e4737   Casey Schaufler   Smack: Simplified...
220

154462353   Casey Schaufler   smack: limit priv...
221
222
223
224
225
  	/*
  	 * Return if a specific label has been designated as the
  	 * only one that gets privilege and current does not
  	 * have that label.
  	 */
676dac4b1   Casey Schaufler   This patch adds a...
226
  	if (smack_onlycap != NULL && smack_onlycap != sp)
ecfcc53fe   Etienne Basset   smack: implement ...
227
  		goto out_audit;
154462353   Casey Schaufler   smack: limit priv...
228

e114e4737   Casey Schaufler   Smack: Simplified...
229
  	if (capable(CAP_MAC_OVERRIDE))
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
230
  		rc = 0;
e114e4737   Casey Schaufler   Smack: Simplified...
231

ecfcc53fe   Etienne Basset   smack: implement ...
232
233
234
235
236
  out_audit:
  #ifdef CONFIG_AUDIT
  	if (a)
  		smack_log(sp, obj_label, mode, rc, a);
  #endif
e114e4737   Casey Schaufler   Smack: Simplified...
237
238
  	return rc;
  }
ecfcc53fe   Etienne Basset   smack: implement ...
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
  #ifdef CONFIG_AUDIT
  /**
   * smack_str_from_perm : helper to transalate an int to a
   * readable string
   * @string : the string to fill
   * @access : the int
   *
   */
  static inline void smack_str_from_perm(char *string, int access)
  {
  	int i = 0;
  	if (access & MAY_READ)
  		string[i++] = 'r';
  	if (access & MAY_WRITE)
  		string[i++] = 'w';
  	if (access & MAY_EXEC)
  		string[i++] = 'x';
  	if (access & MAY_APPEND)
  		string[i++] = 'a';
  	string[i] = '\0';
  }
  /**
   * smack_log_callback - SMACK specific information
   * will be called by generic audit code
   * @ab : the audit_buffer
   * @a  : audit_data
   *
   */
  static void smack_log_callback(struct audit_buffer *ab, void *a)
  {
  	struct common_audit_data *ad = a;
d4131ded4   Thomas Liu   security: Make ls...
270
  	struct smack_audit_data *sad = &ad->smack_audit_data;
ed5215a21   Thomas Liu   Move variable fun...
271
  	audit_log_format(ab, "lsm=SMACK fn=%s action=%s",
d4131ded4   Thomas Liu   security: Make ls...
272
  			 ad->smack_audit_data.function,
ecfcc53fe   Etienne Basset   smack: implement ...
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
  			 sad->result ? "denied" : "granted");
  	audit_log_format(ab, " subject=");
  	audit_log_untrustedstring(ab, sad->subject);
  	audit_log_format(ab, " object=");
  	audit_log_untrustedstring(ab, sad->object);
  	audit_log_format(ab, " requested=%s", sad->request);
  }
  
  /**
   *  smack_log - Audit the granting or denial of permissions.
   *  @subject_label : smack label of the requester
   *  @object_label  : smack label of the object being accessed
   *  @request: requested permissions
   *  @result: result from smk_access
   *  @a:  auxiliary audit data
   *
   * Audit the granting or denial of permissions in accordance
   * with the policy.
   */
  void smack_log(char *subject_label, char *object_label, int request,
  	       int result, struct smk_audit_info *ad)
  {
  	char request_buffer[SMK_NUM_ACCESS_TYPE + 1];
  	struct smack_audit_data *sad;
  	struct common_audit_data *a = &ad->a;
  
  	/* check if we have to log the current event */
  	if (result != 0 && (log_policy & SMACK_AUDIT_DENIED) == 0)
  		return;
  	if (result == 0 && (log_policy & SMACK_AUDIT_ACCEPT) == 0)
  		return;
d4131ded4   Thomas Liu   security: Make ls...
304
305
  	if (a->smack_audit_data.function == NULL)
  		a->smack_audit_data.function = "unknown";
ecfcc53fe   Etienne Basset   smack: implement ...
306
307
  
  	/* end preparing the audit data */
d4131ded4   Thomas Liu   security: Make ls...
308
  	sad = &a->smack_audit_data;
ecfcc53fe   Etienne Basset   smack: implement ...
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
  	smack_str_from_perm(request_buffer, request);
  	sad->subject = subject_label;
  	sad->object  = object_label;
  	sad->request = request_buffer;
  	sad->result  = result;
  	a->lsm_pre_audit = smack_log_callback;
  
  	common_lsm_audit(a);
  }
  #else /* #ifdef CONFIG_AUDIT */
  void smack_log(char *subject_label, char *object_label, int request,
                 int result, struct smk_audit_info *ad)
  {
  }
  #endif
e114e4737   Casey Schaufler   Smack: Simplified...
324
325
326
  static DEFINE_MUTEX(smack_known_lock);
  
  /**
272cd7a8c   Casey Schaufler   Smack: Rule list ...
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
   * smk_find_entry - find a label on the list, return the list entry
   * @string: a text string that might be a Smack label
   *
   * Returns a pointer to the entry in the label list that
   * matches the passed string.
   */
  struct smack_known *smk_find_entry(const char *string)
  {
  	struct smack_known *skp;
  
  	list_for_each_entry_rcu(skp, &smack_known_list, list) {
  		if (strncmp(skp->smk_known, string, SMK_MAXLEN) == 0)
  			return skp;
  	}
  
  	return NULL;
  }
  
  /**
0e94ae17c   Jarkko Sakkinen   Smack: allow to a...
346
347
   * smk_parse_smack - parse smack label from a text string
   * @string: a text string that might contain a Smack label
e114e4737   Casey Schaufler   Smack: Simplified...
348
   * @len: the maximum size, or zero if it is NULL terminated.
0e94ae17c   Jarkko Sakkinen   Smack: allow to a...
349
   * @smack: parsed smack label, or NULL if parse error
e114e4737   Casey Schaufler   Smack: Simplified...
350
   */
0e94ae17c   Jarkko Sakkinen   Smack: allow to a...
351
  void smk_parse_smack(const char *string, int len, char *smack)
e114e4737   Casey Schaufler   Smack: Simplified...
352
  {
e114e4737   Casey Schaufler   Smack: Simplified...
353
354
355
356
357
358
359
360
361
362
  	int found;
  	int i;
  
  	if (len <= 0 || len > SMK_MAXLEN)
  		len = SMK_MAXLEN;
  
  	for (i = 0, found = 0; i < SMK_LABELLEN; i++) {
  		if (found)
  			smack[i] = '\0';
  		else if (i >= len || string[i] > '~' || string[i] <= ' ' ||
ecfcc53fe   Etienne Basset   smack: implement ...
363
364
  			 string[i] == '/' || string[i] == '"' ||
  			 string[i] == '\\' || string[i] == '\'') {
e114e4737   Casey Schaufler   Smack: Simplified...
365
366
367
368
369
  			smack[i] = '\0';
  			found = 1;
  		} else
  			smack[i] = string[i];
  	}
0e94ae17c   Jarkko Sakkinen   Smack: allow to a...
370
371
372
373
374
375
376
377
378
379
380
381
382
383
  }
  
  /**
   * smk_import_entry - import a label, return the list entry
   * @string: a text string that might be a Smack label
   * @len: the maximum size, or zero if it is NULL terminated.
   *
   * Returns a pointer to the entry in the label list that
   * matches the passed string, adding it if necessary.
   */
  struct smack_known *smk_import_entry(const char *string, int len)
  {
  	struct smack_known *skp;
  	char smack[SMK_LABELLEN];
e114e4737   Casey Schaufler   Smack: Simplified...
384

0e94ae17c   Jarkko Sakkinen   Smack: allow to a...
385
  	smk_parse_smack(string, len, smack);
e114e4737   Casey Schaufler   Smack: Simplified...
386
387
388
389
  	if (smack[0] == '\0')
  		return NULL;
  
  	mutex_lock(&smack_known_lock);
272cd7a8c   Casey Schaufler   Smack: Rule list ...
390
  	skp = smk_find_entry(smack);
e114e4737   Casey Schaufler   Smack: Simplified...
391

272cd7a8c   Casey Schaufler   Smack: Rule list ...
392
  	if (skp == NULL) {
e114e4737   Casey Schaufler   Smack: Simplified...
393
394
  		skp = kzalloc(sizeof(struct smack_known), GFP_KERNEL);
  		if (skp != NULL) {
e114e4737   Casey Schaufler   Smack: Simplified...
395
396
397
  			strncpy(skp->smk_known, smack, SMK_MAXLEN);
  			skp->smk_secid = smack_next_secid++;
  			skp->smk_cipso = NULL;
272cd7a8c   Casey Schaufler   Smack: Rule list ...
398
  			INIT_LIST_HEAD(&skp->smk_rules);
e114e4737   Casey Schaufler   Smack: Simplified...
399
  			spin_lock_init(&skp->smk_cipsolock);
272cd7a8c   Casey Schaufler   Smack: Rule list ...
400
  			mutex_init(&skp->smk_rules_lock);
e114e4737   Casey Schaufler   Smack: Simplified...
401
402
403
404
  			/*
  			 * Make sure that the entry is actually
  			 * filled before putting it on the list.
  			 */
7198e2eeb   Etienne Basset   smack: convert sm...
405
  			list_add_rcu(&skp->list, &smack_known_list);
e114e4737   Casey Schaufler   Smack: Simplified...
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
  		}
  	}
  
  	mutex_unlock(&smack_known_lock);
  
  	return skp;
  }
  
  /**
   * smk_import - import a smack label
   * @string: a text string that might be a Smack label
   * @len: the maximum size, or zero if it is NULL terminated.
   *
   * Returns a pointer to the label in the label list that
   * matches the passed string, adding it if necessary.
   */
  char *smk_import(const char *string, int len)
  {
  	struct smack_known *skp;
4303154e8   Etienne Basset   smack: Add a new ...
425
426
427
  	/* labels cannot begin with a '-' */
  	if (string[0] == '-')
  		return NULL;
e114e4737   Casey Schaufler   Smack: Simplified...
428
429
430
431
432
433
434
435
436
437
  	skp = smk_import_entry(string, len);
  	if (skp == NULL)
  		return NULL;
  	return skp->smk_known;
  }
  
  /**
   * smack_from_secid - find the Smack label associated with a secid
   * @secid: an integer that might be associated with a Smack label
   *
25985edce   Lucas De Marchi   Fix common misspe...
438
   * Returns a pointer to the appropriate Smack label if there is one,
e114e4737   Casey Schaufler   Smack: Simplified...
439
440
441
442
443
   * otherwise a pointer to the invalid Smack label.
   */
  char *smack_from_secid(const u32 secid)
  {
  	struct smack_known *skp;
7198e2eeb   Etienne Basset   smack: convert sm...
444
445
446
447
  	rcu_read_lock();
  	list_for_each_entry_rcu(skp, &smack_known_list, list) {
  		if (skp->smk_secid == secid) {
  			rcu_read_unlock();
e114e4737   Casey Schaufler   Smack: Simplified...
448
  			return skp->smk_known;
7198e2eeb   Etienne Basset   smack: convert sm...
449
450
  		}
  	}
e114e4737   Casey Schaufler   Smack: Simplified...
451
452
453
454
455
  
  	/*
  	 * If we got this far someone asked for the translation
  	 * of a secid that is not on the list.
  	 */
7198e2eeb   Etienne Basset   smack: convert sm...
456
  	rcu_read_unlock();
e114e4737   Casey Schaufler   Smack: Simplified...
457
458
459
460
461
462
463
464
465
466
467
468
469
  	return smack_known_invalid.smk_known;
  }
  
  /**
   * smack_to_secid - find the secid associated with a Smack label
   * @smack: the Smack label
   *
   * Returns the appropriate secid if there is one,
   * otherwise 0
   */
  u32 smack_to_secid(const char *smack)
  {
  	struct smack_known *skp;
7198e2eeb   Etienne Basset   smack: convert sm...
470
471
472
473
  	rcu_read_lock();
  	list_for_each_entry_rcu(skp, &smack_known_list, list) {
  		if (strncmp(skp->smk_known, smack, SMK_MAXLEN) == 0) {
  			rcu_read_unlock();
e114e4737   Casey Schaufler   Smack: Simplified...
474
  			return skp->smk_secid;
7198e2eeb   Etienne Basset   smack: convert sm...
475
476
477
  		}
  	}
  	rcu_read_unlock();
e114e4737   Casey Schaufler   Smack: Simplified...
478
479
480
481
482
483
484
  	return 0;
  }
  
  /**
   * smack_from_cipso - find the Smack label associated with a CIPSO option
   * @level: Bell & LaPadula level from the network
   * @cp: Bell & LaPadula categories from the network
e114e4737   Casey Schaufler   Smack: Simplified...
485
486
487
   *
   * This is a simple lookup in the label table.
   *
272cd7a8c   Casey Schaufler   Smack: Rule list ...
488
   * Return the matching label from the label list or NULL.
e114e4737   Casey Schaufler   Smack: Simplified...
489
   */
272cd7a8c   Casey Schaufler   Smack: Rule list ...
490
  char *smack_from_cipso(u32 level, char *cp)
e114e4737   Casey Schaufler   Smack: Simplified...
491
492
493
  {
  	struct smack_known *kp;
  	char *final = NULL;
7198e2eeb   Etienne Basset   smack: convert sm...
494
495
  	rcu_read_lock();
  	list_for_each_entry(kp, &smack_known_list, list) {
e114e4737   Casey Schaufler   Smack: Simplified...
496
497
498
499
500
501
502
503
504
505
  		if (kp->smk_cipso == NULL)
  			continue;
  
  		spin_lock_bh(&kp->smk_cipsolock);
  
  		if (kp->smk_cipso->smk_level == level &&
  		    memcmp(kp->smk_cipso->smk_catset, cp, SMK_LABELLEN) == 0)
  			final = kp->smk_known;
  
  		spin_unlock_bh(&kp->smk_cipsolock);
272cd7a8c   Casey Schaufler   Smack: Rule list ...
506
507
508
  
  		if (final != NULL)
  			break;
e114e4737   Casey Schaufler   Smack: Simplified...
509
  	}
7198e2eeb   Etienne Basset   smack: convert sm...
510
  	rcu_read_unlock();
272cd7a8c   Casey Schaufler   Smack: Rule list ...
511
512
  
  	return final;
e114e4737   Casey Schaufler   Smack: Simplified...
513
514
515
516
517
518
519
520
521
522
523
524
  }
  
  /**
   * smack_to_cipso - find the CIPSO option to go with a Smack label
   * @smack: a pointer to the smack label in question
   * @cp: where to put the result
   *
   * Returns zero if a value is available, non-zero otherwise.
   */
  int smack_to_cipso(const char *smack, struct smack_cipso *cp)
  {
  	struct smack_known *kp;
7198e2eeb   Etienne Basset   smack: convert sm...
525
  	int found = 0;
e114e4737   Casey Schaufler   Smack: Simplified...
526

7198e2eeb   Etienne Basset   smack: convert sm...
527
528
  	rcu_read_lock();
  	list_for_each_entry_rcu(kp, &smack_known_list, list) {
e114e4737   Casey Schaufler   Smack: Simplified...
529
  		if (kp->smk_known == smack ||
7198e2eeb   Etienne Basset   smack: convert sm...
530
531
  		    strcmp(kp->smk_known, smack) == 0) {
  			found = 1;
e114e4737   Casey Schaufler   Smack: Simplified...
532
  			break;
7198e2eeb   Etienne Basset   smack: convert sm...
533
534
535
  		}
  	}
  	rcu_read_unlock();
e114e4737   Casey Schaufler   Smack: Simplified...
536

7198e2eeb   Etienne Basset   smack: convert sm...
537
  	if (found == 0 || kp->smk_cipso == NULL)
e114e4737   Casey Schaufler   Smack: Simplified...
538
539
540
541
542
  		return -ENOENT;
  
  	memcpy(cp, kp->smk_cipso, sizeof(struct smack_cipso));
  	return 0;
  }