1255e72915d4cbddceb435e13d81601755714e9fSE Android#include <stdlib.h>
2255e72915d4cbddceb435e13d81601755714e9fSE Android
3255e72915d4cbddceb435e13d81601755714e9fSE Android#include "debug.h"
4255e72915d4cbddceb435e13d81601755714e9fSE Android#include <sepol/policydb/policydb.h>
5255e72915d4cbddceb435e13d81601755714e9fSE Android#include "policydb_internal.h"
6255e72915d4cbddceb435e13d81601755714e9fSE Android
7255e72915d4cbddceb435e13d81601755714e9fSE Android/* Policy file interfaces. */
8255e72915d4cbddceb435e13d81601755714e9fSE Android
9255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_policy_file_create(sepol_policy_file_t ** pf)
10255e72915d4cbddceb435e13d81601755714e9fSE Android{
11255e72915d4cbddceb435e13d81601755714e9fSE Android	*pf = calloc(1, sizeof(sepol_policy_file_t));
12255e72915d4cbddceb435e13d81601755714e9fSE Android	if (!(*pf))
13255e72915d4cbddceb435e13d81601755714e9fSE Android		return -1;
14255e72915d4cbddceb435e13d81601755714e9fSE Android	return 0;
15255e72915d4cbddceb435e13d81601755714e9fSE Android}
16255e72915d4cbddceb435e13d81601755714e9fSE Android
17255e72915d4cbddceb435e13d81601755714e9fSE Androidvoid sepol_policy_file_set_mem(sepol_policy_file_t * spf,
18255e72915d4cbddceb435e13d81601755714e9fSE Android			       char *data, size_t len)
19255e72915d4cbddceb435e13d81601755714e9fSE Android{
20255e72915d4cbddceb435e13d81601755714e9fSE Android	struct policy_file *pf = &spf->pf;
21255e72915d4cbddceb435e13d81601755714e9fSE Android	if (!len) {
22255e72915d4cbddceb435e13d81601755714e9fSE Android		pf->type = PF_LEN;
23255e72915d4cbddceb435e13d81601755714e9fSE Android		return;
24255e72915d4cbddceb435e13d81601755714e9fSE Android	}
25255e72915d4cbddceb435e13d81601755714e9fSE Android	pf->type = PF_USE_MEMORY;
26255e72915d4cbddceb435e13d81601755714e9fSE Android	pf->data = data;
27255e72915d4cbddceb435e13d81601755714e9fSE Android	pf->len = len;
28255e72915d4cbddceb435e13d81601755714e9fSE Android	pf->size = len;
29255e72915d4cbddceb435e13d81601755714e9fSE Android	return;
30255e72915d4cbddceb435e13d81601755714e9fSE Android}
31255e72915d4cbddceb435e13d81601755714e9fSE Android
32255e72915d4cbddceb435e13d81601755714e9fSE Androidvoid sepol_policy_file_set_fp(sepol_policy_file_t * spf, FILE * fp)
33255e72915d4cbddceb435e13d81601755714e9fSE Android{
34255e72915d4cbddceb435e13d81601755714e9fSE Android	struct policy_file *pf = &spf->pf;
35255e72915d4cbddceb435e13d81601755714e9fSE Android	pf->type = PF_USE_STDIO;
36255e72915d4cbddceb435e13d81601755714e9fSE Android	pf->fp = fp;
37255e72915d4cbddceb435e13d81601755714e9fSE Android	return;
38255e72915d4cbddceb435e13d81601755714e9fSE Android}
39255e72915d4cbddceb435e13d81601755714e9fSE Android
40255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_policy_file_get_len(sepol_policy_file_t * spf, size_t * len)
41255e72915d4cbddceb435e13d81601755714e9fSE Android{
42255e72915d4cbddceb435e13d81601755714e9fSE Android	struct policy_file *pf = &spf->pf;
43255e72915d4cbddceb435e13d81601755714e9fSE Android	if (pf->type != PF_LEN)
44255e72915d4cbddceb435e13d81601755714e9fSE Android		return -1;
45255e72915d4cbddceb435e13d81601755714e9fSE Android	*len = pf->len;
46255e72915d4cbddceb435e13d81601755714e9fSE Android	return 0;
47255e72915d4cbddceb435e13d81601755714e9fSE Android}
48255e72915d4cbddceb435e13d81601755714e9fSE Android
49255e72915d4cbddceb435e13d81601755714e9fSE Androidvoid sepol_policy_file_set_handle(sepol_policy_file_t * pf,
50255e72915d4cbddceb435e13d81601755714e9fSE Android				  sepol_handle_t * handle)
51255e72915d4cbddceb435e13d81601755714e9fSE Android{
52255e72915d4cbddceb435e13d81601755714e9fSE Android	pf->pf.handle = handle;
53255e72915d4cbddceb435e13d81601755714e9fSE Android}
54255e72915d4cbddceb435e13d81601755714e9fSE Android
55255e72915d4cbddceb435e13d81601755714e9fSE Androidvoid sepol_policy_file_free(sepol_policy_file_t * pf)
56255e72915d4cbddceb435e13d81601755714e9fSE Android{
57255e72915d4cbddceb435e13d81601755714e9fSE Android	free(pf);
58255e72915d4cbddceb435e13d81601755714e9fSE Android}
59255e72915d4cbddceb435e13d81601755714e9fSE Android
60255e72915d4cbddceb435e13d81601755714e9fSE Android/* Policydb interfaces. */
61255e72915d4cbddceb435e13d81601755714e9fSE Android
62255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_policydb_create(sepol_policydb_t ** sp)
63255e72915d4cbddceb435e13d81601755714e9fSE Android{
64255e72915d4cbddceb435e13d81601755714e9fSE Android	policydb_t *p;
65255e72915d4cbddceb435e13d81601755714e9fSE Android	*sp = malloc(sizeof(sepol_policydb_t));
66255e72915d4cbddceb435e13d81601755714e9fSE Android	if (!(*sp))
67255e72915d4cbddceb435e13d81601755714e9fSE Android		return -1;
68255e72915d4cbddceb435e13d81601755714e9fSE Android	p = &(*sp)->p;
69255e72915d4cbddceb435e13d81601755714e9fSE Android	if (policydb_init(p)) {
70255e72915d4cbddceb435e13d81601755714e9fSE Android		free(*sp);
71255e72915d4cbddceb435e13d81601755714e9fSE Android		return -1;
72255e72915d4cbddceb435e13d81601755714e9fSE Android	}
73255e72915d4cbddceb435e13d81601755714e9fSE Android	return 0;
74255e72915d4cbddceb435e13d81601755714e9fSE Android}
75255e72915d4cbddceb435e13d81601755714e9fSE Android
76255e72915d4cbddceb435e13d81601755714e9fSE Androidhidden_def(sepol_policydb_create)
77255e72915d4cbddceb435e13d81601755714e9fSE Android
78255e72915d4cbddceb435e13d81601755714e9fSE Androidvoid sepol_policydb_free(sepol_policydb_t * p)
79255e72915d4cbddceb435e13d81601755714e9fSE Android{
80255e72915d4cbddceb435e13d81601755714e9fSE Android	if (!p)
81255e72915d4cbddceb435e13d81601755714e9fSE Android		return;
82255e72915d4cbddceb435e13d81601755714e9fSE Android	policydb_destroy(&p->p);
83255e72915d4cbddceb435e13d81601755714e9fSE Android	free(p);
84255e72915d4cbddceb435e13d81601755714e9fSE Android}
85255e72915d4cbddceb435e13d81601755714e9fSE Android
86255e72915d4cbddceb435e13d81601755714e9fSE Androidhidden_def(sepol_policydb_free)
87255e72915d4cbddceb435e13d81601755714e9fSE Android
88255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_policy_kern_vers_min(void)
89255e72915d4cbddceb435e13d81601755714e9fSE Android{
90255e72915d4cbddceb435e13d81601755714e9fSE Android	return POLICYDB_VERSION_MIN;
91255e72915d4cbddceb435e13d81601755714e9fSE Android}
92255e72915d4cbddceb435e13d81601755714e9fSE Android
93255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_policy_kern_vers_max(void)
94255e72915d4cbddceb435e13d81601755714e9fSE Android{
95255e72915d4cbddceb435e13d81601755714e9fSE Android	return POLICYDB_VERSION_MAX;
96255e72915d4cbddceb435e13d81601755714e9fSE Android}
97255e72915d4cbddceb435e13d81601755714e9fSE Android
98255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_policydb_set_typevers(sepol_policydb_t * sp, unsigned int type)
99255e72915d4cbddceb435e13d81601755714e9fSE Android{
100255e72915d4cbddceb435e13d81601755714e9fSE Android	struct policydb *p = &sp->p;
101255e72915d4cbddceb435e13d81601755714e9fSE Android	switch (type) {
102255e72915d4cbddceb435e13d81601755714e9fSE Android	case POLICY_KERN:
103255e72915d4cbddceb435e13d81601755714e9fSE Android		p->policyvers = POLICYDB_VERSION_MAX;
104255e72915d4cbddceb435e13d81601755714e9fSE Android		break;
105255e72915d4cbddceb435e13d81601755714e9fSE Android	case POLICY_BASE:
106255e72915d4cbddceb435e13d81601755714e9fSE Android	case POLICY_MOD:
107255e72915d4cbddceb435e13d81601755714e9fSE Android		p->policyvers = MOD_POLICYDB_VERSION_MAX;
108255e72915d4cbddceb435e13d81601755714e9fSE Android		break;
109255e72915d4cbddceb435e13d81601755714e9fSE Android	default:
110255e72915d4cbddceb435e13d81601755714e9fSE Android		return -1;
111255e72915d4cbddceb435e13d81601755714e9fSE Android	}
112255e72915d4cbddceb435e13d81601755714e9fSE Android	p->policy_type = type;
113255e72915d4cbddceb435e13d81601755714e9fSE Android	return 0;
114255e72915d4cbddceb435e13d81601755714e9fSE Android}
115255e72915d4cbddceb435e13d81601755714e9fSE Android
116255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_policydb_set_vers(sepol_policydb_t * sp, unsigned int vers)
117255e72915d4cbddceb435e13d81601755714e9fSE Android{
118255e72915d4cbddceb435e13d81601755714e9fSE Android	struct policydb *p = &sp->p;
119255e72915d4cbddceb435e13d81601755714e9fSE Android	switch (p->policy_type) {
120255e72915d4cbddceb435e13d81601755714e9fSE Android	case POLICY_KERN:
121255e72915d4cbddceb435e13d81601755714e9fSE Android		if (vers < POLICYDB_VERSION_MIN || vers > POLICYDB_VERSION_MAX)
122255e72915d4cbddceb435e13d81601755714e9fSE Android			return -1;
123255e72915d4cbddceb435e13d81601755714e9fSE Android		break;
124255e72915d4cbddceb435e13d81601755714e9fSE Android	case POLICY_BASE:
125255e72915d4cbddceb435e13d81601755714e9fSE Android	case POLICY_MOD:
126255e72915d4cbddceb435e13d81601755714e9fSE Android		if (vers < MOD_POLICYDB_VERSION_MIN
127255e72915d4cbddceb435e13d81601755714e9fSE Android		    || vers > MOD_POLICYDB_VERSION_MAX)
128255e72915d4cbddceb435e13d81601755714e9fSE Android			return -1;
129255e72915d4cbddceb435e13d81601755714e9fSE Android		break;
130255e72915d4cbddceb435e13d81601755714e9fSE Android	default:
131255e72915d4cbddceb435e13d81601755714e9fSE Android		return -1;
132255e72915d4cbddceb435e13d81601755714e9fSE Android	}
133255e72915d4cbddceb435e13d81601755714e9fSE Android	p->policyvers = vers;
134255e72915d4cbddceb435e13d81601755714e9fSE Android	return 0;
135255e72915d4cbddceb435e13d81601755714e9fSE Android}
136255e72915d4cbddceb435e13d81601755714e9fSE Android
137255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_policydb_set_handle_unknown(sepol_policydb_t * sp,
138255e72915d4cbddceb435e13d81601755714e9fSE Android				      unsigned int handle_unknown)
139255e72915d4cbddceb435e13d81601755714e9fSE Android{
140255e72915d4cbddceb435e13d81601755714e9fSE Android	struct policydb *p = &sp->p;
141255e72915d4cbddceb435e13d81601755714e9fSE Android
142255e72915d4cbddceb435e13d81601755714e9fSE Android	switch (handle_unknown) {
143255e72915d4cbddceb435e13d81601755714e9fSE Android	case SEPOL_DENY_UNKNOWN:
144255e72915d4cbddceb435e13d81601755714e9fSE Android	case SEPOL_REJECT_UNKNOWN:
145255e72915d4cbddceb435e13d81601755714e9fSE Android	case SEPOL_ALLOW_UNKNOWN:
146255e72915d4cbddceb435e13d81601755714e9fSE Android		break;
147255e72915d4cbddceb435e13d81601755714e9fSE Android	default:
148255e72915d4cbddceb435e13d81601755714e9fSE Android		return -1;
149255e72915d4cbddceb435e13d81601755714e9fSE Android	}
150255e72915d4cbddceb435e13d81601755714e9fSE Android
151255e72915d4cbddceb435e13d81601755714e9fSE Android	p->handle_unknown = handle_unknown;
152255e72915d4cbddceb435e13d81601755714e9fSE Android	return 0;
153255e72915d4cbddceb435e13d81601755714e9fSE Android}
154255e72915d4cbddceb435e13d81601755714e9fSE Android
155255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_policydb_read(sepol_policydb_t * p, sepol_policy_file_t * pf)
156255e72915d4cbddceb435e13d81601755714e9fSE Android{
157255e72915d4cbddceb435e13d81601755714e9fSE Android	return policydb_read(&p->p, &pf->pf, 0);
158255e72915d4cbddceb435e13d81601755714e9fSE Android}
159255e72915d4cbddceb435e13d81601755714e9fSE Android
160255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_policydb_write(sepol_policydb_t * p, sepol_policy_file_t * pf)
161255e72915d4cbddceb435e13d81601755714e9fSE Android{
162255e72915d4cbddceb435e13d81601755714e9fSE Android	return policydb_write(&p->p, &pf->pf);
163255e72915d4cbddceb435e13d81601755714e9fSE Android}
164255e72915d4cbddceb435e13d81601755714e9fSE Android
165255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_policydb_from_image(sepol_handle_t * handle,
166255e72915d4cbddceb435e13d81601755714e9fSE Android			      void *data, size_t len, sepol_policydb_t * p)
167255e72915d4cbddceb435e13d81601755714e9fSE Android{
168255e72915d4cbddceb435e13d81601755714e9fSE Android	return policydb_from_image(handle, data, len, &p->p);
169255e72915d4cbddceb435e13d81601755714e9fSE Android}
170255e72915d4cbddceb435e13d81601755714e9fSE Android
171255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_policydb_to_image(sepol_handle_t * handle,
172255e72915d4cbddceb435e13d81601755714e9fSE Android			    sepol_policydb_t * p, void **newdata,
173255e72915d4cbddceb435e13d81601755714e9fSE Android			    size_t * newlen)
174255e72915d4cbddceb435e13d81601755714e9fSE Android{
175255e72915d4cbddceb435e13d81601755714e9fSE Android	return policydb_to_image(handle, &p->p, newdata, newlen);
176255e72915d4cbddceb435e13d81601755714e9fSE Android}
177255e72915d4cbddceb435e13d81601755714e9fSE Android
178255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_policydb_mls_enabled(const sepol_policydb_t * p)
179255e72915d4cbddceb435e13d81601755714e9fSE Android{
180255e72915d4cbddceb435e13d81601755714e9fSE Android
181255e72915d4cbddceb435e13d81601755714e9fSE Android	return p->p.mls;
182255e72915d4cbddceb435e13d81601755714e9fSE Android}
183255e72915d4cbddceb435e13d81601755714e9fSE Android
184255e72915d4cbddceb435e13d81601755714e9fSE Android/*
185255e72915d4cbddceb435e13d81601755714e9fSE Android * Enable compatibility mode for SELinux network checks iff
186255e72915d4cbddceb435e13d81601755714e9fSE Android * the packet class is not defined in the policy.
187255e72915d4cbddceb435e13d81601755714e9fSE Android */
188255e72915d4cbddceb435e13d81601755714e9fSE Android#define PACKET_CLASS_NAME "packet"
189255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_policydb_compat_net(const sepol_policydb_t * p)
190255e72915d4cbddceb435e13d81601755714e9fSE Android{
191255e72915d4cbddceb435e13d81601755714e9fSE Android	return (hashtab_search(p->p.p_classes.table, PACKET_CLASS_NAME) ==
192255e72915d4cbddceb435e13d81601755714e9fSE Android		NULL);
193255e72915d4cbddceb435e13d81601755714e9fSE Android}
194