Blame view

security/selinux/ss/mls.c 15.7 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
7
8
9
10
  /*
   * Implementation of the multi-level security (MLS) policy.
   *
   * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
   */
  /*
   * Updated: Trusted Computer Solutions, Inc. <dgoeddel@trustedcs.com>
   *
   *	Support for enhanced MLS infrastructure.
   *
376bd9cb3   Darrel Goeddel   [PATCH] support f...
11
   * Copyright (C) 2004-2006 Trusted Computer Solutions, Inc.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
12
   */
7420ed23a   Venkat Yekkirala   [NetLabel]: SELin...
13
  /*
82c21bfab   Paul Moore   doc: Update the e...
14
   * Updated: Hewlett-Packard <paul@paul-moore.com>
7420ed23a   Venkat Yekkirala   [NetLabel]: SELin...
15
   *
027527603   Paul Moore   NetLabel: convert...
16
   *      Added support to import/export the MLS label from NetLabel
7420ed23a   Venkat Yekkirala   [NetLabel]: SELin...
17
18
19
   *
   * (c) Copyright Hewlett-Packard Development Company, L.P., 2006
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
20
21
22
23
24
  
  #include <linux/kernel.h>
  #include <linux/slab.h>
  #include <linux/string.h>
  #include <linux/errno.h>
027527603   Paul Moore   NetLabel: convert...
25
  #include <net/netlabel.h>
f5c1d5b2a   James Morris   [PATCH] SELinux: ...
26
  #include "sidtab.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
27
28
29
30
31
32
33
34
  #include "mls.h"
  #include "policydb.h"
  #include "services.h"
  
  /*
   * Return the length in bytes for the MLS fields of the
   * security context string representation of `context'.
   */
1a5e6f872   Eric Paris   SELinux: mls.c wh...
35
  int mls_compute_context_len(struct context *context)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
36
  {
9fe79ad1e   KaiGai Kohei   SELinux: improve ...
37
38
39
  	int i, l, len, head, prev;
  	char *nm;
  	struct ebitmap *e;
782ebb992   Stephen Smalley   [PATCH] selinux: ...
40
  	struct ebitmap_node *node;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
41

0719aaf5e   Guido Trentalancia   selinux: allow ML...
42
  	if (!policydb.mls_enabled)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
43
44
45
46
  		return 0;
  
  	len = 1; /* for the beginning ":" */
  	for (l = 0; l < 2; l++) {
9fe79ad1e   KaiGai Kohei   SELinux: improve ...
47
  		int index_sens = context->range.level[l].sens;
ac76c05be   Eric Paris   selinux: convert ...
48
  		len += strlen(sym_name(&policydb, SYM_LEVELS, index_sens - 1));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
49

9fe79ad1e   KaiGai Kohei   SELinux: improve ...
50
51
52
53
54
55
56
57
  		/* categories */
  		head = -2;
  		prev = -2;
  		e = &context->range.level[l].cat;
  		ebitmap_for_each_positive_bit(e, node, i) {
  			if (i - prev > 1) {
  				/* one or more negative bits are skipped */
  				if (head != prev) {
ac76c05be   Eric Paris   selinux: convert ...
58
  					nm = sym_name(&policydb, SYM_CATS, prev);
9fe79ad1e   KaiGai Kohei   SELinux: improve ...
59
60
  					len += strlen(nm) + 1;
  				}
ac76c05be   Eric Paris   selinux: convert ...
61
  				nm = sym_name(&policydb, SYM_CATS, i);
9fe79ad1e   KaiGai Kohei   SELinux: improve ...
62
63
  				len += strlen(nm) + 1;
  				head = i;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
64
  			}
9fe79ad1e   KaiGai Kohei   SELinux: improve ...
65
66
67
  			prev = i;
  		}
  		if (prev != head) {
ac76c05be   Eric Paris   selinux: convert ...
68
  			nm = sym_name(&policydb, SYM_CATS, prev);
9fe79ad1e   KaiGai Kohei   SELinux: improve ...
69
  			len += strlen(nm) + 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
70
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
71
72
  		if (l == 0) {
  			if (mls_level_eq(&context->range.level[0],
9fe79ad1e   KaiGai Kohei   SELinux: improve ...
73
  					 &context->range.level[1]))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
  				break;
  			else
  				len++;
  		}
  	}
  
  	return len;
  }
  
  /*
   * Write the security context string representation of
   * the MLS fields of `context' into the string `*scontext'.
   * Update `*scontext' to point to the end of the MLS fields.
   */
  void mls_sid_to_context(struct context *context,
1a5e6f872   Eric Paris   SELinux: mls.c wh...
89
  			char **scontext)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
90
  {
9fe79ad1e   KaiGai Kohei   SELinux: improve ...
91
92
93
  	char *scontextp, *nm;
  	int i, l, head, prev;
  	struct ebitmap *e;
782ebb992   Stephen Smalley   [PATCH] selinux: ...
94
  	struct ebitmap_node *node;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
95

0719aaf5e   Guido Trentalancia   selinux: allow ML...
96
  	if (!policydb.mls_enabled)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
97
98
99
100
101
102
103
104
  		return;
  
  	scontextp = *scontext;
  
  	*scontextp = ':';
  	scontextp++;
  
  	for (l = 0; l < 2; l++) {
ac76c05be   Eric Paris   selinux: convert ...
105
106
  		strcpy(scontextp, sym_name(&policydb, SYM_LEVELS,
  					   context->range.level[l].sens - 1));
9fe79ad1e   KaiGai Kohei   SELinux: improve ...
107
  		scontextp += strlen(scontextp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
108
109
  
  		/* categories */
9fe79ad1e   KaiGai Kohei   SELinux: improve ...
110
111
112
113
114
115
116
117
  		head = -2;
  		prev = -2;
  		e = &context->range.level[l].cat;
  		ebitmap_for_each_positive_bit(e, node, i) {
  			if (i - prev > 1) {
  				/* one or more negative bits are skipped */
  				if (prev != head) {
  					if (prev - head > 1)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
118
119
120
  						*scontextp++ = '.';
  					else
  						*scontextp++ = ',';
ac76c05be   Eric Paris   selinux: convert ...
121
  					nm = sym_name(&policydb, SYM_CATS, prev);
9fe79ad1e   KaiGai Kohei   SELinux: improve ...
122
123
  					strcpy(scontextp, nm);
  					scontextp += strlen(nm);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
124
  				}
9fe79ad1e   KaiGai Kohei   SELinux: improve ...
125
126
127
128
  				if (prev < 0)
  					*scontextp++ = ':';
  				else
  					*scontextp++ = ',';
ac76c05be   Eric Paris   selinux: convert ...
129
  				nm = sym_name(&policydb, SYM_CATS, i);
9fe79ad1e   KaiGai Kohei   SELinux: improve ...
130
131
132
  				strcpy(scontextp, nm);
  				scontextp += strlen(nm);
  				head = i;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
133
  			}
9fe79ad1e   KaiGai Kohei   SELinux: improve ...
134
  			prev = i;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
135
  		}
9fe79ad1e   KaiGai Kohei   SELinux: improve ...
136
137
  		if (prev != head) {
  			if (prev - head > 1)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
138
139
140
  				*scontextp++ = '.';
  			else
  				*scontextp++ = ',';
ac76c05be   Eric Paris   selinux: convert ...
141
  			nm = sym_name(&policydb, SYM_CATS, prev);
9fe79ad1e   KaiGai Kohei   SELinux: improve ...
142
143
  			strcpy(scontextp, nm);
  			scontextp += strlen(nm);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
144
145
146
147
  		}
  
  		if (l == 0) {
  			if (mls_level_eq(&context->range.level[0],
1a5e6f872   Eric Paris   SELinux: mls.c wh...
148
  					 &context->range.level[1]))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
149
  				break;
9fe79ad1e   KaiGai Kohei   SELinux: improve ...
150
151
  			else
  				*scontextp++ = '-';
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
152
153
154
155
156
157
  		}
  	}
  
  	*scontext = scontextp;
  	return;
  }
45e5421eb   Stephen Smalley   SELinux: add more...
158
159
160
  int mls_level_isvalid(struct policydb *p, struct mls_level *l)
  {
  	struct level_datum *levdatum;
45e5421eb   Stephen Smalley   SELinux: add more...
161
162
163
164
  
  	if (!l->sens || l->sens > p->p_levels.nprim)
  		return 0;
  	levdatum = hashtab_search(p->p_levels.table,
ac76c05be   Eric Paris   selinux: convert ...
165
  				  sym_name(p, SYM_LEVELS, l->sens - 1));
45e5421eb   Stephen Smalley   SELinux: add more...
166
167
  	if (!levdatum)
  		return 0;
fee711429   Waiman Long   SELinux: Reduce o...
168
169
170
171
172
173
174
  	/*
  	 * Return 1 iff all the bits set in l->cat are also be set in
  	 * levdatum->level->cat and no bit in l->cat is larger than
  	 * p->p_cats.nprim.
  	 */
  	return ebitmap_contains(&levdatum->level->cat, &l->cat,
  				p->p_cats.nprim);
45e5421eb   Stephen Smalley   SELinux: add more...
175
176
177
178
179
180
181
182
  }
  
  int mls_range_isvalid(struct policydb *p, struct mls_range *r)
  {
  	return (mls_level_isvalid(p, &r->level[0]) &&
  		mls_level_isvalid(p, &r->level[1]) &&
  		mls_level_dom(&r->level[1], &r->level[0]));
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
183
184
185
186
187
188
  /*
   * Return 1 if the MLS fields in the security context
   * structure `c' are valid.  Return 0 otherwise.
   */
  int mls_context_isvalid(struct policydb *p, struct context *c)
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
189
  	struct user_datum *usrdatum;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
190

0719aaf5e   Guido Trentalancia   selinux: allow ML...
191
  	if (!p->mls_enabled)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
192
  		return 1;
45e5421eb   Stephen Smalley   SELinux: add more...
193
  	if (!mls_range_isvalid(p, &c->range))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
194
  		return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
  	if (c->role == OBJECT_R_VAL)
  		return 1;
  
  	/*
  	 * User must be authorized for the MLS range.
  	 */
  	if (!c->user || c->user > p->p_users.nprim)
  		return 0;
  	usrdatum = p->user_val_to_struct[c->user - 1];
  	if (!mls_range_contains(usrdatum->range, c->range))
  		return 0; /* user may not be associated with range */
  
  	return 1;
  }
  
  /*
   * Set the MLS fields in the security context structure
   * `context' based on the string representation in
   * the string `*scontext'.  Update `*scontext' to
   * point to the end of the string representation of
   * the MLS fields.
   *
   * This function modifies the string in place, inserting
   * NULL characters to terminate the MLS fields.
f5c1d5b2a   James Morris   [PATCH] SELinux: ...
219
220
221
222
223
224
225
226
   *
   * If a def_sid is provided and no MLS field is present,
   * copy the MLS field of the associated default context.
   * Used for upgraded to MLS systems where objects may lack
   * MLS fields.
   *
   * Policy read-lock must be held for sidtab lookup.
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
227
   */
12b29f345   Stephen Smalley   selinux: support ...
228
229
  int mls_context_to_sid(struct policydb *pol,
  		       char oldc,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
230
  		       char **scontext,
f5c1d5b2a   James Morris   [PATCH] SELinux: ...
231
232
233
  		       struct context *context,
  		       struct sidtab *s,
  		       u32 def_sid)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
234
235
236
237
238
239
240
  {
  
  	char delim;
  	char *scontextp, *p, *rngptr;
  	struct level_datum *levdatum;
  	struct cat_datum *catdatum, *rngdatum;
  	int l, rc = -EINVAL;
0719aaf5e   Guido Trentalancia   selinux: allow ML...
241
  	if (!pol->mls_enabled) {
e517a0cd8   Stephen Smalley   [PATCH] selinux: ...
242
  		if (def_sid != SECSID_NULL && oldc)
c1a7368a6   wzt.wzt@gmail.com   Security: Fix cod...
243
  			*scontext += strlen(*scontext) + 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
244
  		return 0;
e517a0cd8   Stephen Smalley   [PATCH] selinux: ...
245
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
246

f5c1d5b2a   James Morris   [PATCH] SELinux: ...
247
248
249
250
251
252
253
254
255
256
257
258
259
  	/*
  	 * No MLS component to the security context, try and map to
  	 * default if provided.
  	 */
  	if (!oldc) {
  		struct context *defcon;
  
  		if (def_sid == SECSID_NULL)
  			goto out;
  
  		defcon = sidtab_search(s, def_sid);
  		if (!defcon)
  			goto out;
0efc61eae   Venkat Yekkirala   selinux: Delete m...
260
  		rc = mls_context_cpy(context, defcon);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
261
  		goto out;
f5c1d5b2a   James Morris   [PATCH] SELinux: ...
262
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
263
264
265
266
267
268
269
  
  	/* Extract low sensitivity. */
  	scontextp = p = *scontext;
  	while (*p && *p != ':' && *p != '-')
  		p++;
  
  	delim = *p;
df4ea865f   Vesa-Matti J Kari   SELinux: Trivial ...
270
271
  	if (delim != '\0')
  		*p++ = '\0';
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
272
273
  
  	for (l = 0; l < 2; l++) {
12b29f345   Stephen Smalley   selinux: support ...
274
  		levdatum = hashtab_search(pol->p_levels.table, scontextp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
275
276
277
278
279
280
281
282
283
284
285
286
287
288
  		if (!levdatum) {
  			rc = -EINVAL;
  			goto out;
  		}
  
  		context->range.level[l].sens = levdatum->level->sens;
  
  		if (delim == ':') {
  			/* Extract category set. */
  			while (1) {
  				scontextp = p;
  				while (*p && *p != ',' && *p != '-')
  					p++;
  				delim = *p;
df4ea865f   Vesa-Matti J Kari   SELinux: Trivial ...
289
290
  				if (delim != '\0')
  					*p++ = '\0';
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
291
292
  
  				/* Separate into range if exists */
1a5e6f872   Eric Paris   SELinux: mls.c wh...
293
294
  				rngptr = strchr(scontextp, '.');
  				if (rngptr != NULL) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
295
  					/* Remove '.' */
df4ea865f   Vesa-Matti J Kari   SELinux: Trivial ...
296
  					*rngptr++ = '\0';
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
297
  				}
12b29f345   Stephen Smalley   selinux: support ...
298
  				catdatum = hashtab_search(pol->p_cats.table,
1a5e6f872   Eric Paris   SELinux: mls.c wh...
299
  							  scontextp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
300
301
302
303
304
305
  				if (!catdatum) {
  					rc = -EINVAL;
  					goto out;
  				}
  
  				rc = ebitmap_set_bit(&context->range.level[l].cat,
1a5e6f872   Eric Paris   SELinux: mls.c wh...
306
  						     catdatum->value - 1, 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
307
308
309
310
311
312
  				if (rc)
  					goto out;
  
  				/* If range, set all categories in range */
  				if (rngptr) {
  					int i;
12b29f345   Stephen Smalley   selinux: support ...
313
  					rngdatum = hashtab_search(pol->p_cats.table, rngptr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
  					if (!rngdatum) {
  						rc = -EINVAL;
  						goto out;
  					}
  
  					if (catdatum->value >= rngdatum->value) {
  						rc = -EINVAL;
  						goto out;
  					}
  
  					for (i = catdatum->value; i < rngdatum->value; i++) {
  						rc = ebitmap_set_bit(&context->range.level[l].cat, i, 1);
  						if (rc)
  							goto out;
  					}
  				}
  
  				if (delim != ',')
  					break;
  			}
  		}
  		if (delim == '-') {
  			/* Extract high sensitivity. */
  			scontextp = p;
  			while (*p && *p != ':')
  				p++;
  
  			delim = *p;
df4ea865f   Vesa-Matti J Kari   SELinux: Trivial ...
342
343
  			if (delim != '\0')
  				*p++ = '\0';
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
  		} else
  			break;
  	}
  
  	if (l == 0) {
  		context->range.level[1].sens = context->range.level[0].sens;
  		rc = ebitmap_cpy(&context->range.level[1].cat,
  				 &context->range.level[0].cat);
  		if (rc)
  			goto out;
  	}
  	*scontext = ++p;
  	rc = 0;
  out:
  	return rc;
  }
  
  /*
376bd9cb3   Darrel Goeddel   [PATCH] support f...
362
363
364
365
366
367
368
369
370
   * Set the MLS fields in the security context structure
   * `context' based on the string representation in
   * the string `str'.  This function will allocate temporary memory with the
   * given constraints of gfp_mask.
   */
  int mls_from_string(char *str, struct context *context, gfp_t gfp_mask)
  {
  	char *tmpstr, *freestr;
  	int rc;
0719aaf5e   Guido Trentalancia   selinux: allow ML...
371
  	if (!policydb.mls_enabled)
376bd9cb3   Darrel Goeddel   [PATCH] support f...
372
373
374
375
376
377
378
379
  		return -EINVAL;
  
  	/* we need freestr because mls_context_to_sid will change
  	   the value of tmpstr */
  	tmpstr = freestr = kstrdup(str, gfp_mask);
  	if (!tmpstr) {
  		rc = -ENOMEM;
  	} else {
12b29f345   Stephen Smalley   selinux: support ...
380
  		rc = mls_context_to_sid(&policydb, ':', &tmpstr, context,
1a5e6f872   Eric Paris   SELinux: mls.c wh...
381
  					NULL, SECSID_NULL);
376bd9cb3   Darrel Goeddel   [PATCH] support f...
382
383
384
385
386
387
388
  		kfree(freestr);
  	}
  
  	return rc;
  }
  
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
389
390
   * Copies the MLS range `range' into `context'.
   */
0719aaf5e   Guido Trentalancia   selinux: allow ML...
391
  int mls_range_set(struct context *context,
1a5e6f872   Eric Paris   SELinux: mls.c wh...
392
  				struct mls_range *range)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
  {
  	int l, rc = 0;
  
  	/* Copy the MLS range into the  context */
  	for (l = 0; l < 2; l++) {
  		context->range.level[l].sens = range->level[l].sens;
  		rc = ebitmap_cpy(&context->range.level[l].cat,
  				 &range->level[l].cat);
  		if (rc)
  			break;
  	}
  
  	return rc;
  }
  
  int mls_setup_user_range(struct context *fromcon, struct user_datum *user,
1a5e6f872   Eric Paris   SELinux: mls.c wh...
409
  			 struct context *usercon)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
410
  {
0719aaf5e   Guido Trentalancia   selinux: allow ML...
411
  	if (policydb.mls_enabled) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
412
413
414
415
416
417
418
419
420
  		struct mls_level *fromcon_sen = &(fromcon->range.level[0]);
  		struct mls_level *fromcon_clr = &(fromcon->range.level[1]);
  		struct mls_level *user_low = &(user->range.level[0]);
  		struct mls_level *user_clr = &(user->range.level[1]);
  		struct mls_level *user_def = &(user->dfltlevel);
  		struct mls_level *usercon_sen = &(usercon->range.level[0]);
  		struct mls_level *usercon_clr = &(usercon->range.level[1]);
  
  		/* Honor the user's default level if we can */
f52697107   Eric Paris   SELinux: keep the...
421
  		if (mls_level_between(user_def, fromcon_sen, fromcon_clr))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
422
  			*usercon_sen = *user_def;
f52697107   Eric Paris   SELinux: keep the...
423
  		else if (mls_level_between(fromcon_sen, user_def, user_clr))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
424
  			*usercon_sen = *fromcon_sen;
f52697107   Eric Paris   SELinux: keep the...
425
  		else if (mls_level_between(fromcon_clr, user_low, user_def))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
426
  			*usercon_sen = *user_low;
f52697107   Eric Paris   SELinux: keep the...
427
  		else
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
428
429
430
431
432
433
434
  			return -EINVAL;
  
  		/* Lower the clearance of available contexts
  		   if the clearance of "fromcon" is lower than
  		   that of the user's default clearance (but
  		   only if the "fromcon" clearance dominates
  		   the user's computed sensitivity level) */
1a5e6f872   Eric Paris   SELinux: mls.c wh...
435
  		if (mls_level_dom(user_clr, fromcon_clr))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
436
  			*usercon_clr = *fromcon_clr;
1a5e6f872   Eric Paris   SELinux: mls.c wh...
437
  		else if (mls_level_dom(fromcon_clr, user_clr))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
438
  			*usercon_clr = *user_clr;
1a5e6f872   Eric Paris   SELinux: mls.c wh...
439
  		else
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
  			return -EINVAL;
  	}
  
  	return 0;
  }
  
  /*
   * Convert the MLS fields in the security context
   * structure `c' from the values specified in the
   * policy `oldp' to the values specified in the policy `newp'.
   */
  int mls_convert_context(struct policydb *oldp,
  			struct policydb *newp,
  			struct context *c)
  {
  	struct level_datum *levdatum;
  	struct cat_datum *catdatum;
  	struct ebitmap bitmap;
782ebb992   Stephen Smalley   [PATCH] selinux: ...
458
  	struct ebitmap_node *node;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
459
  	int l, i;
0719aaf5e   Guido Trentalancia   selinux: allow ML...
460
  	if (!policydb.mls_enabled)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
461
462
463
464
  		return 0;
  
  	for (l = 0; l < 2; l++) {
  		levdatum = hashtab_search(newp->p_levels.table,
ac76c05be   Eric Paris   selinux: convert ...
465
466
  					  sym_name(oldp, SYM_LEVELS,
  						   c->range.level[l].sens - 1));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
467
468
469
470
471
472
  
  		if (!levdatum)
  			return -EINVAL;
  		c->range.level[l].sens = levdatum->level->sens;
  
  		ebitmap_init(&bitmap);
9fe79ad1e   KaiGai Kohei   SELinux: improve ...
473
474
475
476
  		ebitmap_for_each_positive_bit(&c->range.level[l].cat, node, i) {
  			int rc;
  
  			catdatum = hashtab_search(newp->p_cats.table,
ac76c05be   Eric Paris   selinux: convert ...
477
  						  sym_name(oldp, SYM_CATS, i));
9fe79ad1e   KaiGai Kohei   SELinux: improve ...
478
479
480
481
482
  			if (!catdatum)
  				return -EINVAL;
  			rc = ebitmap_set_bit(&bitmap, catdatum->value - 1, 1);
  			if (rc)
  				return rc;
9a591f39a   Dave Jones   selinux: conditio...
483
484
  
  			cond_resched();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
485
486
487
488
489
490
491
492
493
494
495
496
  		}
  		ebitmap_destroy(&c->range.level[l].cat);
  		c->range.level[l].cat = bitmap;
  	}
  
  	return 0;
  }
  
  int mls_compute_sid(struct context *scontext,
  		    struct context *tcontext,
  		    u16 tclass,
  		    u32 specified,
6f5317e73   Harry Ciao   SELinux: Socket r...
497
498
  		    struct context *newcontext,
  		    bool sock)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
499
  {
2f3e82d69   Stephen Smalley   selinux: convert ...
500
501
  	struct range_trans rtr;
  	struct mls_range *r;
aa893269d   Eric Paris   SELinux: allow de...
502
503
  	struct class_datum *cladatum;
  	int default_range = 0;
f3f877142   Darrel Goeddel   [PATCH] selinux: ...
504

0719aaf5e   Guido Trentalancia   selinux: allow ML...
505
  	if (!policydb.mls_enabled)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
506
507
508
509
  		return 0;
  
  	switch (specified) {
  	case AVTAB_TRANSITION:
f3f877142   Darrel Goeddel   [PATCH] selinux: ...
510
  		/* Look for a range transition rule. */
2f3e82d69   Stephen Smalley   selinux: convert ...
511
512
513
514
515
516
  		rtr.source_type = scontext->type;
  		rtr.target_type = tcontext->type;
  		rtr.target_class = tclass;
  		r = hashtab_search(policydb.range_tr, &rtr);
  		if (r)
  			return mls_range_set(newcontext, r);
aa893269d   Eric Paris   SELinux: allow de...
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
  
  		if (tclass && tclass <= policydb.p_classes.nprim) {
  			cladatum = policydb.class_val_to_struct[tclass - 1];
  			if (cladatum)
  				default_range = cladatum->default_range;
  		}
  
  		switch (default_range) {
  		case DEFAULT_SOURCE_LOW:
  			return mls_context_cpy_low(newcontext, scontext);
  		case DEFAULT_SOURCE_HIGH:
  			return mls_context_cpy_high(newcontext, scontext);
  		case DEFAULT_SOURCE_LOW_HIGH:
  			return mls_context_cpy(newcontext, scontext);
  		case DEFAULT_TARGET_LOW:
  			return mls_context_cpy_low(newcontext, tcontext);
  		case DEFAULT_TARGET_HIGH:
  			return mls_context_cpy_high(newcontext, tcontext);
  		case DEFAULT_TARGET_LOW_HIGH:
  			return mls_context_cpy(newcontext, tcontext);
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
538
539
  		/* Fallthrough */
  	case AVTAB_CHANGE:
6f5317e73   Harry Ciao   SELinux: Socket r...
540
  		if ((tclass == policydb.process_class) || (sock == true))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
541
  			/* Use the process MLS attributes. */
0efc61eae   Venkat Yekkirala   selinux: Delete m...
542
  			return mls_context_cpy(newcontext, scontext);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
543
544
  		else
  			/* Use the process effective MLS attributes. */
0efc61eae   Venkat Yekkirala   selinux: Delete m...
545
  			return mls_context_cpy_low(newcontext, scontext);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
546
  	case AVTAB_MEMBER:
2e08c0c1c   Eamon Walsh   selinux: make mls...
547
548
  		/* Use the process effective MLS attributes. */
  		return mls_context_cpy_low(newcontext, scontext);
08e3daff2   Amerigo Wang   selinux: remove a...
549
550
  
  	/* fall through */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
551
552
553
  	}
  	return -EINVAL;
  }
027527603   Paul Moore   NetLabel: convert...
554
  #ifdef CONFIG_NETLABEL
7420ed23a   Venkat Yekkirala   [NetLabel]: SELin...
555
  /**
027527603   Paul Moore   NetLabel: convert...
556
   * mls_export_netlbl_lvl - Export the MLS sensitivity levels to NetLabel
7420ed23a   Venkat Yekkirala   [NetLabel]: SELin...
557
   * @context: the security context
027527603   Paul Moore   NetLabel: convert...
558
   * @secattr: the NetLabel security attributes
7420ed23a   Venkat Yekkirala   [NetLabel]: SELin...
559
560
   *
   * Description:
027527603   Paul Moore   NetLabel: convert...
561
562
   * Given the security context copy the low MLS sensitivity level into the
   * NetLabel MLS sensitivity level field.
7420ed23a   Venkat Yekkirala   [NetLabel]: SELin...
563
564
   *
   */
027527603   Paul Moore   NetLabel: convert...
565
566
  void mls_export_netlbl_lvl(struct context *context,
  			   struct netlbl_lsm_secattr *secattr)
7420ed23a   Venkat Yekkirala   [NetLabel]: SELin...
567
  {
0719aaf5e   Guido Trentalancia   selinux: allow ML...
568
  	if (!policydb.mls_enabled)
7420ed23a   Venkat Yekkirala   [NetLabel]: SELin...
569
  		return;
16efd4543   Paul Moore   NetLabel: Add sec...
570
  	secattr->attr.mls.lvl = context->range.level[0].sens - 1;
027527603   Paul Moore   NetLabel: convert...
571
  	secattr->flags |= NETLBL_SECATTR_MLS_LVL;
7420ed23a   Venkat Yekkirala   [NetLabel]: SELin...
572
573
574
  }
  
  /**
027527603   Paul Moore   NetLabel: convert...
575
   * mls_import_netlbl_lvl - Import the NetLabel MLS sensitivity levels
7420ed23a   Venkat Yekkirala   [NetLabel]: SELin...
576
   * @context: the security context
027527603   Paul Moore   NetLabel: convert...
577
   * @secattr: the NetLabel security attributes
7420ed23a   Venkat Yekkirala   [NetLabel]: SELin...
578
579
   *
   * Description:
027527603   Paul Moore   NetLabel: convert...
580
581
   * Given the security context and the NetLabel security attributes, copy the
   * NetLabel MLS sensitivity level into the context.
7420ed23a   Venkat Yekkirala   [NetLabel]: SELin...
582
583
   *
   */
027527603   Paul Moore   NetLabel: convert...
584
585
  void mls_import_netlbl_lvl(struct context *context,
  			   struct netlbl_lsm_secattr *secattr)
7420ed23a   Venkat Yekkirala   [NetLabel]: SELin...
586
  {
0719aaf5e   Guido Trentalancia   selinux: allow ML...
587
  	if (!policydb.mls_enabled)
7420ed23a   Venkat Yekkirala   [NetLabel]: SELin...
588
  		return;
16efd4543   Paul Moore   NetLabel: Add sec...
589
  	context->range.level[0].sens = secattr->attr.mls.lvl + 1;
027527603   Paul Moore   NetLabel: convert...
590
  	context->range.level[1].sens = context->range.level[0].sens;
7420ed23a   Venkat Yekkirala   [NetLabel]: SELin...
591
592
593
  }
  
  /**
027527603   Paul Moore   NetLabel: convert...
594
   * mls_export_netlbl_cat - Export the MLS categories to NetLabel
7420ed23a   Venkat Yekkirala   [NetLabel]: SELin...
595
   * @context: the security context
027527603   Paul Moore   NetLabel: convert...
596
   * @secattr: the NetLabel security attributes
7420ed23a   Venkat Yekkirala   [NetLabel]: SELin...
597
598
   *
   * Description:
027527603   Paul Moore   NetLabel: convert...
599
600
   * Given the security context copy the low MLS categories into the NetLabel
   * MLS category field.  Returns zero on success, negative values on failure.
7420ed23a   Venkat Yekkirala   [NetLabel]: SELin...
601
602
   *
   */
027527603   Paul Moore   NetLabel: convert...
603
604
  int mls_export_netlbl_cat(struct context *context,
  			  struct netlbl_lsm_secattr *secattr)
7420ed23a   Venkat Yekkirala   [NetLabel]: SELin...
605
  {
027527603   Paul Moore   NetLabel: convert...
606
  	int rc;
7420ed23a   Venkat Yekkirala   [NetLabel]: SELin...
607

0719aaf5e   Guido Trentalancia   selinux: allow ML...
608
  	if (!policydb.mls_enabled)
7420ed23a   Venkat Yekkirala   [NetLabel]: SELin...
609
  		return 0;
027527603   Paul Moore   NetLabel: convert...
610
  	rc = ebitmap_netlbl_export(&context->range.level[0].cat,
16efd4543   Paul Moore   NetLabel: Add sec...
611
612
  				   &secattr->attr.mls.cat);
  	if (rc == 0 && secattr->attr.mls.cat != NULL)
027527603   Paul Moore   NetLabel: convert...
613
  		secattr->flags |= NETLBL_SECATTR_MLS_CAT;
7420ed23a   Venkat Yekkirala   [NetLabel]: SELin...
614

7420ed23a   Venkat Yekkirala   [NetLabel]: SELin...
615
616
617
618
  	return rc;
  }
  
  /**
027527603   Paul Moore   NetLabel: convert...
619
   * mls_import_netlbl_cat - Import the MLS categories from NetLabel
7420ed23a   Venkat Yekkirala   [NetLabel]: SELin...
620
   * @context: the security context
027527603   Paul Moore   NetLabel: convert...
621
   * @secattr: the NetLabel security attributes
7420ed23a   Venkat Yekkirala   [NetLabel]: SELin...
622
623
   *
   * Description:
027527603   Paul Moore   NetLabel: convert...
624
625
626
627
   * Copy the NetLabel security attributes into the SELinux context; since the
   * NetLabel security attribute only contains a single MLS category use it for
   * both the low and high categories of the context.  Returns zero on success,
   * negative values on failure.
7420ed23a   Venkat Yekkirala   [NetLabel]: SELin...
628
629
   *
   */
027527603   Paul Moore   NetLabel: convert...
630
631
  int mls_import_netlbl_cat(struct context *context,
  			  struct netlbl_lsm_secattr *secattr)
7420ed23a   Venkat Yekkirala   [NetLabel]: SELin...
632
  {
027527603   Paul Moore   NetLabel: convert...
633
  	int rc;
7420ed23a   Venkat Yekkirala   [NetLabel]: SELin...
634

0719aaf5e   Guido Trentalancia   selinux: allow ML...
635
  	if (!policydb.mls_enabled)
7420ed23a   Venkat Yekkirala   [NetLabel]: SELin...
636
  		return 0;
027527603   Paul Moore   NetLabel: convert...
637
  	rc = ebitmap_netlbl_import(&context->range.level[0].cat,
16efd4543   Paul Moore   NetLabel: Add sec...
638
  				   secattr->attr.mls.cat);
da8026fa0   Paul Moore   selinux: reconcil...
639
  	if (rc)
027527603   Paul Moore   NetLabel: convert...
640
  		goto import_netlbl_cat_failure;
da8026fa0   Paul Moore   selinux: reconcil...
641
642
  	memcpy(&context->range.level[1].cat, &context->range.level[0].cat,
  	       sizeof(context->range.level[0].cat));
7420ed23a   Venkat Yekkirala   [NetLabel]: SELin...
643
644
  
  	return 0;
027527603   Paul Moore   NetLabel: convert...
645
  import_netlbl_cat_failure:
7420ed23a   Venkat Yekkirala   [NetLabel]: SELin...
646
  	ebitmap_destroy(&context->range.level[0].cat);
7420ed23a   Venkat Yekkirala   [NetLabel]: SELin...
647
648
  	return rc;
  }
027527603   Paul Moore   NetLabel: convert...
649
  #endif /* CONFIG_NETLABEL */