xref: /aosp_15_r20/external/selinux/libsepol/src/context.c (revision 2d543d20722ada2425b5bdab9d0d1d29470e7bba)
1*2d543d20SAndroid Build Coastguard Worker #include <stdlib.h>
2*2d543d20SAndroid Build Coastguard Worker #include <string.h>
3*2d543d20SAndroid Build Coastguard Worker #include <errno.h>
4*2d543d20SAndroid Build Coastguard Worker 
5*2d543d20SAndroid Build Coastguard Worker #include <sepol/policydb/policydb.h>
6*2d543d20SAndroid Build Coastguard Worker #include <sepol/policydb/services.h>
7*2d543d20SAndroid Build Coastguard Worker #include "context_internal.h"
8*2d543d20SAndroid Build Coastguard Worker 
9*2d543d20SAndroid Build Coastguard Worker #include "debug.h"
10*2d543d20SAndroid Build Coastguard Worker #include "context.h"
11*2d543d20SAndroid Build Coastguard Worker #include "handle.h"
12*2d543d20SAndroid Build Coastguard Worker #include "mls.h"
13*2d543d20SAndroid Build Coastguard Worker #include "private.h"
14*2d543d20SAndroid Build Coastguard Worker 
15*2d543d20SAndroid Build Coastguard Worker /* ----- Compatibility ---- */
policydb_context_isvalid(const policydb_t * p,const context_struct_t * c)16*2d543d20SAndroid Build Coastguard Worker int policydb_context_isvalid(const policydb_t * p, const context_struct_t * c)
17*2d543d20SAndroid Build Coastguard Worker {
18*2d543d20SAndroid Build Coastguard Worker 
19*2d543d20SAndroid Build Coastguard Worker 	return context_is_valid(p, c);
20*2d543d20SAndroid Build Coastguard Worker }
21*2d543d20SAndroid Build Coastguard Worker 
sepol_check_context(const char * context)22*2d543d20SAndroid Build Coastguard Worker int sepol_check_context(const char *context)
23*2d543d20SAndroid Build Coastguard Worker {
24*2d543d20SAndroid Build Coastguard Worker 
25*2d543d20SAndroid Build Coastguard Worker 	return sepol_context_to_sid(context,
26*2d543d20SAndroid Build Coastguard Worker 				    strlen(context) + 1, NULL);
27*2d543d20SAndroid Build Coastguard Worker }
28*2d543d20SAndroid Build Coastguard Worker 
29*2d543d20SAndroid Build Coastguard Worker /* ---- End compatibility --- */
30*2d543d20SAndroid Build Coastguard Worker 
31*2d543d20SAndroid Build Coastguard Worker /*
32*2d543d20SAndroid Build Coastguard Worker  * Return 1 if the fields in the security context
33*2d543d20SAndroid Build Coastguard Worker  * structure `c' are valid.  Return 0 otherwise.
34*2d543d20SAndroid Build Coastguard Worker  */
context_is_valid(const policydb_t * p,const context_struct_t * c)35*2d543d20SAndroid Build Coastguard Worker int context_is_valid(const policydb_t * p, const context_struct_t * c)
36*2d543d20SAndroid Build Coastguard Worker {
37*2d543d20SAndroid Build Coastguard Worker 
38*2d543d20SAndroid Build Coastguard Worker 	role_datum_t *role;
39*2d543d20SAndroid Build Coastguard Worker 	user_datum_t *usrdatum;
40*2d543d20SAndroid Build Coastguard Worker 	ebitmap_t types, roles;
41*2d543d20SAndroid Build Coastguard Worker 
42*2d543d20SAndroid Build Coastguard Worker 	ebitmap_init(&types);
43*2d543d20SAndroid Build Coastguard Worker 	ebitmap_init(&roles);
44*2d543d20SAndroid Build Coastguard Worker 	if (!c->role || c->role > p->p_roles.nprim)
45*2d543d20SAndroid Build Coastguard Worker 		return 0;
46*2d543d20SAndroid Build Coastguard Worker 
47*2d543d20SAndroid Build Coastguard Worker 	if (!c->user || c->user > p->p_users.nprim)
48*2d543d20SAndroid Build Coastguard Worker 		return 0;
49*2d543d20SAndroid Build Coastguard Worker 
50*2d543d20SAndroid Build Coastguard Worker 	if (!c->type || c->type > p->p_types.nprim)
51*2d543d20SAndroid Build Coastguard Worker 		return 0;
52*2d543d20SAndroid Build Coastguard Worker 
53*2d543d20SAndroid Build Coastguard Worker 	if (c->role != OBJECT_R_VAL) {
54*2d543d20SAndroid Build Coastguard Worker 		/*
55*2d543d20SAndroid Build Coastguard Worker 		 * Role must be authorized for the type.
56*2d543d20SAndroid Build Coastguard Worker 		 */
57*2d543d20SAndroid Build Coastguard Worker 		role = p->role_val_to_struct[c->role - 1];
58*2d543d20SAndroid Build Coastguard Worker 		if (!role || !ebitmap_get_bit(&role->cache, c->type - 1))
59*2d543d20SAndroid Build Coastguard Worker 			/* role may not be associated with type */
60*2d543d20SAndroid Build Coastguard Worker 			return 0;
61*2d543d20SAndroid Build Coastguard Worker 
62*2d543d20SAndroid Build Coastguard Worker 		/*
63*2d543d20SAndroid Build Coastguard Worker 		 * User must be authorized for the role.
64*2d543d20SAndroid Build Coastguard Worker 		 */
65*2d543d20SAndroid Build Coastguard Worker 		usrdatum = p->user_val_to_struct[c->user - 1];
66*2d543d20SAndroid Build Coastguard Worker 		if (!usrdatum)
67*2d543d20SAndroid Build Coastguard Worker 			return 0;
68*2d543d20SAndroid Build Coastguard Worker 
69*2d543d20SAndroid Build Coastguard Worker 		if (!ebitmap_get_bit(&usrdatum->cache, c->role - 1))
70*2d543d20SAndroid Build Coastguard Worker 			/* user may not be associated with role */
71*2d543d20SAndroid Build Coastguard Worker 			return 0;
72*2d543d20SAndroid Build Coastguard Worker 	}
73*2d543d20SAndroid Build Coastguard Worker 
74*2d543d20SAndroid Build Coastguard Worker 	if (!mls_context_isvalid(p, c))
75*2d543d20SAndroid Build Coastguard Worker 		return 0;
76*2d543d20SAndroid Build Coastguard Worker 
77*2d543d20SAndroid Build Coastguard Worker 	return 1;
78*2d543d20SAndroid Build Coastguard Worker }
79*2d543d20SAndroid Build Coastguard Worker 
80*2d543d20SAndroid Build Coastguard Worker /*
81*2d543d20SAndroid Build Coastguard Worker  * Write the security context string representation of
82*2d543d20SAndroid Build Coastguard Worker  * the context structure `context' into a dynamically
83*2d543d20SAndroid Build Coastguard Worker  * allocated string of the correct size.  Set `*scontext'
84*2d543d20SAndroid Build Coastguard Worker  * to point to this string and set `*scontext_len' to
85*2d543d20SAndroid Build Coastguard Worker  * the length of the string.
86*2d543d20SAndroid Build Coastguard Worker  */
context_to_string(sepol_handle_t * handle,const policydb_t * policydb,const context_struct_t * context,char ** result,size_t * result_len)87*2d543d20SAndroid Build Coastguard Worker int context_to_string(sepol_handle_t * handle,
88*2d543d20SAndroid Build Coastguard Worker 		      const policydb_t * policydb,
89*2d543d20SAndroid Build Coastguard Worker 		      const context_struct_t * context,
90*2d543d20SAndroid Build Coastguard Worker 		      char **result, size_t * result_len)
91*2d543d20SAndroid Build Coastguard Worker {
92*2d543d20SAndroid Build Coastguard Worker 
93*2d543d20SAndroid Build Coastguard Worker 	char *scontext = NULL;
94*2d543d20SAndroid Build Coastguard Worker 	size_t scontext_len = 0;
95*2d543d20SAndroid Build Coastguard Worker 	char *ptr;
96*2d543d20SAndroid Build Coastguard Worker 
97*2d543d20SAndroid Build Coastguard Worker 	/* Compute the size of the context. */
98*2d543d20SAndroid Build Coastguard Worker 	scontext_len +=
99*2d543d20SAndroid Build Coastguard Worker 	    strlen(policydb->p_user_val_to_name[context->user - 1]) + 1;
100*2d543d20SAndroid Build Coastguard Worker 	scontext_len +=
101*2d543d20SAndroid Build Coastguard Worker 	    strlen(policydb->p_role_val_to_name[context->role - 1]) + 1;
102*2d543d20SAndroid Build Coastguard Worker 	scontext_len += strlen(policydb->p_type_val_to_name[context->type - 1]);
103*2d543d20SAndroid Build Coastguard Worker 	scontext_len += mls_compute_context_len(policydb, context);
104*2d543d20SAndroid Build Coastguard Worker 
105*2d543d20SAndroid Build Coastguard Worker 	/* We must null terminate the string */
106*2d543d20SAndroid Build Coastguard Worker 	scontext_len += 1;
107*2d543d20SAndroid Build Coastguard Worker 
108*2d543d20SAndroid Build Coastguard Worker 	/* Allocate space for the context; caller must free this space. */
109*2d543d20SAndroid Build Coastguard Worker 	scontext = malloc(scontext_len);
110*2d543d20SAndroid Build Coastguard Worker 	if (!scontext)
111*2d543d20SAndroid Build Coastguard Worker 		goto omem;
112*2d543d20SAndroid Build Coastguard Worker 	scontext[scontext_len - 1] = '\0';
113*2d543d20SAndroid Build Coastguard Worker 
114*2d543d20SAndroid Build Coastguard Worker 	/*
115*2d543d20SAndroid Build Coastguard Worker 	 * Copy the user name, role name and type name into the context.
116*2d543d20SAndroid Build Coastguard Worker 	 */
117*2d543d20SAndroid Build Coastguard Worker 	ptr = scontext;
118*2d543d20SAndroid Build Coastguard Worker 	sprintf(ptr, "%s:%s:%s",
119*2d543d20SAndroid Build Coastguard Worker 		policydb->p_user_val_to_name[context->user - 1],
120*2d543d20SAndroid Build Coastguard Worker 		policydb->p_role_val_to_name[context->role - 1],
121*2d543d20SAndroid Build Coastguard Worker 		policydb->p_type_val_to_name[context->type - 1]);
122*2d543d20SAndroid Build Coastguard Worker 
123*2d543d20SAndroid Build Coastguard Worker 	ptr +=
124*2d543d20SAndroid Build Coastguard Worker 	    strlen(policydb->p_user_val_to_name[context->user - 1]) + 1 +
125*2d543d20SAndroid Build Coastguard Worker 	    strlen(policydb->p_role_val_to_name[context->role - 1]) + 1 +
126*2d543d20SAndroid Build Coastguard Worker 	    strlen(policydb->p_type_val_to_name[context->type - 1]);
127*2d543d20SAndroid Build Coastguard Worker 
128*2d543d20SAndroid Build Coastguard Worker 	mls_sid_to_context(policydb, context, &ptr);
129*2d543d20SAndroid Build Coastguard Worker 
130*2d543d20SAndroid Build Coastguard Worker 	*result = scontext;
131*2d543d20SAndroid Build Coastguard Worker 	*result_len = scontext_len;
132*2d543d20SAndroid Build Coastguard Worker 	return STATUS_SUCCESS;
133*2d543d20SAndroid Build Coastguard Worker 
134*2d543d20SAndroid Build Coastguard Worker       omem:
135*2d543d20SAndroid Build Coastguard Worker 	ERR(handle, "out of memory, could not convert " "context to string");
136*2d543d20SAndroid Build Coastguard Worker 	free(scontext);
137*2d543d20SAndroid Build Coastguard Worker 	return STATUS_ERR;
138*2d543d20SAndroid Build Coastguard Worker }
139*2d543d20SAndroid Build Coastguard Worker 
140*2d543d20SAndroid Build Coastguard Worker /*
141*2d543d20SAndroid Build Coastguard Worker  * Create a context structure from the given record
142*2d543d20SAndroid Build Coastguard Worker  */
context_from_record(sepol_handle_t * handle,const policydb_t * policydb,context_struct_t ** cptr,const sepol_context_t * record)143*2d543d20SAndroid Build Coastguard Worker int context_from_record(sepol_handle_t * handle,
144*2d543d20SAndroid Build Coastguard Worker 			const policydb_t * policydb,
145*2d543d20SAndroid Build Coastguard Worker 			context_struct_t ** cptr,
146*2d543d20SAndroid Build Coastguard Worker 			const sepol_context_t * record)
147*2d543d20SAndroid Build Coastguard Worker {
148*2d543d20SAndroid Build Coastguard Worker 
149*2d543d20SAndroid Build Coastguard Worker 	context_struct_t *scontext = NULL;
150*2d543d20SAndroid Build Coastguard Worker 	user_datum_t *usrdatum;
151*2d543d20SAndroid Build Coastguard Worker 	role_datum_t *roldatum;
152*2d543d20SAndroid Build Coastguard Worker 	type_datum_t *typdatum;
153*2d543d20SAndroid Build Coastguard Worker 
154*2d543d20SAndroid Build Coastguard Worker 	/* Hashtab keys are not constant - suppress warnings */
155*2d543d20SAndroid Build Coastguard Worker 	char *user = strdup(sepol_context_get_user(record));
156*2d543d20SAndroid Build Coastguard Worker 	char *role = strdup(sepol_context_get_role(record));
157*2d543d20SAndroid Build Coastguard Worker 	char *type = strdup(sepol_context_get_type(record));
158*2d543d20SAndroid Build Coastguard Worker 	const char *mls = sepol_context_get_mls(record);
159*2d543d20SAndroid Build Coastguard Worker 
160*2d543d20SAndroid Build Coastguard Worker 	scontext = (context_struct_t *) malloc(sizeof(context_struct_t));
161*2d543d20SAndroid Build Coastguard Worker 	if (!user || !role || !type || !scontext) {
162*2d543d20SAndroid Build Coastguard Worker 		ERR(handle, "out of memory");
163*2d543d20SAndroid Build Coastguard Worker 		goto err;
164*2d543d20SAndroid Build Coastguard Worker 	}
165*2d543d20SAndroid Build Coastguard Worker 	context_init(scontext);
166*2d543d20SAndroid Build Coastguard Worker 
167*2d543d20SAndroid Build Coastguard Worker 	/* User */
168*2d543d20SAndroid Build Coastguard Worker 	usrdatum = (user_datum_t *) hashtab_search(policydb->p_users.table,
169*2d543d20SAndroid Build Coastguard Worker 						   (hashtab_key_t) user);
170*2d543d20SAndroid Build Coastguard Worker 	if (!usrdatum) {
171*2d543d20SAndroid Build Coastguard Worker 		ERR(handle, "user %s is not defined", user);
172*2d543d20SAndroid Build Coastguard Worker 		goto err_destroy;
173*2d543d20SAndroid Build Coastguard Worker 	}
174*2d543d20SAndroid Build Coastguard Worker 	scontext->user = usrdatum->s.value;
175*2d543d20SAndroid Build Coastguard Worker 
176*2d543d20SAndroid Build Coastguard Worker 	/* Role */
177*2d543d20SAndroid Build Coastguard Worker 	roldatum = (role_datum_t *) hashtab_search(policydb->p_roles.table,
178*2d543d20SAndroid Build Coastguard Worker 						   (hashtab_key_t) role);
179*2d543d20SAndroid Build Coastguard Worker 	if (!roldatum) {
180*2d543d20SAndroid Build Coastguard Worker 		ERR(handle, "role %s is not defined", role);
181*2d543d20SAndroid Build Coastguard Worker 		goto err_destroy;
182*2d543d20SAndroid Build Coastguard Worker 	}
183*2d543d20SAndroid Build Coastguard Worker 	scontext->role = roldatum->s.value;
184*2d543d20SAndroid Build Coastguard Worker 
185*2d543d20SAndroid Build Coastguard Worker 	/* Type */
186*2d543d20SAndroid Build Coastguard Worker 	typdatum = (type_datum_t *) hashtab_search(policydb->p_types.table,
187*2d543d20SAndroid Build Coastguard Worker 						   (hashtab_key_t) type);
188*2d543d20SAndroid Build Coastguard Worker 	if (!typdatum || typdatum->flavor == TYPE_ATTRIB) {
189*2d543d20SAndroid Build Coastguard Worker 		ERR(handle, "type %s is not defined", type);
190*2d543d20SAndroid Build Coastguard Worker 		goto err_destroy;
191*2d543d20SAndroid Build Coastguard Worker 	}
192*2d543d20SAndroid Build Coastguard Worker 	scontext->type = typdatum->s.value;
193*2d543d20SAndroid Build Coastguard Worker 
194*2d543d20SAndroid Build Coastguard Worker 	/* MLS */
195*2d543d20SAndroid Build Coastguard Worker 	if (mls && !policydb->mls) {
196*2d543d20SAndroid Build Coastguard Worker 		ERR(handle, "MLS is disabled, but MLS context \"%s\" found",
197*2d543d20SAndroid Build Coastguard Worker 		    mls);
198*2d543d20SAndroid Build Coastguard Worker 		goto err_destroy;
199*2d543d20SAndroid Build Coastguard Worker 	} else if (!mls && policydb->mls) {
200*2d543d20SAndroid Build Coastguard Worker 		ERR(handle, "MLS is enabled, but no MLS context found");
201*2d543d20SAndroid Build Coastguard Worker 		goto err_destroy;
202*2d543d20SAndroid Build Coastguard Worker 	}
203*2d543d20SAndroid Build Coastguard Worker 	if (mls && (mls_from_string(handle, policydb, mls, scontext) < 0))
204*2d543d20SAndroid Build Coastguard Worker 		goto err_destroy;
205*2d543d20SAndroid Build Coastguard Worker 
206*2d543d20SAndroid Build Coastguard Worker 	/* Validity check */
207*2d543d20SAndroid Build Coastguard Worker 	if (!context_is_valid(policydb, scontext)) {
208*2d543d20SAndroid Build Coastguard Worker 		if (mls) {
209*2d543d20SAndroid Build Coastguard Worker 			ERR(handle,
210*2d543d20SAndroid Build Coastguard Worker 			    "invalid security context: \"%s:%s:%s:%s\"",
211*2d543d20SAndroid Build Coastguard Worker 			    user, role, type, mls);
212*2d543d20SAndroid Build Coastguard Worker 		} else {
213*2d543d20SAndroid Build Coastguard Worker 			ERR(handle,
214*2d543d20SAndroid Build Coastguard Worker 			    "invalid security context: \"%s:%s:%s\"",
215*2d543d20SAndroid Build Coastguard Worker 			    user, role, type);
216*2d543d20SAndroid Build Coastguard Worker 		}
217*2d543d20SAndroid Build Coastguard Worker 		goto err_destroy;
218*2d543d20SAndroid Build Coastguard Worker 	}
219*2d543d20SAndroid Build Coastguard Worker 
220*2d543d20SAndroid Build Coastguard Worker 	*cptr = scontext;
221*2d543d20SAndroid Build Coastguard Worker 	free(user);
222*2d543d20SAndroid Build Coastguard Worker 	free(type);
223*2d543d20SAndroid Build Coastguard Worker 	free(role);
224*2d543d20SAndroid Build Coastguard Worker 	return STATUS_SUCCESS;
225*2d543d20SAndroid Build Coastguard Worker 
226*2d543d20SAndroid Build Coastguard Worker       err_destroy:
227*2d543d20SAndroid Build Coastguard Worker 	errno = EINVAL;
228*2d543d20SAndroid Build Coastguard Worker 	context_destroy(scontext);
229*2d543d20SAndroid Build Coastguard Worker 
230*2d543d20SAndroid Build Coastguard Worker       err:
231*2d543d20SAndroid Build Coastguard Worker 	free(scontext);
232*2d543d20SAndroid Build Coastguard Worker 	free(user);
233*2d543d20SAndroid Build Coastguard Worker 	free(type);
234*2d543d20SAndroid Build Coastguard Worker 	free(role);
235*2d543d20SAndroid Build Coastguard Worker 	ERR(handle, "could not create context structure");
236*2d543d20SAndroid Build Coastguard Worker 	return STATUS_ERR;
237*2d543d20SAndroid Build Coastguard Worker }
238*2d543d20SAndroid Build Coastguard Worker 
239*2d543d20SAndroid Build Coastguard Worker /*
240*2d543d20SAndroid Build Coastguard Worker  * Create a record from the given context structure
241*2d543d20SAndroid Build Coastguard Worker  */
context_to_record(sepol_handle_t * handle,const policydb_t * policydb,const context_struct_t * context,sepol_context_t ** record)242*2d543d20SAndroid Build Coastguard Worker int context_to_record(sepol_handle_t * handle,
243*2d543d20SAndroid Build Coastguard Worker 		      const policydb_t * policydb,
244*2d543d20SAndroid Build Coastguard Worker 		      const context_struct_t * context,
245*2d543d20SAndroid Build Coastguard Worker 		      sepol_context_t ** record)
246*2d543d20SAndroid Build Coastguard Worker {
247*2d543d20SAndroid Build Coastguard Worker 
248*2d543d20SAndroid Build Coastguard Worker 	sepol_context_t *tmp_record = NULL;
249*2d543d20SAndroid Build Coastguard Worker 	char *mls = NULL;
250*2d543d20SAndroid Build Coastguard Worker 
251*2d543d20SAndroid Build Coastguard Worker 	if (sepol_context_create(handle, &tmp_record) < 0)
252*2d543d20SAndroid Build Coastguard Worker 		goto err;
253*2d543d20SAndroid Build Coastguard Worker 
254*2d543d20SAndroid Build Coastguard Worker 	if (sepol_context_set_user(handle, tmp_record,
255*2d543d20SAndroid Build Coastguard Worker 				   policydb->p_user_val_to_name[context->user -
256*2d543d20SAndroid Build Coastguard Worker 								1]) < 0)
257*2d543d20SAndroid Build Coastguard Worker 		goto err;
258*2d543d20SAndroid Build Coastguard Worker 
259*2d543d20SAndroid Build Coastguard Worker 	if (sepol_context_set_role(handle, tmp_record,
260*2d543d20SAndroid Build Coastguard Worker 				   policydb->p_role_val_to_name[context->role -
261*2d543d20SAndroid Build Coastguard Worker 								1]) < 0)
262*2d543d20SAndroid Build Coastguard Worker 		goto err;
263*2d543d20SAndroid Build Coastguard Worker 
264*2d543d20SAndroid Build Coastguard Worker 	if (sepol_context_set_type(handle, tmp_record,
265*2d543d20SAndroid Build Coastguard Worker 				   policydb->p_type_val_to_name[context->type -
266*2d543d20SAndroid Build Coastguard Worker 								1]) < 0)
267*2d543d20SAndroid Build Coastguard Worker 		goto err;
268*2d543d20SAndroid Build Coastguard Worker 
269*2d543d20SAndroid Build Coastguard Worker 	if (policydb->mls) {
270*2d543d20SAndroid Build Coastguard Worker 		if (mls_to_string(handle, policydb, context, &mls) < 0)
271*2d543d20SAndroid Build Coastguard Worker 			goto err;
272*2d543d20SAndroid Build Coastguard Worker 
273*2d543d20SAndroid Build Coastguard Worker 		if (sepol_context_set_mls(handle, tmp_record, mls) < 0)
274*2d543d20SAndroid Build Coastguard Worker 			goto err;
275*2d543d20SAndroid Build Coastguard Worker 	}
276*2d543d20SAndroid Build Coastguard Worker 
277*2d543d20SAndroid Build Coastguard Worker 	free(mls);
278*2d543d20SAndroid Build Coastguard Worker 	*record = tmp_record;
279*2d543d20SAndroid Build Coastguard Worker 	return STATUS_SUCCESS;
280*2d543d20SAndroid Build Coastguard Worker 
281*2d543d20SAndroid Build Coastguard Worker       err:
282*2d543d20SAndroid Build Coastguard Worker 	ERR(handle, "could not create context record");
283*2d543d20SAndroid Build Coastguard Worker 	sepol_context_free(tmp_record);
284*2d543d20SAndroid Build Coastguard Worker 	free(mls);
285*2d543d20SAndroid Build Coastguard Worker 	return STATUS_ERR;
286*2d543d20SAndroid Build Coastguard Worker }
287*2d543d20SAndroid Build Coastguard Worker 
288*2d543d20SAndroid Build Coastguard Worker /*
289*2d543d20SAndroid Build Coastguard Worker  * Create a context structure from the provided string.
290*2d543d20SAndroid Build Coastguard Worker  */
context_from_string(sepol_handle_t * handle,const policydb_t * policydb,context_struct_t ** cptr,const char * con_str,size_t con_str_len)291*2d543d20SAndroid Build Coastguard Worker int context_from_string(sepol_handle_t * handle,
292*2d543d20SAndroid Build Coastguard Worker 			const policydb_t * policydb,
293*2d543d20SAndroid Build Coastguard Worker 			context_struct_t ** cptr,
294*2d543d20SAndroid Build Coastguard Worker 			const char *con_str, size_t con_str_len)
295*2d543d20SAndroid Build Coastguard Worker {
296*2d543d20SAndroid Build Coastguard Worker 
297*2d543d20SAndroid Build Coastguard Worker 	char *con_cpy = NULL;
298*2d543d20SAndroid Build Coastguard Worker 	sepol_context_t *ctx_record = NULL;
299*2d543d20SAndroid Build Coastguard Worker 
300*2d543d20SAndroid Build Coastguard Worker 	if (zero_or_saturated(con_str_len)) {
301*2d543d20SAndroid Build Coastguard Worker 		ERR(handle, "Invalid context length");
302*2d543d20SAndroid Build Coastguard Worker 		goto err;
303*2d543d20SAndroid Build Coastguard Worker 	}
304*2d543d20SAndroid Build Coastguard Worker 
305*2d543d20SAndroid Build Coastguard Worker 	/* sepol_context_from_string expects a NULL-terminated string */
306*2d543d20SAndroid Build Coastguard Worker 	con_cpy = malloc(con_str_len + 1);
307*2d543d20SAndroid Build Coastguard Worker 	if (!con_cpy) {
308*2d543d20SAndroid Build Coastguard Worker 		ERR(handle, "out of memory");
309*2d543d20SAndroid Build Coastguard Worker 		goto err;
310*2d543d20SAndroid Build Coastguard Worker 	}
311*2d543d20SAndroid Build Coastguard Worker 
312*2d543d20SAndroid Build Coastguard Worker 	memcpy(con_cpy, con_str, con_str_len);
313*2d543d20SAndroid Build Coastguard Worker 	con_cpy[con_str_len] = '\0';
314*2d543d20SAndroid Build Coastguard Worker 
315*2d543d20SAndroid Build Coastguard Worker 	if (sepol_context_from_string(handle, con_cpy, &ctx_record) < 0)
316*2d543d20SAndroid Build Coastguard Worker 		goto err;
317*2d543d20SAndroid Build Coastguard Worker 
318*2d543d20SAndroid Build Coastguard Worker 	/* Now create from the data structure */
319*2d543d20SAndroid Build Coastguard Worker 	if (context_from_record(handle, policydb, cptr, ctx_record) < 0)
320*2d543d20SAndroid Build Coastguard Worker 		goto err;
321*2d543d20SAndroid Build Coastguard Worker 
322*2d543d20SAndroid Build Coastguard Worker 	free(con_cpy);
323*2d543d20SAndroid Build Coastguard Worker 	sepol_context_free(ctx_record);
324*2d543d20SAndroid Build Coastguard Worker 	return STATUS_SUCCESS;
325*2d543d20SAndroid Build Coastguard Worker 
326*2d543d20SAndroid Build Coastguard Worker       err:
327*2d543d20SAndroid Build Coastguard Worker 	ERR(handle, "could not create context structure");
328*2d543d20SAndroid Build Coastguard Worker 	free(con_cpy);
329*2d543d20SAndroid Build Coastguard Worker 	sepol_context_free(ctx_record);
330*2d543d20SAndroid Build Coastguard Worker 	return STATUS_ERR;
331*2d543d20SAndroid Build Coastguard Worker }
332*2d543d20SAndroid Build Coastguard Worker 
sepol_context_check(sepol_handle_t * handle,const sepol_policydb_t * policydb,const sepol_context_t * context)333*2d543d20SAndroid Build Coastguard Worker int sepol_context_check(sepol_handle_t * handle,
334*2d543d20SAndroid Build Coastguard Worker 			const sepol_policydb_t * policydb,
335*2d543d20SAndroid Build Coastguard Worker 			const sepol_context_t * context)
336*2d543d20SAndroid Build Coastguard Worker {
337*2d543d20SAndroid Build Coastguard Worker 
338*2d543d20SAndroid Build Coastguard Worker 	context_struct_t *con = NULL;
339*2d543d20SAndroid Build Coastguard Worker 	int ret = context_from_record(handle, &policydb->p, &con, context);
340*2d543d20SAndroid Build Coastguard Worker 	context_destroy(con);
341*2d543d20SAndroid Build Coastguard Worker 	free(con);
342*2d543d20SAndroid Build Coastguard Worker 	return ret;
343*2d543d20SAndroid Build Coastguard Worker }
344