1 #include <stdlib.h>
2 
3 #include "debug.h"
4 #include <sepol/policydb/policydb.h>
5 #include "policydb_internal.h"
6 
7 /* Policy file interfaces. */
8 
sepol_policy_file_create(sepol_policy_file_t ** pf)9 int sepol_policy_file_create(sepol_policy_file_t ** pf)
10 {
11 	*pf = calloc(1, sizeof(sepol_policy_file_t));
12 	if (!(*pf))
13 		return -1;
14 	return 0;
15 }
16 
sepol_policy_file_set_mem(sepol_policy_file_t * spf,char * data,size_t len)17 void sepol_policy_file_set_mem(sepol_policy_file_t * spf,
18 			       char *data, size_t len)
19 {
20 	struct policy_file *pf = &spf->pf;
21 	if (!len) {
22 		pf->type = PF_LEN;
23 		return;
24 	}
25 	pf->type = PF_USE_MEMORY;
26 	pf->data = data;
27 	pf->len = len;
28 	pf->size = len;
29 	return;
30 }
31 
sepol_policy_file_set_fp(sepol_policy_file_t * spf,FILE * fp)32 void sepol_policy_file_set_fp(sepol_policy_file_t * spf, FILE * fp)
33 {
34 	struct policy_file *pf = &spf->pf;
35 	pf->type = PF_USE_STDIO;
36 	pf->fp = fp;
37 	return;
38 }
39 
sepol_policy_file_get_len(sepol_policy_file_t * spf,size_t * len)40 int sepol_policy_file_get_len(sepol_policy_file_t * spf, size_t * len)
41 {
42 	struct policy_file *pf = &spf->pf;
43 	if (pf->type != PF_LEN)
44 		return -1;
45 	*len = pf->len;
46 	return 0;
47 }
48 
sepol_policy_file_set_handle(sepol_policy_file_t * pf,sepol_handle_t * handle)49 void sepol_policy_file_set_handle(sepol_policy_file_t * pf,
50 				  sepol_handle_t * handle)
51 {
52 	pf->pf.handle = handle;
53 }
54 
sepol_policy_file_free(sepol_policy_file_t * pf)55 void sepol_policy_file_free(sepol_policy_file_t * pf)
56 {
57 	free(pf);
58 }
59 
60 /* Policydb interfaces. */
61 
sepol_policydb_create(sepol_policydb_t ** sp)62 int sepol_policydb_create(sepol_policydb_t ** sp)
63 {
64 	policydb_t *p;
65 	*sp = malloc(sizeof(sepol_policydb_t));
66 	if (!(*sp))
67 		return -1;
68 	p = &(*sp)->p;
69 	if (policydb_init(p)) {
70 		free(*sp);
71 		return -1;
72 	}
73 	return 0;
74 }
75 
hidden_def(sepol_policydb_create)76 hidden_def(sepol_policydb_create)
77 
78 void sepol_policydb_free(sepol_policydb_t * p)
79 {
80 	if (!p)
81 		return;
82 	policydb_destroy(&p->p);
83 	free(p);
84 }
85 
hidden_def(sepol_policydb_free)86 hidden_def(sepol_policydb_free)
87 
88 int sepol_policy_kern_vers_min(void)
89 {
90 	return POLICYDB_VERSION_MIN;
91 }
92 
sepol_policy_kern_vers_max(void)93 int sepol_policy_kern_vers_max(void)
94 {
95 	return POLICYDB_VERSION_MAX;
96 }
97 
sepol_policydb_set_typevers(sepol_policydb_t * sp,unsigned int type)98 int sepol_policydb_set_typevers(sepol_policydb_t * sp, unsigned int type)
99 {
100 	struct policydb *p = &sp->p;
101 	switch (type) {
102 	case POLICY_KERN:
103 		p->policyvers = POLICYDB_VERSION_MAX;
104 		break;
105 	case POLICY_BASE:
106 	case POLICY_MOD:
107 		p->policyvers = MOD_POLICYDB_VERSION_MAX;
108 		break;
109 	default:
110 		return -1;
111 	}
112 	p->policy_type = type;
113 	return 0;
114 }
115 
sepol_policydb_set_vers(sepol_policydb_t * sp,unsigned int vers)116 int sepol_policydb_set_vers(sepol_policydb_t * sp, unsigned int vers)
117 {
118 	struct policydb *p = &sp->p;
119 	switch (p->policy_type) {
120 	case POLICY_KERN:
121 		if (vers < POLICYDB_VERSION_MIN || vers > POLICYDB_VERSION_MAX)
122 			return -1;
123 		break;
124 	case POLICY_BASE:
125 	case POLICY_MOD:
126 		if (vers < MOD_POLICYDB_VERSION_MIN
127 		    || vers > MOD_POLICYDB_VERSION_MAX)
128 			return -1;
129 		break;
130 	default:
131 		return -1;
132 	}
133 	p->policyvers = vers;
134 	return 0;
135 }
136 
sepol_policydb_set_handle_unknown(sepol_policydb_t * sp,unsigned int handle_unknown)137 int sepol_policydb_set_handle_unknown(sepol_policydb_t * sp,
138 				      unsigned int handle_unknown)
139 {
140 	struct policydb *p = &sp->p;
141 
142 	switch (handle_unknown) {
143 	case SEPOL_DENY_UNKNOWN:
144 	case SEPOL_REJECT_UNKNOWN:
145 	case SEPOL_ALLOW_UNKNOWN:
146 		break;
147 	default:
148 		return -1;
149 	}
150 
151 	p->handle_unknown = handle_unknown;
152 	return 0;
153 }
154 
sepol_policydb_set_target_platform(sepol_policydb_t * sp,int target_platform)155 int sepol_policydb_set_target_platform(sepol_policydb_t * sp,
156 				      int target_platform)
157 {
158 	struct policydb *p = &sp->p;
159 
160 	switch (target_platform) {
161 	case SEPOL_TARGET_SELINUX:
162 	case SEPOL_TARGET_XEN:
163 		break;
164 	default:
165 		return -1;
166 	}
167 
168 	p->target_platform = target_platform;
169 	return 0;
170 }
171 
sepol_policydb_read(sepol_policydb_t * p,sepol_policy_file_t * pf)172 int sepol_policydb_read(sepol_policydb_t * p, sepol_policy_file_t * pf)
173 {
174 	return policydb_read(&p->p, &pf->pf, 0);
175 }
176 
sepol_policydb_write(sepol_policydb_t * p,sepol_policy_file_t * pf)177 int sepol_policydb_write(sepol_policydb_t * p, sepol_policy_file_t * pf)
178 {
179 	return policydb_write(&p->p, &pf->pf);
180 }
181 
sepol_policydb_from_image(sepol_handle_t * handle,void * data,size_t len,sepol_policydb_t * p)182 int sepol_policydb_from_image(sepol_handle_t * handle,
183 			      void *data, size_t len, sepol_policydb_t * p)
184 {
185 	return policydb_from_image(handle, data, len, &p->p);
186 }
187 
sepol_policydb_to_image(sepol_handle_t * handle,sepol_policydb_t * p,void ** newdata,size_t * newlen)188 int sepol_policydb_to_image(sepol_handle_t * handle,
189 			    sepol_policydb_t * p, void **newdata,
190 			    size_t * newlen)
191 {
192 	return policydb_to_image(handle, &p->p, newdata, newlen);
193 }
194 
sepol_policydb_mls_enabled(const sepol_policydb_t * p)195 int sepol_policydb_mls_enabled(const sepol_policydb_t * p)
196 {
197 
198 	return p->p.mls;
199 }
200 
201 /*
202  * Enable compatibility mode for SELinux network checks iff
203  * the packet class is not defined in the policy.
204  */
205 #define PACKET_CLASS_NAME "packet"
sepol_policydb_compat_net(const sepol_policydb_t * p)206 int sepol_policydb_compat_net(const sepol_policydb_t * p)
207 {
208 	return (hashtab_search(p->p.p_classes.table, PACKET_CLASS_NAME) ==
209 		NULL);
210 }
211