xref: /aosp_15_r20/system/sepolicy/tests/sepol_wrap.cpp (revision e4a36f4174b17bbab9dc043f4a65dc8d87377290)
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