1255e72915d4cbddceb435e13d81601755714e9fSE Android#include <stdlib.h>
2255e72915d4cbddceb435e13d81601755714e9fSE Android#include <string.h>
3255e72915d4cbddceb435e13d81601755714e9fSE Android#include <errno.h>
4255e72915d4cbddceb435e13d81601755714e9fSE Android
5255e72915d4cbddceb435e13d81601755714e9fSE Android#include <sepol/policydb/policydb.h>
6255e72915d4cbddceb435e13d81601755714e9fSE Android#include <sepol/policydb/services.h>
7255e72915d4cbddceb435e13d81601755714e9fSE Android#include "context_internal.h"
8255e72915d4cbddceb435e13d81601755714e9fSE Android
9255e72915d4cbddceb435e13d81601755714e9fSE Android#include "debug.h"
10255e72915d4cbddceb435e13d81601755714e9fSE Android#include "context.h"
11255e72915d4cbddceb435e13d81601755714e9fSE Android#include "handle.h"
12255e72915d4cbddceb435e13d81601755714e9fSE Android#include "mls.h"
13255e72915d4cbddceb435e13d81601755714e9fSE Android
14255e72915d4cbddceb435e13d81601755714e9fSE Android/* ----- Compatibility ---- */
15255e72915d4cbddceb435e13d81601755714e9fSE Androidint policydb_context_isvalid(const policydb_t * p, const context_struct_t * c)
16255e72915d4cbddceb435e13d81601755714e9fSE Android{
17255e72915d4cbddceb435e13d81601755714e9fSE Android
18255e72915d4cbddceb435e13d81601755714e9fSE Android	return context_is_valid(p, c);
19255e72915d4cbddceb435e13d81601755714e9fSE Android}
20255e72915d4cbddceb435e13d81601755714e9fSE Android
21255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_check_context(const char *context)
22255e72915d4cbddceb435e13d81601755714e9fSE Android{
23255e72915d4cbddceb435e13d81601755714e9fSE Android
24255e72915d4cbddceb435e13d81601755714e9fSE Android	return sepol_context_to_sid((const sepol_security_context_t)context,
25255e72915d4cbddceb435e13d81601755714e9fSE Android				    strlen(context) + 1, NULL);
26255e72915d4cbddceb435e13d81601755714e9fSE Android}
27255e72915d4cbddceb435e13d81601755714e9fSE Android
28255e72915d4cbddceb435e13d81601755714e9fSE Android/* ---- End compatibility --- */
29255e72915d4cbddceb435e13d81601755714e9fSE Android
30255e72915d4cbddceb435e13d81601755714e9fSE Android/*
31255e72915d4cbddceb435e13d81601755714e9fSE Android * Return 1 if the fields in the security context
32255e72915d4cbddceb435e13d81601755714e9fSE Android * structure `c' are valid.  Return 0 otherwise.
33255e72915d4cbddceb435e13d81601755714e9fSE Android */
34255e72915d4cbddceb435e13d81601755714e9fSE Androidint context_is_valid(const policydb_t * p, const context_struct_t * c)
35255e72915d4cbddceb435e13d81601755714e9fSE Android{
36255e72915d4cbddceb435e13d81601755714e9fSE Android
37255e72915d4cbddceb435e13d81601755714e9fSE Android	role_datum_t *role;
38255e72915d4cbddceb435e13d81601755714e9fSE Android	user_datum_t *usrdatum;
39255e72915d4cbddceb435e13d81601755714e9fSE Android	ebitmap_t types, roles;
40255e72915d4cbddceb435e13d81601755714e9fSE Android	int ret = 1;
41255e72915d4cbddceb435e13d81601755714e9fSE Android
42255e72915d4cbddceb435e13d81601755714e9fSE Android	ebitmap_init(&types);
43255e72915d4cbddceb435e13d81601755714e9fSE Android	ebitmap_init(&roles);
44255e72915d4cbddceb435e13d81601755714e9fSE Android	if (!c->role || c->role > p->p_roles.nprim)
45255e72915d4cbddceb435e13d81601755714e9fSE Android		return 0;
46255e72915d4cbddceb435e13d81601755714e9fSE Android
47255e72915d4cbddceb435e13d81601755714e9fSE Android	if (!c->user || c->user > p->p_users.nprim)
48255e72915d4cbddceb435e13d81601755714e9fSE Android		return 0;
49255e72915d4cbddceb435e13d81601755714e9fSE Android
50255e72915d4cbddceb435e13d81601755714e9fSE Android	if (!c->type || c->type > p->p_types.nprim)
51255e72915d4cbddceb435e13d81601755714e9fSE Android		return 0;
52255e72915d4cbddceb435e13d81601755714e9fSE Android
53255e72915d4cbddceb435e13d81601755714e9fSE Android	if (c->role != OBJECT_R_VAL) {
54255e72915d4cbddceb435e13d81601755714e9fSE Android		/*
55255e72915d4cbddceb435e13d81601755714e9fSE Android		 * Role must be authorized for the type.
56255e72915d4cbddceb435e13d81601755714e9fSE Android		 */
57255e72915d4cbddceb435e13d81601755714e9fSE Android		role = p->role_val_to_struct[c->role - 1];
58255e72915d4cbddceb435e13d81601755714e9fSE Android		if (!ebitmap_get_bit(&role->cache, c->type - 1))
59255e72915d4cbddceb435e13d81601755714e9fSE Android			/* role may not be associated with type */
60255e72915d4cbddceb435e13d81601755714e9fSE Android			return 0;
61255e72915d4cbddceb435e13d81601755714e9fSE Android
62255e72915d4cbddceb435e13d81601755714e9fSE Android		/*
63255e72915d4cbddceb435e13d81601755714e9fSE Android		 * User must be authorized for the role.
64255e72915d4cbddceb435e13d81601755714e9fSE Android		 */
65255e72915d4cbddceb435e13d81601755714e9fSE Android		usrdatum = p->user_val_to_struct[c->user - 1];
66255e72915d4cbddceb435e13d81601755714e9fSE Android		if (!usrdatum)
67255e72915d4cbddceb435e13d81601755714e9fSE Android			return 0;
68255e72915d4cbddceb435e13d81601755714e9fSE Android
69255e72915d4cbddceb435e13d81601755714e9fSE Android		if (!ebitmap_get_bit(&usrdatum->cache, c->role - 1))
70255e72915d4cbddceb435e13d81601755714e9fSE Android			/* user may not be associated with role */
71255e72915d4cbddceb435e13d81601755714e9fSE Android			return 0;
72255e72915d4cbddceb435e13d81601755714e9fSE Android	}
73255e72915d4cbddceb435e13d81601755714e9fSE Android
74255e72915d4cbddceb435e13d81601755714e9fSE Android	if (!mls_context_isvalid(p, c))
75255e72915d4cbddceb435e13d81601755714e9fSE Android		return 0;
76255e72915d4cbddceb435e13d81601755714e9fSE Android
77255e72915d4cbddceb435e13d81601755714e9fSE Android	return ret;
78255e72915d4cbddceb435e13d81601755714e9fSE Android}
79255e72915d4cbddceb435e13d81601755714e9fSE Android
80255e72915d4cbddceb435e13d81601755714e9fSE Android/*
81255e72915d4cbddceb435e13d81601755714e9fSE Android * Write the security context string representation of
82255e72915d4cbddceb435e13d81601755714e9fSE Android * the context structure `context' into a dynamically
83255e72915d4cbddceb435e13d81601755714e9fSE Android * allocated string of the correct size.  Set `*scontext'
84255e72915d4cbddceb435e13d81601755714e9fSE Android * to point to this string and set `*scontext_len' to
85255e72915d4cbddceb435e13d81601755714e9fSE Android * the length of the string.
86255e72915d4cbddceb435e13d81601755714e9fSE Android */
87255e72915d4cbddceb435e13d81601755714e9fSE Androidint context_to_string(sepol_handle_t * handle,
88255e72915d4cbddceb435e13d81601755714e9fSE Android		      const policydb_t * policydb,
89255e72915d4cbddceb435e13d81601755714e9fSE Android		      const context_struct_t * context,
90255e72915d4cbddceb435e13d81601755714e9fSE Android		      char **result, size_t * result_len)
91255e72915d4cbddceb435e13d81601755714e9fSE Android{
92255e72915d4cbddceb435e13d81601755714e9fSE Android
93255e72915d4cbddceb435e13d81601755714e9fSE Android	char *scontext = NULL;
94255e72915d4cbddceb435e13d81601755714e9fSE Android	size_t scontext_len = 0;
95255e72915d4cbddceb435e13d81601755714e9fSE Android	char *ptr;
96255e72915d4cbddceb435e13d81601755714e9fSE Android
97255e72915d4cbddceb435e13d81601755714e9fSE Android	/* Compute the size of the context. */
98255e72915d4cbddceb435e13d81601755714e9fSE Android	scontext_len +=
99255e72915d4cbddceb435e13d81601755714e9fSE Android	    strlen(policydb->p_user_val_to_name[context->user - 1]) + 1;
100255e72915d4cbddceb435e13d81601755714e9fSE Android	scontext_len +=
101255e72915d4cbddceb435e13d81601755714e9fSE Android	    strlen(policydb->p_role_val_to_name[context->role - 1]) + 1;
102255e72915d4cbddceb435e13d81601755714e9fSE Android	scontext_len += strlen(policydb->p_type_val_to_name[context->type - 1]);
103255e72915d4cbddceb435e13d81601755714e9fSE Android	scontext_len += mls_compute_context_len(policydb, context);
104255e72915d4cbddceb435e13d81601755714e9fSE Android
105255e72915d4cbddceb435e13d81601755714e9fSE Android	/* We must null terminate the string */
106255e72915d4cbddceb435e13d81601755714e9fSE Android	scontext_len += 1;
107255e72915d4cbddceb435e13d81601755714e9fSE Android
108255e72915d4cbddceb435e13d81601755714e9fSE Android	/* Allocate space for the context; caller must free this space. */
109255e72915d4cbddceb435e13d81601755714e9fSE Android	scontext = malloc(scontext_len);
110255e72915d4cbddceb435e13d81601755714e9fSE Android	if (!scontext)
111255e72915d4cbddceb435e13d81601755714e9fSE Android		goto omem;
112255e72915d4cbddceb435e13d81601755714e9fSE Android	scontext[scontext_len - 1] = '\0';
113255e72915d4cbddceb435e13d81601755714e9fSE Android
114255e72915d4cbddceb435e13d81601755714e9fSE Android	/*
115255e72915d4cbddceb435e13d81601755714e9fSE Android	 * Copy the user name, role name and type name into the context.
116255e72915d4cbddceb435e13d81601755714e9fSE Android	 */
117255e72915d4cbddceb435e13d81601755714e9fSE Android	ptr = scontext;
118255e72915d4cbddceb435e13d81601755714e9fSE Android	sprintf(ptr, "%s:%s:%s",
119255e72915d4cbddceb435e13d81601755714e9fSE Android		policydb->p_user_val_to_name[context->user - 1],
120255e72915d4cbddceb435e13d81601755714e9fSE Android		policydb->p_role_val_to_name[context->role - 1],
121255e72915d4cbddceb435e13d81601755714e9fSE Android		policydb->p_type_val_to_name[context->type - 1]);
122255e72915d4cbddceb435e13d81601755714e9fSE Android
123255e72915d4cbddceb435e13d81601755714e9fSE Android	ptr +=
124255e72915d4cbddceb435e13d81601755714e9fSE Android	    strlen(policydb->p_user_val_to_name[context->user - 1]) + 1 +
125255e72915d4cbddceb435e13d81601755714e9fSE Android	    strlen(policydb->p_role_val_to_name[context->role - 1]) + 1 +
126255e72915d4cbddceb435e13d81601755714e9fSE Android	    strlen(policydb->p_type_val_to_name[context->type - 1]);
127255e72915d4cbddceb435e13d81601755714e9fSE Android
128255e72915d4cbddceb435e13d81601755714e9fSE Android	mls_sid_to_context(policydb, context, &ptr);
129255e72915d4cbddceb435e13d81601755714e9fSE Android
130255e72915d4cbddceb435e13d81601755714e9fSE Android	*result = scontext;
131255e72915d4cbddceb435e13d81601755714e9fSE Android	*result_len = scontext_len;
132255e72915d4cbddceb435e13d81601755714e9fSE Android	return STATUS_SUCCESS;
133255e72915d4cbddceb435e13d81601755714e9fSE Android
134255e72915d4cbddceb435e13d81601755714e9fSE Android      omem:
135255e72915d4cbddceb435e13d81601755714e9fSE Android	ERR(handle, "out of memory, could not convert " "context to string");
136255e72915d4cbddceb435e13d81601755714e9fSE Android	free(scontext);
137255e72915d4cbddceb435e13d81601755714e9fSE Android	return STATUS_ERR;
138255e72915d4cbddceb435e13d81601755714e9fSE Android}
139255e72915d4cbddceb435e13d81601755714e9fSE Android
140255e72915d4cbddceb435e13d81601755714e9fSE Android/*
141255e72915d4cbddceb435e13d81601755714e9fSE Android * Create a context structure from the given record
142255e72915d4cbddceb435e13d81601755714e9fSE Android */
143255e72915d4cbddceb435e13d81601755714e9fSE Androidint context_from_record(sepol_handle_t * handle,
144255e72915d4cbddceb435e13d81601755714e9fSE Android			const policydb_t * policydb,
145255e72915d4cbddceb435e13d81601755714e9fSE Android			context_struct_t ** cptr,
146255e72915d4cbddceb435e13d81601755714e9fSE Android			const sepol_context_t * record)
147255e72915d4cbddceb435e13d81601755714e9fSE Android{
148255e72915d4cbddceb435e13d81601755714e9fSE Android
149255e72915d4cbddceb435e13d81601755714e9fSE Android	context_struct_t *scontext = NULL;
150255e72915d4cbddceb435e13d81601755714e9fSE Android	user_datum_t *usrdatum;
151255e72915d4cbddceb435e13d81601755714e9fSE Android	role_datum_t *roldatum;
152255e72915d4cbddceb435e13d81601755714e9fSE Android	type_datum_t *typdatum;
153255e72915d4cbddceb435e13d81601755714e9fSE Android
154255e72915d4cbddceb435e13d81601755714e9fSE Android	/* Hashtab keys are not constant - suppress warnings */
155255e72915d4cbddceb435e13d81601755714e9fSE Android	char *user = strdup(sepol_context_get_user(record));
156255e72915d4cbddceb435e13d81601755714e9fSE Android	char *role = strdup(sepol_context_get_role(record));
157255e72915d4cbddceb435e13d81601755714e9fSE Android	char *type = strdup(sepol_context_get_type(record));
158255e72915d4cbddceb435e13d81601755714e9fSE Android	const char *mls = sepol_context_get_mls(record);
159255e72915d4cbddceb435e13d81601755714e9fSE Android
160255e72915d4cbddceb435e13d81601755714e9fSE Android	scontext = (context_struct_t *) malloc(sizeof(context_struct_t));
161255e72915d4cbddceb435e13d81601755714e9fSE Android	if (!user || !role || !type || !scontext) {
162255e72915d4cbddceb435e13d81601755714e9fSE Android		ERR(handle, "out of memory");
163255e72915d4cbddceb435e13d81601755714e9fSE Android		goto err;
164255e72915d4cbddceb435e13d81601755714e9fSE Android	}
165255e72915d4cbddceb435e13d81601755714e9fSE Android	context_init(scontext);
166255e72915d4cbddceb435e13d81601755714e9fSE Android
167255e72915d4cbddceb435e13d81601755714e9fSE Android	/* User */
168255e72915d4cbddceb435e13d81601755714e9fSE Android	usrdatum = (user_datum_t *) hashtab_search(policydb->p_users.table,
169255e72915d4cbddceb435e13d81601755714e9fSE Android						   (hashtab_key_t) user);
170255e72915d4cbddceb435e13d81601755714e9fSE Android	if (!usrdatum) {
171255e72915d4cbddceb435e13d81601755714e9fSE Android		ERR(handle, "user %s is not defined", user);
172255e72915d4cbddceb435e13d81601755714e9fSE Android		goto err_destroy;
173255e72915d4cbddceb435e13d81601755714e9fSE Android	}
174255e72915d4cbddceb435e13d81601755714e9fSE Android	scontext->user = usrdatum->s.value;
175255e72915d4cbddceb435e13d81601755714e9fSE Android
176255e72915d4cbddceb435e13d81601755714e9fSE Android	/* Role */
177255e72915d4cbddceb435e13d81601755714e9fSE Android	roldatum = (role_datum_t *) hashtab_search(policydb->p_roles.table,
178255e72915d4cbddceb435e13d81601755714e9fSE Android						   (hashtab_key_t) role);
179255e72915d4cbddceb435e13d81601755714e9fSE Android	if (!roldatum) {
180255e72915d4cbddceb435e13d81601755714e9fSE Android		ERR(handle, "role %s is not defined", role);
181255e72915d4cbddceb435e13d81601755714e9fSE Android		goto err_destroy;
182255e72915d4cbddceb435e13d81601755714e9fSE Android	}
183255e72915d4cbddceb435e13d81601755714e9fSE Android	scontext->role = roldatum->s.value;
184255e72915d4cbddceb435e13d81601755714e9fSE Android
185255e72915d4cbddceb435e13d81601755714e9fSE Android	/* Type */
186255e72915d4cbddceb435e13d81601755714e9fSE Android	typdatum = (type_datum_t *) hashtab_search(policydb->p_types.table,
187255e72915d4cbddceb435e13d81601755714e9fSE Android						   (hashtab_key_t) type);
188255e72915d4cbddceb435e13d81601755714e9fSE Android	if (!typdatum || typdatum->flavor == TYPE_ATTRIB) {
189255e72915d4cbddceb435e13d81601755714e9fSE Android		ERR(handle, "type %s is not defined", type);
190255e72915d4cbddceb435e13d81601755714e9fSE Android		goto err_destroy;
191255e72915d4cbddceb435e13d81601755714e9fSE Android	}
192255e72915d4cbddceb435e13d81601755714e9fSE Android	scontext->type = typdatum->s.value;
193255e72915d4cbddceb435e13d81601755714e9fSE Android
194255e72915d4cbddceb435e13d81601755714e9fSE Android	/* MLS */
195255e72915d4cbddceb435e13d81601755714e9fSE Android	if (mls && !policydb->mls) {
196255e72915d4cbddceb435e13d81601755714e9fSE Android		ERR(handle, "MLS is disabled, but MLS context \"%s\" found",
197255e72915d4cbddceb435e13d81601755714e9fSE Android		    mls);
198255e72915d4cbddceb435e13d81601755714e9fSE Android		goto err_destroy;
199255e72915d4cbddceb435e13d81601755714e9fSE Android	} else if (!mls && policydb->mls) {
200255e72915d4cbddceb435e13d81601755714e9fSE Android		ERR(handle, "MLS is enabled, but no MLS context found");
201255e72915d4cbddceb435e13d81601755714e9fSE Android		goto err_destroy;
202255e72915d4cbddceb435e13d81601755714e9fSE Android	}
203255e72915d4cbddceb435e13d81601755714e9fSE Android	if (mls && (mls_from_string(handle, policydb, mls, scontext) < 0))
204255e72915d4cbddceb435e13d81601755714e9fSE Android		goto err_destroy;
205255e72915d4cbddceb435e13d81601755714e9fSE Android
206255e72915d4cbddceb435e13d81601755714e9fSE Android	/* Validity check */
207255e72915d4cbddceb435e13d81601755714e9fSE Android	if (!context_is_valid(policydb, scontext)) {
208255e72915d4cbddceb435e13d81601755714e9fSE Android		if (mls) {
209255e72915d4cbddceb435e13d81601755714e9fSE Android			ERR(handle,
210255e72915d4cbddceb435e13d81601755714e9fSE Android			    "invalid security context: \"%s:%s:%s:%s\"",
211255e72915d4cbddceb435e13d81601755714e9fSE Android			    user, role, type, mls);
212255e72915d4cbddceb435e13d81601755714e9fSE Android		} else {
213255e72915d4cbddceb435e13d81601755714e9fSE Android			ERR(handle,
214255e72915d4cbddceb435e13d81601755714e9fSE Android			    "invalid security context: \"%s:%s:%s\"",
215255e72915d4cbddceb435e13d81601755714e9fSE Android			    user, role, type);
216255e72915d4cbddceb435e13d81601755714e9fSE Android		}
217255e72915d4cbddceb435e13d81601755714e9fSE Android		goto err_destroy;
218255e72915d4cbddceb435e13d81601755714e9fSE Android	}
219255e72915d4cbddceb435e13d81601755714e9fSE Android
220255e72915d4cbddceb435e13d81601755714e9fSE Android	*cptr = scontext;
221255e72915d4cbddceb435e13d81601755714e9fSE Android	free(user);
222255e72915d4cbddceb435e13d81601755714e9fSE Android	free(type);
223255e72915d4cbddceb435e13d81601755714e9fSE Android	free(role);
224255e72915d4cbddceb435e13d81601755714e9fSE Android	return STATUS_SUCCESS;
225255e72915d4cbddceb435e13d81601755714e9fSE Android
226255e72915d4cbddceb435e13d81601755714e9fSE Android      err_destroy:
227255e72915d4cbddceb435e13d81601755714e9fSE Android	errno = EINVAL;
228255e72915d4cbddceb435e13d81601755714e9fSE Android	context_destroy(scontext);
229255e72915d4cbddceb435e13d81601755714e9fSE Android
230255e72915d4cbddceb435e13d81601755714e9fSE Android      err:
231255e72915d4cbddceb435e13d81601755714e9fSE Android	free(scontext);
232255e72915d4cbddceb435e13d81601755714e9fSE Android	free(user);
233255e72915d4cbddceb435e13d81601755714e9fSE Android	free(type);
234255e72915d4cbddceb435e13d81601755714e9fSE Android	free(role);
235255e72915d4cbddceb435e13d81601755714e9fSE Android	ERR(handle, "could not create context structure");
236255e72915d4cbddceb435e13d81601755714e9fSE Android	return STATUS_ERR;
237255e72915d4cbddceb435e13d81601755714e9fSE Android}
238255e72915d4cbddceb435e13d81601755714e9fSE Android
239255e72915d4cbddceb435e13d81601755714e9fSE Android/*
240255e72915d4cbddceb435e13d81601755714e9fSE Android * Create a record from the given context structure
241255e72915d4cbddceb435e13d81601755714e9fSE Android */
242255e72915d4cbddceb435e13d81601755714e9fSE Androidint context_to_record(sepol_handle_t * handle,
243255e72915d4cbddceb435e13d81601755714e9fSE Android		      const policydb_t * policydb,
244255e72915d4cbddceb435e13d81601755714e9fSE Android		      const context_struct_t * context,
245255e72915d4cbddceb435e13d81601755714e9fSE Android		      sepol_context_t ** record)
246255e72915d4cbddceb435e13d81601755714e9fSE Android{
247255e72915d4cbddceb435e13d81601755714e9fSE Android
248255e72915d4cbddceb435e13d81601755714e9fSE Android	sepol_context_t *tmp_record = NULL;
249255e72915d4cbddceb435e13d81601755714e9fSE Android	char *mls = NULL;
250255e72915d4cbddceb435e13d81601755714e9fSE Android
251255e72915d4cbddceb435e13d81601755714e9fSE Android	if (sepol_context_create(handle, &tmp_record) < 0)
252255e72915d4cbddceb435e13d81601755714e9fSE Android		goto err;
253255e72915d4cbddceb435e13d81601755714e9fSE Android
254255e72915d4cbddceb435e13d81601755714e9fSE Android	if (sepol_context_set_user(handle, tmp_record,
255255e72915d4cbddceb435e13d81601755714e9fSE Android				   policydb->p_user_val_to_name[context->user -
256255e72915d4cbddceb435e13d81601755714e9fSE Android								1]) < 0)
257255e72915d4cbddceb435e13d81601755714e9fSE Android		goto err;
258255e72915d4cbddceb435e13d81601755714e9fSE Android
259255e72915d4cbddceb435e13d81601755714e9fSE Android	if (sepol_context_set_role(handle, tmp_record,
260255e72915d4cbddceb435e13d81601755714e9fSE Android				   policydb->p_role_val_to_name[context->role -
261255e72915d4cbddceb435e13d81601755714e9fSE Android								1]) < 0)
262255e72915d4cbddceb435e13d81601755714e9fSE Android		goto err;
263255e72915d4cbddceb435e13d81601755714e9fSE Android
264255e72915d4cbddceb435e13d81601755714e9fSE Android	if (sepol_context_set_type(handle, tmp_record,
265255e72915d4cbddceb435e13d81601755714e9fSE Android				   policydb->p_type_val_to_name[context->type -
266255e72915d4cbddceb435e13d81601755714e9fSE Android								1]) < 0)
267255e72915d4cbddceb435e13d81601755714e9fSE Android		goto err;
268255e72915d4cbddceb435e13d81601755714e9fSE Android
269255e72915d4cbddceb435e13d81601755714e9fSE Android	if (policydb->mls) {
270255e72915d4cbddceb435e13d81601755714e9fSE Android		if (mls_to_string(handle, policydb, context, &mls) < 0)
271255e72915d4cbddceb435e13d81601755714e9fSE Android			goto err;
272255e72915d4cbddceb435e13d81601755714e9fSE Android
273255e72915d4cbddceb435e13d81601755714e9fSE Android		if (sepol_context_set_mls(handle, tmp_record, mls) < 0)
274255e72915d4cbddceb435e13d81601755714e9fSE Android			goto err;
275255e72915d4cbddceb435e13d81601755714e9fSE Android	}
276255e72915d4cbddceb435e13d81601755714e9fSE Android
277255e72915d4cbddceb435e13d81601755714e9fSE Android	free(mls);
278255e72915d4cbddceb435e13d81601755714e9fSE Android	*record = tmp_record;
279255e72915d4cbddceb435e13d81601755714e9fSE Android	return STATUS_SUCCESS;
280255e72915d4cbddceb435e13d81601755714e9fSE Android
281255e72915d4cbddceb435e13d81601755714e9fSE Android      err:
282255e72915d4cbddceb435e13d81601755714e9fSE Android	ERR(handle, "could not create context record");
283255e72915d4cbddceb435e13d81601755714e9fSE Android	sepol_context_free(tmp_record);
284255e72915d4cbddceb435e13d81601755714e9fSE Android	free(mls);
285255e72915d4cbddceb435e13d81601755714e9fSE Android	return STATUS_ERR;
286255e72915d4cbddceb435e13d81601755714e9fSE Android}
287255e72915d4cbddceb435e13d81601755714e9fSE Android
288255e72915d4cbddceb435e13d81601755714e9fSE Android/*
289255e72915d4cbddceb435e13d81601755714e9fSE Android * Create a context structure from the provided string.
290255e72915d4cbddceb435e13d81601755714e9fSE Android */
291255e72915d4cbddceb435e13d81601755714e9fSE Androidint context_from_string(sepol_handle_t * handle,
292255e72915d4cbddceb435e13d81601755714e9fSE Android			const policydb_t * policydb,
293255e72915d4cbddceb435e13d81601755714e9fSE Android			context_struct_t ** cptr,
294255e72915d4cbddceb435e13d81601755714e9fSE Android			const char *con_str, size_t con_str_len)
295255e72915d4cbddceb435e13d81601755714e9fSE Android{
296255e72915d4cbddceb435e13d81601755714e9fSE Android
297255e72915d4cbddceb435e13d81601755714e9fSE Android	char *con_cpy = NULL;
298255e72915d4cbddceb435e13d81601755714e9fSE Android	sepol_context_t *ctx_record = NULL;
299255e72915d4cbddceb435e13d81601755714e9fSE Android
300255e72915d4cbddceb435e13d81601755714e9fSE Android	/* sepol_context_from_string expects a NULL-terminated string */
301255e72915d4cbddceb435e13d81601755714e9fSE Android	con_cpy = malloc(con_str_len + 1);
302255e72915d4cbddceb435e13d81601755714e9fSE Android	if (!con_cpy)
303255e72915d4cbddceb435e13d81601755714e9fSE Android		goto omem;
304255e72915d4cbddceb435e13d81601755714e9fSE Android	memcpy(con_cpy, con_str, con_str_len);
305255e72915d4cbddceb435e13d81601755714e9fSE Android	con_cpy[con_str_len] = '\0';
306255e72915d4cbddceb435e13d81601755714e9fSE Android
307255e72915d4cbddceb435e13d81601755714e9fSE Android	if (sepol_context_from_string(handle, con_cpy, &ctx_record) < 0)
308255e72915d4cbddceb435e13d81601755714e9fSE Android		goto err;
309255e72915d4cbddceb435e13d81601755714e9fSE Android
310255e72915d4cbddceb435e13d81601755714e9fSE Android	/* Now create from the data structure */
311255e72915d4cbddceb435e13d81601755714e9fSE Android	if (context_from_record(handle, policydb, cptr, ctx_record) < 0)
312255e72915d4cbddceb435e13d81601755714e9fSE Android		goto err;
313255e72915d4cbddceb435e13d81601755714e9fSE Android
314255e72915d4cbddceb435e13d81601755714e9fSE Android	free(con_cpy);
315255e72915d4cbddceb435e13d81601755714e9fSE Android	sepol_context_free(ctx_record);
316255e72915d4cbddceb435e13d81601755714e9fSE Android	return STATUS_SUCCESS;
317255e72915d4cbddceb435e13d81601755714e9fSE Android
318255e72915d4cbddceb435e13d81601755714e9fSE Android      omem:
319255e72915d4cbddceb435e13d81601755714e9fSE Android	ERR(handle, "out of memory");
320255e72915d4cbddceb435e13d81601755714e9fSE Android
321255e72915d4cbddceb435e13d81601755714e9fSE Android      err:
322255e72915d4cbddceb435e13d81601755714e9fSE Android	ERR(handle, "could not create context structure");
323255e72915d4cbddceb435e13d81601755714e9fSE Android	free(con_cpy);
324255e72915d4cbddceb435e13d81601755714e9fSE Android	sepol_context_free(ctx_record);
325255e72915d4cbddceb435e13d81601755714e9fSE Android	return STATUS_ERR;
326255e72915d4cbddceb435e13d81601755714e9fSE Android}
327255e72915d4cbddceb435e13d81601755714e9fSE Android
328255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_context_check(sepol_handle_t * handle,
329255e72915d4cbddceb435e13d81601755714e9fSE Android			const sepol_policydb_t * policydb,
330255e72915d4cbddceb435e13d81601755714e9fSE Android			const sepol_context_t * context)
331255e72915d4cbddceb435e13d81601755714e9fSE Android{
332255e72915d4cbddceb435e13d81601755714e9fSE Android
333255e72915d4cbddceb435e13d81601755714e9fSE Android	context_struct_t *con = NULL;
334255e72915d4cbddceb435e13d81601755714e9fSE Android	int ret = context_from_record(handle, &policydb->p, &con, context);
335255e72915d4cbddceb435e13d81601755714e9fSE Android	context_destroy(con);
336255e72915d4cbddceb435e13d81601755714e9fSE Android	free(con);
337255e72915d4cbddceb435e13d81601755714e9fSE Android	return ret;
338255e72915d4cbddceb435e13d81601755714e9fSE Android}
339