services.c revision 23970741720360de9dd0a4e87fbeb1d5927aa474
1/*
2 * Implementation of the security services.
3 *
4 * Authors : Stephen Smalley, <sds@epoch.ncsc.mil>
5 *           James Morris <jmorris@redhat.com>
6 *
7 * Updated: Trusted Computer Solutions, Inc. <dgoeddel@trustedcs.com>
8 *
9 *	Support for enhanced MLS infrastructure.
10 *	Support for context based audit filters.
11 *
12 * Updated: Frank Mayer <mayerf@tresys.com> and Karl MacMillan <kmacmillan@tresys.com>
13 *
14 * 	Added conditional policy language extensions
15 *
16 * Updated: Hewlett-Packard <paul.moore@hp.com>
17 *
18 *      Added support for NetLabel
19 *
20 * Copyright (C) 2006 Hewlett-Packard Development Company, L.P.
21 * Copyright (C) 2004-2006 Trusted Computer Solutions, Inc.
22 * Copyright (C) 2003 - 2004 Tresys Technology, LLC
23 * Copyright (C) 2003 Red Hat, Inc., James Morris <jmorris@redhat.com>
24 *	This program is free software; you can redistribute it and/or modify
25 *  	it under the terms of the GNU General Public License as published by
26 *	the Free Software Foundation, version 2.
27 */
28#include <linux/kernel.h>
29#include <linux/slab.h>
30#include <linux/string.h>
31#include <linux/spinlock.h>
32#include <linux/errno.h>
33#include <linux/in.h>
34#include <linux/sched.h>
35#include <linux/audit.h>
36#include <linux/mutex.h>
37#include <net/sock.h>
38#include <net/netlabel.h>
39
40#include "flask.h"
41#include "avc.h"
42#include "avc_ss.h"
43#include "security.h"
44#include "context.h"
45#include "policydb.h"
46#include "sidtab.h"
47#include "services.h"
48#include "conditional.h"
49#include "mls.h"
50#include "objsec.h"
51#include "selinux_netlabel.h"
52
53extern void selnl_notify_policyload(u32 seqno);
54unsigned int policydb_loaded_version;
55
56static DEFINE_RWLOCK(policy_rwlock);
57#define POLICY_RDLOCK read_lock(&policy_rwlock)
58#define POLICY_WRLOCK write_lock_irq(&policy_rwlock)
59#define POLICY_RDUNLOCK read_unlock(&policy_rwlock)
60#define POLICY_WRUNLOCK write_unlock_irq(&policy_rwlock)
61
62static DEFINE_MUTEX(load_mutex);
63#define LOAD_LOCK mutex_lock(&load_mutex)
64#define LOAD_UNLOCK mutex_unlock(&load_mutex)
65
66static struct sidtab sidtab;
67struct policydb policydb;
68int ss_initialized = 0;
69
70/*
71 * The largest sequence number that has been used when
72 * providing an access decision to the access vector cache.
73 * The sequence number only changes when a policy change
74 * occurs.
75 */
76static u32 latest_granting = 0;
77
78/* Forward declaration. */
79static int context_struct_to_string(struct context *context, char **scontext,
80				    u32 *scontext_len);
81
82/*
83 * Return the boolean value of a constraint expression
84 * when it is applied to the specified source and target
85 * security contexts.
86 *
87 * xcontext is a special beast...  It is used by the validatetrans rules
88 * only.  For these rules, scontext is the context before the transition,
89 * tcontext is the context after the transition, and xcontext is the context
90 * of the process performing the transition.  All other callers of
91 * constraint_expr_eval should pass in NULL for xcontext.
92 */
93static int constraint_expr_eval(struct context *scontext,
94				struct context *tcontext,
95				struct context *xcontext,
96				struct constraint_expr *cexpr)
97{
98	u32 val1, val2;
99	struct context *c;
100	struct role_datum *r1, *r2;
101	struct mls_level *l1, *l2;
102	struct constraint_expr *e;
103	int s[CEXPR_MAXDEPTH];
104	int sp = -1;
105
106	for (e = cexpr; e; e = e->next) {
107		switch (e->expr_type) {
108		case CEXPR_NOT:
109			BUG_ON(sp < 0);
110			s[sp] = !s[sp];
111			break;
112		case CEXPR_AND:
113			BUG_ON(sp < 1);
114			sp--;
115			s[sp] &= s[sp+1];
116			break;
117		case CEXPR_OR:
118			BUG_ON(sp < 1);
119			sp--;
120			s[sp] |= s[sp+1];
121			break;
122		case CEXPR_ATTR:
123			if (sp == (CEXPR_MAXDEPTH-1))
124				return 0;
125			switch (e->attr) {
126			case CEXPR_USER:
127				val1 = scontext->user;
128				val2 = tcontext->user;
129				break;
130			case CEXPR_TYPE:
131				val1 = scontext->type;
132				val2 = tcontext->type;
133				break;
134			case CEXPR_ROLE:
135				val1 = scontext->role;
136				val2 = tcontext->role;
137				r1 = policydb.role_val_to_struct[val1 - 1];
138				r2 = policydb.role_val_to_struct[val2 - 1];
139				switch (e->op) {
140				case CEXPR_DOM:
141					s[++sp] = ebitmap_get_bit(&r1->dominates,
142								  val2 - 1);
143					continue;
144				case CEXPR_DOMBY:
145					s[++sp] = ebitmap_get_bit(&r2->dominates,
146								  val1 - 1);
147					continue;
148				case CEXPR_INCOMP:
149					s[++sp] = ( !ebitmap_get_bit(&r1->dominates,
150								     val2 - 1) &&
151						    !ebitmap_get_bit(&r2->dominates,
152								     val1 - 1) );
153					continue;
154				default:
155					break;
156				}
157				break;
158			case CEXPR_L1L2:
159				l1 = &(scontext->range.level[0]);
160				l2 = &(tcontext->range.level[0]);
161				goto mls_ops;
162			case CEXPR_L1H2:
163				l1 = &(scontext->range.level[0]);
164				l2 = &(tcontext->range.level[1]);
165				goto mls_ops;
166			case CEXPR_H1L2:
167				l1 = &(scontext->range.level[1]);
168				l2 = &(tcontext->range.level[0]);
169				goto mls_ops;
170			case CEXPR_H1H2:
171				l1 = &(scontext->range.level[1]);
172				l2 = &(tcontext->range.level[1]);
173				goto mls_ops;
174			case CEXPR_L1H1:
175				l1 = &(scontext->range.level[0]);
176				l2 = &(scontext->range.level[1]);
177				goto mls_ops;
178			case CEXPR_L2H2:
179				l1 = &(tcontext->range.level[0]);
180				l2 = &(tcontext->range.level[1]);
181				goto mls_ops;
182mls_ops:
183			switch (e->op) {
184			case CEXPR_EQ:
185				s[++sp] = mls_level_eq(l1, l2);
186				continue;
187			case CEXPR_NEQ:
188				s[++sp] = !mls_level_eq(l1, l2);
189				continue;
190			case CEXPR_DOM:
191				s[++sp] = mls_level_dom(l1, l2);
192				continue;
193			case CEXPR_DOMBY:
194				s[++sp] = mls_level_dom(l2, l1);
195				continue;
196			case CEXPR_INCOMP:
197				s[++sp] = mls_level_incomp(l2, l1);
198				continue;
199			default:
200				BUG();
201				return 0;
202			}
203			break;
204			default:
205				BUG();
206				return 0;
207			}
208
209			switch (e->op) {
210			case CEXPR_EQ:
211				s[++sp] = (val1 == val2);
212				break;
213			case CEXPR_NEQ:
214				s[++sp] = (val1 != val2);
215				break;
216			default:
217				BUG();
218				return 0;
219			}
220			break;
221		case CEXPR_NAMES:
222			if (sp == (CEXPR_MAXDEPTH-1))
223				return 0;
224			c = scontext;
225			if (e->attr & CEXPR_TARGET)
226				c = tcontext;
227			else if (e->attr & CEXPR_XTARGET) {
228				c = xcontext;
229				if (!c) {
230					BUG();
231					return 0;
232				}
233			}
234			if (e->attr & CEXPR_USER)
235				val1 = c->user;
236			else if (e->attr & CEXPR_ROLE)
237				val1 = c->role;
238			else if (e->attr & CEXPR_TYPE)
239				val1 = c->type;
240			else {
241				BUG();
242				return 0;
243			}
244
245			switch (e->op) {
246			case CEXPR_EQ:
247				s[++sp] = ebitmap_get_bit(&e->names, val1 - 1);
248				break;
249			case CEXPR_NEQ:
250				s[++sp] = !ebitmap_get_bit(&e->names, val1 - 1);
251				break;
252			default:
253				BUG();
254				return 0;
255			}
256			break;
257		default:
258			BUG();
259			return 0;
260		}
261	}
262
263	BUG_ON(sp != 0);
264	return s[0];
265}
266
267/*
268 * Compute access vectors based on a context structure pair for
269 * the permissions in a particular class.
270 */
271static int context_struct_compute_av(struct context *scontext,
272				     struct context *tcontext,
273				     u16 tclass,
274				     u32 requested,
275				     struct av_decision *avd)
276{
277	struct constraint_node *constraint;
278	struct role_allow *ra;
279	struct avtab_key avkey;
280	struct avtab_node *node;
281	struct class_datum *tclass_datum;
282	struct ebitmap *sattr, *tattr;
283	struct ebitmap_node *snode, *tnode;
284	unsigned int i, j;
285
286	/*
287	 * Remap extended Netlink classes for old policy versions.
288	 * Do this here rather than socket_type_to_security_class()
289	 * in case a newer policy version is loaded, allowing sockets
290	 * to remain in the correct class.
291	 */
292	if (policydb_loaded_version < POLICYDB_VERSION_NLCLASS)
293		if (tclass >= SECCLASS_NETLINK_ROUTE_SOCKET &&
294		    tclass <= SECCLASS_NETLINK_DNRT_SOCKET)
295			tclass = SECCLASS_NETLINK_SOCKET;
296
297	if (!tclass || tclass > policydb.p_classes.nprim) {
298		printk(KERN_ERR "security_compute_av:  unrecognized class %d\n",
299		       tclass);
300		return -EINVAL;
301	}
302	tclass_datum = policydb.class_val_to_struct[tclass - 1];
303
304	/*
305	 * Initialize the access vectors to the default values.
306	 */
307	avd->allowed = 0;
308	avd->decided = 0xffffffff;
309	avd->auditallow = 0;
310	avd->auditdeny = 0xffffffff;
311	avd->seqno = latest_granting;
312
313	/*
314	 * If a specific type enforcement rule was defined for
315	 * this permission check, then use it.
316	 */
317	avkey.target_class = tclass;
318	avkey.specified = AVTAB_AV;
319	sattr = &policydb.type_attr_map[scontext->type - 1];
320	tattr = &policydb.type_attr_map[tcontext->type - 1];
321	ebitmap_for_each_bit(sattr, snode, i) {
322		if (!ebitmap_node_get_bit(snode, i))
323			continue;
324		ebitmap_for_each_bit(tattr, tnode, j) {
325			if (!ebitmap_node_get_bit(tnode, j))
326				continue;
327			avkey.source_type = i + 1;
328			avkey.target_type = j + 1;
329			for (node = avtab_search_node(&policydb.te_avtab, &avkey);
330			     node != NULL;
331			     node = avtab_search_node_next(node, avkey.specified)) {
332				if (node->key.specified == AVTAB_ALLOWED)
333					avd->allowed |= node->datum.data;
334				else if (node->key.specified == AVTAB_AUDITALLOW)
335					avd->auditallow |= node->datum.data;
336				else if (node->key.specified == AVTAB_AUDITDENY)
337					avd->auditdeny &= node->datum.data;
338			}
339
340			/* Check conditional av table for additional permissions */
341			cond_compute_av(&policydb.te_cond_avtab, &avkey, avd);
342
343		}
344	}
345
346	/*
347	 * Remove any permissions prohibited by a constraint (this includes
348	 * the MLS policy).
349	 */
350	constraint = tclass_datum->constraints;
351	while (constraint) {
352		if ((constraint->permissions & (avd->allowed)) &&
353		    !constraint_expr_eval(scontext, tcontext, NULL,
354					  constraint->expr)) {
355			avd->allowed = (avd->allowed) & ~(constraint->permissions);
356		}
357		constraint = constraint->next;
358	}
359
360	/*
361	 * If checking process transition permission and the
362	 * role is changing, then check the (current_role, new_role)
363	 * pair.
364	 */
365	if (tclass == SECCLASS_PROCESS &&
366	    (avd->allowed & (PROCESS__TRANSITION | PROCESS__DYNTRANSITION)) &&
367	    scontext->role != tcontext->role) {
368		for (ra = policydb.role_allow; ra; ra = ra->next) {
369			if (scontext->role == ra->role &&
370			    tcontext->role == ra->new_role)
371				break;
372		}
373		if (!ra)
374			avd->allowed = (avd->allowed) & ~(PROCESS__TRANSITION |
375			                                PROCESS__DYNTRANSITION);
376	}
377
378	return 0;
379}
380
381static int security_validtrans_handle_fail(struct context *ocontext,
382                                           struct context *ncontext,
383                                           struct context *tcontext,
384                                           u16 tclass)
385{
386	char *o = NULL, *n = NULL, *t = NULL;
387	u32 olen, nlen, tlen;
388
389	if (context_struct_to_string(ocontext, &o, &olen) < 0)
390		goto out;
391	if (context_struct_to_string(ncontext, &n, &nlen) < 0)
392		goto out;
393	if (context_struct_to_string(tcontext, &t, &tlen) < 0)
394		goto out;
395	audit_log(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR,
396	          "security_validate_transition:  denied for"
397	          " oldcontext=%s newcontext=%s taskcontext=%s tclass=%s",
398	          o, n, t, policydb.p_class_val_to_name[tclass-1]);
399out:
400	kfree(o);
401	kfree(n);
402	kfree(t);
403
404	if (!selinux_enforcing)
405		return 0;
406	return -EPERM;
407}
408
409int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid,
410                                 u16 tclass)
411{
412	struct context *ocontext;
413	struct context *ncontext;
414	struct context *tcontext;
415	struct class_datum *tclass_datum;
416	struct constraint_node *constraint;
417	int rc = 0;
418
419	if (!ss_initialized)
420		return 0;
421
422	POLICY_RDLOCK;
423
424	/*
425	 * Remap extended Netlink classes for old policy versions.
426	 * Do this here rather than socket_type_to_security_class()
427	 * in case a newer policy version is loaded, allowing sockets
428	 * to remain in the correct class.
429	 */
430	if (policydb_loaded_version < POLICYDB_VERSION_NLCLASS)
431		if (tclass >= SECCLASS_NETLINK_ROUTE_SOCKET &&
432		    tclass <= SECCLASS_NETLINK_DNRT_SOCKET)
433			tclass = SECCLASS_NETLINK_SOCKET;
434
435	if (!tclass || tclass > policydb.p_classes.nprim) {
436		printk(KERN_ERR "security_validate_transition:  "
437		       "unrecognized class %d\n", tclass);
438		rc = -EINVAL;
439		goto out;
440	}
441	tclass_datum = policydb.class_val_to_struct[tclass - 1];
442
443	ocontext = sidtab_search(&sidtab, oldsid);
444	if (!ocontext) {
445		printk(KERN_ERR "security_validate_transition: "
446		       " unrecognized SID %d\n", oldsid);
447		rc = -EINVAL;
448		goto out;
449	}
450
451	ncontext = sidtab_search(&sidtab, newsid);
452	if (!ncontext) {
453		printk(KERN_ERR "security_validate_transition: "
454		       " unrecognized SID %d\n", newsid);
455		rc = -EINVAL;
456		goto out;
457	}
458
459	tcontext = sidtab_search(&sidtab, tasksid);
460	if (!tcontext) {
461		printk(KERN_ERR "security_validate_transition: "
462		       " unrecognized SID %d\n", tasksid);
463		rc = -EINVAL;
464		goto out;
465	}
466
467	constraint = tclass_datum->validatetrans;
468	while (constraint) {
469		if (!constraint_expr_eval(ocontext, ncontext, tcontext,
470		                          constraint->expr)) {
471			rc = security_validtrans_handle_fail(ocontext, ncontext,
472			                                     tcontext, tclass);
473			goto out;
474		}
475		constraint = constraint->next;
476	}
477
478out:
479	POLICY_RDUNLOCK;
480	return rc;
481}
482
483/**
484 * security_compute_av - Compute access vector decisions.
485 * @ssid: source security identifier
486 * @tsid: target security identifier
487 * @tclass: target security class
488 * @requested: requested permissions
489 * @avd: access vector decisions
490 *
491 * Compute a set of access vector decisions based on the
492 * SID pair (@ssid, @tsid) for the permissions in @tclass.
493 * Return -%EINVAL if any of the parameters are invalid or %0
494 * if the access vector decisions were computed successfully.
495 */
496int security_compute_av(u32 ssid,
497			u32 tsid,
498			u16 tclass,
499			u32 requested,
500			struct av_decision *avd)
501{
502	struct context *scontext = NULL, *tcontext = NULL;
503	int rc = 0;
504
505	if (!ss_initialized) {
506		avd->allowed = 0xffffffff;
507		avd->decided = 0xffffffff;
508		avd->auditallow = 0;
509		avd->auditdeny = 0xffffffff;
510		avd->seqno = latest_granting;
511		return 0;
512	}
513
514	POLICY_RDLOCK;
515
516	scontext = sidtab_search(&sidtab, ssid);
517	if (!scontext) {
518		printk(KERN_ERR "security_compute_av:  unrecognized SID %d\n",
519		       ssid);
520		rc = -EINVAL;
521		goto out;
522	}
523	tcontext = sidtab_search(&sidtab, tsid);
524	if (!tcontext) {
525		printk(KERN_ERR "security_compute_av:  unrecognized SID %d\n",
526		       tsid);
527		rc = -EINVAL;
528		goto out;
529	}
530
531	rc = context_struct_compute_av(scontext, tcontext, tclass,
532				       requested, avd);
533out:
534	POLICY_RDUNLOCK;
535	return rc;
536}
537
538/*
539 * Write the security context string representation of
540 * the context structure `context' into a dynamically
541 * allocated string of the correct size.  Set `*scontext'
542 * to point to this string and set `*scontext_len' to
543 * the length of the string.
544 */
545static int context_struct_to_string(struct context *context, char **scontext, u32 *scontext_len)
546{
547	char *scontextp;
548
549	*scontext = NULL;
550	*scontext_len = 0;
551
552	/* Compute the size of the context. */
553	*scontext_len += strlen(policydb.p_user_val_to_name[context->user - 1]) + 1;
554	*scontext_len += strlen(policydb.p_role_val_to_name[context->role - 1]) + 1;
555	*scontext_len += strlen(policydb.p_type_val_to_name[context->type - 1]) + 1;
556	*scontext_len += mls_compute_context_len(context);
557
558	/* Allocate space for the context; caller must free this space. */
559	scontextp = kmalloc(*scontext_len, GFP_ATOMIC);
560	if (!scontextp) {
561		return -ENOMEM;
562	}
563	*scontext = scontextp;
564
565	/*
566	 * Copy the user name, role name and type name into the context.
567	 */
568	sprintf(scontextp, "%s:%s:%s",
569		policydb.p_user_val_to_name[context->user - 1],
570		policydb.p_role_val_to_name[context->role - 1],
571		policydb.p_type_val_to_name[context->type - 1]);
572	scontextp += strlen(policydb.p_user_val_to_name[context->user - 1]) +
573	             1 + strlen(policydb.p_role_val_to_name[context->role - 1]) +
574	             1 + strlen(policydb.p_type_val_to_name[context->type - 1]);
575
576	mls_sid_to_context(context, &scontextp);
577
578	*scontextp = 0;
579
580	return 0;
581}
582
583#include "initial_sid_to_string.h"
584
585/**
586 * security_sid_to_context - Obtain a context for a given SID.
587 * @sid: security identifier, SID
588 * @scontext: security context
589 * @scontext_len: length in bytes
590 *
591 * Write the string representation of the context associated with @sid
592 * into a dynamically allocated string of the correct size.  Set @scontext
593 * to point to this string and set @scontext_len to the length of the string.
594 */
595int security_sid_to_context(u32 sid, char **scontext, u32 *scontext_len)
596{
597	struct context *context;
598	int rc = 0;
599
600	if (!ss_initialized) {
601		if (sid <= SECINITSID_NUM) {
602			char *scontextp;
603
604			*scontext_len = strlen(initial_sid_to_string[sid]) + 1;
605			scontextp = kmalloc(*scontext_len,GFP_ATOMIC);
606			if (!scontextp) {
607				rc = -ENOMEM;
608				goto out;
609			}
610			strcpy(scontextp, initial_sid_to_string[sid]);
611			*scontext = scontextp;
612			goto out;
613		}
614		printk(KERN_ERR "security_sid_to_context:  called before initial "
615		       "load_policy on unknown SID %d\n", sid);
616		rc = -EINVAL;
617		goto out;
618	}
619	POLICY_RDLOCK;
620	context = sidtab_search(&sidtab, sid);
621	if (!context) {
622		printk(KERN_ERR "security_sid_to_context:  unrecognized SID "
623		       "%d\n", sid);
624		rc = -EINVAL;
625		goto out_unlock;
626	}
627	rc = context_struct_to_string(context, scontext, scontext_len);
628out_unlock:
629	POLICY_RDUNLOCK;
630out:
631	return rc;
632
633}
634
635static int security_context_to_sid_core(char *scontext, u32 scontext_len, u32 *sid, u32 def_sid)
636{
637	char *scontext2;
638	struct context context;
639	struct role_datum *role;
640	struct type_datum *typdatum;
641	struct user_datum *usrdatum;
642	char *scontextp, *p, oldc;
643	int rc = 0;
644
645	if (!ss_initialized) {
646		int i;
647
648		for (i = 1; i < SECINITSID_NUM; i++) {
649			if (!strcmp(initial_sid_to_string[i], scontext)) {
650				*sid = i;
651				goto out;
652			}
653		}
654		*sid = SECINITSID_KERNEL;
655		goto out;
656	}
657	*sid = SECSID_NULL;
658
659	/* Copy the string so that we can modify the copy as we parse it.
660	   The string should already by null terminated, but we append a
661	   null suffix to the copy to avoid problems with the existing
662	   attr package, which doesn't view the null terminator as part
663	   of the attribute value. */
664	scontext2 = kmalloc(scontext_len+1,GFP_KERNEL);
665	if (!scontext2) {
666		rc = -ENOMEM;
667		goto out;
668	}
669	memcpy(scontext2, scontext, scontext_len);
670	scontext2[scontext_len] = 0;
671
672	context_init(&context);
673	*sid = SECSID_NULL;
674
675	POLICY_RDLOCK;
676
677	/* Parse the security context. */
678
679	rc = -EINVAL;
680	scontextp = (char *) scontext2;
681
682	/* Extract the user. */
683	p = scontextp;
684	while (*p && *p != ':')
685		p++;
686
687	if (*p == 0)
688		goto out_unlock;
689
690	*p++ = 0;
691
692	usrdatum = hashtab_search(policydb.p_users.table, scontextp);
693	if (!usrdatum)
694		goto out_unlock;
695
696	context.user = usrdatum->value;
697
698	/* Extract role. */
699	scontextp = p;
700	while (*p && *p != ':')
701		p++;
702
703	if (*p == 0)
704		goto out_unlock;
705
706	*p++ = 0;
707
708	role = hashtab_search(policydb.p_roles.table, scontextp);
709	if (!role)
710		goto out_unlock;
711	context.role = role->value;
712
713	/* Extract type. */
714	scontextp = p;
715	while (*p && *p != ':')
716		p++;
717	oldc = *p;
718	*p++ = 0;
719
720	typdatum = hashtab_search(policydb.p_types.table, scontextp);
721	if (!typdatum)
722		goto out_unlock;
723
724	context.type = typdatum->value;
725
726	rc = mls_context_to_sid(oldc, &p, &context, &sidtab, def_sid);
727	if (rc)
728		goto out_unlock;
729
730	if ((p - scontext2) < scontext_len) {
731		rc = -EINVAL;
732		goto out_unlock;
733	}
734
735	/* Check the validity of the new context. */
736	if (!policydb_context_isvalid(&policydb, &context)) {
737		rc = -EINVAL;
738		goto out_unlock;
739	}
740	/* Obtain the new sid. */
741	rc = sidtab_context_to_sid(&sidtab, &context, sid);
742out_unlock:
743	POLICY_RDUNLOCK;
744	context_destroy(&context);
745	kfree(scontext2);
746out:
747	return rc;
748}
749
750/**
751 * security_context_to_sid - Obtain a SID for a given security context.
752 * @scontext: security context
753 * @scontext_len: length in bytes
754 * @sid: security identifier, SID
755 *
756 * Obtains a SID associated with the security context that
757 * has the string representation specified by @scontext.
758 * Returns -%EINVAL if the context is invalid, -%ENOMEM if insufficient
759 * memory is available, or 0 on success.
760 */
761int security_context_to_sid(char *scontext, u32 scontext_len, u32 *sid)
762{
763	return security_context_to_sid_core(scontext, scontext_len,
764	                                    sid, SECSID_NULL);
765}
766
767/**
768 * security_context_to_sid_default - Obtain a SID for a given security context,
769 * falling back to specified default if needed.
770 *
771 * @scontext: security context
772 * @scontext_len: length in bytes
773 * @sid: security identifier, SID
774 * @def_sid: default SID to assign on errror
775 *
776 * Obtains a SID associated with the security context that
777 * has the string representation specified by @scontext.
778 * The default SID is passed to the MLS layer to be used to allow
779 * kernel labeling of the MLS field if the MLS field is not present
780 * (for upgrading to MLS without full relabel).
781 * Returns -%EINVAL if the context is invalid, -%ENOMEM if insufficient
782 * memory is available, or 0 on success.
783 */
784int security_context_to_sid_default(char *scontext, u32 scontext_len, u32 *sid, u32 def_sid)
785{
786	return security_context_to_sid_core(scontext, scontext_len,
787	                                    sid, def_sid);
788}
789
790static int compute_sid_handle_invalid_context(
791	struct context *scontext,
792	struct context *tcontext,
793	u16 tclass,
794	struct context *newcontext)
795{
796	char *s = NULL, *t = NULL, *n = NULL;
797	u32 slen, tlen, nlen;
798
799	if (context_struct_to_string(scontext, &s, &slen) < 0)
800		goto out;
801	if (context_struct_to_string(tcontext, &t, &tlen) < 0)
802		goto out;
803	if (context_struct_to_string(newcontext, &n, &nlen) < 0)
804		goto out;
805	audit_log(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR,
806		  "security_compute_sid:  invalid context %s"
807		  " for scontext=%s"
808		  " tcontext=%s"
809		  " tclass=%s",
810		  n, s, t, policydb.p_class_val_to_name[tclass-1]);
811out:
812	kfree(s);
813	kfree(t);
814	kfree(n);
815	if (!selinux_enforcing)
816		return 0;
817	return -EACCES;
818}
819
820static int security_compute_sid(u32 ssid,
821				u32 tsid,
822				u16 tclass,
823				u32 specified,
824				u32 *out_sid)
825{
826	struct context *scontext = NULL, *tcontext = NULL, newcontext;
827	struct role_trans *roletr = NULL;
828	struct avtab_key avkey;
829	struct avtab_datum *avdatum;
830	struct avtab_node *node;
831	int rc = 0;
832
833	if (!ss_initialized) {
834		switch (tclass) {
835		case SECCLASS_PROCESS:
836			*out_sid = ssid;
837			break;
838		default:
839			*out_sid = tsid;
840			break;
841		}
842		goto out;
843	}
844
845	context_init(&newcontext);
846
847	POLICY_RDLOCK;
848
849	scontext = sidtab_search(&sidtab, ssid);
850	if (!scontext) {
851		printk(KERN_ERR "security_compute_sid:  unrecognized SID %d\n",
852		       ssid);
853		rc = -EINVAL;
854		goto out_unlock;
855	}
856	tcontext = sidtab_search(&sidtab, tsid);
857	if (!tcontext) {
858		printk(KERN_ERR "security_compute_sid:  unrecognized SID %d\n",
859		       tsid);
860		rc = -EINVAL;
861		goto out_unlock;
862	}
863
864	/* Set the user identity. */
865	switch (specified) {
866	case AVTAB_TRANSITION:
867	case AVTAB_CHANGE:
868		/* Use the process user identity. */
869		newcontext.user = scontext->user;
870		break;
871	case AVTAB_MEMBER:
872		/* Use the related object owner. */
873		newcontext.user = tcontext->user;
874		break;
875	}
876
877	/* Set the role and type to default values. */
878	switch (tclass) {
879	case SECCLASS_PROCESS:
880		/* Use the current role and type of process. */
881		newcontext.role = scontext->role;
882		newcontext.type = scontext->type;
883		break;
884	default:
885		/* Use the well-defined object role. */
886		newcontext.role = OBJECT_R_VAL;
887		/* Use the type of the related object. */
888		newcontext.type = tcontext->type;
889	}
890
891	/* Look for a type transition/member/change rule. */
892	avkey.source_type = scontext->type;
893	avkey.target_type = tcontext->type;
894	avkey.target_class = tclass;
895	avkey.specified = specified;
896	avdatum = avtab_search(&policydb.te_avtab, &avkey);
897
898	/* If no permanent rule, also check for enabled conditional rules */
899	if(!avdatum) {
900		node = avtab_search_node(&policydb.te_cond_avtab, &avkey);
901		for (; node != NULL; node = avtab_search_node_next(node, specified)) {
902			if (node->key.specified & AVTAB_ENABLED) {
903				avdatum = &node->datum;
904				break;
905			}
906		}
907	}
908
909	if (avdatum) {
910		/* Use the type from the type transition/member/change rule. */
911		newcontext.type = avdatum->data;
912	}
913
914	/* Check for class-specific changes. */
915	switch (tclass) {
916	case SECCLASS_PROCESS:
917		if (specified & AVTAB_TRANSITION) {
918			/* Look for a role transition rule. */
919			for (roletr = policydb.role_tr; roletr;
920			     roletr = roletr->next) {
921				if (roletr->role == scontext->role &&
922				    roletr->type == tcontext->type) {
923					/* Use the role transition rule. */
924					newcontext.role = roletr->new_role;
925					break;
926				}
927			}
928		}
929		break;
930	default:
931		break;
932	}
933
934	/* Set the MLS attributes.
935	   This is done last because it may allocate memory. */
936	rc = mls_compute_sid(scontext, tcontext, tclass, specified, &newcontext);
937	if (rc)
938		goto out_unlock;
939
940	/* Check the validity of the context. */
941	if (!policydb_context_isvalid(&policydb, &newcontext)) {
942		rc = compute_sid_handle_invalid_context(scontext,
943							tcontext,
944							tclass,
945							&newcontext);
946		if (rc)
947			goto out_unlock;
948	}
949	/* Obtain the sid for the context. */
950	rc = sidtab_context_to_sid(&sidtab, &newcontext, out_sid);
951out_unlock:
952	POLICY_RDUNLOCK;
953	context_destroy(&newcontext);
954out:
955	return rc;
956}
957
958/**
959 * security_transition_sid - Compute the SID for a new subject/object.
960 * @ssid: source security identifier
961 * @tsid: target security identifier
962 * @tclass: target security class
963 * @out_sid: security identifier for new subject/object
964 *
965 * Compute a SID to use for labeling a new subject or object in the
966 * class @tclass based on a SID pair (@ssid, @tsid).
967 * Return -%EINVAL if any of the parameters are invalid, -%ENOMEM
968 * if insufficient memory is available, or %0 if the new SID was
969 * computed successfully.
970 */
971int security_transition_sid(u32 ssid,
972			    u32 tsid,
973			    u16 tclass,
974			    u32 *out_sid)
975{
976	return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION, out_sid);
977}
978
979/**
980 * security_member_sid - Compute the SID for member selection.
981 * @ssid: source security identifier
982 * @tsid: target security identifier
983 * @tclass: target security class
984 * @out_sid: security identifier for selected member
985 *
986 * Compute a SID to use when selecting a member of a polyinstantiated
987 * object of class @tclass based on a SID pair (@ssid, @tsid).
988 * Return -%EINVAL if any of the parameters are invalid, -%ENOMEM
989 * if insufficient memory is available, or %0 if the SID was
990 * computed successfully.
991 */
992int security_member_sid(u32 ssid,
993			u32 tsid,
994			u16 tclass,
995			u32 *out_sid)
996{
997	return security_compute_sid(ssid, tsid, tclass, AVTAB_MEMBER, out_sid);
998}
999
1000/**
1001 * security_change_sid - Compute the SID for object relabeling.
1002 * @ssid: source security identifier
1003 * @tsid: target security identifier
1004 * @tclass: target security class
1005 * @out_sid: security identifier for selected member
1006 *
1007 * Compute a SID to use for relabeling an object of class @tclass
1008 * based on a SID pair (@ssid, @tsid).
1009 * Return -%EINVAL if any of the parameters are invalid, -%ENOMEM
1010 * if insufficient memory is available, or %0 if the SID was
1011 * computed successfully.
1012 */
1013int security_change_sid(u32 ssid,
1014			u32 tsid,
1015			u16 tclass,
1016			u32 *out_sid)
1017{
1018	return security_compute_sid(ssid, tsid, tclass, AVTAB_CHANGE, out_sid);
1019}
1020
1021/*
1022 * Verify that each permission that is defined under the
1023 * existing policy is still defined with the same value
1024 * in the new policy.
1025 */
1026static int validate_perm(void *key, void *datum, void *p)
1027{
1028	struct hashtab *h;
1029	struct perm_datum *perdatum, *perdatum2;
1030	int rc = 0;
1031
1032
1033	h = p;
1034	perdatum = datum;
1035
1036	perdatum2 = hashtab_search(h, key);
1037	if (!perdatum2) {
1038		printk(KERN_ERR "security:  permission %s disappeared",
1039		       (char *)key);
1040		rc = -ENOENT;
1041		goto out;
1042	}
1043	if (perdatum->value != perdatum2->value) {
1044		printk(KERN_ERR "security:  the value of permission %s changed",
1045		       (char *)key);
1046		rc = -EINVAL;
1047	}
1048out:
1049	return rc;
1050}
1051
1052/*
1053 * Verify that each class that is defined under the
1054 * existing policy is still defined with the same
1055 * attributes in the new policy.
1056 */
1057static int validate_class(void *key, void *datum, void *p)
1058{
1059	struct policydb *newp;
1060	struct class_datum *cladatum, *cladatum2;
1061	int rc;
1062
1063	newp = p;
1064	cladatum = datum;
1065
1066	cladatum2 = hashtab_search(newp->p_classes.table, key);
1067	if (!cladatum2) {
1068		printk(KERN_ERR "security:  class %s disappeared\n",
1069		       (char *)key);
1070		rc = -ENOENT;
1071		goto out;
1072	}
1073	if (cladatum->value != cladatum2->value) {
1074		printk(KERN_ERR "security:  the value of class %s changed\n",
1075		       (char *)key);
1076		rc = -EINVAL;
1077		goto out;
1078	}
1079	if ((cladatum->comdatum && !cladatum2->comdatum) ||
1080	    (!cladatum->comdatum && cladatum2->comdatum)) {
1081		printk(KERN_ERR "security:  the inherits clause for the access "
1082		       "vector definition for class %s changed\n", (char *)key);
1083		rc = -EINVAL;
1084		goto out;
1085	}
1086	if (cladatum->comdatum) {
1087		rc = hashtab_map(cladatum->comdatum->permissions.table, validate_perm,
1088		                 cladatum2->comdatum->permissions.table);
1089		if (rc) {
1090			printk(" in the access vector definition for class "
1091			       "%s\n", (char *)key);
1092			goto out;
1093		}
1094	}
1095	rc = hashtab_map(cladatum->permissions.table, validate_perm,
1096	                 cladatum2->permissions.table);
1097	if (rc)
1098		printk(" in access vector definition for class %s\n",
1099		       (char *)key);
1100out:
1101	return rc;
1102}
1103
1104/* Clone the SID into the new SID table. */
1105static int clone_sid(u32 sid,
1106		     struct context *context,
1107		     void *arg)
1108{
1109	struct sidtab *s = arg;
1110
1111	return sidtab_insert(s, sid, context);
1112}
1113
1114static inline int convert_context_handle_invalid_context(struct context *context)
1115{
1116	int rc = 0;
1117
1118	if (selinux_enforcing) {
1119		rc = -EINVAL;
1120	} else {
1121		char *s;
1122		u32 len;
1123
1124		context_struct_to_string(context, &s, &len);
1125		printk(KERN_ERR "security:  context %s is invalid\n", s);
1126		kfree(s);
1127	}
1128	return rc;
1129}
1130
1131struct convert_context_args {
1132	struct policydb *oldp;
1133	struct policydb *newp;
1134};
1135
1136/*
1137 * Convert the values in the security context
1138 * structure `c' from the values specified
1139 * in the policy `p->oldp' to the values specified
1140 * in the policy `p->newp'.  Verify that the
1141 * context is valid under the new policy.
1142 */
1143static int convert_context(u32 key,
1144			   struct context *c,
1145			   void *p)
1146{
1147	struct convert_context_args *args;
1148	struct context oldc;
1149	struct role_datum *role;
1150	struct type_datum *typdatum;
1151	struct user_datum *usrdatum;
1152	char *s;
1153	u32 len;
1154	int rc;
1155
1156	args = p;
1157
1158	rc = context_cpy(&oldc, c);
1159	if (rc)
1160		goto out;
1161
1162	rc = -EINVAL;
1163
1164	/* Convert the user. */
1165	usrdatum = hashtab_search(args->newp->p_users.table,
1166	                          args->oldp->p_user_val_to_name[c->user - 1]);
1167	if (!usrdatum) {
1168		goto bad;
1169	}
1170	c->user = usrdatum->value;
1171
1172	/* Convert the role. */
1173	role = hashtab_search(args->newp->p_roles.table,
1174	                      args->oldp->p_role_val_to_name[c->role - 1]);
1175	if (!role) {
1176		goto bad;
1177	}
1178	c->role = role->value;
1179
1180	/* Convert the type. */
1181	typdatum = hashtab_search(args->newp->p_types.table,
1182	                          args->oldp->p_type_val_to_name[c->type - 1]);
1183	if (!typdatum) {
1184		goto bad;
1185	}
1186	c->type = typdatum->value;
1187
1188	rc = mls_convert_context(args->oldp, args->newp, c);
1189	if (rc)
1190		goto bad;
1191
1192	/* Check the validity of the new context. */
1193	if (!policydb_context_isvalid(args->newp, c)) {
1194		rc = convert_context_handle_invalid_context(&oldc);
1195		if (rc)
1196			goto bad;
1197	}
1198
1199	context_destroy(&oldc);
1200out:
1201	return rc;
1202bad:
1203	context_struct_to_string(&oldc, &s, &len);
1204	context_destroy(&oldc);
1205	printk(KERN_ERR "security:  invalidating context %s\n", s);
1206	kfree(s);
1207	goto out;
1208}
1209
1210extern void selinux_complete_init(void);
1211
1212/**
1213 * security_load_policy - Load a security policy configuration.
1214 * @data: binary policy data
1215 * @len: length of data in bytes
1216 *
1217 * Load a new set of security policy configuration data,
1218 * validate it and convert the SID table as necessary.
1219 * This function will flush the access vector cache after
1220 * loading the new policy.
1221 */
1222int security_load_policy(void *data, size_t len)
1223{
1224	struct policydb oldpolicydb, newpolicydb;
1225	struct sidtab oldsidtab, newsidtab;
1226	struct convert_context_args args;
1227	u32 seqno;
1228	int rc = 0;
1229	struct policy_file file = { data, len }, *fp = &file;
1230
1231	LOAD_LOCK;
1232
1233	if (!ss_initialized) {
1234		avtab_cache_init();
1235		if (policydb_read(&policydb, fp)) {
1236			LOAD_UNLOCK;
1237			avtab_cache_destroy();
1238			return -EINVAL;
1239		}
1240		if (policydb_load_isids(&policydb, &sidtab)) {
1241			LOAD_UNLOCK;
1242			policydb_destroy(&policydb);
1243			avtab_cache_destroy();
1244			return -EINVAL;
1245		}
1246		policydb_loaded_version = policydb.policyvers;
1247		ss_initialized = 1;
1248		seqno = ++latest_granting;
1249		LOAD_UNLOCK;
1250		selinux_complete_init();
1251		avc_ss_reset(seqno);
1252		selnl_notify_policyload(seqno);
1253		selinux_netlbl_cache_invalidate();
1254		return 0;
1255	}
1256
1257#if 0
1258	sidtab_hash_eval(&sidtab, "sids");
1259#endif
1260
1261	if (policydb_read(&newpolicydb, fp)) {
1262		LOAD_UNLOCK;
1263		return -EINVAL;
1264	}
1265
1266	sidtab_init(&newsidtab);
1267
1268	/* Verify that the existing classes did not change. */
1269	if (hashtab_map(policydb.p_classes.table, validate_class, &newpolicydb)) {
1270		printk(KERN_ERR "security:  the definition of an existing "
1271		       "class changed\n");
1272		rc = -EINVAL;
1273		goto err;
1274	}
1275
1276	/* Clone the SID table. */
1277	sidtab_shutdown(&sidtab);
1278	if (sidtab_map(&sidtab, clone_sid, &newsidtab)) {
1279		rc = -ENOMEM;
1280		goto err;
1281	}
1282
1283	/* Convert the internal representations of contexts
1284	   in the new SID table and remove invalid SIDs. */
1285	args.oldp = &policydb;
1286	args.newp = &newpolicydb;
1287	sidtab_map_remove_on_error(&newsidtab, convert_context, &args);
1288
1289	/* Save the old policydb and SID table to free later. */
1290	memcpy(&oldpolicydb, &policydb, sizeof policydb);
1291	sidtab_set(&oldsidtab, &sidtab);
1292
1293	/* Install the new policydb and SID table. */
1294	POLICY_WRLOCK;
1295	memcpy(&policydb, &newpolicydb, sizeof policydb);
1296	sidtab_set(&sidtab, &newsidtab);
1297	seqno = ++latest_granting;
1298	policydb_loaded_version = policydb.policyvers;
1299	POLICY_WRUNLOCK;
1300	LOAD_UNLOCK;
1301
1302	/* Free the old policydb and SID table. */
1303	policydb_destroy(&oldpolicydb);
1304	sidtab_destroy(&oldsidtab);
1305
1306	avc_ss_reset(seqno);
1307	selnl_notify_policyload(seqno);
1308	selinux_netlbl_cache_invalidate();
1309
1310	return 0;
1311
1312err:
1313	LOAD_UNLOCK;
1314	sidtab_destroy(&newsidtab);
1315	policydb_destroy(&newpolicydb);
1316	return rc;
1317
1318}
1319
1320/**
1321 * security_port_sid - Obtain the SID for a port.
1322 * @domain: communication domain aka address family
1323 * @type: socket type
1324 * @protocol: protocol number
1325 * @port: port number
1326 * @out_sid: security identifier
1327 */
1328int security_port_sid(u16 domain,
1329		      u16 type,
1330		      u8 protocol,
1331		      u16 port,
1332		      u32 *out_sid)
1333{
1334	struct ocontext *c;
1335	int rc = 0;
1336
1337	POLICY_RDLOCK;
1338
1339	c = policydb.ocontexts[OCON_PORT];
1340	while (c) {
1341		if (c->u.port.protocol == protocol &&
1342		    c->u.port.low_port <= port &&
1343		    c->u.port.high_port >= port)
1344			break;
1345		c = c->next;
1346	}
1347
1348	if (c) {
1349		if (!c->sid[0]) {
1350			rc = sidtab_context_to_sid(&sidtab,
1351						   &c->context[0],
1352						   &c->sid[0]);
1353			if (rc)
1354				goto out;
1355		}
1356		*out_sid = c->sid[0];
1357	} else {
1358		*out_sid = SECINITSID_PORT;
1359	}
1360
1361out:
1362	POLICY_RDUNLOCK;
1363	return rc;
1364}
1365
1366/**
1367 * security_netif_sid - Obtain the SID for a network interface.
1368 * @name: interface name
1369 * @if_sid: interface SID
1370 * @msg_sid: default SID for received packets
1371 */
1372int security_netif_sid(char *name,
1373		       u32 *if_sid,
1374		       u32 *msg_sid)
1375{
1376	int rc = 0;
1377	struct ocontext *c;
1378
1379	POLICY_RDLOCK;
1380
1381	c = policydb.ocontexts[OCON_NETIF];
1382	while (c) {
1383		if (strcmp(name, c->u.name) == 0)
1384			break;
1385		c = c->next;
1386	}
1387
1388	if (c) {
1389		if (!c->sid[0] || !c->sid[1]) {
1390			rc = sidtab_context_to_sid(&sidtab,
1391						  &c->context[0],
1392						  &c->sid[0]);
1393			if (rc)
1394				goto out;
1395			rc = sidtab_context_to_sid(&sidtab,
1396						   &c->context[1],
1397						   &c->sid[1]);
1398			if (rc)
1399				goto out;
1400		}
1401		*if_sid = c->sid[0];
1402		*msg_sid = c->sid[1];
1403	} else {
1404		*if_sid = SECINITSID_NETIF;
1405		*msg_sid = SECINITSID_NETMSG;
1406	}
1407
1408out:
1409	POLICY_RDUNLOCK;
1410	return rc;
1411}
1412
1413static int match_ipv6_addrmask(u32 *input, u32 *addr, u32 *mask)
1414{
1415	int i, fail = 0;
1416
1417	for(i = 0; i < 4; i++)
1418		if(addr[i] != (input[i] & mask[i])) {
1419			fail = 1;
1420			break;
1421		}
1422
1423	return !fail;
1424}
1425
1426/**
1427 * security_node_sid - Obtain the SID for a node (host).
1428 * @domain: communication domain aka address family
1429 * @addrp: address
1430 * @addrlen: address length in bytes
1431 * @out_sid: security identifier
1432 */
1433int security_node_sid(u16 domain,
1434		      void *addrp,
1435		      u32 addrlen,
1436		      u32 *out_sid)
1437{
1438	int rc = 0;
1439	struct ocontext *c;
1440
1441	POLICY_RDLOCK;
1442
1443	switch (domain) {
1444	case AF_INET: {
1445		u32 addr;
1446
1447		if (addrlen != sizeof(u32)) {
1448			rc = -EINVAL;
1449			goto out;
1450		}
1451
1452		addr = *((u32 *)addrp);
1453
1454		c = policydb.ocontexts[OCON_NODE];
1455		while (c) {
1456			if (c->u.node.addr == (addr & c->u.node.mask))
1457				break;
1458			c = c->next;
1459		}
1460		break;
1461	}
1462
1463	case AF_INET6:
1464		if (addrlen != sizeof(u64) * 2) {
1465			rc = -EINVAL;
1466			goto out;
1467		}
1468		c = policydb.ocontexts[OCON_NODE6];
1469		while (c) {
1470			if (match_ipv6_addrmask(addrp, c->u.node6.addr,
1471						c->u.node6.mask))
1472				break;
1473			c = c->next;
1474		}
1475		break;
1476
1477	default:
1478		*out_sid = SECINITSID_NODE;
1479		goto out;
1480	}
1481
1482	if (c) {
1483		if (!c->sid[0]) {
1484			rc = sidtab_context_to_sid(&sidtab,
1485						   &c->context[0],
1486						   &c->sid[0]);
1487			if (rc)
1488				goto out;
1489		}
1490		*out_sid = c->sid[0];
1491	} else {
1492		*out_sid = SECINITSID_NODE;
1493	}
1494
1495out:
1496	POLICY_RDUNLOCK;
1497	return rc;
1498}
1499
1500#define SIDS_NEL 25
1501
1502/**
1503 * security_get_user_sids - Obtain reachable SIDs for a user.
1504 * @fromsid: starting SID
1505 * @username: username
1506 * @sids: array of reachable SIDs for user
1507 * @nel: number of elements in @sids
1508 *
1509 * Generate the set of SIDs for legal security contexts
1510 * for a given user that can be reached by @fromsid.
1511 * Set *@sids to point to a dynamically allocated
1512 * array containing the set of SIDs.  Set *@nel to the
1513 * number of elements in the array.
1514 */
1515
1516int security_get_user_sids(u32 fromsid,
1517	                   char *username,
1518			   u32 **sids,
1519			   u32 *nel)
1520{
1521	struct context *fromcon, usercon;
1522	u32 *mysids, *mysids2, sid;
1523	u32 mynel = 0, maxnel = SIDS_NEL;
1524	struct user_datum *user;
1525	struct role_datum *role;
1526	struct av_decision avd;
1527	struct ebitmap_node *rnode, *tnode;
1528	int rc = 0, i, j;
1529
1530	if (!ss_initialized) {
1531		*sids = NULL;
1532		*nel = 0;
1533		goto out;
1534	}
1535
1536	POLICY_RDLOCK;
1537
1538	fromcon = sidtab_search(&sidtab, fromsid);
1539	if (!fromcon) {
1540		rc = -EINVAL;
1541		goto out_unlock;
1542	}
1543
1544	user = hashtab_search(policydb.p_users.table, username);
1545	if (!user) {
1546		rc = -EINVAL;
1547		goto out_unlock;
1548	}
1549	usercon.user = user->value;
1550
1551	mysids = kcalloc(maxnel, sizeof(*mysids), GFP_ATOMIC);
1552	if (!mysids) {
1553		rc = -ENOMEM;
1554		goto out_unlock;
1555	}
1556
1557	ebitmap_for_each_bit(&user->roles, rnode, i) {
1558		if (!ebitmap_node_get_bit(rnode, i))
1559			continue;
1560		role = policydb.role_val_to_struct[i];
1561		usercon.role = i+1;
1562		ebitmap_for_each_bit(&role->types, tnode, j) {
1563			if (!ebitmap_node_get_bit(tnode, j))
1564				continue;
1565			usercon.type = j+1;
1566
1567			if (mls_setup_user_range(fromcon, user, &usercon))
1568				continue;
1569
1570			rc = context_struct_compute_av(fromcon, &usercon,
1571						       SECCLASS_PROCESS,
1572						       PROCESS__TRANSITION,
1573						       &avd);
1574			if (rc ||  !(avd.allowed & PROCESS__TRANSITION))
1575				continue;
1576			rc = sidtab_context_to_sid(&sidtab, &usercon, &sid);
1577			if (rc) {
1578				kfree(mysids);
1579				goto out_unlock;
1580			}
1581			if (mynel < maxnel) {
1582				mysids[mynel++] = sid;
1583			} else {
1584				maxnel += SIDS_NEL;
1585				mysids2 = kcalloc(maxnel, sizeof(*mysids2), GFP_ATOMIC);
1586				if (!mysids2) {
1587					rc = -ENOMEM;
1588					kfree(mysids);
1589					goto out_unlock;
1590				}
1591				memcpy(mysids2, mysids, mynel * sizeof(*mysids2));
1592				kfree(mysids);
1593				mysids = mysids2;
1594				mysids[mynel++] = sid;
1595			}
1596		}
1597	}
1598
1599	*sids = mysids;
1600	*nel = mynel;
1601
1602out_unlock:
1603	POLICY_RDUNLOCK;
1604out:
1605	return rc;
1606}
1607
1608/**
1609 * security_genfs_sid - Obtain a SID for a file in a filesystem
1610 * @fstype: filesystem type
1611 * @path: path from root of mount
1612 * @sclass: file security class
1613 * @sid: SID for path
1614 *
1615 * Obtain a SID to use for a file in a filesystem that
1616 * cannot support xattr or use a fixed labeling behavior like
1617 * transition SIDs or task SIDs.
1618 */
1619int security_genfs_sid(const char *fstype,
1620	               char *path,
1621		       u16 sclass,
1622		       u32 *sid)
1623{
1624	int len;
1625	struct genfs *genfs;
1626	struct ocontext *c;
1627	int rc = 0, cmp = 0;
1628
1629	POLICY_RDLOCK;
1630
1631	for (genfs = policydb.genfs; genfs; genfs = genfs->next) {
1632		cmp = strcmp(fstype, genfs->fstype);
1633		if (cmp <= 0)
1634			break;
1635	}
1636
1637	if (!genfs || cmp) {
1638		*sid = SECINITSID_UNLABELED;
1639		rc = -ENOENT;
1640		goto out;
1641	}
1642
1643	for (c = genfs->head; c; c = c->next) {
1644		len = strlen(c->u.name);
1645		if ((!c->v.sclass || sclass == c->v.sclass) &&
1646		    (strncmp(c->u.name, path, len) == 0))
1647			break;
1648	}
1649
1650	if (!c) {
1651		*sid = SECINITSID_UNLABELED;
1652		rc = -ENOENT;
1653		goto out;
1654	}
1655
1656	if (!c->sid[0]) {
1657		rc = sidtab_context_to_sid(&sidtab,
1658					   &c->context[0],
1659					   &c->sid[0]);
1660		if (rc)
1661			goto out;
1662	}
1663
1664	*sid = c->sid[0];
1665out:
1666	POLICY_RDUNLOCK;
1667	return rc;
1668}
1669
1670/**
1671 * security_fs_use - Determine how to handle labeling for a filesystem.
1672 * @fstype: filesystem type
1673 * @behavior: labeling behavior
1674 * @sid: SID for filesystem (superblock)
1675 */
1676int security_fs_use(
1677	const char *fstype,
1678	unsigned int *behavior,
1679	u32 *sid)
1680{
1681	int rc = 0;
1682	struct ocontext *c;
1683
1684	POLICY_RDLOCK;
1685
1686	c = policydb.ocontexts[OCON_FSUSE];
1687	while (c) {
1688		if (strcmp(fstype, c->u.name) == 0)
1689			break;
1690		c = c->next;
1691	}
1692
1693	if (c) {
1694		*behavior = c->v.behavior;
1695		if (!c->sid[0]) {
1696			rc = sidtab_context_to_sid(&sidtab,
1697						   &c->context[0],
1698						   &c->sid[0]);
1699			if (rc)
1700				goto out;
1701		}
1702		*sid = c->sid[0];
1703	} else {
1704		rc = security_genfs_sid(fstype, "/", SECCLASS_DIR, sid);
1705		if (rc) {
1706			*behavior = SECURITY_FS_USE_NONE;
1707			rc = 0;
1708		} else {
1709			*behavior = SECURITY_FS_USE_GENFS;
1710		}
1711	}
1712
1713out:
1714	POLICY_RDUNLOCK;
1715	return rc;
1716}
1717
1718int security_get_bools(int *len, char ***names, int **values)
1719{
1720	int i, rc = -ENOMEM;
1721
1722	POLICY_RDLOCK;
1723	*names = NULL;
1724	*values = NULL;
1725
1726	*len = policydb.p_bools.nprim;
1727	if (!*len) {
1728		rc = 0;
1729		goto out;
1730	}
1731
1732       *names = kcalloc(*len, sizeof(char*), GFP_ATOMIC);
1733	if (!*names)
1734		goto err;
1735
1736       *values = kcalloc(*len, sizeof(int), GFP_ATOMIC);
1737	if (!*values)
1738		goto err;
1739
1740	for (i = 0; i < *len; i++) {
1741		size_t name_len;
1742		(*values)[i] = policydb.bool_val_to_struct[i]->state;
1743		name_len = strlen(policydb.p_bool_val_to_name[i]) + 1;
1744               (*names)[i] = kmalloc(sizeof(char) * name_len, GFP_ATOMIC);
1745		if (!(*names)[i])
1746			goto err;
1747		strncpy((*names)[i], policydb.p_bool_val_to_name[i], name_len);
1748		(*names)[i][name_len - 1] = 0;
1749	}
1750	rc = 0;
1751out:
1752	POLICY_RDUNLOCK;
1753	return rc;
1754err:
1755	if (*names) {
1756		for (i = 0; i < *len; i++)
1757			kfree((*names)[i]);
1758	}
1759	kfree(*values);
1760	goto out;
1761}
1762
1763
1764int security_set_bools(int len, int *values)
1765{
1766	int i, rc = 0;
1767	int lenp, seqno = 0;
1768	struct cond_node *cur;
1769
1770	POLICY_WRLOCK;
1771
1772	lenp = policydb.p_bools.nprim;
1773	if (len != lenp) {
1774		rc = -EFAULT;
1775		goto out;
1776	}
1777
1778	for (i = 0; i < len; i++) {
1779		if (!!values[i] != policydb.bool_val_to_struct[i]->state) {
1780			audit_log(current->audit_context, GFP_ATOMIC,
1781				AUDIT_MAC_CONFIG_CHANGE,
1782				"bool=%s val=%d old_val=%d auid=%u",
1783				policydb.p_bool_val_to_name[i],
1784				!!values[i],
1785				policydb.bool_val_to_struct[i]->state,
1786				audit_get_loginuid(current->audit_context));
1787		}
1788		if (values[i]) {
1789			policydb.bool_val_to_struct[i]->state = 1;
1790		} else {
1791			policydb.bool_val_to_struct[i]->state = 0;
1792		}
1793	}
1794
1795	for (cur = policydb.cond_list; cur != NULL; cur = cur->next) {
1796		rc = evaluate_cond_node(&policydb, cur);
1797		if (rc)
1798			goto out;
1799	}
1800
1801	seqno = ++latest_granting;
1802
1803out:
1804	POLICY_WRUNLOCK;
1805	if (!rc) {
1806		avc_ss_reset(seqno);
1807		selnl_notify_policyload(seqno);
1808	}
1809	return rc;
1810}
1811
1812int security_get_bool_value(int bool)
1813{
1814	int rc = 0;
1815	int len;
1816
1817	POLICY_RDLOCK;
1818
1819	len = policydb.p_bools.nprim;
1820	if (bool >= len) {
1821		rc = -EFAULT;
1822		goto out;
1823	}
1824
1825	rc = policydb.bool_val_to_struct[bool]->state;
1826out:
1827	POLICY_RDUNLOCK;
1828	return rc;
1829}
1830
1831/*
1832 * security_sid_mls_copy() - computes a new sid based on the given
1833 * sid and the mls portion of mls_sid.
1834 */
1835int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid)
1836{
1837	struct context *context1;
1838	struct context *context2;
1839	struct context newcon;
1840	char *s;
1841	u32 len;
1842	int rc = 0;
1843
1844	if (!ss_initialized || !selinux_mls_enabled) {
1845		*new_sid = sid;
1846		goto out;
1847	}
1848
1849	context_init(&newcon);
1850
1851	POLICY_RDLOCK;
1852	context1 = sidtab_search(&sidtab, sid);
1853	if (!context1) {
1854		printk(KERN_ERR "security_sid_mls_copy:  unrecognized SID "
1855		       "%d\n", sid);
1856		rc = -EINVAL;
1857		goto out_unlock;
1858	}
1859
1860	context2 = sidtab_search(&sidtab, mls_sid);
1861	if (!context2) {
1862		printk(KERN_ERR "security_sid_mls_copy:  unrecognized SID "
1863		       "%d\n", mls_sid);
1864		rc = -EINVAL;
1865		goto out_unlock;
1866	}
1867
1868	newcon.user = context1->user;
1869	newcon.role = context1->role;
1870	newcon.type = context1->type;
1871	rc = mls_copy_context(&newcon, context2);
1872	if (rc)
1873		goto out_unlock;
1874
1875
1876	/* Check the validity of the new context. */
1877	if (!policydb_context_isvalid(&policydb, &newcon)) {
1878		rc = convert_context_handle_invalid_context(&newcon);
1879		if (rc)
1880			goto bad;
1881	}
1882
1883	rc = sidtab_context_to_sid(&sidtab, &newcon, new_sid);
1884	goto out_unlock;
1885
1886bad:
1887	if (!context_struct_to_string(&newcon, &s, &len)) {
1888		audit_log(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR,
1889			  "security_sid_mls_copy: invalid context %s", s);
1890		kfree(s);
1891	}
1892
1893out_unlock:
1894	POLICY_RDUNLOCK;
1895	context_destroy(&newcon);
1896out:
1897	return rc;
1898}
1899
1900struct selinux_audit_rule {
1901	u32 au_seqno;
1902	struct context au_ctxt;
1903};
1904
1905void selinux_audit_rule_free(struct selinux_audit_rule *rule)
1906{
1907	if (rule) {
1908		context_destroy(&rule->au_ctxt);
1909		kfree(rule);
1910	}
1911}
1912
1913int selinux_audit_rule_init(u32 field, u32 op, char *rulestr,
1914                            struct selinux_audit_rule **rule)
1915{
1916	struct selinux_audit_rule *tmprule;
1917	struct role_datum *roledatum;
1918	struct type_datum *typedatum;
1919	struct user_datum *userdatum;
1920	int rc = 0;
1921
1922	*rule = NULL;
1923
1924	if (!ss_initialized)
1925		return -ENOTSUPP;
1926
1927	switch (field) {
1928	case AUDIT_SUBJ_USER:
1929	case AUDIT_SUBJ_ROLE:
1930	case AUDIT_SUBJ_TYPE:
1931	case AUDIT_OBJ_USER:
1932	case AUDIT_OBJ_ROLE:
1933	case AUDIT_OBJ_TYPE:
1934		/* only 'equals' and 'not equals' fit user, role, and type */
1935		if (op != AUDIT_EQUAL && op != AUDIT_NOT_EQUAL)
1936			return -EINVAL;
1937		break;
1938	case AUDIT_SUBJ_SEN:
1939	case AUDIT_SUBJ_CLR:
1940	case AUDIT_OBJ_LEV_LOW:
1941	case AUDIT_OBJ_LEV_HIGH:
1942		/* we do not allow a range, indicated by the presense of '-' */
1943		if (strchr(rulestr, '-'))
1944			return -EINVAL;
1945		break;
1946	default:
1947		/* only the above fields are valid */
1948		return -EINVAL;
1949	}
1950
1951	tmprule = kzalloc(sizeof(struct selinux_audit_rule), GFP_KERNEL);
1952	if (!tmprule)
1953		return -ENOMEM;
1954
1955	context_init(&tmprule->au_ctxt);
1956
1957	POLICY_RDLOCK;
1958
1959	tmprule->au_seqno = latest_granting;
1960
1961	switch (field) {
1962	case AUDIT_SUBJ_USER:
1963	case AUDIT_OBJ_USER:
1964		userdatum = hashtab_search(policydb.p_users.table, rulestr);
1965		if (!userdatum)
1966			rc = -EINVAL;
1967		else
1968			tmprule->au_ctxt.user = userdatum->value;
1969		break;
1970	case AUDIT_SUBJ_ROLE:
1971	case AUDIT_OBJ_ROLE:
1972		roledatum = hashtab_search(policydb.p_roles.table, rulestr);
1973		if (!roledatum)
1974			rc = -EINVAL;
1975		else
1976			tmprule->au_ctxt.role = roledatum->value;
1977		break;
1978	case AUDIT_SUBJ_TYPE:
1979	case AUDIT_OBJ_TYPE:
1980		typedatum = hashtab_search(policydb.p_types.table, rulestr);
1981		if (!typedatum)
1982			rc = -EINVAL;
1983		else
1984			tmprule->au_ctxt.type = typedatum->value;
1985		break;
1986	case AUDIT_SUBJ_SEN:
1987	case AUDIT_SUBJ_CLR:
1988	case AUDIT_OBJ_LEV_LOW:
1989	case AUDIT_OBJ_LEV_HIGH:
1990		rc = mls_from_string(rulestr, &tmprule->au_ctxt, GFP_ATOMIC);
1991		break;
1992	}
1993
1994	POLICY_RDUNLOCK;
1995
1996	if (rc) {
1997		selinux_audit_rule_free(tmprule);
1998		tmprule = NULL;
1999	}
2000
2001	*rule = tmprule;
2002
2003	return rc;
2004}
2005
2006int selinux_audit_rule_match(u32 sid, u32 field, u32 op,
2007                             struct selinux_audit_rule *rule,
2008                             struct audit_context *actx)
2009{
2010	struct context *ctxt;
2011	struct mls_level *level;
2012	int match = 0;
2013
2014	if (!rule) {
2015		audit_log(actx, GFP_ATOMIC, AUDIT_SELINUX_ERR,
2016		          "selinux_audit_rule_match: missing rule\n");
2017		return -ENOENT;
2018	}
2019
2020	POLICY_RDLOCK;
2021
2022	if (rule->au_seqno < latest_granting) {
2023		audit_log(actx, GFP_ATOMIC, AUDIT_SELINUX_ERR,
2024		          "selinux_audit_rule_match: stale rule\n");
2025		match = -ESTALE;
2026		goto out;
2027	}
2028
2029	ctxt = sidtab_search(&sidtab, sid);
2030	if (!ctxt) {
2031		audit_log(actx, GFP_ATOMIC, AUDIT_SELINUX_ERR,
2032		          "selinux_audit_rule_match: unrecognized SID %d\n",
2033		          sid);
2034		match = -ENOENT;
2035		goto out;
2036	}
2037
2038	/* a field/op pair that is not caught here will simply fall through
2039	   without a match */
2040	switch (field) {
2041	case AUDIT_SUBJ_USER:
2042	case AUDIT_OBJ_USER:
2043		switch (op) {
2044		case AUDIT_EQUAL:
2045			match = (ctxt->user == rule->au_ctxt.user);
2046			break;
2047		case AUDIT_NOT_EQUAL:
2048			match = (ctxt->user != rule->au_ctxt.user);
2049			break;
2050		}
2051		break;
2052	case AUDIT_SUBJ_ROLE:
2053	case AUDIT_OBJ_ROLE:
2054		switch (op) {
2055		case AUDIT_EQUAL:
2056			match = (ctxt->role == rule->au_ctxt.role);
2057			break;
2058		case AUDIT_NOT_EQUAL:
2059			match = (ctxt->role != rule->au_ctxt.role);
2060			break;
2061		}
2062		break;
2063	case AUDIT_SUBJ_TYPE:
2064	case AUDIT_OBJ_TYPE:
2065		switch (op) {
2066		case AUDIT_EQUAL:
2067			match = (ctxt->type == rule->au_ctxt.type);
2068			break;
2069		case AUDIT_NOT_EQUAL:
2070			match = (ctxt->type != rule->au_ctxt.type);
2071			break;
2072		}
2073		break;
2074	case AUDIT_SUBJ_SEN:
2075	case AUDIT_SUBJ_CLR:
2076	case AUDIT_OBJ_LEV_LOW:
2077	case AUDIT_OBJ_LEV_HIGH:
2078		level = ((field == AUDIT_SUBJ_SEN ||
2079		          field == AUDIT_OBJ_LEV_LOW) ?
2080		         &ctxt->range.level[0] : &ctxt->range.level[1]);
2081		switch (op) {
2082		case AUDIT_EQUAL:
2083			match = mls_level_eq(&rule->au_ctxt.range.level[0],
2084			                     level);
2085			break;
2086		case AUDIT_NOT_EQUAL:
2087			match = !mls_level_eq(&rule->au_ctxt.range.level[0],
2088			                      level);
2089			break;
2090		case AUDIT_LESS_THAN:
2091			match = (mls_level_dom(&rule->au_ctxt.range.level[0],
2092			                       level) &&
2093			         !mls_level_eq(&rule->au_ctxt.range.level[0],
2094			                       level));
2095			break;
2096		case AUDIT_LESS_THAN_OR_EQUAL:
2097			match = mls_level_dom(&rule->au_ctxt.range.level[0],
2098			                      level);
2099			break;
2100		case AUDIT_GREATER_THAN:
2101			match = (mls_level_dom(level,
2102			                      &rule->au_ctxt.range.level[0]) &&
2103			         !mls_level_eq(level,
2104			                       &rule->au_ctxt.range.level[0]));
2105			break;
2106		case AUDIT_GREATER_THAN_OR_EQUAL:
2107			match = mls_level_dom(level,
2108			                      &rule->au_ctxt.range.level[0]);
2109			break;
2110		}
2111	}
2112
2113out:
2114	POLICY_RDUNLOCK;
2115	return match;
2116}
2117
2118static int (*aurule_callback)(void) = NULL;
2119
2120static int aurule_avc_callback(u32 event, u32 ssid, u32 tsid,
2121                               u16 class, u32 perms, u32 *retained)
2122{
2123	int err = 0;
2124
2125	if (event == AVC_CALLBACK_RESET && aurule_callback)
2126		err = aurule_callback();
2127	return err;
2128}
2129
2130static int __init aurule_init(void)
2131{
2132	int err;
2133
2134	err = avc_add_callback(aurule_avc_callback, AVC_CALLBACK_RESET,
2135	                       SECSID_NULL, SECSID_NULL, SECCLASS_NULL, 0);
2136	if (err)
2137		panic("avc_add_callback() failed, error %d\n", err);
2138
2139	return err;
2140}
2141__initcall(aurule_init);
2142
2143void selinux_audit_set_callback(int (*callback)(void))
2144{
2145	aurule_callback = callback;
2146}
2147
2148#ifdef CONFIG_NETLABEL
2149/*
2150 * This is the structure we store inside the NetLabel cache block.
2151 */
2152#define NETLBL_CACHE(x)           ((struct netlbl_cache *)(x))
2153#define NETLBL_CACHE_T_NONE       0
2154#define NETLBL_CACHE_T_SID        1
2155#define NETLBL_CACHE_T_MLS        2
2156struct netlbl_cache {
2157	u32 type;
2158	union {
2159		u32 sid;
2160		struct mls_range mls_label;
2161	} data;
2162};
2163
2164/**
2165 * selinux_netlbl_cache_free - Free the NetLabel cached data
2166 * @data: the data to free
2167 *
2168 * Description:
2169 * This function is intended to be used as the free() callback inside the
2170 * netlbl_lsm_cache structure.
2171 *
2172 */
2173static void selinux_netlbl_cache_free(const void *data)
2174{
2175	struct netlbl_cache *cache = NETLBL_CACHE(data);
2176	switch (cache->type) {
2177	case NETLBL_CACHE_T_MLS:
2178		ebitmap_destroy(&cache->data.mls_label.level[0].cat);
2179		break;
2180	}
2181	kfree(data);
2182}
2183
2184/**
2185 * selinux_netlbl_cache_add - Add an entry to the NetLabel cache
2186 * @skb: the packet
2187 * @ctx: the SELinux context
2188 *
2189 * Description:
2190 * Attempt to cache the context in @ctx, which was derived from the packet in
2191 * @skb, in the NetLabel subsystem cache.
2192 *
2193 */
2194static void selinux_netlbl_cache_add(struct sk_buff *skb, struct context *ctx)
2195{
2196	struct netlbl_cache *cache = NULL;
2197	struct netlbl_lsm_secattr secattr;
2198
2199	netlbl_secattr_init(&secattr);
2200
2201	cache = kzalloc(sizeof(*cache),	GFP_ATOMIC);
2202	if (cache == NULL)
2203		goto netlbl_cache_add_failure;
2204	secattr.cache.free = selinux_netlbl_cache_free;
2205	secattr.cache.data = (void *)cache;
2206
2207	cache->type = NETLBL_CACHE_T_MLS;
2208	if (ebitmap_cpy(&cache->data.mls_label.level[0].cat,
2209			&ctx->range.level[0].cat) != 0)
2210		goto netlbl_cache_add_failure;
2211	cache->data.mls_label.level[1].cat.highbit =
2212		cache->data.mls_label.level[0].cat.highbit;
2213	cache->data.mls_label.level[1].cat.node =
2214		cache->data.mls_label.level[0].cat.node;
2215	cache->data.mls_label.level[0].sens = ctx->range.level[0].sens;
2216	cache->data.mls_label.level[1].sens = ctx->range.level[0].sens;
2217
2218	if (netlbl_cache_add(skb, &secattr) != 0)
2219		goto netlbl_cache_add_failure;
2220
2221	return;
2222
2223netlbl_cache_add_failure:
2224	netlbl_secattr_destroy(&secattr, 1);
2225}
2226
2227/**
2228 * selinux_netlbl_cache_invalidate - Invalidate the NetLabel cache
2229 *
2230 * Description:
2231 * Invalidate the NetLabel security attribute mapping cache.
2232 *
2233 */
2234void selinux_netlbl_cache_invalidate(void)
2235{
2236	netlbl_cache_invalidate();
2237}
2238
2239/**
2240 * selinux_netlbl_secattr_to_sid - Convert a NetLabel secattr to a SELinux SID
2241 * @skb: the network packet
2242 * @secattr: the NetLabel packet security attributes
2243 * @base_sid: the SELinux SID to use as a context for MLS only attributes
2244 * @sid: the SELinux SID
2245 *
2246 * Description:
2247 * Convert the given NetLabel packet security attributes in @secattr into a
2248 * SELinux SID.  If the @secattr field does not contain a full SELinux
2249 * SID/context then use the context in @base_sid as the foundation.  If @skb
2250 * is not NULL attempt to cache as much data as possibile.  Returns zero on
2251 * success, negative values on failure.
2252 *
2253 */
2254static int selinux_netlbl_secattr_to_sid(struct sk_buff *skb,
2255					 struct netlbl_lsm_secattr *secattr,
2256					 u32 base_sid,
2257					 u32 *sid)
2258{
2259	int rc = -EIDRM;
2260	struct context *ctx;
2261	struct context ctx_new;
2262	struct netlbl_cache *cache;
2263
2264	POLICY_RDLOCK;
2265
2266	if (secattr->cache.data) {
2267		cache = NETLBL_CACHE(secattr->cache.data);
2268		switch (cache->type) {
2269		case NETLBL_CACHE_T_SID:
2270			*sid = cache->data.sid;
2271			rc = 0;
2272			break;
2273		case NETLBL_CACHE_T_MLS:
2274			ctx = sidtab_search(&sidtab, base_sid);
2275			if (ctx == NULL)
2276				goto netlbl_secattr_to_sid_return;
2277
2278			ctx_new.user = ctx->user;
2279			ctx_new.role = ctx->role;
2280			ctx_new.type = ctx->type;
2281			ctx_new.range.level[0].sens =
2282				cache->data.mls_label.level[0].sens;
2283			ctx_new.range.level[0].cat.highbit =
2284				cache->data.mls_label.level[0].cat.highbit;
2285			ctx_new.range.level[0].cat.node =
2286				cache->data.mls_label.level[0].cat.node;
2287			ctx_new.range.level[1].sens =
2288				cache->data.mls_label.level[1].sens;
2289			ctx_new.range.level[1].cat.highbit =
2290				cache->data.mls_label.level[1].cat.highbit;
2291			ctx_new.range.level[1].cat.node =
2292				cache->data.mls_label.level[1].cat.node;
2293
2294			rc = sidtab_context_to_sid(&sidtab, &ctx_new, sid);
2295			break;
2296		default:
2297			goto netlbl_secattr_to_sid_return;
2298		}
2299	} else if (secattr->mls_lvl_vld) {
2300		ctx = sidtab_search(&sidtab, base_sid);
2301		if (ctx == NULL)
2302			goto netlbl_secattr_to_sid_return;
2303
2304		ctx_new.user = ctx->user;
2305		ctx_new.role = ctx->role;
2306		ctx_new.type = ctx->type;
2307		mls_import_lvl(&ctx_new, secattr->mls_lvl, secattr->mls_lvl);
2308		if (secattr->mls_cat) {
2309			if (mls_import_cat(&ctx_new,
2310					   secattr->mls_cat,
2311					   secattr->mls_cat_len,
2312					   NULL,
2313					   0) != 0)
2314				goto netlbl_secattr_to_sid_return;
2315			ctx_new.range.level[1].cat.highbit =
2316				ctx_new.range.level[0].cat.highbit;
2317			ctx_new.range.level[1].cat.node =
2318				ctx_new.range.level[0].cat.node;
2319		} else {
2320			ebitmap_init(&ctx_new.range.level[0].cat);
2321			ebitmap_init(&ctx_new.range.level[1].cat);
2322		}
2323		if (mls_context_isvalid(&policydb, &ctx_new) != 1)
2324			goto netlbl_secattr_to_sid_return_cleanup;
2325
2326		rc = sidtab_context_to_sid(&sidtab, &ctx_new, sid);
2327		if (rc != 0)
2328			goto netlbl_secattr_to_sid_return_cleanup;
2329
2330		if (skb != NULL)
2331			selinux_netlbl_cache_add(skb, &ctx_new);
2332		ebitmap_destroy(&ctx_new.range.level[0].cat);
2333	} else {
2334		*sid = SECINITSID_UNLABELED;
2335		rc = 0;
2336	}
2337
2338netlbl_secattr_to_sid_return:
2339	POLICY_RDUNLOCK;
2340	return rc;
2341netlbl_secattr_to_sid_return_cleanup:
2342	ebitmap_destroy(&ctx_new.range.level[0].cat);
2343	goto netlbl_secattr_to_sid_return;
2344}
2345
2346/**
2347 * selinux_netlbl_skbuff_getsid - Get the sid of a packet using NetLabel
2348 * @skb: the packet
2349 * @base_sid: the SELinux SID to use as a context for MLS only attributes
2350 * @sid: the SID
2351 *
2352 * Description:
2353 * Call the NetLabel mechanism to get the security attributes of the given
2354 * packet and use those attributes to determine the correct context/SID to
2355 * assign to the packet.  Returns zero on success, negative values on failure.
2356 *
2357 */
2358static int selinux_netlbl_skbuff_getsid(struct sk_buff *skb,
2359					u32 base_sid,
2360					u32 *sid)
2361{
2362	int rc;
2363	struct netlbl_lsm_secattr secattr;
2364
2365	netlbl_secattr_init(&secattr);
2366	rc = netlbl_skbuff_getattr(skb, &secattr);
2367	if (rc == 0)
2368		rc = selinux_netlbl_secattr_to_sid(skb,
2369						   &secattr,
2370						   base_sid,
2371						   sid);
2372	netlbl_secattr_destroy(&secattr, 0);
2373
2374	return rc;
2375}
2376
2377/**
2378 * selinux_netlbl_socket_setsid - Label a socket using the NetLabel mechanism
2379 * @sock: the socket to label
2380 * @sid: the SID to use
2381 *
2382 * Description:
2383 * Attempt to label a socket using the NetLabel mechanism using the given
2384 * SID.  Returns zero values on success, negative values on failure.
2385 *
2386 */
2387static int selinux_netlbl_socket_setsid(struct socket *sock, u32 sid)
2388{
2389	int rc = -ENOENT;
2390	struct sk_security_struct *sksec = sock->sk->sk_security;
2391	struct netlbl_lsm_secattr secattr;
2392	struct context *ctx;
2393
2394	if (!ss_initialized)
2395		return 0;
2396
2397	POLICY_RDLOCK;
2398
2399	ctx = sidtab_search(&sidtab, sid);
2400	if (ctx == NULL)
2401		goto netlbl_socket_setsid_return;
2402
2403	netlbl_secattr_init(&secattr);
2404	secattr.domain = kstrdup(policydb.p_type_val_to_name[ctx->type - 1],
2405				 GFP_ATOMIC);
2406	mls_export_lvl(ctx, &secattr.mls_lvl, NULL);
2407	secattr.mls_lvl_vld = 1;
2408	mls_export_cat(ctx,
2409		       &secattr.mls_cat,
2410		       &secattr.mls_cat_len,
2411		       NULL,
2412		       NULL);
2413
2414	rc = netlbl_socket_setattr(sock, &secattr);
2415	if (rc == 0)
2416		sksec->nlbl_state = NLBL_LABELED;
2417
2418	netlbl_secattr_destroy(&secattr, 0);
2419
2420netlbl_socket_setsid_return:
2421	POLICY_RDUNLOCK;
2422	return rc;
2423}
2424
2425/**
2426 * selinux_netlbl_sk_security_init - Setup the NetLabel fields
2427 * @ssec: the sk_security_struct
2428 * @family: the socket family
2429 *
2430 * Description:
2431 * Called when a new sk_security_struct is allocated to initialize the NetLabel
2432 * fields.
2433 *
2434 */
2435void selinux_netlbl_sk_security_init(struct sk_security_struct *ssec,
2436				     int family)
2437{
2438        if (family == PF_INET)
2439		ssec->nlbl_state = NLBL_REQUIRE;
2440	else
2441		ssec->nlbl_state = NLBL_UNSET;
2442}
2443
2444/**
2445 * selinux_netlbl_sk_clone_security - Copy the NetLabel fields
2446 * @ssec: the original sk_security_struct
2447 * @newssec: the cloned sk_security_struct
2448 *
2449 * Description:
2450 * Clone the NetLabel specific sk_security_struct fields from @ssec to
2451 * @newssec.
2452 *
2453 */
2454void selinux_netlbl_sk_clone_security(struct sk_security_struct *ssec,
2455				      struct sk_security_struct *newssec)
2456{
2457	newssec->sclass = ssec->sclass;
2458	if (ssec->nlbl_state != NLBL_UNSET)
2459		newssec->nlbl_state = NLBL_REQUIRE;
2460	else
2461		newssec->nlbl_state = NLBL_UNSET;
2462}
2463
2464/**
2465 * selinux_netlbl_socket_post_create - Label a socket using NetLabel
2466 * @sock: the socket to label
2467 * @sock_family: the socket family
2468 * @sid: the SID to use
2469 *
2470 * Description:
2471 * Attempt to label a socket using the NetLabel mechanism using the given
2472 * SID.  Returns zero values on success, negative values on failure.
2473 *
2474 */
2475int selinux_netlbl_socket_post_create(struct socket *sock,
2476				      int sock_family,
2477				      u32 sid)
2478{
2479	struct inode_security_struct *isec = SOCK_INODE(sock)->i_security;
2480	struct sk_security_struct *sksec = sock->sk->sk_security;
2481
2482	sksec->sclass = isec->sclass;
2483
2484	if (sock_family != PF_INET)
2485		return 0;
2486
2487	sksec->nlbl_state = NLBL_REQUIRE;
2488	return selinux_netlbl_socket_setsid(sock, sid);
2489}
2490
2491/**
2492 * selinux_netlbl_sock_graft - Netlabel the new socket
2493 * @sk: the new connection
2494 * @sock: the new socket
2495 *
2496 * Description:
2497 * The connection represented by @sk is being grafted onto @sock so set the
2498 * socket's NetLabel to match the SID of @sk.
2499 *
2500 */
2501void selinux_netlbl_sock_graft(struct sock *sk, struct socket *sock)
2502{
2503	struct inode_security_struct *isec = SOCK_INODE(sock)->i_security;
2504	struct sk_security_struct *sksec = sk->sk_security;
2505	struct netlbl_lsm_secattr secattr;
2506	u32 nlbl_peer_sid;
2507
2508	sksec->sclass = isec->sclass;
2509
2510	if (sk->sk_family != PF_INET)
2511		return;
2512
2513	netlbl_secattr_init(&secattr);
2514	if (netlbl_sock_getattr(sk, &secattr) == 0 &&
2515	    selinux_netlbl_secattr_to_sid(NULL,
2516					  &secattr,
2517					  sksec->sid,
2518					  &nlbl_peer_sid) == 0)
2519		sksec->peer_sid = nlbl_peer_sid;
2520	netlbl_secattr_destroy(&secattr, 0);
2521
2522	sksec->nlbl_state = NLBL_REQUIRE;
2523
2524	/* Try to set the NetLabel on the socket to save time later, if we fail
2525	 * here we will pick up the pieces in later calls to
2526	 * selinux_netlbl_inode_permission(). */
2527	selinux_netlbl_socket_setsid(sock, sksec->sid);
2528}
2529
2530/**
2531 * selinux_netlbl_inet_conn_request - Handle a new connection request
2532 * @skb: the packet
2533 * @sock_sid: the SID of the parent socket
2534 *
2535 * Description:
2536 * If present, use the security attributes of the packet in @skb and the
2537 * parent sock's SID to arrive at a SID for the new child sock.  Returns the
2538 * SID of the connection or SECSID_NULL on failure.
2539 *
2540 */
2541u32 selinux_netlbl_inet_conn_request(struct sk_buff *skb, u32 sock_sid)
2542{
2543	int rc;
2544	u32 peer_sid;
2545
2546	rc = selinux_netlbl_skbuff_getsid(skb, sock_sid, &peer_sid);
2547	if (rc != 0)
2548		return SECSID_NULL;
2549
2550	if (peer_sid == SECINITSID_UNLABELED)
2551		return SECSID_NULL;
2552
2553	return peer_sid;
2554}
2555
2556/**
2557 * selinux_netlbl_inode_permission - Verify the socket is NetLabel labeled
2558 * @inode: the file descriptor's inode
2559 * @mask: the permission mask
2560 *
2561 * Description:
2562 * Looks at a file's inode and if it is marked as a socket protected by
2563 * NetLabel then verify that the socket has been labeled, if not try to label
2564 * the socket now with the inode's SID.  Returns zero on success, negative
2565 * values on failure.
2566 *
2567 */
2568int selinux_netlbl_inode_permission(struct inode *inode, int mask)
2569{
2570	int rc;
2571	struct inode_security_struct *isec;
2572	struct sk_security_struct *sksec;
2573	struct socket *sock;
2574
2575	if (!S_ISSOCK(inode->i_mode))
2576		return 0;
2577
2578	sock = SOCKET_I(inode);
2579	isec = inode->i_security;
2580	sksec = sock->sk->sk_security;
2581	mutex_lock(&isec->lock);
2582	if (unlikely(sksec->nlbl_state == NLBL_REQUIRE &&
2583		     (mask & (MAY_WRITE | MAY_APPEND)))) {
2584		lock_sock(sock->sk);
2585		rc = selinux_netlbl_socket_setsid(sock, sksec->sid);
2586		release_sock(sock->sk);
2587	} else
2588		rc = 0;
2589	mutex_unlock(&isec->lock);
2590
2591	return rc;
2592}
2593
2594/**
2595 * selinux_netlbl_sock_rcv_skb - Do an inbound access check using NetLabel
2596 * @sksec: the sock's sk_security_struct
2597 * @skb: the packet
2598 * @ad: the audit data
2599 *
2600 * Description:
2601 * Fetch the NetLabel security attributes from @skb and perform an access check
2602 * against the receiving socket.  Returns zero on success, negative values on
2603 * error.
2604 *
2605 */
2606int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec,
2607				struct sk_buff *skb,
2608				struct avc_audit_data *ad)
2609{
2610	int rc;
2611	u32 netlbl_sid;
2612	u32 recv_perm;
2613
2614	rc = selinux_netlbl_skbuff_getsid(skb, SECINITSID_NETMSG, &netlbl_sid);
2615	if (rc != 0)
2616		return rc;
2617
2618	if (netlbl_sid == SECINITSID_UNLABELED)
2619		return 0;
2620
2621	switch (sksec->sclass) {
2622	case SECCLASS_UDP_SOCKET:
2623		recv_perm = UDP_SOCKET__RECVFROM;
2624		break;
2625	case SECCLASS_TCP_SOCKET:
2626		recv_perm = TCP_SOCKET__RECVFROM;
2627		break;
2628	default:
2629		recv_perm = RAWIP_SOCKET__RECVFROM;
2630	}
2631
2632	rc = avc_has_perm(sksec->sid,
2633			  netlbl_sid,
2634			  sksec->sclass,
2635			  recv_perm,
2636			  ad);
2637	if (rc == 0)
2638		return 0;
2639
2640	netlbl_skbuff_err(skb, rc);
2641	return rc;
2642}
2643
2644/**
2645 * selinux_netlbl_socket_getpeersec_stream - Return the connected peer's SID
2646 * @sock: the socket
2647 *
2648 * Description:
2649 * Examine @sock to find the connected peer's SID.  Returns the SID on success
2650 * or SECSID_NULL on error.
2651 *
2652 */
2653u32 selinux_netlbl_socket_getpeersec_stream(struct socket *sock)
2654{
2655	struct sk_security_struct *sksec = sock->sk->sk_security;
2656
2657	if (sksec->peer_sid == SECINITSID_UNLABELED)
2658		return SECSID_NULL;
2659
2660	return sksec->peer_sid;
2661}
2662
2663/**
2664 * selinux_netlbl_socket_getpeersec_dgram - Return the SID of a NetLabel packet
2665 * @skb: the packet
2666 *
2667 * Description:
2668 * Examine @skb to find the SID assigned to it by NetLabel.  Returns the SID on
2669 * success, SECSID_NULL on error.
2670 *
2671 */
2672u32 selinux_netlbl_socket_getpeersec_dgram(struct sk_buff *skb)
2673{
2674	int peer_sid;
2675	struct sock *sk = skb->sk;
2676	struct inode_security_struct *isec;
2677
2678	if (sk == NULL || sk->sk_socket == NULL)
2679		return SECSID_NULL;
2680
2681	isec = SOCK_INODE(sk->sk_socket)->i_security;
2682	if (selinux_netlbl_skbuff_getsid(skb, isec->sid, &peer_sid) != 0)
2683		return SECSID_NULL;
2684	if (peer_sid == SECINITSID_UNLABELED)
2685		return SECSID_NULL;
2686
2687	return peer_sid;
2688}
2689#endif /* CONFIG_NETLABEL */
2690