1*e4a36f41SAndroid Build Coastguard Worker #include <stdio.h>
2*e4a36f41SAndroid Build Coastguard Worker #include <string>
3*e4a36f41SAndroid Build Coastguard Worker #include <sstream>
4*e4a36f41SAndroid Build Coastguard Worker #include <stdlib.h>
5*e4a36f41SAndroid Build Coastguard Worker #include <unistd.h>
6*e4a36f41SAndroid Build Coastguard Worker #include <iostream>
7*e4a36f41SAndroid Build Coastguard Worker #include <sys/mman.h>
8*e4a36f41SAndroid Build Coastguard Worker #include <sys/stat.h>
9*e4a36f41SAndroid Build Coastguard Worker #include <sepol/policydb/avtab.h>
10*e4a36f41SAndroid Build Coastguard Worker #include <sepol/policydb/policydb.h>
11*e4a36f41SAndroid Build Coastguard Worker #include <sepol/policydb/services.h>
12*e4a36f41SAndroid Build Coastguard Worker #include <sepol/policydb/util.h>
13*e4a36f41SAndroid Build Coastguard Worker #include <sys/types.h>
14*e4a36f41SAndroid Build Coastguard Worker #include <fstream>
15*e4a36f41SAndroid Build Coastguard Worker
16*e4a36f41SAndroid Build Coastguard Worker #include <android-base/file.h>
17*e4a36f41SAndroid Build Coastguard Worker #include <android-base/strings.h>
18*e4a36f41SAndroid Build Coastguard Worker #include <sepol_wrap.h>
19*e4a36f41SAndroid Build Coastguard Worker
20*e4a36f41SAndroid Build Coastguard Worker struct genfs_iter {
21*e4a36f41SAndroid Build Coastguard Worker genfs_t *genfs;
22*e4a36f41SAndroid Build Coastguard Worker ocontext_t *ocon;
23*e4a36f41SAndroid Build Coastguard Worker };
24*e4a36f41SAndroid Build Coastguard Worker
init_genfs_iter(void * policydbp)25*e4a36f41SAndroid Build Coastguard Worker void *init_genfs_iter(void *policydbp)
26*e4a36f41SAndroid Build Coastguard Worker {
27*e4a36f41SAndroid Build Coastguard Worker struct genfs_iter *out = (struct genfs_iter *)
28*e4a36f41SAndroid Build Coastguard Worker calloc(1, sizeof(struct genfs_iter));
29*e4a36f41SAndroid Build Coastguard Worker
30*e4a36f41SAndroid Build Coastguard Worker if (!out) {
31*e4a36f41SAndroid Build Coastguard Worker std::cerr << "Failed to allocate genfs iterator" << std::endl;
32*e4a36f41SAndroid Build Coastguard Worker return nullptr;
33*e4a36f41SAndroid Build Coastguard Worker }
34*e4a36f41SAndroid Build Coastguard Worker
35*e4a36f41SAndroid Build Coastguard Worker policydb_t *db = static_cast<policydb_t *>(policydbp);
36*e4a36f41SAndroid Build Coastguard Worker
37*e4a36f41SAndroid Build Coastguard Worker out->genfs = db->genfs;
38*e4a36f41SAndroid Build Coastguard Worker out->ocon = db->genfs->head;
39*e4a36f41SAndroid Build Coastguard Worker
40*e4a36f41SAndroid Build Coastguard Worker return static_cast<void *>(out);
41*e4a36f41SAndroid Build Coastguard Worker }
42*e4a36f41SAndroid Build Coastguard Worker
43*e4a36f41SAndroid Build Coastguard Worker /*
44*e4a36f41SAndroid Build Coastguard Worker * print genfs path into *out buffer.
45*e4a36f41SAndroid Build Coastguard Worker *
46*e4a36f41SAndroid Build Coastguard Worker * Returns -1 on error.
47*e4a36f41SAndroid Build Coastguard Worker * Returns 0 on successfully retrieving a genfs entry.
48*e4a36f41SAndroid Build Coastguard Worker * Returns 1 on successfully retrieving the final genfs entry.
49*e4a36f41SAndroid Build Coastguard Worker */
get_genfs(char * out,size_t max_size,void * policydbp,void * genfs_iterp)50*e4a36f41SAndroid Build Coastguard Worker int get_genfs(char *out, size_t max_size, void *policydbp, void *genfs_iterp)
51*e4a36f41SAndroid Build Coastguard Worker {
52*e4a36f41SAndroid Build Coastguard Worker size_t len;
53*e4a36f41SAndroid Build Coastguard Worker struct genfs_iter *i = static_cast<struct genfs_iter *>(genfs_iterp);
54*e4a36f41SAndroid Build Coastguard Worker policydb_t *db = static_cast<policydb_t *>(policydbp);
55*e4a36f41SAndroid Build Coastguard Worker
56*e4a36f41SAndroid Build Coastguard Worker len = snprintf(out, max_size, "%s %s %s:%s:%s:s0",
57*e4a36f41SAndroid Build Coastguard Worker i->genfs->fstype,
58*e4a36f41SAndroid Build Coastguard Worker i->ocon->u.name,
59*e4a36f41SAndroid Build Coastguard Worker db->p_user_val_to_name[i->ocon->context->user-1],
60*e4a36f41SAndroid Build Coastguard Worker db->p_role_val_to_name[i->ocon->context->role-1],
61*e4a36f41SAndroid Build Coastguard Worker db->p_type_val_to_name[i->ocon->context->type-1]);
62*e4a36f41SAndroid Build Coastguard Worker
63*e4a36f41SAndroid Build Coastguard Worker if (len >= max_size) {
64*e4a36f41SAndroid Build Coastguard Worker std::cerr << "genfs path exceeds buffer size." << std::endl;
65*e4a36f41SAndroid Build Coastguard Worker return -1;
66*e4a36f41SAndroid Build Coastguard Worker }
67*e4a36f41SAndroid Build Coastguard Worker
68*e4a36f41SAndroid Build Coastguard Worker i->ocon = i->ocon->next;
69*e4a36f41SAndroid Build Coastguard Worker if (i->ocon == nullptr) {
70*e4a36f41SAndroid Build Coastguard Worker if (i->genfs->next != nullptr) {
71*e4a36f41SAndroid Build Coastguard Worker i->genfs = i->genfs->next;
72*e4a36f41SAndroid Build Coastguard Worker i->ocon = i->genfs->head;
73*e4a36f41SAndroid Build Coastguard Worker } else {
74*e4a36f41SAndroid Build Coastguard Worker return 1;
75*e4a36f41SAndroid Build Coastguard Worker }
76*e4a36f41SAndroid Build Coastguard Worker }
77*e4a36f41SAndroid Build Coastguard Worker
78*e4a36f41SAndroid Build Coastguard Worker return 0;
79*e4a36f41SAndroid Build Coastguard Worker }
80*e4a36f41SAndroid Build Coastguard Worker
destroy_genfs_iter(void * genfs_iterp)81*e4a36f41SAndroid Build Coastguard Worker void destroy_genfs_iter(void *genfs_iterp)
82*e4a36f41SAndroid Build Coastguard Worker {
83*e4a36f41SAndroid Build Coastguard Worker struct genfs_iter *genfs_i = static_cast<struct genfs_iter *>(genfs_iterp);
84*e4a36f41SAndroid Build Coastguard Worker free(genfs_i);
85*e4a36f41SAndroid Build Coastguard Worker }
86*e4a36f41SAndroid Build Coastguard Worker
87*e4a36f41SAndroid Build Coastguard Worker #define TYPE_ITER_LOOKUP 0
88*e4a36f41SAndroid Build Coastguard Worker #define TYPE_ITER_ALLTYPES 1
89*e4a36f41SAndroid Build Coastguard Worker #define TYPE_ITER_ALLATTRS 2
90*e4a36f41SAndroid Build Coastguard Worker struct type_iter {
91*e4a36f41SAndroid Build Coastguard Worker unsigned int alltypes;
92*e4a36f41SAndroid Build Coastguard Worker type_datum *d;
93*e4a36f41SAndroid Build Coastguard Worker ebitmap_node *n;
94*e4a36f41SAndroid Build Coastguard Worker unsigned int length;
95*e4a36f41SAndroid Build Coastguard Worker unsigned int bit;
96*e4a36f41SAndroid Build Coastguard Worker };
97*e4a36f41SAndroid Build Coastguard Worker
init_type_iter(void * policydbp,const char * type,bool is_attr)98*e4a36f41SAndroid Build Coastguard Worker void *init_type_iter(void *policydbp, const char *type, bool is_attr)
99*e4a36f41SAndroid Build Coastguard Worker {
100*e4a36f41SAndroid Build Coastguard Worker policydb_t *db = static_cast<policydb_t *>(policydbp);
101*e4a36f41SAndroid Build Coastguard Worker struct type_iter *out = (struct type_iter *)
102*e4a36f41SAndroid Build Coastguard Worker calloc(1, sizeof(struct type_iter));
103*e4a36f41SAndroid Build Coastguard Worker
104*e4a36f41SAndroid Build Coastguard Worker if (!out) {
105*e4a36f41SAndroid Build Coastguard Worker std::cerr << "Failed to allocate type type iterator" << std::endl;
106*e4a36f41SAndroid Build Coastguard Worker return nullptr;
107*e4a36f41SAndroid Build Coastguard Worker }
108*e4a36f41SAndroid Build Coastguard Worker
109*e4a36f41SAndroid Build Coastguard Worker if (type == nullptr) {
110*e4a36f41SAndroid Build Coastguard Worker out->length = db->p_types.nprim;
111*e4a36f41SAndroid Build Coastguard Worker out->bit = 0;
112*e4a36f41SAndroid Build Coastguard Worker if (is_attr)
113*e4a36f41SAndroid Build Coastguard Worker out->alltypes = TYPE_ITER_ALLATTRS;
114*e4a36f41SAndroid Build Coastguard Worker else
115*e4a36f41SAndroid Build Coastguard Worker out->alltypes = TYPE_ITER_ALLTYPES;
116*e4a36f41SAndroid Build Coastguard Worker } else {
117*e4a36f41SAndroid Build Coastguard Worker out->alltypes = TYPE_ITER_LOOKUP;
118*e4a36f41SAndroid Build Coastguard Worker out->d = static_cast<type_datum *>(hashtab_search(db->p_types.table, type));
119*e4a36f41SAndroid Build Coastguard Worker if (out->d == nullptr) {
120*e4a36f41SAndroid Build Coastguard Worker std::cerr << "\"" << type << "\" does not exist" << std::endl;
121*e4a36f41SAndroid Build Coastguard Worker free(out);
122*e4a36f41SAndroid Build Coastguard Worker return nullptr;
123*e4a36f41SAndroid Build Coastguard Worker }
124*e4a36f41SAndroid Build Coastguard Worker if (is_attr && out->d->flavor != TYPE_ATTRIB) {
125*e4a36f41SAndroid Build Coastguard Worker std::cerr << "\"" << type << "\" MUST be an attribute in the policy" << std::endl;
126*e4a36f41SAndroid Build Coastguard Worker free(out);
127*e4a36f41SAndroid Build Coastguard Worker return nullptr;
128*e4a36f41SAndroid Build Coastguard Worker } else if (!is_attr && out->d->flavor != TYPE_TYPE) {
129*e4a36f41SAndroid Build Coastguard Worker std::cerr << "\"" << type << "\" MUST be a type in the policy" << std::endl;
130*e4a36f41SAndroid Build Coastguard Worker free(out);
131*e4a36f41SAndroid Build Coastguard Worker return nullptr;
132*e4a36f41SAndroid Build Coastguard Worker }
133*e4a36f41SAndroid Build Coastguard Worker
134*e4a36f41SAndroid Build Coastguard Worker if (is_attr) {
135*e4a36f41SAndroid Build Coastguard Worker out->bit = ebitmap_start(&db->attr_type_map[out->d->s.value - 1], &out->n);
136*e4a36f41SAndroid Build Coastguard Worker out->length = ebitmap_length(&db->attr_type_map[out->d->s.value - 1]);
137*e4a36f41SAndroid Build Coastguard Worker } else {
138*e4a36f41SAndroid Build Coastguard Worker out->bit = ebitmap_start(&db->type_attr_map[out->d->s.value - 1], &out->n);
139*e4a36f41SAndroid Build Coastguard Worker out->length = ebitmap_length(&db->type_attr_map[out->d->s.value - 1]);
140*e4a36f41SAndroid Build Coastguard Worker }
141*e4a36f41SAndroid Build Coastguard Worker }
142*e4a36f41SAndroid Build Coastguard Worker
143*e4a36f41SAndroid Build Coastguard Worker return static_cast<void *>(out);
144*e4a36f41SAndroid Build Coastguard Worker }
145*e4a36f41SAndroid Build Coastguard Worker
destroy_type_iter(void * type_iterp)146*e4a36f41SAndroid Build Coastguard Worker void destroy_type_iter(void *type_iterp)
147*e4a36f41SAndroid Build Coastguard Worker {
148*e4a36f41SAndroid Build Coastguard Worker struct type_iter *type_i = static_cast<struct type_iter *>(type_iterp);
149*e4a36f41SAndroid Build Coastguard Worker free(type_i);
150*e4a36f41SAndroid Build Coastguard Worker }
151*e4a36f41SAndroid Build Coastguard Worker
152*e4a36f41SAndroid Build Coastguard Worker /*
153*e4a36f41SAndroid Build Coastguard Worker * print type into *out buffer.
154*e4a36f41SAndroid Build Coastguard Worker *
155*e4a36f41SAndroid Build Coastguard Worker * Returns -1 on error.
156*e4a36f41SAndroid Build Coastguard Worker * Returns 0 on successfully reading an avtab entry.
157*e4a36f41SAndroid Build Coastguard Worker * Returns 1 on complete
158*e4a36f41SAndroid Build Coastguard Worker */
get_type(char * out,size_t max_size,void * policydbp,void * type_iterp)159*e4a36f41SAndroid Build Coastguard Worker int get_type(char *out, size_t max_size, void *policydbp, void *type_iterp)
160*e4a36f41SAndroid Build Coastguard Worker {
161*e4a36f41SAndroid Build Coastguard Worker size_t len;
162*e4a36f41SAndroid Build Coastguard Worker policydb_t *db = static_cast<policydb_t *>(policydbp);
163*e4a36f41SAndroid Build Coastguard Worker struct type_iter *i = static_cast<struct type_iter *>(type_iterp);
164*e4a36f41SAndroid Build Coastguard Worker
165*e4a36f41SAndroid Build Coastguard Worker if (!i->alltypes) {
166*e4a36f41SAndroid Build Coastguard Worker for (; i->bit < i->length; i->bit = ebitmap_next(&i->n, i->bit)) {
167*e4a36f41SAndroid Build Coastguard Worker if (!ebitmap_node_get_bit(i->n, i->bit)) {
168*e4a36f41SAndroid Build Coastguard Worker continue;
169*e4a36f41SAndroid Build Coastguard Worker }
170*e4a36f41SAndroid Build Coastguard Worker break;
171*e4a36f41SAndroid Build Coastguard Worker }
172*e4a36f41SAndroid Build Coastguard Worker }
173*e4a36f41SAndroid Build Coastguard Worker while (i->bit < i->length &&
174*e4a36f41SAndroid Build Coastguard Worker ((i->alltypes == TYPE_ITER_ALLATTRS
175*e4a36f41SAndroid Build Coastguard Worker && db->type_val_to_struct[i->bit]->flavor != TYPE_ATTRIB)
176*e4a36f41SAndroid Build Coastguard Worker || (i->alltypes == TYPE_ITER_ALLTYPES
177*e4a36f41SAndroid Build Coastguard Worker && db->type_val_to_struct[i->bit]->flavor != TYPE_TYPE))) {
178*e4a36f41SAndroid Build Coastguard Worker i->bit++;
179*e4a36f41SAndroid Build Coastguard Worker }
180*e4a36f41SAndroid Build Coastguard Worker if (i->bit >= i->length)
181*e4a36f41SAndroid Build Coastguard Worker return 1;
182*e4a36f41SAndroid Build Coastguard Worker len = snprintf(out, max_size, "%s", db->p_type_val_to_name[i->bit]);
183*e4a36f41SAndroid Build Coastguard Worker if (len >= max_size) {
184*e4a36f41SAndroid Build Coastguard Worker std::cerr << "type name exceeds buffer size." << std::endl;
185*e4a36f41SAndroid Build Coastguard Worker return -1;
186*e4a36f41SAndroid Build Coastguard Worker }
187*e4a36f41SAndroid Build Coastguard Worker i->alltypes ? i->bit++ : i->bit = ebitmap_next(&i->n, i->bit);
188*e4a36f41SAndroid Build Coastguard Worker return 0;
189*e4a36f41SAndroid Build Coastguard Worker }
190*e4a36f41SAndroid Build Coastguard Worker
load_policy(const char * policy_path)191*e4a36f41SAndroid Build Coastguard Worker void *load_policy(const char *policy_path)
192*e4a36f41SAndroid Build Coastguard Worker {
193*e4a36f41SAndroid Build Coastguard Worker FILE *fp;
194*e4a36f41SAndroid Build Coastguard Worker policydb_t *db;
195*e4a36f41SAndroid Build Coastguard Worker
196*e4a36f41SAndroid Build Coastguard Worker fp = fopen(policy_path, "re");
197*e4a36f41SAndroid Build Coastguard Worker if (!fp) {
198*e4a36f41SAndroid Build Coastguard Worker std::cerr << "Invalid or non-existing policy file: " << policy_path << std::endl;
199*e4a36f41SAndroid Build Coastguard Worker return nullptr;
200*e4a36f41SAndroid Build Coastguard Worker }
201*e4a36f41SAndroid Build Coastguard Worker
202*e4a36f41SAndroid Build Coastguard Worker db = (policydb_t *) calloc(1, sizeof(policydb_t));
203*e4a36f41SAndroid Build Coastguard Worker if (!db) {
204*e4a36f41SAndroid Build Coastguard Worker std::cerr << "Failed to allocate memory for policy db." << std::endl;
205*e4a36f41SAndroid Build Coastguard Worker fclose(fp);
206*e4a36f41SAndroid Build Coastguard Worker return nullptr;
207*e4a36f41SAndroid Build Coastguard Worker }
208*e4a36f41SAndroid Build Coastguard Worker
209*e4a36f41SAndroid Build Coastguard Worker sidtab_t sidtab;
210*e4a36f41SAndroid Build Coastguard Worker sepol_set_sidtab(&sidtab);
211*e4a36f41SAndroid Build Coastguard Worker sepol_set_policydb(db);
212*e4a36f41SAndroid Build Coastguard Worker
213*e4a36f41SAndroid Build Coastguard Worker struct stat sb;
214*e4a36f41SAndroid Build Coastguard Worker if (fstat(fileno(fp), &sb)) {
215*e4a36f41SAndroid Build Coastguard Worker std::cerr << "Failed to stat the policy file" << std::endl;
216*e4a36f41SAndroid Build Coastguard Worker free(db);
217*e4a36f41SAndroid Build Coastguard Worker fclose(fp);
218*e4a36f41SAndroid Build Coastguard Worker return nullptr;
219*e4a36f41SAndroid Build Coastguard Worker }
220*e4a36f41SAndroid Build Coastguard Worker
221*e4a36f41SAndroid Build Coastguard Worker auto unmap = [=](void *ptr) { munmap(ptr, sb.st_size); };
222*e4a36f41SAndroid Build Coastguard Worker std::unique_ptr<void, decltype(unmap)> map(
223*e4a36f41SAndroid Build Coastguard Worker mmap(nullptr, sb.st_size, PROT_READ, MAP_PRIVATE, fileno(fp), 0), unmap);
224*e4a36f41SAndroid Build Coastguard Worker if (!map) {
225*e4a36f41SAndroid Build Coastguard Worker std::cerr << "Failed to map the policy file" << std::endl;
226*e4a36f41SAndroid Build Coastguard Worker free(db);
227*e4a36f41SAndroid Build Coastguard Worker fclose(fp);
228*e4a36f41SAndroid Build Coastguard Worker return nullptr;
229*e4a36f41SAndroid Build Coastguard Worker }
230*e4a36f41SAndroid Build Coastguard Worker
231*e4a36f41SAndroid Build Coastguard Worker struct policy_file pf;
232*e4a36f41SAndroid Build Coastguard Worker policy_file_init(&pf);
233*e4a36f41SAndroid Build Coastguard Worker pf.type = PF_USE_MEMORY;
234*e4a36f41SAndroid Build Coastguard Worker pf.data = static_cast<char *>(map.get());
235*e4a36f41SAndroid Build Coastguard Worker pf.len = sb.st_size;
236*e4a36f41SAndroid Build Coastguard Worker if (policydb_init(db)) {
237*e4a36f41SAndroid Build Coastguard Worker std::cerr << "Failed to initialize policydb" << std::endl;
238*e4a36f41SAndroid Build Coastguard Worker free(db);
239*e4a36f41SAndroid Build Coastguard Worker fclose(fp);
240*e4a36f41SAndroid Build Coastguard Worker return nullptr;
241*e4a36f41SAndroid Build Coastguard Worker }
242*e4a36f41SAndroid Build Coastguard Worker
243*e4a36f41SAndroid Build Coastguard Worker if (policydb_read(db, &pf, 0)) {
244*e4a36f41SAndroid Build Coastguard Worker std::cerr << "Failed to read binary policy" << std::endl;
245*e4a36f41SAndroid Build Coastguard Worker policydb_destroy(db);
246*e4a36f41SAndroid Build Coastguard Worker free(db);
247*e4a36f41SAndroid Build Coastguard Worker fclose(fp);
248*e4a36f41SAndroid Build Coastguard Worker return nullptr;
249*e4a36f41SAndroid Build Coastguard Worker }
250*e4a36f41SAndroid Build Coastguard Worker
251*e4a36f41SAndroid Build Coastguard Worker return static_cast<void *>(db);
252*e4a36f41SAndroid Build Coastguard Worker }
253*e4a36f41SAndroid Build Coastguard Worker
254*e4a36f41SAndroid Build Coastguard Worker /* items needed to iterate over the avtab */
255*e4a36f41SAndroid Build Coastguard Worker struct avtab_iter {
256*e4a36f41SAndroid Build Coastguard Worker avtab_t *avtab;
257*e4a36f41SAndroid Build Coastguard Worker uint32_t i;
258*e4a36f41SAndroid Build Coastguard Worker avtab_ptr_t cur;
259*e4a36f41SAndroid Build Coastguard Worker };
260*e4a36f41SAndroid Build Coastguard Worker
261*e4a36f41SAndroid Build Coastguard Worker /*
262*e4a36f41SAndroid Build Coastguard Worker * print allow rule into *out buffer.
263*e4a36f41SAndroid Build Coastguard Worker *
264*e4a36f41SAndroid Build Coastguard Worker * Returns -1 on error.
265*e4a36f41SAndroid Build Coastguard Worker * Returns 0 on successfully reading an avtab entry.
266*e4a36f41SAndroid Build Coastguard Worker * Returns 1 on complete
267*e4a36f41SAndroid Build Coastguard Worker */
get_avtab_allow_rule(char * out,size_t max_size,policydb_t * db,struct avtab_iter * avtab_i)268*e4a36f41SAndroid Build Coastguard Worker static int get_avtab_allow_rule(char *out, size_t max_size, policydb_t *db,
269*e4a36f41SAndroid Build Coastguard Worker struct avtab_iter *avtab_i)
270*e4a36f41SAndroid Build Coastguard Worker {
271*e4a36f41SAndroid Build Coastguard Worker size_t len;
272*e4a36f41SAndroid Build Coastguard Worker
273*e4a36f41SAndroid Build Coastguard Worker for (; avtab_i->i < avtab_i->avtab->nslot; (avtab_i->i)++) {
274*e4a36f41SAndroid Build Coastguard Worker if (avtab_i->cur == nullptr) {
275*e4a36f41SAndroid Build Coastguard Worker avtab_i->cur = avtab_i->avtab->htable[avtab_i->i];
276*e4a36f41SAndroid Build Coastguard Worker }
277*e4a36f41SAndroid Build Coastguard Worker for (; avtab_i->cur; avtab_i->cur = (avtab_i->cur)->next) {
278*e4a36f41SAndroid Build Coastguard Worker if (!((avtab_i->cur)->key.specified & AVTAB_ALLOWED)) continue;
279*e4a36f41SAndroid Build Coastguard Worker
280*e4a36f41SAndroid Build Coastguard Worker len = snprintf(out, max_size, "allow,%s,%s,%s,%s",
281*e4a36f41SAndroid Build Coastguard Worker db->p_type_val_to_name[(avtab_i->cur)->key.source_type - 1],
282*e4a36f41SAndroid Build Coastguard Worker db->p_type_val_to_name[(avtab_i->cur)->key.target_type - 1],
283*e4a36f41SAndroid Build Coastguard Worker db->p_class_val_to_name[(avtab_i->cur)->key.target_class - 1],
284*e4a36f41SAndroid Build Coastguard Worker sepol_av_to_string(db, (avtab_i->cur)->key.target_class, (avtab_i->cur)->datum.data));
285*e4a36f41SAndroid Build Coastguard Worker avtab_i->cur = (avtab_i->cur)->next;
286*e4a36f41SAndroid Build Coastguard Worker if (!(avtab_i->cur))
287*e4a36f41SAndroid Build Coastguard Worker (avtab_i->i)++;
288*e4a36f41SAndroid Build Coastguard Worker if (len >= max_size) {
289*e4a36f41SAndroid Build Coastguard Worker std::cerr << "Allow rule exceeds buffer size." << std::endl;
290*e4a36f41SAndroid Build Coastguard Worker return -1;
291*e4a36f41SAndroid Build Coastguard Worker }
292*e4a36f41SAndroid Build Coastguard Worker return 0;
293*e4a36f41SAndroid Build Coastguard Worker }
294*e4a36f41SAndroid Build Coastguard Worker avtab_i->cur = nullptr;
295*e4a36f41SAndroid Build Coastguard Worker }
296*e4a36f41SAndroid Build Coastguard Worker
297*e4a36f41SAndroid Build Coastguard Worker return 1;
298*e4a36f41SAndroid Build Coastguard Worker }
299*e4a36f41SAndroid Build Coastguard Worker
get_allow_rule(char * out,size_t len,void * policydbp,void * avtab_iterp)300*e4a36f41SAndroid Build Coastguard Worker int get_allow_rule(char *out, size_t len, void *policydbp, void *avtab_iterp)
301*e4a36f41SAndroid Build Coastguard Worker {
302*e4a36f41SAndroid Build Coastguard Worker policydb_t *db = static_cast<policydb_t *>(policydbp);
303*e4a36f41SAndroid Build Coastguard Worker struct avtab_iter *avtab_i = static_cast<struct avtab_iter *>(avtab_iterp);
304*e4a36f41SAndroid Build Coastguard Worker
305*e4a36f41SAndroid Build Coastguard Worker return get_avtab_allow_rule(out, len, db, avtab_i);
306*e4a36f41SAndroid Build Coastguard Worker }
307*e4a36f41SAndroid Build Coastguard Worker
init_avtab_common(avtab_t * in)308*e4a36f41SAndroid Build Coastguard Worker static avtab_iter *init_avtab_common(avtab_t *in)
309*e4a36f41SAndroid Build Coastguard Worker {
310*e4a36f41SAndroid Build Coastguard Worker struct avtab_iter *out = (struct avtab_iter *)
311*e4a36f41SAndroid Build Coastguard Worker calloc(1, sizeof(struct avtab_iter));
312*e4a36f41SAndroid Build Coastguard Worker if (!out) {
313*e4a36f41SAndroid Build Coastguard Worker std::cerr << "Failed to allocate avtab iterator" << std::endl;
314*e4a36f41SAndroid Build Coastguard Worker return nullptr;
315*e4a36f41SAndroid Build Coastguard Worker }
316*e4a36f41SAndroid Build Coastguard Worker
317*e4a36f41SAndroid Build Coastguard Worker out->avtab = in;
318*e4a36f41SAndroid Build Coastguard Worker return out;
319*e4a36f41SAndroid Build Coastguard Worker }
320*e4a36f41SAndroid Build Coastguard Worker
init_avtab(void * policydbp)321*e4a36f41SAndroid Build Coastguard Worker void *init_avtab(void *policydbp)
322*e4a36f41SAndroid Build Coastguard Worker {
323*e4a36f41SAndroid Build Coastguard Worker policydb_t *p = static_cast<policydb_t *>(policydbp);
324*e4a36f41SAndroid Build Coastguard Worker return static_cast<void *>(init_avtab_common(&p->te_avtab));
325*e4a36f41SAndroid Build Coastguard Worker }
326*e4a36f41SAndroid Build Coastguard Worker
init_cond_avtab(void * policydbp)327*e4a36f41SAndroid Build Coastguard Worker void *init_cond_avtab(void *policydbp)
328*e4a36f41SAndroid Build Coastguard Worker {
329*e4a36f41SAndroid Build Coastguard Worker policydb_t *p = static_cast<policydb_t *>(policydbp);
330*e4a36f41SAndroid Build Coastguard Worker return static_cast<void *>(init_avtab_common(&p->te_cond_avtab));
331*e4a36f41SAndroid Build Coastguard Worker }
332*e4a36f41SAndroid Build Coastguard Worker
destroy_avtab(void * avtab_iterp)333*e4a36f41SAndroid Build Coastguard Worker void destroy_avtab(void *avtab_iterp)
334*e4a36f41SAndroid Build Coastguard Worker {
335*e4a36f41SAndroid Build Coastguard Worker struct avtab_iter *avtab_i = static_cast<struct avtab_iter *>(avtab_iterp);
336*e4a36f41SAndroid Build Coastguard Worker free(avtab_i);
337*e4a36f41SAndroid Build Coastguard Worker }
338*e4a36f41SAndroid Build Coastguard Worker
339*e4a36f41SAndroid Build Coastguard Worker /*
340*e4a36f41SAndroid Build Coastguard Worker * <sepol/policydb/expand.h->conditional.h> uses 'bool' as a variable name
341*e4a36f41SAndroid Build Coastguard Worker * inside extern "C" { .. } construct, which clang doesn't like.
342*e4a36f41SAndroid Build Coastguard Worker * So, declare the function we need from expand.h ourselves.
343*e4a36f41SAndroid Build Coastguard Worker */
344*e4a36f41SAndroid Build Coastguard Worker extern "C" int expand_avtab(policydb_t *p, avtab_t *a, avtab_t *expa);
345*e4a36f41SAndroid Build Coastguard Worker
init_expanded_avtab_common(avtab_t * in,policydb_t * p)346*e4a36f41SAndroid Build Coastguard Worker static avtab_iter *init_expanded_avtab_common(avtab_t *in, policydb_t *p)
347*e4a36f41SAndroid Build Coastguard Worker {
348*e4a36f41SAndroid Build Coastguard Worker struct avtab_iter *out = (struct avtab_iter *)
349*e4a36f41SAndroid Build Coastguard Worker calloc(1, sizeof(struct avtab_iter));
350*e4a36f41SAndroid Build Coastguard Worker if (!out) {
351*e4a36f41SAndroid Build Coastguard Worker std::cerr << "Failed to allocate avtab iterator" << std::endl;
352*e4a36f41SAndroid Build Coastguard Worker return nullptr;
353*e4a36f41SAndroid Build Coastguard Worker }
354*e4a36f41SAndroid Build Coastguard Worker
355*e4a36f41SAndroid Build Coastguard Worker avtab_t *avtab = (avtab_t *) calloc(1, sizeof(avtab_t));
356*e4a36f41SAndroid Build Coastguard Worker
357*e4a36f41SAndroid Build Coastguard Worker if (!avtab) {
358*e4a36f41SAndroid Build Coastguard Worker std::cerr << "Failed to allocate avtab" << std::endl;
359*e4a36f41SAndroid Build Coastguard Worker free(out);
360*e4a36f41SAndroid Build Coastguard Worker return nullptr;
361*e4a36f41SAndroid Build Coastguard Worker }
362*e4a36f41SAndroid Build Coastguard Worker
363*e4a36f41SAndroid Build Coastguard Worker out->avtab = avtab;
364*e4a36f41SAndroid Build Coastguard Worker if (avtab_init(out->avtab)) {
365*e4a36f41SAndroid Build Coastguard Worker std::cerr << "Failed to initialize avtab" << std::endl;
366*e4a36f41SAndroid Build Coastguard Worker free(avtab);
367*e4a36f41SAndroid Build Coastguard Worker free(out);
368*e4a36f41SAndroid Build Coastguard Worker return nullptr;
369*e4a36f41SAndroid Build Coastguard Worker }
370*e4a36f41SAndroid Build Coastguard Worker
371*e4a36f41SAndroid Build Coastguard Worker if (expand_avtab(p, in, out->avtab)) {
372*e4a36f41SAndroid Build Coastguard Worker std::cerr << "Failed to expand avtab" << std::endl;
373*e4a36f41SAndroid Build Coastguard Worker free(avtab);
374*e4a36f41SAndroid Build Coastguard Worker free(out);
375*e4a36f41SAndroid Build Coastguard Worker return nullptr;
376*e4a36f41SAndroid Build Coastguard Worker }
377*e4a36f41SAndroid Build Coastguard Worker return out;
378*e4a36f41SAndroid Build Coastguard Worker }
379*e4a36f41SAndroid Build Coastguard Worker
init_expanded_avtab(void * policydbp)380*e4a36f41SAndroid Build Coastguard Worker void *init_expanded_avtab(void *policydbp)
381*e4a36f41SAndroid Build Coastguard Worker {
382*e4a36f41SAndroid Build Coastguard Worker policydb_t *p = static_cast<policydb_t *>(policydbp);
383*e4a36f41SAndroid Build Coastguard Worker return static_cast<void *>(init_expanded_avtab_common(&p->te_avtab, p));
384*e4a36f41SAndroid Build Coastguard Worker }
385*e4a36f41SAndroid Build Coastguard Worker
init_expanded_cond_avtab(void * policydbp)386*e4a36f41SAndroid Build Coastguard Worker void *init_expanded_cond_avtab(void *policydbp)
387*e4a36f41SAndroid Build Coastguard Worker {
388*e4a36f41SAndroid Build Coastguard Worker policydb_t *p = static_cast<policydb_t *>(policydbp);
389*e4a36f41SAndroid Build Coastguard Worker return static_cast<void *>(init_expanded_avtab_common(&p->te_cond_avtab, p));
390*e4a36f41SAndroid Build Coastguard Worker }
391*e4a36f41SAndroid Build Coastguard Worker
destroy_expanded_avtab(void * avtab_iterp)392*e4a36f41SAndroid Build Coastguard Worker void destroy_expanded_avtab(void *avtab_iterp)
393*e4a36f41SAndroid Build Coastguard Worker {
394*e4a36f41SAndroid Build Coastguard Worker struct avtab_iter *avtab_i = static_cast<struct avtab_iter *>(avtab_iterp);
395*e4a36f41SAndroid Build Coastguard Worker avtab_destroy(avtab_i->avtab);
396*e4a36f41SAndroid Build Coastguard Worker free(avtab_i->avtab);
397*e4a36f41SAndroid Build Coastguard Worker free(avtab_i);
398*e4a36f41SAndroid Build Coastguard Worker }
399*e4a36f41SAndroid Build Coastguard Worker
destroy_policy(void * policydbp)400*e4a36f41SAndroid Build Coastguard Worker void destroy_policy(void *policydbp)
401*e4a36f41SAndroid Build Coastguard Worker {
402*e4a36f41SAndroid Build Coastguard Worker policydb_t *p = static_cast<policydb_t *>(policydbp);
403*e4a36f41SAndroid Build Coastguard Worker policydb_destroy(p);
404*e4a36f41SAndroid Build Coastguard Worker }
405