xref: /aosp_15_r20/external/selinux/libsepol/src/policydb.c (revision 2d543d20722ada2425b5bdab9d0d1d29470e7bba)
1*2d543d20SAndroid Build Coastguard Worker 
2*2d543d20SAndroid Build Coastguard Worker /* Author : Stephen Smalley, <[email protected]> */
3*2d543d20SAndroid Build Coastguard Worker 
4*2d543d20SAndroid Build Coastguard Worker /*
5*2d543d20SAndroid Build Coastguard Worker  * Updated: Trusted Computer Solutions, Inc. <[email protected]>
6*2d543d20SAndroid Build Coastguard Worker  *
7*2d543d20SAndroid Build Coastguard Worker  *	Support for enhanced MLS infrastructure.
8*2d543d20SAndroid Build Coastguard Worker  *
9*2d543d20SAndroid Build Coastguard Worker  * Updated: Frank Mayer <[email protected]> and Karl MacMillan <[email protected]>
10*2d543d20SAndroid Build Coastguard Worker  *
11*2d543d20SAndroid Build Coastguard Worker  * 	Added conditional policy language extensions
12*2d543d20SAndroid Build Coastguard Worker  *
13*2d543d20SAndroid Build Coastguard Worker  * Updated: Red Hat, Inc.  James Morris <[email protected]>
14*2d543d20SAndroid Build Coastguard Worker  *      Fine-grained netlink support
15*2d543d20SAndroid Build Coastguard Worker  *      IPv6 support
16*2d543d20SAndroid Build Coastguard Worker  *      Code cleanup
17*2d543d20SAndroid Build Coastguard Worker  *
18*2d543d20SAndroid Build Coastguard Worker  * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc.
19*2d543d20SAndroid Build Coastguard Worker  * Copyright (C) 2003 - 2005 Tresys Technology, LLC
20*2d543d20SAndroid Build Coastguard Worker  * Copyright (C) 2003 - 2007 Red Hat, Inc.
21*2d543d20SAndroid Build Coastguard Worker  * Copyright (C) 2017 Mellanox Technologies Inc.
22*2d543d20SAndroid Build Coastguard Worker  *
23*2d543d20SAndroid Build Coastguard Worker  *  This library is free software; you can redistribute it and/or
24*2d543d20SAndroid Build Coastguard Worker  *  modify it under the terms of the GNU Lesser General Public
25*2d543d20SAndroid Build Coastguard Worker  *  License as published by the Free Software Foundation; either
26*2d543d20SAndroid Build Coastguard Worker  *  version 2.1 of the License, or (at your option) any later version.
27*2d543d20SAndroid Build Coastguard Worker  *
28*2d543d20SAndroid Build Coastguard Worker  *  This library is distributed in the hope that it will be useful,
29*2d543d20SAndroid Build Coastguard Worker  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
30*2d543d20SAndroid Build Coastguard Worker  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
31*2d543d20SAndroid Build Coastguard Worker  *  Lesser General Public License for more details.
32*2d543d20SAndroid Build Coastguard Worker  *
33*2d543d20SAndroid Build Coastguard Worker  *  You should have received a copy of the GNU Lesser General Public
34*2d543d20SAndroid Build Coastguard Worker  *  License along with this library; if not, write to the Free Software
35*2d543d20SAndroid Build Coastguard Worker  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
36*2d543d20SAndroid Build Coastguard Worker  */
37*2d543d20SAndroid Build Coastguard Worker 
38*2d543d20SAndroid Build Coastguard Worker /* FLASK */
39*2d543d20SAndroid Build Coastguard Worker 
40*2d543d20SAndroid Build Coastguard Worker /*
41*2d543d20SAndroid Build Coastguard Worker  * Implementation of the policy database.
42*2d543d20SAndroid Build Coastguard Worker  */
43*2d543d20SAndroid Build Coastguard Worker 
44*2d543d20SAndroid Build Coastguard Worker #include <assert.h>
45*2d543d20SAndroid Build Coastguard Worker #include <stdlib.h>
46*2d543d20SAndroid Build Coastguard Worker 
47*2d543d20SAndroid Build Coastguard Worker #include <sepol/policydb/policydb.h>
48*2d543d20SAndroid Build Coastguard Worker #include <sepol/policydb/expand.h>
49*2d543d20SAndroid Build Coastguard Worker #include <sepol/policydb/conditional.h>
50*2d543d20SAndroid Build Coastguard Worker #include <sepol/policydb/avrule_block.h>
51*2d543d20SAndroid Build Coastguard Worker #include <sepol/policydb/util.h>
52*2d543d20SAndroid Build Coastguard Worker 
53*2d543d20SAndroid Build Coastguard Worker #include "kernel_to_common.h"
54*2d543d20SAndroid Build Coastguard Worker #include "private.h"
55*2d543d20SAndroid Build Coastguard Worker #include "debug.h"
56*2d543d20SAndroid Build Coastguard Worker #include "mls.h"
57*2d543d20SAndroid Build Coastguard Worker #include "policydb_validate.h"
58*2d543d20SAndroid Build Coastguard Worker 
59*2d543d20SAndroid Build Coastguard Worker #define POLICYDB_TARGET_SZ   ARRAY_SIZE(policydb_target_strings)
60*2d543d20SAndroid Build Coastguard Worker const char * const policydb_target_strings[] = { POLICYDB_STRING, POLICYDB_XEN_STRING };
61*2d543d20SAndroid Build Coastguard Worker 
62*2d543d20SAndroid Build Coastguard Worker /* These need to be updated if SYM_NUM or OCON_NUM changes */
63*2d543d20SAndroid Build Coastguard Worker static const struct policydb_compat_info policydb_compat[] = {
64*2d543d20SAndroid Build Coastguard Worker 	{
65*2d543d20SAndroid Build Coastguard Worker 	 .type = POLICY_KERN,
66*2d543d20SAndroid Build Coastguard Worker 	 .version = POLICYDB_VERSION_BOUNDARY,
67*2d543d20SAndroid Build Coastguard Worker 	 .sym_num = SYM_NUM,
68*2d543d20SAndroid Build Coastguard Worker 	 .ocon_num = OCON_XEN_PCIDEVICE + 1,
69*2d543d20SAndroid Build Coastguard Worker 	 .target_platform = SEPOL_TARGET_XEN,
70*2d543d20SAndroid Build Coastguard Worker 	 },
71*2d543d20SAndroid Build Coastguard Worker 	{
72*2d543d20SAndroid Build Coastguard Worker 	 .type = POLICY_KERN,
73*2d543d20SAndroid Build Coastguard Worker 	 .version = POLICYDB_VERSION_XEN_DEVICETREE,
74*2d543d20SAndroid Build Coastguard Worker 	 .sym_num = SYM_NUM,
75*2d543d20SAndroid Build Coastguard Worker 	 .ocon_num = OCON_XEN_DEVICETREE + 1,
76*2d543d20SAndroid Build Coastguard Worker 	 .target_platform = SEPOL_TARGET_XEN,
77*2d543d20SAndroid Build Coastguard Worker 	 },
78*2d543d20SAndroid Build Coastguard Worker 	{
79*2d543d20SAndroid Build Coastguard Worker 	 .type = POLICY_KERN,
80*2d543d20SAndroid Build Coastguard Worker 	 .version = POLICYDB_VERSION_BASE,
81*2d543d20SAndroid Build Coastguard Worker 	 .sym_num = SYM_NUM - 3,
82*2d543d20SAndroid Build Coastguard Worker 	 .ocon_num = OCON_FSUSE + 1,
83*2d543d20SAndroid Build Coastguard Worker 	 .target_platform = SEPOL_TARGET_SELINUX,
84*2d543d20SAndroid Build Coastguard Worker 	 },
85*2d543d20SAndroid Build Coastguard Worker 	{
86*2d543d20SAndroid Build Coastguard Worker 	 .type = POLICY_KERN,
87*2d543d20SAndroid Build Coastguard Worker 	 .version = POLICYDB_VERSION_BOOL,
88*2d543d20SAndroid Build Coastguard Worker 	 .sym_num = SYM_NUM - 2,
89*2d543d20SAndroid Build Coastguard Worker 	 .ocon_num = OCON_FSUSE + 1,
90*2d543d20SAndroid Build Coastguard Worker 	 .target_platform = SEPOL_TARGET_SELINUX,
91*2d543d20SAndroid Build Coastguard Worker 	 },
92*2d543d20SAndroid Build Coastguard Worker 	{
93*2d543d20SAndroid Build Coastguard Worker 	 .type = POLICY_KERN,
94*2d543d20SAndroid Build Coastguard Worker 	 .version = POLICYDB_VERSION_IPV6,
95*2d543d20SAndroid Build Coastguard Worker 	 .sym_num = SYM_NUM - 2,
96*2d543d20SAndroid Build Coastguard Worker 	 .ocon_num = OCON_NODE6 + 1,
97*2d543d20SAndroid Build Coastguard Worker 	 .target_platform = SEPOL_TARGET_SELINUX,
98*2d543d20SAndroid Build Coastguard Worker 	 },
99*2d543d20SAndroid Build Coastguard Worker 	{
100*2d543d20SAndroid Build Coastguard Worker 	 .type = POLICY_KERN,
101*2d543d20SAndroid Build Coastguard Worker 	 .version = POLICYDB_VERSION_NLCLASS,
102*2d543d20SAndroid Build Coastguard Worker 	 .sym_num = SYM_NUM - 2,
103*2d543d20SAndroid Build Coastguard Worker 	 .ocon_num = OCON_NODE6 + 1,
104*2d543d20SAndroid Build Coastguard Worker 	 .target_platform = SEPOL_TARGET_SELINUX,
105*2d543d20SAndroid Build Coastguard Worker 	 },
106*2d543d20SAndroid Build Coastguard Worker 	{
107*2d543d20SAndroid Build Coastguard Worker 	 .type = POLICY_KERN,
108*2d543d20SAndroid Build Coastguard Worker 	 .version = POLICYDB_VERSION_MLS,
109*2d543d20SAndroid Build Coastguard Worker 	 .sym_num = SYM_NUM,
110*2d543d20SAndroid Build Coastguard Worker 	 .ocon_num = OCON_NODE6 + 1,
111*2d543d20SAndroid Build Coastguard Worker 	 .target_platform = SEPOL_TARGET_SELINUX,
112*2d543d20SAndroid Build Coastguard Worker 	 },
113*2d543d20SAndroid Build Coastguard Worker 	{
114*2d543d20SAndroid Build Coastguard Worker 	 .type = POLICY_KERN,
115*2d543d20SAndroid Build Coastguard Worker 	 .version = POLICYDB_VERSION_AVTAB,
116*2d543d20SAndroid Build Coastguard Worker 	 .sym_num = SYM_NUM,
117*2d543d20SAndroid Build Coastguard Worker 	 .ocon_num = OCON_NODE6 + 1,
118*2d543d20SAndroid Build Coastguard Worker 	 .target_platform = SEPOL_TARGET_SELINUX,
119*2d543d20SAndroid Build Coastguard Worker 	 },
120*2d543d20SAndroid Build Coastguard Worker 	{
121*2d543d20SAndroid Build Coastguard Worker 	 .type = POLICY_KERN,
122*2d543d20SAndroid Build Coastguard Worker 	 .version = POLICYDB_VERSION_RANGETRANS,
123*2d543d20SAndroid Build Coastguard Worker 	 .sym_num = SYM_NUM,
124*2d543d20SAndroid Build Coastguard Worker 	 .ocon_num = OCON_NODE6 + 1,
125*2d543d20SAndroid Build Coastguard Worker 	 .target_platform = SEPOL_TARGET_SELINUX,
126*2d543d20SAndroid Build Coastguard Worker 	 },
127*2d543d20SAndroid Build Coastguard Worker 	{
128*2d543d20SAndroid Build Coastguard Worker 	 .type = POLICY_KERN,
129*2d543d20SAndroid Build Coastguard Worker 	 .version = POLICYDB_VERSION_POLCAP,
130*2d543d20SAndroid Build Coastguard Worker 	 .sym_num = SYM_NUM,
131*2d543d20SAndroid Build Coastguard Worker 	 .ocon_num = OCON_NODE6 + 1,
132*2d543d20SAndroid Build Coastguard Worker 	 .target_platform = SEPOL_TARGET_SELINUX,
133*2d543d20SAndroid Build Coastguard Worker 	 },
134*2d543d20SAndroid Build Coastguard Worker 	{
135*2d543d20SAndroid Build Coastguard Worker 	 .type = POLICY_KERN,
136*2d543d20SAndroid Build Coastguard Worker 	 .version = POLICYDB_VERSION_PERMISSIVE,
137*2d543d20SAndroid Build Coastguard Worker 	 .sym_num = SYM_NUM,
138*2d543d20SAndroid Build Coastguard Worker 	 .ocon_num = OCON_NODE6 + 1,
139*2d543d20SAndroid Build Coastguard Worker 	 .target_platform = SEPOL_TARGET_SELINUX,
140*2d543d20SAndroid Build Coastguard Worker 	 },
141*2d543d20SAndroid Build Coastguard Worker         {
142*2d543d20SAndroid Build Coastguard Worker 	 .type = POLICY_KERN,
143*2d543d20SAndroid Build Coastguard Worker 	 .version = POLICYDB_VERSION_BOUNDARY,
144*2d543d20SAndroid Build Coastguard Worker 	 .sym_num = SYM_NUM,
145*2d543d20SAndroid Build Coastguard Worker 	 .ocon_num = OCON_NODE6 + 1,
146*2d543d20SAndroid Build Coastguard Worker 	 .target_platform = SEPOL_TARGET_SELINUX,
147*2d543d20SAndroid Build Coastguard Worker 	},
148*2d543d20SAndroid Build Coastguard Worker 	{
149*2d543d20SAndroid Build Coastguard Worker 	 .type = POLICY_KERN,
150*2d543d20SAndroid Build Coastguard Worker 	 .version = POLICYDB_VERSION_FILENAME_TRANS,
151*2d543d20SAndroid Build Coastguard Worker 	 .sym_num = SYM_NUM,
152*2d543d20SAndroid Build Coastguard Worker 	 .ocon_num = OCON_NODE6 + 1,
153*2d543d20SAndroid Build Coastguard Worker 	 .target_platform = SEPOL_TARGET_SELINUX,
154*2d543d20SAndroid Build Coastguard Worker 	},
155*2d543d20SAndroid Build Coastguard Worker 	{
156*2d543d20SAndroid Build Coastguard Worker 	 .type = POLICY_KERN,
157*2d543d20SAndroid Build Coastguard Worker 	 .version = POLICYDB_VERSION_ROLETRANS,
158*2d543d20SAndroid Build Coastguard Worker 	 .sym_num = SYM_NUM,
159*2d543d20SAndroid Build Coastguard Worker 	 .ocon_num = OCON_NODE6 + 1,
160*2d543d20SAndroid Build Coastguard Worker 	 .target_platform = SEPOL_TARGET_SELINUX,
161*2d543d20SAndroid Build Coastguard Worker 	},
162*2d543d20SAndroid Build Coastguard Worker 	{
163*2d543d20SAndroid Build Coastguard Worker 	 .type = POLICY_KERN,
164*2d543d20SAndroid Build Coastguard Worker 	 .version = POLICYDB_VERSION_NEW_OBJECT_DEFAULTS,
165*2d543d20SAndroid Build Coastguard Worker 	 .sym_num = SYM_NUM,
166*2d543d20SAndroid Build Coastguard Worker 	 .ocon_num = OCON_NODE6 + 1,
167*2d543d20SAndroid Build Coastguard Worker 	 .target_platform = SEPOL_TARGET_SELINUX,
168*2d543d20SAndroid Build Coastguard Worker 	},
169*2d543d20SAndroid Build Coastguard Worker 	{
170*2d543d20SAndroid Build Coastguard Worker 	 .type = POLICY_KERN,
171*2d543d20SAndroid Build Coastguard Worker 	 .version = POLICYDB_VERSION_DEFAULT_TYPE,
172*2d543d20SAndroid Build Coastguard Worker 	 .sym_num = SYM_NUM,
173*2d543d20SAndroid Build Coastguard Worker 	 .ocon_num = OCON_NODE6 + 1,
174*2d543d20SAndroid Build Coastguard Worker 	 .target_platform = SEPOL_TARGET_SELINUX,
175*2d543d20SAndroid Build Coastguard Worker 	},
176*2d543d20SAndroid Build Coastguard Worker 	{
177*2d543d20SAndroid Build Coastguard Worker 	 .type = POLICY_KERN,
178*2d543d20SAndroid Build Coastguard Worker 	 .version = POLICYDB_VERSION_CONSTRAINT_NAMES,
179*2d543d20SAndroid Build Coastguard Worker 	 .sym_num = SYM_NUM,
180*2d543d20SAndroid Build Coastguard Worker 	 .ocon_num = OCON_NODE6 + 1,
181*2d543d20SAndroid Build Coastguard Worker 	 .target_platform = SEPOL_TARGET_SELINUX,
182*2d543d20SAndroid Build Coastguard Worker 	},
183*2d543d20SAndroid Build Coastguard Worker 	{
184*2d543d20SAndroid Build Coastguard Worker 	 .type = POLICY_KERN,
185*2d543d20SAndroid Build Coastguard Worker 	 .version = POLICYDB_VERSION_XPERMS_IOCTL,
186*2d543d20SAndroid Build Coastguard Worker 	 .sym_num = SYM_NUM,
187*2d543d20SAndroid Build Coastguard Worker 	 .ocon_num = OCON_NODE6 + 1,
188*2d543d20SAndroid Build Coastguard Worker 	 .target_platform = SEPOL_TARGET_SELINUX,
189*2d543d20SAndroid Build Coastguard Worker 	},
190*2d543d20SAndroid Build Coastguard Worker 	{
191*2d543d20SAndroid Build Coastguard Worker 	 .type = POLICY_KERN,
192*2d543d20SAndroid Build Coastguard Worker 	 .version = POLICYDB_VERSION_INFINIBAND,
193*2d543d20SAndroid Build Coastguard Worker 	 .sym_num = SYM_NUM,
194*2d543d20SAndroid Build Coastguard Worker 	 .ocon_num = OCON_IBENDPORT + 1,
195*2d543d20SAndroid Build Coastguard Worker 	 .target_platform = SEPOL_TARGET_SELINUX,
196*2d543d20SAndroid Build Coastguard Worker 	},
197*2d543d20SAndroid Build Coastguard Worker 	{
198*2d543d20SAndroid Build Coastguard Worker 	 .type = POLICY_KERN,
199*2d543d20SAndroid Build Coastguard Worker 	 .version = POLICYDB_VERSION_GLBLUB,
200*2d543d20SAndroid Build Coastguard Worker 	 .sym_num = SYM_NUM,
201*2d543d20SAndroid Build Coastguard Worker 	 .ocon_num = OCON_IBENDPORT + 1,
202*2d543d20SAndroid Build Coastguard Worker 	 .target_platform = SEPOL_TARGET_SELINUX,
203*2d543d20SAndroid Build Coastguard Worker 	},
204*2d543d20SAndroid Build Coastguard Worker 	{
205*2d543d20SAndroid Build Coastguard Worker 	 .type = POLICY_KERN,
206*2d543d20SAndroid Build Coastguard Worker 	 .version = POLICYDB_VERSION_COMP_FTRANS,
207*2d543d20SAndroid Build Coastguard Worker 	 .sym_num = SYM_NUM,
208*2d543d20SAndroid Build Coastguard Worker 	 .ocon_num = OCON_IBENDPORT + 1,
209*2d543d20SAndroid Build Coastguard Worker 	 .target_platform = SEPOL_TARGET_SELINUX,
210*2d543d20SAndroid Build Coastguard Worker 	},
211*2d543d20SAndroid Build Coastguard Worker 	{
212*2d543d20SAndroid Build Coastguard Worker 	 .type = POLICY_BASE,
213*2d543d20SAndroid Build Coastguard Worker 	 .version = MOD_POLICYDB_VERSION_BASE,
214*2d543d20SAndroid Build Coastguard Worker 	 .sym_num = SYM_NUM,
215*2d543d20SAndroid Build Coastguard Worker 	 .ocon_num = OCON_NODE6 + 1,
216*2d543d20SAndroid Build Coastguard Worker 	 .target_platform = SEPOL_TARGET_SELINUX,
217*2d543d20SAndroid Build Coastguard Worker 	 },
218*2d543d20SAndroid Build Coastguard Worker 	{
219*2d543d20SAndroid Build Coastguard Worker 	 .type = POLICY_BASE,
220*2d543d20SAndroid Build Coastguard Worker 	 .version = MOD_POLICYDB_VERSION_MLS,
221*2d543d20SAndroid Build Coastguard Worker 	 .sym_num = SYM_NUM,
222*2d543d20SAndroid Build Coastguard Worker 	 .ocon_num = OCON_NODE6 + 1,
223*2d543d20SAndroid Build Coastguard Worker 	 .target_platform = SEPOL_TARGET_SELINUX,
224*2d543d20SAndroid Build Coastguard Worker 	 },
225*2d543d20SAndroid Build Coastguard Worker 	{
226*2d543d20SAndroid Build Coastguard Worker 	 .type = POLICY_BASE,
227*2d543d20SAndroid Build Coastguard Worker 	 .version = MOD_POLICYDB_VERSION_MLS_USERS,
228*2d543d20SAndroid Build Coastguard Worker 	 .sym_num = SYM_NUM,
229*2d543d20SAndroid Build Coastguard Worker 	 .ocon_num = OCON_NODE6 + 1,
230*2d543d20SAndroid Build Coastguard Worker 	 .target_platform = SEPOL_TARGET_SELINUX,
231*2d543d20SAndroid Build Coastguard Worker 	 },
232*2d543d20SAndroid Build Coastguard Worker 	{
233*2d543d20SAndroid Build Coastguard Worker 	 .type = POLICY_BASE,
234*2d543d20SAndroid Build Coastguard Worker 	 .version = MOD_POLICYDB_VERSION_POLCAP,
235*2d543d20SAndroid Build Coastguard Worker 	 .sym_num = SYM_NUM,
236*2d543d20SAndroid Build Coastguard Worker 	 .ocon_num = OCON_NODE6 + 1,
237*2d543d20SAndroid Build Coastguard Worker 	 .target_platform = SEPOL_TARGET_SELINUX,
238*2d543d20SAndroid Build Coastguard Worker 	 },
239*2d543d20SAndroid Build Coastguard Worker 	{
240*2d543d20SAndroid Build Coastguard Worker 	 .type = POLICY_BASE,
241*2d543d20SAndroid Build Coastguard Worker 	 .version = MOD_POLICYDB_VERSION_PERMISSIVE,
242*2d543d20SAndroid Build Coastguard Worker 	 .sym_num = SYM_NUM,
243*2d543d20SAndroid Build Coastguard Worker 	 .ocon_num = OCON_NODE6 + 1,
244*2d543d20SAndroid Build Coastguard Worker 	 .target_platform = SEPOL_TARGET_SELINUX,
245*2d543d20SAndroid Build Coastguard Worker 	 },
246*2d543d20SAndroid Build Coastguard Worker 	{
247*2d543d20SAndroid Build Coastguard Worker 	 .type = POLICY_BASE,
248*2d543d20SAndroid Build Coastguard Worker 	 .version = MOD_POLICYDB_VERSION_BOUNDARY,
249*2d543d20SAndroid Build Coastguard Worker 	 .sym_num = SYM_NUM,
250*2d543d20SAndroid Build Coastguard Worker 	 .ocon_num = OCON_NODE6 + 1,
251*2d543d20SAndroid Build Coastguard Worker 	 .target_platform = SEPOL_TARGET_SELINUX,
252*2d543d20SAndroid Build Coastguard Worker 	},
253*2d543d20SAndroid Build Coastguard Worker 	{
254*2d543d20SAndroid Build Coastguard Worker 	 .type = POLICY_BASE,
255*2d543d20SAndroid Build Coastguard Worker 	 .version = MOD_POLICYDB_VERSION_BOUNDARY_ALIAS,
256*2d543d20SAndroid Build Coastguard Worker 	 .sym_num = SYM_NUM,
257*2d543d20SAndroid Build Coastguard Worker 	 .ocon_num = OCON_NODE6 + 1,
258*2d543d20SAndroid Build Coastguard Worker 	 .target_platform = SEPOL_TARGET_SELINUX,
259*2d543d20SAndroid Build Coastguard Worker 	},
260*2d543d20SAndroid Build Coastguard Worker 	{
261*2d543d20SAndroid Build Coastguard Worker 	 .type = POLICY_BASE,
262*2d543d20SAndroid Build Coastguard Worker 	 .version = MOD_POLICYDB_VERSION_FILENAME_TRANS,
263*2d543d20SAndroid Build Coastguard Worker 	 .sym_num = SYM_NUM,
264*2d543d20SAndroid Build Coastguard Worker 	 .ocon_num = OCON_NODE6 + 1,
265*2d543d20SAndroid Build Coastguard Worker 	 .target_platform = SEPOL_TARGET_SELINUX,
266*2d543d20SAndroid Build Coastguard Worker 	},
267*2d543d20SAndroid Build Coastguard Worker 	{
268*2d543d20SAndroid Build Coastguard Worker 	 .type = POLICY_BASE,
269*2d543d20SAndroid Build Coastguard Worker 	 .version = MOD_POLICYDB_VERSION_ROLETRANS,
270*2d543d20SAndroid Build Coastguard Worker 	 .sym_num = SYM_NUM,
271*2d543d20SAndroid Build Coastguard Worker 	 .ocon_num = OCON_NODE6 + 1,
272*2d543d20SAndroid Build Coastguard Worker 	 .target_platform = SEPOL_TARGET_SELINUX,
273*2d543d20SAndroid Build Coastguard Worker 	},
274*2d543d20SAndroid Build Coastguard Worker 	{
275*2d543d20SAndroid Build Coastguard Worker 	 .type = POLICY_BASE,
276*2d543d20SAndroid Build Coastguard Worker 	 .version = MOD_POLICYDB_VERSION_ROLEATTRIB,
277*2d543d20SAndroid Build Coastguard Worker 	 .sym_num = SYM_NUM,
278*2d543d20SAndroid Build Coastguard Worker 	 .ocon_num = OCON_NODE6 + 1,
279*2d543d20SAndroid Build Coastguard Worker 	 .target_platform = SEPOL_TARGET_SELINUX,
280*2d543d20SAndroid Build Coastguard Worker 	},
281*2d543d20SAndroid Build Coastguard Worker 	{
282*2d543d20SAndroid Build Coastguard Worker 	 .type = POLICY_BASE,
283*2d543d20SAndroid Build Coastguard Worker 	 .version = MOD_POLICYDB_VERSION_TUNABLE_SEP,
284*2d543d20SAndroid Build Coastguard Worker 	 .sym_num = SYM_NUM,
285*2d543d20SAndroid Build Coastguard Worker 	 .ocon_num = OCON_NODE6 + 1,
286*2d543d20SAndroid Build Coastguard Worker 	 .target_platform = SEPOL_TARGET_SELINUX,
287*2d543d20SAndroid Build Coastguard Worker 	},
288*2d543d20SAndroid Build Coastguard Worker 	{
289*2d543d20SAndroid Build Coastguard Worker 	 .type = POLICY_BASE,
290*2d543d20SAndroid Build Coastguard Worker 	 .version = MOD_POLICYDB_VERSION_NEW_OBJECT_DEFAULTS,
291*2d543d20SAndroid Build Coastguard Worker 	 .sym_num = SYM_NUM,
292*2d543d20SAndroid Build Coastguard Worker 	 .ocon_num = OCON_NODE6 + 1,
293*2d543d20SAndroid Build Coastguard Worker 	 .target_platform = SEPOL_TARGET_SELINUX,
294*2d543d20SAndroid Build Coastguard Worker 	},
295*2d543d20SAndroid Build Coastguard Worker 	{
296*2d543d20SAndroid Build Coastguard Worker 	 .type = POLICY_BASE,
297*2d543d20SAndroid Build Coastguard Worker 	 .version = MOD_POLICYDB_VERSION_DEFAULT_TYPE,
298*2d543d20SAndroid Build Coastguard Worker 	 .sym_num = SYM_NUM,
299*2d543d20SAndroid Build Coastguard Worker 	 .ocon_num = OCON_NODE6 + 1,
300*2d543d20SAndroid Build Coastguard Worker 	 .target_platform = SEPOL_TARGET_SELINUX,
301*2d543d20SAndroid Build Coastguard Worker 	},
302*2d543d20SAndroid Build Coastguard Worker 	{
303*2d543d20SAndroid Build Coastguard Worker 	 .type = POLICY_BASE,
304*2d543d20SAndroid Build Coastguard Worker 	 .version = MOD_POLICYDB_VERSION_CONSTRAINT_NAMES,
305*2d543d20SAndroid Build Coastguard Worker 	 .sym_num = SYM_NUM,
306*2d543d20SAndroid Build Coastguard Worker 	 .ocon_num = OCON_NODE6 + 1,
307*2d543d20SAndroid Build Coastguard Worker 	 .target_platform = SEPOL_TARGET_SELINUX,
308*2d543d20SAndroid Build Coastguard Worker 	},
309*2d543d20SAndroid Build Coastguard Worker 	{
310*2d543d20SAndroid Build Coastguard Worker 	 .type = POLICY_BASE,
311*2d543d20SAndroid Build Coastguard Worker 	 .version = MOD_POLICYDB_VERSION_XPERMS_IOCTL,
312*2d543d20SAndroid Build Coastguard Worker 	 .sym_num = SYM_NUM,
313*2d543d20SAndroid Build Coastguard Worker 	 .ocon_num = OCON_NODE6 + 1,
314*2d543d20SAndroid Build Coastguard Worker 	 .target_platform = SEPOL_TARGET_SELINUX,
315*2d543d20SAndroid Build Coastguard Worker 	},
316*2d543d20SAndroid Build Coastguard Worker 	{
317*2d543d20SAndroid Build Coastguard Worker 	 .type = POLICY_BASE,
318*2d543d20SAndroid Build Coastguard Worker 	 .version = MOD_POLICYDB_VERSION_INFINIBAND,
319*2d543d20SAndroid Build Coastguard Worker 	 .sym_num = SYM_NUM,
320*2d543d20SAndroid Build Coastguard Worker 	 .ocon_num = OCON_IBENDPORT + 1,
321*2d543d20SAndroid Build Coastguard Worker 	 .target_platform = SEPOL_TARGET_SELINUX,
322*2d543d20SAndroid Build Coastguard Worker 	},
323*2d543d20SAndroid Build Coastguard Worker 	{
324*2d543d20SAndroid Build Coastguard Worker 	 .type = POLICY_BASE,
325*2d543d20SAndroid Build Coastguard Worker 	 .version = MOD_POLICYDB_VERSION_GLBLUB,
326*2d543d20SAndroid Build Coastguard Worker 	 .sym_num = SYM_NUM,
327*2d543d20SAndroid Build Coastguard Worker 	 .ocon_num = OCON_IBENDPORT + 1,
328*2d543d20SAndroid Build Coastguard Worker 	 .target_platform = SEPOL_TARGET_SELINUX,
329*2d543d20SAndroid Build Coastguard Worker 	},
330*2d543d20SAndroid Build Coastguard Worker 	{
331*2d543d20SAndroid Build Coastguard Worker 	 .type = POLICY_BASE,
332*2d543d20SAndroid Build Coastguard Worker 	 .version = MOD_POLICYDB_VERSION_SELF_TYPETRANS,
333*2d543d20SAndroid Build Coastguard Worker 	 .sym_num = SYM_NUM,
334*2d543d20SAndroid Build Coastguard Worker 	 .ocon_num = OCON_IBENDPORT + 1,
335*2d543d20SAndroid Build Coastguard Worker 	 .target_platform = SEPOL_TARGET_SELINUX,
336*2d543d20SAndroid Build Coastguard Worker 	},
337*2d543d20SAndroid Build Coastguard Worker 	{
338*2d543d20SAndroid Build Coastguard Worker 	 .type = POLICY_MOD,
339*2d543d20SAndroid Build Coastguard Worker 	 .version = MOD_POLICYDB_VERSION_BASE,
340*2d543d20SAndroid Build Coastguard Worker 	 .sym_num = SYM_NUM,
341*2d543d20SAndroid Build Coastguard Worker 	 .ocon_num = 0,
342*2d543d20SAndroid Build Coastguard Worker 	 .target_platform = SEPOL_TARGET_SELINUX,
343*2d543d20SAndroid Build Coastguard Worker 	 },
344*2d543d20SAndroid Build Coastguard Worker 	{
345*2d543d20SAndroid Build Coastguard Worker 	 .type = POLICY_MOD,
346*2d543d20SAndroid Build Coastguard Worker 	 .version = MOD_POLICYDB_VERSION_MLS,
347*2d543d20SAndroid Build Coastguard Worker 	 .sym_num = SYM_NUM,
348*2d543d20SAndroid Build Coastguard Worker 	 .ocon_num = 0,
349*2d543d20SAndroid Build Coastguard Worker 	 .target_platform = SEPOL_TARGET_SELINUX,
350*2d543d20SAndroid Build Coastguard Worker 	 },
351*2d543d20SAndroid Build Coastguard Worker 	{
352*2d543d20SAndroid Build Coastguard Worker 	 .type = POLICY_MOD,
353*2d543d20SAndroid Build Coastguard Worker 	 .version = MOD_POLICYDB_VERSION_MLS_USERS,
354*2d543d20SAndroid Build Coastguard Worker 	 .sym_num = SYM_NUM,
355*2d543d20SAndroid Build Coastguard Worker 	 .ocon_num = 0,
356*2d543d20SAndroid Build Coastguard Worker 	 .target_platform = SEPOL_TARGET_SELINUX,
357*2d543d20SAndroid Build Coastguard Worker 	 },
358*2d543d20SAndroid Build Coastguard Worker 	{
359*2d543d20SAndroid Build Coastguard Worker 	 .type = POLICY_MOD,
360*2d543d20SAndroid Build Coastguard Worker 	 .version = MOD_POLICYDB_VERSION_POLCAP,
361*2d543d20SAndroid Build Coastguard Worker 	 .sym_num = SYM_NUM,
362*2d543d20SAndroid Build Coastguard Worker 	 .ocon_num = 0,
363*2d543d20SAndroid Build Coastguard Worker 	 .target_platform = SEPOL_TARGET_SELINUX,
364*2d543d20SAndroid Build Coastguard Worker 	 },
365*2d543d20SAndroid Build Coastguard Worker 	{
366*2d543d20SAndroid Build Coastguard Worker 	 .type = POLICY_MOD,
367*2d543d20SAndroid Build Coastguard Worker 	 .version = MOD_POLICYDB_VERSION_PERMISSIVE,
368*2d543d20SAndroid Build Coastguard Worker 	 .sym_num = SYM_NUM,
369*2d543d20SAndroid Build Coastguard Worker 	 .ocon_num = 0,
370*2d543d20SAndroid Build Coastguard Worker 	 .target_platform = SEPOL_TARGET_SELINUX,
371*2d543d20SAndroid Build Coastguard Worker 	 },
372*2d543d20SAndroid Build Coastguard Worker 	{
373*2d543d20SAndroid Build Coastguard Worker 	 .type = POLICY_MOD,
374*2d543d20SAndroid Build Coastguard Worker 	 .version = MOD_POLICYDB_VERSION_BOUNDARY,
375*2d543d20SAndroid Build Coastguard Worker 	 .sym_num = SYM_NUM,
376*2d543d20SAndroid Build Coastguard Worker 	 .ocon_num = 0,
377*2d543d20SAndroid Build Coastguard Worker 	 .target_platform = SEPOL_TARGET_SELINUX,
378*2d543d20SAndroid Build Coastguard Worker 	},
379*2d543d20SAndroid Build Coastguard Worker 	{
380*2d543d20SAndroid Build Coastguard Worker 	 .type = POLICY_MOD,
381*2d543d20SAndroid Build Coastguard Worker 	 .version = MOD_POLICYDB_VERSION_BOUNDARY_ALIAS,
382*2d543d20SAndroid Build Coastguard Worker 	 .sym_num = SYM_NUM,
383*2d543d20SAndroid Build Coastguard Worker 	 .ocon_num = 0,
384*2d543d20SAndroid Build Coastguard Worker 	 .target_platform = SEPOL_TARGET_SELINUX,
385*2d543d20SAndroid Build Coastguard Worker 	},
386*2d543d20SAndroid Build Coastguard Worker 	{
387*2d543d20SAndroid Build Coastguard Worker 	 .type = POLICY_MOD,
388*2d543d20SAndroid Build Coastguard Worker 	 .version = MOD_POLICYDB_VERSION_FILENAME_TRANS,
389*2d543d20SAndroid Build Coastguard Worker 	 .sym_num = SYM_NUM,
390*2d543d20SAndroid Build Coastguard Worker 	 .ocon_num = 0,
391*2d543d20SAndroid Build Coastguard Worker 	 .target_platform = SEPOL_TARGET_SELINUX,
392*2d543d20SAndroid Build Coastguard Worker 	},
393*2d543d20SAndroid Build Coastguard Worker 	{
394*2d543d20SAndroid Build Coastguard Worker 	 .type = POLICY_MOD,
395*2d543d20SAndroid Build Coastguard Worker 	 .version = MOD_POLICYDB_VERSION_ROLETRANS,
396*2d543d20SAndroid Build Coastguard Worker 	 .sym_num = SYM_NUM,
397*2d543d20SAndroid Build Coastguard Worker 	 .ocon_num = 0,
398*2d543d20SAndroid Build Coastguard Worker 	 .target_platform = SEPOL_TARGET_SELINUX,
399*2d543d20SAndroid Build Coastguard Worker 	},
400*2d543d20SAndroid Build Coastguard Worker 	{
401*2d543d20SAndroid Build Coastguard Worker 	 .type = POLICY_MOD,
402*2d543d20SAndroid Build Coastguard Worker 	 .version = MOD_POLICYDB_VERSION_ROLEATTRIB,
403*2d543d20SAndroid Build Coastguard Worker 	 .sym_num = SYM_NUM,
404*2d543d20SAndroid Build Coastguard Worker 	 .ocon_num = 0,
405*2d543d20SAndroid Build Coastguard Worker 	 .target_platform = SEPOL_TARGET_SELINUX,
406*2d543d20SAndroid Build Coastguard Worker 	},
407*2d543d20SAndroid Build Coastguard Worker 	{
408*2d543d20SAndroid Build Coastguard Worker 	 .type = POLICY_MOD,
409*2d543d20SAndroid Build Coastguard Worker 	 .version = MOD_POLICYDB_VERSION_TUNABLE_SEP,
410*2d543d20SAndroid Build Coastguard Worker 	 .sym_num = SYM_NUM,
411*2d543d20SAndroid Build Coastguard Worker 	 .ocon_num = 0,
412*2d543d20SAndroid Build Coastguard Worker 	 .target_platform = SEPOL_TARGET_SELINUX,
413*2d543d20SAndroid Build Coastguard Worker 	},
414*2d543d20SAndroid Build Coastguard Worker 	{
415*2d543d20SAndroid Build Coastguard Worker 	 .type = POLICY_MOD,
416*2d543d20SAndroid Build Coastguard Worker 	 .version = MOD_POLICYDB_VERSION_NEW_OBJECT_DEFAULTS,
417*2d543d20SAndroid Build Coastguard Worker 	 .sym_num = SYM_NUM,
418*2d543d20SAndroid Build Coastguard Worker 	 .ocon_num = 0,
419*2d543d20SAndroid Build Coastguard Worker 	 .target_platform = SEPOL_TARGET_SELINUX,
420*2d543d20SAndroid Build Coastguard Worker 	},
421*2d543d20SAndroid Build Coastguard Worker 	{
422*2d543d20SAndroid Build Coastguard Worker 	 .type = POLICY_MOD,
423*2d543d20SAndroid Build Coastguard Worker 	 .version = MOD_POLICYDB_VERSION_DEFAULT_TYPE,
424*2d543d20SAndroid Build Coastguard Worker 	 .sym_num = SYM_NUM,
425*2d543d20SAndroid Build Coastguard Worker 	 .ocon_num = 0,
426*2d543d20SAndroid Build Coastguard Worker 	 .target_platform = SEPOL_TARGET_SELINUX,
427*2d543d20SAndroid Build Coastguard Worker 	},
428*2d543d20SAndroid Build Coastguard Worker 	{
429*2d543d20SAndroid Build Coastguard Worker 	 .type = POLICY_MOD,
430*2d543d20SAndroid Build Coastguard Worker 	 .version = MOD_POLICYDB_VERSION_CONSTRAINT_NAMES,
431*2d543d20SAndroid Build Coastguard Worker 	 .sym_num = SYM_NUM,
432*2d543d20SAndroid Build Coastguard Worker 	 .ocon_num = 0,
433*2d543d20SAndroid Build Coastguard Worker 	 .target_platform = SEPOL_TARGET_SELINUX,
434*2d543d20SAndroid Build Coastguard Worker 	},
435*2d543d20SAndroid Build Coastguard Worker 	{
436*2d543d20SAndroid Build Coastguard Worker 	 .type = POLICY_MOD,
437*2d543d20SAndroid Build Coastguard Worker 	 .version = MOD_POLICYDB_VERSION_XPERMS_IOCTL,
438*2d543d20SAndroid Build Coastguard Worker 	 .sym_num = SYM_NUM,
439*2d543d20SAndroid Build Coastguard Worker 	 .ocon_num = 0,
440*2d543d20SAndroid Build Coastguard Worker 	 .target_platform = SEPOL_TARGET_SELINUX,
441*2d543d20SAndroid Build Coastguard Worker 	},
442*2d543d20SAndroid Build Coastguard Worker 	{
443*2d543d20SAndroid Build Coastguard Worker 	 .type = POLICY_MOD,
444*2d543d20SAndroid Build Coastguard Worker 	 .version = MOD_POLICYDB_VERSION_INFINIBAND,
445*2d543d20SAndroid Build Coastguard Worker 	 .sym_num = SYM_NUM,
446*2d543d20SAndroid Build Coastguard Worker 	 .ocon_num = 0,
447*2d543d20SAndroid Build Coastguard Worker 	 .target_platform = SEPOL_TARGET_SELINUX,
448*2d543d20SAndroid Build Coastguard Worker 	},
449*2d543d20SAndroid Build Coastguard Worker 	{
450*2d543d20SAndroid Build Coastguard Worker 	 .type = POLICY_MOD,
451*2d543d20SAndroid Build Coastguard Worker 	 .version = MOD_POLICYDB_VERSION_GLBLUB,
452*2d543d20SAndroid Build Coastguard Worker 	 .sym_num = SYM_NUM,
453*2d543d20SAndroid Build Coastguard Worker 	 .ocon_num = 0,
454*2d543d20SAndroid Build Coastguard Worker 	 .target_platform = SEPOL_TARGET_SELINUX,
455*2d543d20SAndroid Build Coastguard Worker 	},
456*2d543d20SAndroid Build Coastguard Worker 	{
457*2d543d20SAndroid Build Coastguard Worker 	 .type = POLICY_MOD,
458*2d543d20SAndroid Build Coastguard Worker 	 .version = MOD_POLICYDB_VERSION_SELF_TYPETRANS,
459*2d543d20SAndroid Build Coastguard Worker 	 .sym_num = SYM_NUM,
460*2d543d20SAndroid Build Coastguard Worker 	 .ocon_num = 0,
461*2d543d20SAndroid Build Coastguard Worker 	 .target_platform = SEPOL_TARGET_SELINUX,
462*2d543d20SAndroid Build Coastguard Worker 	},
463*2d543d20SAndroid Build Coastguard Worker };
464*2d543d20SAndroid Build Coastguard Worker 
465*2d543d20SAndroid Build Coastguard Worker #if 0
466*2d543d20SAndroid Build Coastguard Worker static char *symtab_name[SYM_NUM] = {
467*2d543d20SAndroid Build Coastguard Worker 	"common prefixes",
468*2d543d20SAndroid Build Coastguard Worker 	"classes",
469*2d543d20SAndroid Build Coastguard Worker 	"roles",
470*2d543d20SAndroid Build Coastguard Worker 	"types",
471*2d543d20SAndroid Build Coastguard Worker 	"users",
472*2d543d20SAndroid Build Coastguard Worker 	"bools" mls_symtab_names cond_symtab_names
473*2d543d20SAndroid Build Coastguard Worker };
474*2d543d20SAndroid Build Coastguard Worker #endif
475*2d543d20SAndroid Build Coastguard Worker 
476*2d543d20SAndroid Build Coastguard Worker static const unsigned int symtab_sizes[SYM_NUM] = {
477*2d543d20SAndroid Build Coastguard Worker 	2,
478*2d543d20SAndroid Build Coastguard Worker 	32,
479*2d543d20SAndroid Build Coastguard Worker 	16,
480*2d543d20SAndroid Build Coastguard Worker 	512,
481*2d543d20SAndroid Build Coastguard Worker 	128,
482*2d543d20SAndroid Build Coastguard Worker 	16,
483*2d543d20SAndroid Build Coastguard Worker 	16,
484*2d543d20SAndroid Build Coastguard Worker 	16,
485*2d543d20SAndroid Build Coastguard Worker };
486*2d543d20SAndroid Build Coastguard Worker 
policydb_lookup_compat(unsigned int version,unsigned int type,unsigned int target_platform)487*2d543d20SAndroid Build Coastguard Worker const struct policydb_compat_info *policydb_lookup_compat(unsigned int version,
488*2d543d20SAndroid Build Coastguard Worker 						          unsigned int type,
489*2d543d20SAndroid Build Coastguard Worker 						          unsigned int target_platform)
490*2d543d20SAndroid Build Coastguard Worker {
491*2d543d20SAndroid Build Coastguard Worker 	unsigned int i;
492*2d543d20SAndroid Build Coastguard Worker 	const struct policydb_compat_info *info = NULL;
493*2d543d20SAndroid Build Coastguard Worker 
494*2d543d20SAndroid Build Coastguard Worker 	for (i = 0; i < sizeof(policydb_compat) / sizeof(*info); i++) {
495*2d543d20SAndroid Build Coastguard Worker 		if (policydb_compat[i].version == version &&
496*2d543d20SAndroid Build Coastguard Worker 		    policydb_compat[i].type == type &&
497*2d543d20SAndroid Build Coastguard Worker 		    policydb_compat[i].target_platform == target_platform) {
498*2d543d20SAndroid Build Coastguard Worker 			info = &policydb_compat[i];
499*2d543d20SAndroid Build Coastguard Worker 			break;
500*2d543d20SAndroid Build Coastguard Worker 		}
501*2d543d20SAndroid Build Coastguard Worker 	}
502*2d543d20SAndroid Build Coastguard Worker 	return info;
503*2d543d20SAndroid Build Coastguard Worker }
504*2d543d20SAndroid Build Coastguard Worker 
type_set_init(type_set_t * x)505*2d543d20SAndroid Build Coastguard Worker void type_set_init(type_set_t * x)
506*2d543d20SAndroid Build Coastguard Worker {
507*2d543d20SAndroid Build Coastguard Worker 	memset(x, 0, sizeof(type_set_t));
508*2d543d20SAndroid Build Coastguard Worker 	ebitmap_init(&x->types);
509*2d543d20SAndroid Build Coastguard Worker 	ebitmap_init(&x->negset);
510*2d543d20SAndroid Build Coastguard Worker }
511*2d543d20SAndroid Build Coastguard Worker 
type_set_destroy(type_set_t * x)512*2d543d20SAndroid Build Coastguard Worker void type_set_destroy(type_set_t * x)
513*2d543d20SAndroid Build Coastguard Worker {
514*2d543d20SAndroid Build Coastguard Worker 	if (x != NULL) {
515*2d543d20SAndroid Build Coastguard Worker 		ebitmap_destroy(&x->types);
516*2d543d20SAndroid Build Coastguard Worker 		ebitmap_destroy(&x->negset);
517*2d543d20SAndroid Build Coastguard Worker 	}
518*2d543d20SAndroid Build Coastguard Worker }
519*2d543d20SAndroid Build Coastguard Worker 
role_set_init(role_set_t * x)520*2d543d20SAndroid Build Coastguard Worker void role_set_init(role_set_t * x)
521*2d543d20SAndroid Build Coastguard Worker {
522*2d543d20SAndroid Build Coastguard Worker 	memset(x, 0, sizeof(role_set_t));
523*2d543d20SAndroid Build Coastguard Worker 	ebitmap_init(&x->roles);
524*2d543d20SAndroid Build Coastguard Worker }
525*2d543d20SAndroid Build Coastguard Worker 
role_set_destroy(role_set_t * x)526*2d543d20SAndroid Build Coastguard Worker void role_set_destroy(role_set_t * x)
527*2d543d20SAndroid Build Coastguard Worker {
528*2d543d20SAndroid Build Coastguard Worker 	ebitmap_destroy(&x->roles);
529*2d543d20SAndroid Build Coastguard Worker }
530*2d543d20SAndroid Build Coastguard Worker 
role_datum_init(role_datum_t * x)531*2d543d20SAndroid Build Coastguard Worker void role_datum_init(role_datum_t * x)
532*2d543d20SAndroid Build Coastguard Worker {
533*2d543d20SAndroid Build Coastguard Worker 	memset(x, 0, sizeof(role_datum_t));
534*2d543d20SAndroid Build Coastguard Worker 	ebitmap_init(&x->dominates);
535*2d543d20SAndroid Build Coastguard Worker 	type_set_init(&x->types);
536*2d543d20SAndroid Build Coastguard Worker 	ebitmap_init(&x->cache);
537*2d543d20SAndroid Build Coastguard Worker 	ebitmap_init(&x->roles);
538*2d543d20SAndroid Build Coastguard Worker }
539*2d543d20SAndroid Build Coastguard Worker 
role_datum_destroy(role_datum_t * x)540*2d543d20SAndroid Build Coastguard Worker void role_datum_destroy(role_datum_t * x)
541*2d543d20SAndroid Build Coastguard Worker {
542*2d543d20SAndroid Build Coastguard Worker 	if (x != NULL) {
543*2d543d20SAndroid Build Coastguard Worker 		ebitmap_destroy(&x->dominates);
544*2d543d20SAndroid Build Coastguard Worker 		type_set_destroy(&x->types);
545*2d543d20SAndroid Build Coastguard Worker 		ebitmap_destroy(&x->cache);
546*2d543d20SAndroid Build Coastguard Worker 		ebitmap_destroy(&x->roles);
547*2d543d20SAndroid Build Coastguard Worker 	}
548*2d543d20SAndroid Build Coastguard Worker }
549*2d543d20SAndroid Build Coastguard Worker 
type_datum_init(type_datum_t * x)550*2d543d20SAndroid Build Coastguard Worker void type_datum_init(type_datum_t * x)
551*2d543d20SAndroid Build Coastguard Worker {
552*2d543d20SAndroid Build Coastguard Worker 	memset(x, 0, sizeof(*x));
553*2d543d20SAndroid Build Coastguard Worker 	ebitmap_init(&x->types);
554*2d543d20SAndroid Build Coastguard Worker }
555*2d543d20SAndroid Build Coastguard Worker 
type_datum_destroy(type_datum_t * x)556*2d543d20SAndroid Build Coastguard Worker void type_datum_destroy(type_datum_t * x)
557*2d543d20SAndroid Build Coastguard Worker {
558*2d543d20SAndroid Build Coastguard Worker 	if (x != NULL) {
559*2d543d20SAndroid Build Coastguard Worker 		ebitmap_destroy(&x->types);
560*2d543d20SAndroid Build Coastguard Worker 	}
561*2d543d20SAndroid Build Coastguard Worker }
562*2d543d20SAndroid Build Coastguard Worker 
user_datum_init(user_datum_t * x)563*2d543d20SAndroid Build Coastguard Worker void user_datum_init(user_datum_t * x)
564*2d543d20SAndroid Build Coastguard Worker {
565*2d543d20SAndroid Build Coastguard Worker 	memset(x, 0, sizeof(user_datum_t));
566*2d543d20SAndroid Build Coastguard Worker 	role_set_init(&x->roles);
567*2d543d20SAndroid Build Coastguard Worker 	mls_semantic_range_init(&x->range);
568*2d543d20SAndroid Build Coastguard Worker 	mls_semantic_level_init(&x->dfltlevel);
569*2d543d20SAndroid Build Coastguard Worker 	ebitmap_init(&x->cache);
570*2d543d20SAndroid Build Coastguard Worker 	mls_range_init(&x->exp_range);
571*2d543d20SAndroid Build Coastguard Worker 	mls_level_init(&x->exp_dfltlevel);
572*2d543d20SAndroid Build Coastguard Worker }
573*2d543d20SAndroid Build Coastguard Worker 
user_datum_destroy(user_datum_t * x)574*2d543d20SAndroid Build Coastguard Worker void user_datum_destroy(user_datum_t * x)
575*2d543d20SAndroid Build Coastguard Worker {
576*2d543d20SAndroid Build Coastguard Worker 	if (x != NULL) {
577*2d543d20SAndroid Build Coastguard Worker 		role_set_destroy(&x->roles);
578*2d543d20SAndroid Build Coastguard Worker 		mls_semantic_range_destroy(&x->range);
579*2d543d20SAndroid Build Coastguard Worker 		mls_semantic_level_destroy(&x->dfltlevel);
580*2d543d20SAndroid Build Coastguard Worker 		ebitmap_destroy(&x->cache);
581*2d543d20SAndroid Build Coastguard Worker 		mls_range_destroy(&x->exp_range);
582*2d543d20SAndroid Build Coastguard Worker 		mls_level_destroy(&x->exp_dfltlevel);
583*2d543d20SAndroid Build Coastguard Worker 	}
584*2d543d20SAndroid Build Coastguard Worker }
585*2d543d20SAndroid Build Coastguard Worker 
level_datum_init(level_datum_t * x)586*2d543d20SAndroid Build Coastguard Worker void level_datum_init(level_datum_t * x)
587*2d543d20SAndroid Build Coastguard Worker {
588*2d543d20SAndroid Build Coastguard Worker 	memset(x, 0, sizeof(level_datum_t));
589*2d543d20SAndroid Build Coastguard Worker }
590*2d543d20SAndroid Build Coastguard Worker 
level_datum_destroy(level_datum_t * x)591*2d543d20SAndroid Build Coastguard Worker void level_datum_destroy(level_datum_t * x __attribute__ ((unused)))
592*2d543d20SAndroid Build Coastguard Worker {
593*2d543d20SAndroid Build Coastguard Worker 	/* the mls_level_t referenced by the level_datum is managed
594*2d543d20SAndroid Build Coastguard Worker 	 * separately for now, so there is nothing to destroy */
595*2d543d20SAndroid Build Coastguard Worker 	return;
596*2d543d20SAndroid Build Coastguard Worker }
597*2d543d20SAndroid Build Coastguard Worker 
cat_datum_init(cat_datum_t * x)598*2d543d20SAndroid Build Coastguard Worker void cat_datum_init(cat_datum_t * x)
599*2d543d20SAndroid Build Coastguard Worker {
600*2d543d20SAndroid Build Coastguard Worker 	memset(x, 0, sizeof(cat_datum_t));
601*2d543d20SAndroid Build Coastguard Worker }
602*2d543d20SAndroid Build Coastguard Worker 
cat_datum_destroy(cat_datum_t * x)603*2d543d20SAndroid Build Coastguard Worker void cat_datum_destroy(cat_datum_t * x __attribute__ ((unused)))
604*2d543d20SAndroid Build Coastguard Worker {
605*2d543d20SAndroid Build Coastguard Worker 	/* it's currently a simple struct - really nothing to destroy */
606*2d543d20SAndroid Build Coastguard Worker 	return;
607*2d543d20SAndroid Build Coastguard Worker }
608*2d543d20SAndroid Build Coastguard Worker 
class_perm_node_init(class_perm_node_t * x)609*2d543d20SAndroid Build Coastguard Worker void class_perm_node_init(class_perm_node_t * x)
610*2d543d20SAndroid Build Coastguard Worker {
611*2d543d20SAndroid Build Coastguard Worker 	memset(x, 0, sizeof(class_perm_node_t));
612*2d543d20SAndroid Build Coastguard Worker }
613*2d543d20SAndroid Build Coastguard Worker 
avrule_init(avrule_t * x)614*2d543d20SAndroid Build Coastguard Worker void avrule_init(avrule_t * x)
615*2d543d20SAndroid Build Coastguard Worker {
616*2d543d20SAndroid Build Coastguard Worker 	memset(x, 0, sizeof(avrule_t));
617*2d543d20SAndroid Build Coastguard Worker 	type_set_init(&x->stypes);
618*2d543d20SAndroid Build Coastguard Worker 	type_set_init(&x->ttypes);
619*2d543d20SAndroid Build Coastguard Worker }
620*2d543d20SAndroid Build Coastguard Worker 
avrule_destroy(avrule_t * x)621*2d543d20SAndroid Build Coastguard Worker void avrule_destroy(avrule_t * x)
622*2d543d20SAndroid Build Coastguard Worker {
623*2d543d20SAndroid Build Coastguard Worker 	class_perm_node_t *cur, *next;
624*2d543d20SAndroid Build Coastguard Worker 
625*2d543d20SAndroid Build Coastguard Worker 	if (x == NULL) {
626*2d543d20SAndroid Build Coastguard Worker 		return;
627*2d543d20SAndroid Build Coastguard Worker 	}
628*2d543d20SAndroid Build Coastguard Worker 	type_set_destroy(&x->stypes);
629*2d543d20SAndroid Build Coastguard Worker 	type_set_destroy(&x->ttypes);
630*2d543d20SAndroid Build Coastguard Worker 
631*2d543d20SAndroid Build Coastguard Worker 	free(x->source_filename);
632*2d543d20SAndroid Build Coastguard Worker 
633*2d543d20SAndroid Build Coastguard Worker 	next = x->perms;
634*2d543d20SAndroid Build Coastguard Worker 	while (next) {
635*2d543d20SAndroid Build Coastguard Worker 		cur = next;
636*2d543d20SAndroid Build Coastguard Worker 		next = cur->next;
637*2d543d20SAndroid Build Coastguard Worker 		free(cur);
638*2d543d20SAndroid Build Coastguard Worker 	}
639*2d543d20SAndroid Build Coastguard Worker 
640*2d543d20SAndroid Build Coastguard Worker 	free(x->xperms);
641*2d543d20SAndroid Build Coastguard Worker }
642*2d543d20SAndroid Build Coastguard Worker 
role_trans_rule_init(role_trans_rule_t * x)643*2d543d20SAndroid Build Coastguard Worker void role_trans_rule_init(role_trans_rule_t * x)
644*2d543d20SAndroid Build Coastguard Worker {
645*2d543d20SAndroid Build Coastguard Worker 	memset(x, 0, sizeof(*x));
646*2d543d20SAndroid Build Coastguard Worker 	role_set_init(&x->roles);
647*2d543d20SAndroid Build Coastguard Worker 	type_set_init(&x->types);
648*2d543d20SAndroid Build Coastguard Worker 	ebitmap_init(&x->classes);
649*2d543d20SAndroid Build Coastguard Worker }
650*2d543d20SAndroid Build Coastguard Worker 
role_trans_rule_destroy(role_trans_rule_t * x)651*2d543d20SAndroid Build Coastguard Worker static void role_trans_rule_destroy(role_trans_rule_t * x)
652*2d543d20SAndroid Build Coastguard Worker {
653*2d543d20SAndroid Build Coastguard Worker 	if (x != NULL) {
654*2d543d20SAndroid Build Coastguard Worker 		role_set_destroy(&x->roles);
655*2d543d20SAndroid Build Coastguard Worker 		type_set_destroy(&x->types);
656*2d543d20SAndroid Build Coastguard Worker 		ebitmap_destroy(&x->classes);
657*2d543d20SAndroid Build Coastguard Worker 	}
658*2d543d20SAndroid Build Coastguard Worker }
659*2d543d20SAndroid Build Coastguard Worker 
role_trans_rule_list_destroy(role_trans_rule_t * x)660*2d543d20SAndroid Build Coastguard Worker void role_trans_rule_list_destroy(role_trans_rule_t * x)
661*2d543d20SAndroid Build Coastguard Worker {
662*2d543d20SAndroid Build Coastguard Worker 	while (x != NULL) {
663*2d543d20SAndroid Build Coastguard Worker 		role_trans_rule_t *next = x->next;
664*2d543d20SAndroid Build Coastguard Worker 		role_trans_rule_destroy(x);
665*2d543d20SAndroid Build Coastguard Worker 		free(x);
666*2d543d20SAndroid Build Coastguard Worker 		x = next;
667*2d543d20SAndroid Build Coastguard Worker 	}
668*2d543d20SAndroid Build Coastguard Worker }
669*2d543d20SAndroid Build Coastguard Worker 
filename_trans_rule_init(filename_trans_rule_t * x)670*2d543d20SAndroid Build Coastguard Worker void filename_trans_rule_init(filename_trans_rule_t * x)
671*2d543d20SAndroid Build Coastguard Worker {
672*2d543d20SAndroid Build Coastguard Worker 	memset(x, 0, sizeof(*x));
673*2d543d20SAndroid Build Coastguard Worker 	type_set_init(&x->stypes);
674*2d543d20SAndroid Build Coastguard Worker 	type_set_init(&x->ttypes);
675*2d543d20SAndroid Build Coastguard Worker }
676*2d543d20SAndroid Build Coastguard Worker 
filename_trans_rule_destroy(filename_trans_rule_t * x)677*2d543d20SAndroid Build Coastguard Worker static void filename_trans_rule_destroy(filename_trans_rule_t * x)
678*2d543d20SAndroid Build Coastguard Worker {
679*2d543d20SAndroid Build Coastguard Worker 	if (!x)
680*2d543d20SAndroid Build Coastguard Worker 		return;
681*2d543d20SAndroid Build Coastguard Worker 	type_set_destroy(&x->stypes);
682*2d543d20SAndroid Build Coastguard Worker 	type_set_destroy(&x->ttypes);
683*2d543d20SAndroid Build Coastguard Worker 	free(x->name);
684*2d543d20SAndroid Build Coastguard Worker }
685*2d543d20SAndroid Build Coastguard Worker 
filename_trans_rule_list_destroy(filename_trans_rule_t * x)686*2d543d20SAndroid Build Coastguard Worker void filename_trans_rule_list_destroy(filename_trans_rule_t * x)
687*2d543d20SAndroid Build Coastguard Worker {
688*2d543d20SAndroid Build Coastguard Worker 	filename_trans_rule_t *next;
689*2d543d20SAndroid Build Coastguard Worker 	while (x) {
690*2d543d20SAndroid Build Coastguard Worker 		next = x->next;
691*2d543d20SAndroid Build Coastguard Worker 		filename_trans_rule_destroy(x);
692*2d543d20SAndroid Build Coastguard Worker 		free(x);
693*2d543d20SAndroid Build Coastguard Worker 		x = next;
694*2d543d20SAndroid Build Coastguard Worker 	}
695*2d543d20SAndroid Build Coastguard Worker }
696*2d543d20SAndroid Build Coastguard Worker 
role_allow_rule_init(role_allow_rule_t * x)697*2d543d20SAndroid Build Coastguard Worker void role_allow_rule_init(role_allow_rule_t * x)
698*2d543d20SAndroid Build Coastguard Worker {
699*2d543d20SAndroid Build Coastguard Worker 	memset(x, 0, sizeof(role_allow_rule_t));
700*2d543d20SAndroid Build Coastguard Worker 	role_set_init(&x->roles);
701*2d543d20SAndroid Build Coastguard Worker 	role_set_init(&x->new_roles);
702*2d543d20SAndroid Build Coastguard Worker }
703*2d543d20SAndroid Build Coastguard Worker 
role_allow_rule_destroy(role_allow_rule_t * x)704*2d543d20SAndroid Build Coastguard Worker void role_allow_rule_destroy(role_allow_rule_t * x)
705*2d543d20SAndroid Build Coastguard Worker {
706*2d543d20SAndroid Build Coastguard Worker 	role_set_destroy(&x->roles);
707*2d543d20SAndroid Build Coastguard Worker 	role_set_destroy(&x->new_roles);
708*2d543d20SAndroid Build Coastguard Worker }
709*2d543d20SAndroid Build Coastguard Worker 
role_allow_rule_list_destroy(role_allow_rule_t * x)710*2d543d20SAndroid Build Coastguard Worker void role_allow_rule_list_destroy(role_allow_rule_t * x)
711*2d543d20SAndroid Build Coastguard Worker {
712*2d543d20SAndroid Build Coastguard Worker 	while (x != NULL) {
713*2d543d20SAndroid Build Coastguard Worker 		role_allow_rule_t *next = x->next;
714*2d543d20SAndroid Build Coastguard Worker 		role_allow_rule_destroy(x);
715*2d543d20SAndroid Build Coastguard Worker 		free(x);
716*2d543d20SAndroid Build Coastguard Worker 		x = next;
717*2d543d20SAndroid Build Coastguard Worker 	}
718*2d543d20SAndroid Build Coastguard Worker }
719*2d543d20SAndroid Build Coastguard Worker 
range_trans_rule_init(range_trans_rule_t * x)720*2d543d20SAndroid Build Coastguard Worker void range_trans_rule_init(range_trans_rule_t * x)
721*2d543d20SAndroid Build Coastguard Worker {
722*2d543d20SAndroid Build Coastguard Worker 	type_set_init(&x->stypes);
723*2d543d20SAndroid Build Coastguard Worker 	type_set_init(&x->ttypes);
724*2d543d20SAndroid Build Coastguard Worker 	ebitmap_init(&x->tclasses);
725*2d543d20SAndroid Build Coastguard Worker 	mls_semantic_range_init(&x->trange);
726*2d543d20SAndroid Build Coastguard Worker 	x->next = NULL;
727*2d543d20SAndroid Build Coastguard Worker }
728*2d543d20SAndroid Build Coastguard Worker 
range_trans_rule_destroy(range_trans_rule_t * x)729*2d543d20SAndroid Build Coastguard Worker void range_trans_rule_destroy(range_trans_rule_t * x)
730*2d543d20SAndroid Build Coastguard Worker {
731*2d543d20SAndroid Build Coastguard Worker 	type_set_destroy(&x->stypes);
732*2d543d20SAndroid Build Coastguard Worker 	type_set_destroy(&x->ttypes);
733*2d543d20SAndroid Build Coastguard Worker 	ebitmap_destroy(&x->tclasses);
734*2d543d20SAndroid Build Coastguard Worker 	mls_semantic_range_destroy(&x->trange);
735*2d543d20SAndroid Build Coastguard Worker }
736*2d543d20SAndroid Build Coastguard Worker 
range_trans_rule_list_destroy(range_trans_rule_t * x)737*2d543d20SAndroid Build Coastguard Worker void range_trans_rule_list_destroy(range_trans_rule_t * x)
738*2d543d20SAndroid Build Coastguard Worker {
739*2d543d20SAndroid Build Coastguard Worker 	while (x != NULL) {
740*2d543d20SAndroid Build Coastguard Worker 		range_trans_rule_t *next = x->next;
741*2d543d20SAndroid Build Coastguard Worker 		range_trans_rule_destroy(x);
742*2d543d20SAndroid Build Coastguard Worker 		free(x);
743*2d543d20SAndroid Build Coastguard Worker 		x = next;
744*2d543d20SAndroid Build Coastguard Worker 	}
745*2d543d20SAndroid Build Coastguard Worker }
746*2d543d20SAndroid Build Coastguard Worker 
avrule_list_destroy(avrule_t * x)747*2d543d20SAndroid Build Coastguard Worker void avrule_list_destroy(avrule_t * x)
748*2d543d20SAndroid Build Coastguard Worker {
749*2d543d20SAndroid Build Coastguard Worker 	avrule_t *next, *cur;
750*2d543d20SAndroid Build Coastguard Worker 
751*2d543d20SAndroid Build Coastguard Worker 	if (!x)
752*2d543d20SAndroid Build Coastguard Worker 		return;
753*2d543d20SAndroid Build Coastguard Worker 
754*2d543d20SAndroid Build Coastguard Worker 	next = x;
755*2d543d20SAndroid Build Coastguard Worker 	while (next) {
756*2d543d20SAndroid Build Coastguard Worker 		cur = next;
757*2d543d20SAndroid Build Coastguard Worker 		next = next->next;
758*2d543d20SAndroid Build Coastguard Worker 		avrule_destroy(cur);
759*2d543d20SAndroid Build Coastguard Worker 		free(cur);
760*2d543d20SAndroid Build Coastguard Worker 	}
761*2d543d20SAndroid Build Coastguard Worker }
762*2d543d20SAndroid Build Coastguard Worker 
763*2d543d20SAndroid Build Coastguard Worker /*
764*2d543d20SAndroid Build Coastguard Worker  * Initialize the role table by implicitly adding role 'object_r'.  If
765*2d543d20SAndroid Build Coastguard Worker  * the policy is a module, set object_r's scope to be SCOPE_REQ,
766*2d543d20SAndroid Build Coastguard Worker  * otherwise set it to SCOPE_DECL.
767*2d543d20SAndroid Build Coastguard Worker  */
roles_init(policydb_t * p)768*2d543d20SAndroid Build Coastguard Worker static int roles_init(policydb_t * p)
769*2d543d20SAndroid Build Coastguard Worker {
770*2d543d20SAndroid Build Coastguard Worker 	char *key = 0;
771*2d543d20SAndroid Build Coastguard Worker 	int rc;
772*2d543d20SAndroid Build Coastguard Worker 	role_datum_t *role;
773*2d543d20SAndroid Build Coastguard Worker 
774*2d543d20SAndroid Build Coastguard Worker 	role = calloc(1, sizeof(role_datum_t));
775*2d543d20SAndroid Build Coastguard Worker 	if (!role) {
776*2d543d20SAndroid Build Coastguard Worker 		rc = -ENOMEM;
777*2d543d20SAndroid Build Coastguard Worker 		goto out;
778*2d543d20SAndroid Build Coastguard Worker 	}
779*2d543d20SAndroid Build Coastguard Worker 	key = strdup(OBJECT_R);
780*2d543d20SAndroid Build Coastguard Worker 	if (!key) {
781*2d543d20SAndroid Build Coastguard Worker 		rc = -ENOMEM;
782*2d543d20SAndroid Build Coastguard Worker 		goto out_free_role;
783*2d543d20SAndroid Build Coastguard Worker 	}
784*2d543d20SAndroid Build Coastguard Worker 	rc = symtab_insert(p, SYM_ROLES, key, role,
785*2d543d20SAndroid Build Coastguard Worker 			   (p->policy_type ==
786*2d543d20SAndroid Build Coastguard Worker 			    POLICY_MOD ? SCOPE_REQ : SCOPE_DECL), 1,
787*2d543d20SAndroid Build Coastguard Worker 			   &role->s.value);
788*2d543d20SAndroid Build Coastguard Worker 	if (rc)
789*2d543d20SAndroid Build Coastguard Worker 		goto out_free_key;
790*2d543d20SAndroid Build Coastguard Worker 	if (role->s.value != OBJECT_R_VAL) {
791*2d543d20SAndroid Build Coastguard Worker 		rc = -EINVAL;
792*2d543d20SAndroid Build Coastguard Worker 		goto out_free_role;
793*2d543d20SAndroid Build Coastguard Worker 	}
794*2d543d20SAndroid Build Coastguard Worker       out:
795*2d543d20SAndroid Build Coastguard Worker 	return rc;
796*2d543d20SAndroid Build Coastguard Worker 
797*2d543d20SAndroid Build Coastguard Worker       out_free_key:
798*2d543d20SAndroid Build Coastguard Worker 	free(key);
799*2d543d20SAndroid Build Coastguard Worker       out_free_role:
800*2d543d20SAndroid Build Coastguard Worker 	free(role);
801*2d543d20SAndroid Build Coastguard Worker 	goto out;
802*2d543d20SAndroid Build Coastguard Worker }
803*2d543d20SAndroid Build Coastguard Worker 
804*2d543d20SAndroid Build Coastguard Worker ignore_unsigned_overflow_
805*2d543d20SAndroid Build Coastguard Worker static inline unsigned long
partial_name_hash(unsigned long c,unsigned long prevhash)806*2d543d20SAndroid Build Coastguard Worker partial_name_hash(unsigned long c, unsigned long prevhash)
807*2d543d20SAndroid Build Coastguard Worker {
808*2d543d20SAndroid Build Coastguard Worker 	return (prevhash + (c << 4) + (c >> 4)) * 11;
809*2d543d20SAndroid Build Coastguard Worker }
810*2d543d20SAndroid Build Coastguard Worker 
filenametr_hash(hashtab_t h,const_hashtab_key_t k)811*2d543d20SAndroid Build Coastguard Worker static unsigned int filenametr_hash(hashtab_t h, const_hashtab_key_t k)
812*2d543d20SAndroid Build Coastguard Worker {
813*2d543d20SAndroid Build Coastguard Worker 	const filename_trans_key_t *ft = (const filename_trans_key_t *)k;
814*2d543d20SAndroid Build Coastguard Worker 	unsigned long hash;
815*2d543d20SAndroid Build Coastguard Worker 	unsigned int byte_num;
816*2d543d20SAndroid Build Coastguard Worker 	unsigned char focus;
817*2d543d20SAndroid Build Coastguard Worker 
818*2d543d20SAndroid Build Coastguard Worker 	hash = ft->ttype ^ ft->tclass;
819*2d543d20SAndroid Build Coastguard Worker 
820*2d543d20SAndroid Build Coastguard Worker 	byte_num = 0;
821*2d543d20SAndroid Build Coastguard Worker 	while ((focus = ft->name[byte_num++]))
822*2d543d20SAndroid Build Coastguard Worker 		hash = partial_name_hash(focus, hash);
823*2d543d20SAndroid Build Coastguard Worker 	return hash & (h->size - 1);
824*2d543d20SAndroid Build Coastguard Worker }
825*2d543d20SAndroid Build Coastguard Worker 
filenametr_cmp(hashtab_t h,const_hashtab_key_t k1,const_hashtab_key_t k2)826*2d543d20SAndroid Build Coastguard Worker static int filenametr_cmp(hashtab_t h __attribute__ ((unused)),
827*2d543d20SAndroid Build Coastguard Worker 			  const_hashtab_key_t k1, const_hashtab_key_t k2)
828*2d543d20SAndroid Build Coastguard Worker {
829*2d543d20SAndroid Build Coastguard Worker 	const filename_trans_key_t *ft1 = (const filename_trans_key_t *)k1;
830*2d543d20SAndroid Build Coastguard Worker 	const filename_trans_key_t *ft2 = (const filename_trans_key_t *)k2;
831*2d543d20SAndroid Build Coastguard Worker 	int v;
832*2d543d20SAndroid Build Coastguard Worker 
833*2d543d20SAndroid Build Coastguard Worker 	v = spaceship_cmp(ft1->ttype, ft2->ttype);
834*2d543d20SAndroid Build Coastguard Worker 	if (v)
835*2d543d20SAndroid Build Coastguard Worker 		return v;
836*2d543d20SAndroid Build Coastguard Worker 
837*2d543d20SAndroid Build Coastguard Worker 	v = spaceship_cmp(ft1->tclass, ft2->tclass);
838*2d543d20SAndroid Build Coastguard Worker 	if (v)
839*2d543d20SAndroid Build Coastguard Worker 		return v;
840*2d543d20SAndroid Build Coastguard Worker 
841*2d543d20SAndroid Build Coastguard Worker 	return strcmp(ft1->name, ft2->name);
842*2d543d20SAndroid Build Coastguard Worker 
843*2d543d20SAndroid Build Coastguard Worker }
844*2d543d20SAndroid Build Coastguard Worker 
rangetr_hash(hashtab_t h,const_hashtab_key_t k)845*2d543d20SAndroid Build Coastguard Worker static unsigned int rangetr_hash(hashtab_t h, const_hashtab_key_t k)
846*2d543d20SAndroid Build Coastguard Worker {
847*2d543d20SAndroid Build Coastguard Worker 	const struct range_trans *key = (const struct range_trans *)k;
848*2d543d20SAndroid Build Coastguard Worker 	return (key->source_type + (key->target_type << 3) +
849*2d543d20SAndroid Build Coastguard Worker 		(key->target_class << 5)) & (h->size - 1);
850*2d543d20SAndroid Build Coastguard Worker }
851*2d543d20SAndroid Build Coastguard Worker 
rangetr_cmp(hashtab_t h,const_hashtab_key_t k1,const_hashtab_key_t k2)852*2d543d20SAndroid Build Coastguard Worker static int rangetr_cmp(hashtab_t h __attribute__ ((unused)),
853*2d543d20SAndroid Build Coastguard Worker 		       const_hashtab_key_t k1, const_hashtab_key_t k2)
854*2d543d20SAndroid Build Coastguard Worker {
855*2d543d20SAndroid Build Coastguard Worker 	const struct range_trans *key1 = (const struct range_trans *)k1;
856*2d543d20SAndroid Build Coastguard Worker 	const struct range_trans *key2 = (const struct range_trans *)k2;
857*2d543d20SAndroid Build Coastguard Worker 	int v;
858*2d543d20SAndroid Build Coastguard Worker 
859*2d543d20SAndroid Build Coastguard Worker 	v = spaceship_cmp(key1->source_type, key2->source_type);
860*2d543d20SAndroid Build Coastguard Worker 	if (v)
861*2d543d20SAndroid Build Coastguard Worker 		return v;
862*2d543d20SAndroid Build Coastguard Worker 
863*2d543d20SAndroid Build Coastguard Worker 	v = spaceship_cmp(key1->target_type, key2->target_type);
864*2d543d20SAndroid Build Coastguard Worker 	if (v)
865*2d543d20SAndroid Build Coastguard Worker 		return v;
866*2d543d20SAndroid Build Coastguard Worker 
867*2d543d20SAndroid Build Coastguard Worker 	v = spaceship_cmp(key1->target_class, key2->target_class);
868*2d543d20SAndroid Build Coastguard Worker 
869*2d543d20SAndroid Build Coastguard Worker 	return v;
870*2d543d20SAndroid Build Coastguard Worker }
871*2d543d20SAndroid Build Coastguard Worker 
872*2d543d20SAndroid Build Coastguard Worker /*
873*2d543d20SAndroid Build Coastguard Worker  * Initialize a policy database structure.
874*2d543d20SAndroid Build Coastguard Worker  */
policydb_init(policydb_t * p)875*2d543d20SAndroid Build Coastguard Worker int policydb_init(policydb_t * p)
876*2d543d20SAndroid Build Coastguard Worker {
877*2d543d20SAndroid Build Coastguard Worker 	int i, rc;
878*2d543d20SAndroid Build Coastguard Worker 
879*2d543d20SAndroid Build Coastguard Worker 	memset(p, 0, sizeof(policydb_t));
880*2d543d20SAndroid Build Coastguard Worker 
881*2d543d20SAndroid Build Coastguard Worker 	for (i = 0; i < SYM_NUM; i++) {
882*2d543d20SAndroid Build Coastguard Worker 		p->sym_val_to_name[i] = NULL;
883*2d543d20SAndroid Build Coastguard Worker 		rc = symtab_init(&p->symtab[i], symtab_sizes[i]);
884*2d543d20SAndroid Build Coastguard Worker 		if (rc)
885*2d543d20SAndroid Build Coastguard Worker 			goto err;
886*2d543d20SAndroid Build Coastguard Worker 	}
887*2d543d20SAndroid Build Coastguard Worker 
888*2d543d20SAndroid Build Coastguard Worker 	/* initialize the module stuff */
889*2d543d20SAndroid Build Coastguard Worker 	for (i = 0; i < SYM_NUM; i++) {
890*2d543d20SAndroid Build Coastguard Worker 		if (symtab_init(&p->scope[i], symtab_sizes[i])) {
891*2d543d20SAndroid Build Coastguard Worker 			goto err;
892*2d543d20SAndroid Build Coastguard Worker 		}
893*2d543d20SAndroid Build Coastguard Worker 	}
894*2d543d20SAndroid Build Coastguard Worker 	if ((p->global = avrule_block_create()) == NULL ||
895*2d543d20SAndroid Build Coastguard Worker 	    (p->global->branch_list = avrule_decl_create(1)) == NULL) {
896*2d543d20SAndroid Build Coastguard Worker 		goto err;
897*2d543d20SAndroid Build Coastguard Worker 	}
898*2d543d20SAndroid Build Coastguard Worker 	p->decl_val_to_struct = NULL;
899*2d543d20SAndroid Build Coastguard Worker 
900*2d543d20SAndroid Build Coastguard Worker 	rc = avtab_init(&p->te_avtab);
901*2d543d20SAndroid Build Coastguard Worker 	if (rc)
902*2d543d20SAndroid Build Coastguard Worker 		goto err;
903*2d543d20SAndroid Build Coastguard Worker 
904*2d543d20SAndroid Build Coastguard Worker 	rc = roles_init(p);
905*2d543d20SAndroid Build Coastguard Worker 	if (rc)
906*2d543d20SAndroid Build Coastguard Worker 		goto err;
907*2d543d20SAndroid Build Coastguard Worker 
908*2d543d20SAndroid Build Coastguard Worker 	rc = cond_policydb_init(p);
909*2d543d20SAndroid Build Coastguard Worker 	if (rc)
910*2d543d20SAndroid Build Coastguard Worker 		goto err;
911*2d543d20SAndroid Build Coastguard Worker 
912*2d543d20SAndroid Build Coastguard Worker 	p->filename_trans = hashtab_create(filenametr_hash, filenametr_cmp, (1 << 10));
913*2d543d20SAndroid Build Coastguard Worker 	if (!p->filename_trans) {
914*2d543d20SAndroid Build Coastguard Worker 		rc = -ENOMEM;
915*2d543d20SAndroid Build Coastguard Worker 		goto err;
916*2d543d20SAndroid Build Coastguard Worker 	}
917*2d543d20SAndroid Build Coastguard Worker 
918*2d543d20SAndroid Build Coastguard Worker 	p->range_tr = hashtab_create(rangetr_hash, rangetr_cmp, 256);
919*2d543d20SAndroid Build Coastguard Worker 	if (!p->range_tr) {
920*2d543d20SAndroid Build Coastguard Worker 		rc = -ENOMEM;
921*2d543d20SAndroid Build Coastguard Worker 		goto err;
922*2d543d20SAndroid Build Coastguard Worker 	}
923*2d543d20SAndroid Build Coastguard Worker 
924*2d543d20SAndroid Build Coastguard Worker 	ebitmap_init(&p->policycaps);
925*2d543d20SAndroid Build Coastguard Worker 	ebitmap_init(&p->permissive_map);
926*2d543d20SAndroid Build Coastguard Worker 
927*2d543d20SAndroid Build Coastguard Worker 	return 0;
928*2d543d20SAndroid Build Coastguard Worker err:
929*2d543d20SAndroid Build Coastguard Worker 	hashtab_destroy(p->filename_trans);
930*2d543d20SAndroid Build Coastguard Worker 	hashtab_destroy(p->range_tr);
931*2d543d20SAndroid Build Coastguard Worker 	for (i = 0; i < SYM_NUM; i++) {
932*2d543d20SAndroid Build Coastguard Worker 		hashtab_destroy(p->symtab[i].table);
933*2d543d20SAndroid Build Coastguard Worker 		hashtab_destroy(p->scope[i].table);
934*2d543d20SAndroid Build Coastguard Worker 	}
935*2d543d20SAndroid Build Coastguard Worker 	avrule_block_list_destroy(p->global);
936*2d543d20SAndroid Build Coastguard Worker 	return rc;
937*2d543d20SAndroid Build Coastguard Worker }
938*2d543d20SAndroid Build Coastguard Worker 
policydb_role_cache(hashtab_key_t key,hashtab_datum_t datum,void * arg)939*2d543d20SAndroid Build Coastguard Worker int policydb_role_cache(hashtab_key_t key
940*2d543d20SAndroid Build Coastguard Worker 			__attribute__ ((unused)), hashtab_datum_t datum,
941*2d543d20SAndroid Build Coastguard Worker 			void *arg)
942*2d543d20SAndroid Build Coastguard Worker {
943*2d543d20SAndroid Build Coastguard Worker 	policydb_t *p;
944*2d543d20SAndroid Build Coastguard Worker 	role_datum_t *role;
945*2d543d20SAndroid Build Coastguard Worker 
946*2d543d20SAndroid Build Coastguard Worker 	role = (role_datum_t *) datum;
947*2d543d20SAndroid Build Coastguard Worker 	p = (policydb_t *) arg;
948*2d543d20SAndroid Build Coastguard Worker 
949*2d543d20SAndroid Build Coastguard Worker 	ebitmap_destroy(&role->cache);
950*2d543d20SAndroid Build Coastguard Worker 	if (type_set_expand(&role->types, &role->cache, p, 1)) {
951*2d543d20SAndroid Build Coastguard Worker 		return -1;
952*2d543d20SAndroid Build Coastguard Worker 	}
953*2d543d20SAndroid Build Coastguard Worker 
954*2d543d20SAndroid Build Coastguard Worker 	return 0;
955*2d543d20SAndroid Build Coastguard Worker }
956*2d543d20SAndroid Build Coastguard Worker 
policydb_user_cache(hashtab_key_t key,hashtab_datum_t datum,void * arg)957*2d543d20SAndroid Build Coastguard Worker int policydb_user_cache(hashtab_key_t key
958*2d543d20SAndroid Build Coastguard Worker 			__attribute__ ((unused)), hashtab_datum_t datum,
959*2d543d20SAndroid Build Coastguard Worker 			void *arg)
960*2d543d20SAndroid Build Coastguard Worker {
961*2d543d20SAndroid Build Coastguard Worker 	policydb_t *p;
962*2d543d20SAndroid Build Coastguard Worker 	user_datum_t *user;
963*2d543d20SAndroid Build Coastguard Worker 
964*2d543d20SAndroid Build Coastguard Worker 	user = (user_datum_t *) datum;
965*2d543d20SAndroid Build Coastguard Worker 	p = (policydb_t *) arg;
966*2d543d20SAndroid Build Coastguard Worker 
967*2d543d20SAndroid Build Coastguard Worker 	ebitmap_destroy(&user->cache);
968*2d543d20SAndroid Build Coastguard Worker 	if (role_set_expand(&user->roles, &user->cache, p, NULL, NULL)) {
969*2d543d20SAndroid Build Coastguard Worker 		return -1;
970*2d543d20SAndroid Build Coastguard Worker 	}
971*2d543d20SAndroid Build Coastguard Worker 
972*2d543d20SAndroid Build Coastguard Worker 	/* we do not expand user's MLS info in kernel policies because the
973*2d543d20SAndroid Build Coastguard Worker 	 * semantic representation is not present and we do not expand user's
974*2d543d20SAndroid Build Coastguard Worker 	 * MLS info in module policies because all of the necessary mls
975*2d543d20SAndroid Build Coastguard Worker 	 * information is not present */
976*2d543d20SAndroid Build Coastguard Worker 	if (p->policy_type != POLICY_KERN && p->policy_type != POLICY_MOD) {
977*2d543d20SAndroid Build Coastguard Worker 		mls_range_destroy(&user->exp_range);
978*2d543d20SAndroid Build Coastguard Worker 		if (mls_semantic_range_expand(&user->range,
979*2d543d20SAndroid Build Coastguard Worker 					      &user->exp_range, p, NULL)) {
980*2d543d20SAndroid Build Coastguard Worker 			return -1;
981*2d543d20SAndroid Build Coastguard Worker 		}
982*2d543d20SAndroid Build Coastguard Worker 
983*2d543d20SAndroid Build Coastguard Worker 		mls_level_destroy(&user->exp_dfltlevel);
984*2d543d20SAndroid Build Coastguard Worker 		if (mls_semantic_level_expand(&user->dfltlevel,
985*2d543d20SAndroid Build Coastguard Worker 					      &user->exp_dfltlevel, p, NULL)) {
986*2d543d20SAndroid Build Coastguard Worker 			return -1;
987*2d543d20SAndroid Build Coastguard Worker 		}
988*2d543d20SAndroid Build Coastguard Worker 	}
989*2d543d20SAndroid Build Coastguard Worker 
990*2d543d20SAndroid Build Coastguard Worker 	return 0;
991*2d543d20SAndroid Build Coastguard Worker }
992*2d543d20SAndroid Build Coastguard Worker 
993*2d543d20SAndroid Build Coastguard Worker /*
994*2d543d20SAndroid Build Coastguard Worker  * The following *_index functions are used to
995*2d543d20SAndroid Build Coastguard Worker  * define the val_to_name and val_to_struct arrays
996*2d543d20SAndroid Build Coastguard Worker  * in a policy database structure.  The val_to_name
997*2d543d20SAndroid Build Coastguard Worker  * arrays are used when converting security context
998*2d543d20SAndroid Build Coastguard Worker  * structures into string representations.  The
999*2d543d20SAndroid Build Coastguard Worker  * val_to_struct arrays are used when the attributes
1000*2d543d20SAndroid Build Coastguard Worker  * of a class, role, or user are needed.
1001*2d543d20SAndroid Build Coastguard Worker  */
1002*2d543d20SAndroid Build Coastguard Worker 
common_index(hashtab_key_t key,hashtab_datum_t datum,void * datap)1003*2d543d20SAndroid Build Coastguard Worker static int common_index(hashtab_key_t key, hashtab_datum_t datum, void *datap)
1004*2d543d20SAndroid Build Coastguard Worker {
1005*2d543d20SAndroid Build Coastguard Worker 	policydb_t *p;
1006*2d543d20SAndroid Build Coastguard Worker 	common_datum_t *comdatum;
1007*2d543d20SAndroid Build Coastguard Worker 
1008*2d543d20SAndroid Build Coastguard Worker 	comdatum = (common_datum_t *) datum;
1009*2d543d20SAndroid Build Coastguard Worker 	p = (policydb_t *) datap;
1010*2d543d20SAndroid Build Coastguard Worker 	if (!value_isvalid(comdatum->s.value, p->p_commons.nprim))
1011*2d543d20SAndroid Build Coastguard Worker 		return -EINVAL;
1012*2d543d20SAndroid Build Coastguard Worker 	if (p->p_common_val_to_name[comdatum->s.value - 1] != NULL)
1013*2d543d20SAndroid Build Coastguard Worker 		return -EINVAL;
1014*2d543d20SAndroid Build Coastguard Worker 	p->p_common_val_to_name[comdatum->s.value - 1] = (char *)key;
1015*2d543d20SAndroid Build Coastguard Worker 
1016*2d543d20SAndroid Build Coastguard Worker 	return 0;
1017*2d543d20SAndroid Build Coastguard Worker }
1018*2d543d20SAndroid Build Coastguard Worker 
class_index(hashtab_key_t key,hashtab_datum_t datum,void * datap)1019*2d543d20SAndroid Build Coastguard Worker static int class_index(hashtab_key_t key, hashtab_datum_t datum, void *datap)
1020*2d543d20SAndroid Build Coastguard Worker {
1021*2d543d20SAndroid Build Coastguard Worker 	policydb_t *p;
1022*2d543d20SAndroid Build Coastguard Worker 	class_datum_t *cladatum;
1023*2d543d20SAndroid Build Coastguard Worker 
1024*2d543d20SAndroid Build Coastguard Worker 	cladatum = (class_datum_t *) datum;
1025*2d543d20SAndroid Build Coastguard Worker 	p = (policydb_t *) datap;
1026*2d543d20SAndroid Build Coastguard Worker 	if (!value_isvalid(cladatum->s.value, p->p_classes.nprim))
1027*2d543d20SAndroid Build Coastguard Worker 		return -EINVAL;
1028*2d543d20SAndroid Build Coastguard Worker 	if (p->p_class_val_to_name[cladatum->s.value - 1] != NULL)
1029*2d543d20SAndroid Build Coastguard Worker 		return -EINVAL;
1030*2d543d20SAndroid Build Coastguard Worker 	p->p_class_val_to_name[cladatum->s.value - 1] = (char *)key;
1031*2d543d20SAndroid Build Coastguard Worker 	p->class_val_to_struct[cladatum->s.value - 1] = cladatum;
1032*2d543d20SAndroid Build Coastguard Worker 
1033*2d543d20SAndroid Build Coastguard Worker 	return 0;
1034*2d543d20SAndroid Build Coastguard Worker }
1035*2d543d20SAndroid Build Coastguard Worker 
role_index(hashtab_key_t key,hashtab_datum_t datum,void * datap)1036*2d543d20SAndroid Build Coastguard Worker static int role_index(hashtab_key_t key, hashtab_datum_t datum, void *datap)
1037*2d543d20SAndroid Build Coastguard Worker {
1038*2d543d20SAndroid Build Coastguard Worker 	policydb_t *p;
1039*2d543d20SAndroid Build Coastguard Worker 	role_datum_t *role;
1040*2d543d20SAndroid Build Coastguard Worker 
1041*2d543d20SAndroid Build Coastguard Worker 	role = (role_datum_t *) datum;
1042*2d543d20SAndroid Build Coastguard Worker 	p = (policydb_t *) datap;
1043*2d543d20SAndroid Build Coastguard Worker 	if (!value_isvalid(role->s.value, p->p_roles.nprim))
1044*2d543d20SAndroid Build Coastguard Worker 		return -EINVAL;
1045*2d543d20SAndroid Build Coastguard Worker 	if (p->p_role_val_to_name[role->s.value - 1] != NULL)
1046*2d543d20SAndroid Build Coastguard Worker 		return -EINVAL;
1047*2d543d20SAndroid Build Coastguard Worker 	p->p_role_val_to_name[role->s.value - 1] = (char *)key;
1048*2d543d20SAndroid Build Coastguard Worker 	p->role_val_to_struct[role->s.value - 1] = role;
1049*2d543d20SAndroid Build Coastguard Worker 
1050*2d543d20SAndroid Build Coastguard Worker 	return 0;
1051*2d543d20SAndroid Build Coastguard Worker }
1052*2d543d20SAndroid Build Coastguard Worker 
type_index(hashtab_key_t key,hashtab_datum_t datum,void * datap)1053*2d543d20SAndroid Build Coastguard Worker static int type_index(hashtab_key_t key, hashtab_datum_t datum, void *datap)
1054*2d543d20SAndroid Build Coastguard Worker {
1055*2d543d20SAndroid Build Coastguard Worker 	policydb_t *p;
1056*2d543d20SAndroid Build Coastguard Worker 	type_datum_t *typdatum;
1057*2d543d20SAndroid Build Coastguard Worker 
1058*2d543d20SAndroid Build Coastguard Worker 	typdatum = (type_datum_t *) datum;
1059*2d543d20SAndroid Build Coastguard Worker 	p = (policydb_t *) datap;
1060*2d543d20SAndroid Build Coastguard Worker 
1061*2d543d20SAndroid Build Coastguard Worker 	if (typdatum->primary) {
1062*2d543d20SAndroid Build Coastguard Worker 		if (!value_isvalid(typdatum->s.value, p->p_types.nprim))
1063*2d543d20SAndroid Build Coastguard Worker 			return -EINVAL;
1064*2d543d20SAndroid Build Coastguard Worker 		if (p->p_type_val_to_name[typdatum->s.value - 1] != NULL)
1065*2d543d20SAndroid Build Coastguard Worker 			return -EINVAL;
1066*2d543d20SAndroid Build Coastguard Worker 		p->p_type_val_to_name[typdatum->s.value - 1] = (char *)key;
1067*2d543d20SAndroid Build Coastguard Worker 		p->type_val_to_struct[typdatum->s.value - 1] = typdatum;
1068*2d543d20SAndroid Build Coastguard Worker 	}
1069*2d543d20SAndroid Build Coastguard Worker 
1070*2d543d20SAndroid Build Coastguard Worker 	return 0;
1071*2d543d20SAndroid Build Coastguard Worker }
1072*2d543d20SAndroid Build Coastguard Worker 
user_index(hashtab_key_t key,hashtab_datum_t datum,void * datap)1073*2d543d20SAndroid Build Coastguard Worker static int user_index(hashtab_key_t key, hashtab_datum_t datum, void *datap)
1074*2d543d20SAndroid Build Coastguard Worker {
1075*2d543d20SAndroid Build Coastguard Worker 	policydb_t *p;
1076*2d543d20SAndroid Build Coastguard Worker 	user_datum_t *usrdatum;
1077*2d543d20SAndroid Build Coastguard Worker 
1078*2d543d20SAndroid Build Coastguard Worker 	usrdatum = (user_datum_t *) datum;
1079*2d543d20SAndroid Build Coastguard Worker 	p = (policydb_t *) datap;
1080*2d543d20SAndroid Build Coastguard Worker 
1081*2d543d20SAndroid Build Coastguard Worker 	if (!value_isvalid(usrdatum->s.value, p->p_users.nprim))
1082*2d543d20SAndroid Build Coastguard Worker 		return -EINVAL;
1083*2d543d20SAndroid Build Coastguard Worker 	if (p->p_user_val_to_name[usrdatum->s.value - 1] != NULL)
1084*2d543d20SAndroid Build Coastguard Worker 		return -EINVAL;
1085*2d543d20SAndroid Build Coastguard Worker 	p->p_user_val_to_name[usrdatum->s.value - 1] = (char *)key;
1086*2d543d20SAndroid Build Coastguard Worker 	p->user_val_to_struct[usrdatum->s.value - 1] = usrdatum;
1087*2d543d20SAndroid Build Coastguard Worker 
1088*2d543d20SAndroid Build Coastguard Worker 	return 0;
1089*2d543d20SAndroid Build Coastguard Worker }
1090*2d543d20SAndroid Build Coastguard Worker 
sens_index(hashtab_key_t key,hashtab_datum_t datum,void * datap)1091*2d543d20SAndroid Build Coastguard Worker static int sens_index(hashtab_key_t key, hashtab_datum_t datum, void *datap)
1092*2d543d20SAndroid Build Coastguard Worker {
1093*2d543d20SAndroid Build Coastguard Worker 	policydb_t *p;
1094*2d543d20SAndroid Build Coastguard Worker 	level_datum_t *levdatum;
1095*2d543d20SAndroid Build Coastguard Worker 
1096*2d543d20SAndroid Build Coastguard Worker 	levdatum = (level_datum_t *) datum;
1097*2d543d20SAndroid Build Coastguard Worker 	p = (policydb_t *) datap;
1098*2d543d20SAndroid Build Coastguard Worker 
1099*2d543d20SAndroid Build Coastguard Worker 	if (!levdatum->isalias) {
1100*2d543d20SAndroid Build Coastguard Worker 		if (!value_isvalid(levdatum->level->sens, p->p_levels.nprim))
1101*2d543d20SAndroid Build Coastguard Worker 			return -EINVAL;
1102*2d543d20SAndroid Build Coastguard Worker 		if (p->p_sens_val_to_name[levdatum->level->sens - 1] != NULL)
1103*2d543d20SAndroid Build Coastguard Worker 			return -EINVAL;
1104*2d543d20SAndroid Build Coastguard Worker 		p->p_sens_val_to_name[levdatum->level->sens - 1] = (char *)key;
1105*2d543d20SAndroid Build Coastguard Worker 	}
1106*2d543d20SAndroid Build Coastguard Worker 
1107*2d543d20SAndroid Build Coastguard Worker 	return 0;
1108*2d543d20SAndroid Build Coastguard Worker }
1109*2d543d20SAndroid Build Coastguard Worker 
cat_index(hashtab_key_t key,hashtab_datum_t datum,void * datap)1110*2d543d20SAndroid Build Coastguard Worker static int cat_index(hashtab_key_t key, hashtab_datum_t datum, void *datap)
1111*2d543d20SAndroid Build Coastguard Worker {
1112*2d543d20SAndroid Build Coastguard Worker 	policydb_t *p;
1113*2d543d20SAndroid Build Coastguard Worker 	cat_datum_t *catdatum;
1114*2d543d20SAndroid Build Coastguard Worker 
1115*2d543d20SAndroid Build Coastguard Worker 	catdatum = (cat_datum_t *) datum;
1116*2d543d20SAndroid Build Coastguard Worker 	p = (policydb_t *) datap;
1117*2d543d20SAndroid Build Coastguard Worker 
1118*2d543d20SAndroid Build Coastguard Worker 	if (!catdatum->isalias) {
1119*2d543d20SAndroid Build Coastguard Worker 		if (!value_isvalid(catdatum->s.value, p->p_cats.nprim))
1120*2d543d20SAndroid Build Coastguard Worker 			return -EINVAL;
1121*2d543d20SAndroid Build Coastguard Worker 		if (p->p_cat_val_to_name[catdatum->s.value - 1] != NULL)
1122*2d543d20SAndroid Build Coastguard Worker 			return -EINVAL;
1123*2d543d20SAndroid Build Coastguard Worker 		p->p_cat_val_to_name[catdatum->s.value - 1] = (char *)key;
1124*2d543d20SAndroid Build Coastguard Worker 	}
1125*2d543d20SAndroid Build Coastguard Worker 
1126*2d543d20SAndroid Build Coastguard Worker 	return 0;
1127*2d543d20SAndroid Build Coastguard Worker }
1128*2d543d20SAndroid Build Coastguard Worker 
1129*2d543d20SAndroid Build Coastguard Worker static int (*const index_f[SYM_NUM]) (hashtab_key_t key, hashtab_datum_t datum,
1130*2d543d20SAndroid Build Coastguard Worker 				void *datap) = {
1131*2d543d20SAndroid Build Coastguard Worker common_index, class_index, role_index, type_index, user_index,
1132*2d543d20SAndroid Build Coastguard Worker 	    cond_index_bool, sens_index, cat_index,};
1133*2d543d20SAndroid Build Coastguard Worker 
1134*2d543d20SAndroid Build Coastguard Worker /*
1135*2d543d20SAndroid Build Coastguard Worker  * Define the common val_to_name array and the class
1136*2d543d20SAndroid Build Coastguard Worker  * val_to_name and val_to_struct arrays in a policy
1137*2d543d20SAndroid Build Coastguard Worker  * database structure.
1138*2d543d20SAndroid Build Coastguard Worker  */
policydb_index_classes(policydb_t * p)1139*2d543d20SAndroid Build Coastguard Worker int policydb_index_classes(policydb_t * p)
1140*2d543d20SAndroid Build Coastguard Worker {
1141*2d543d20SAndroid Build Coastguard Worker 	free(p->p_common_val_to_name);
1142*2d543d20SAndroid Build Coastguard Worker 	p->p_common_val_to_name = (char **)
1143*2d543d20SAndroid Build Coastguard Worker 	    calloc(p->p_commons.nprim, sizeof(char *));
1144*2d543d20SAndroid Build Coastguard Worker 	if (!p->p_common_val_to_name)
1145*2d543d20SAndroid Build Coastguard Worker 		return -1;
1146*2d543d20SAndroid Build Coastguard Worker 
1147*2d543d20SAndroid Build Coastguard Worker 	if (hashtab_map(p->p_commons.table, common_index, p))
1148*2d543d20SAndroid Build Coastguard Worker 		return -1;
1149*2d543d20SAndroid Build Coastguard Worker 
1150*2d543d20SAndroid Build Coastguard Worker 	free(p->class_val_to_struct);
1151*2d543d20SAndroid Build Coastguard Worker 	p->class_val_to_struct = (class_datum_t **)
1152*2d543d20SAndroid Build Coastguard Worker 	    calloc(p->p_classes.nprim, sizeof(class_datum_t *));
1153*2d543d20SAndroid Build Coastguard Worker 	if (!p->class_val_to_struct)
1154*2d543d20SAndroid Build Coastguard Worker 		return -1;
1155*2d543d20SAndroid Build Coastguard Worker 
1156*2d543d20SAndroid Build Coastguard Worker 	free(p->p_class_val_to_name);
1157*2d543d20SAndroid Build Coastguard Worker 	p->p_class_val_to_name = (char **)
1158*2d543d20SAndroid Build Coastguard Worker 	    calloc(p->p_classes.nprim, sizeof(char *));
1159*2d543d20SAndroid Build Coastguard Worker 	if (!p->p_class_val_to_name)
1160*2d543d20SAndroid Build Coastguard Worker 		return -1;
1161*2d543d20SAndroid Build Coastguard Worker 
1162*2d543d20SAndroid Build Coastguard Worker 	if (hashtab_map(p->p_classes.table, class_index, p))
1163*2d543d20SAndroid Build Coastguard Worker 		return -1;
1164*2d543d20SAndroid Build Coastguard Worker 
1165*2d543d20SAndroid Build Coastguard Worker 	return 0;
1166*2d543d20SAndroid Build Coastguard Worker }
1167*2d543d20SAndroid Build Coastguard Worker 
policydb_index_bools(policydb_t * p)1168*2d543d20SAndroid Build Coastguard Worker int policydb_index_bools(policydb_t * p)
1169*2d543d20SAndroid Build Coastguard Worker {
1170*2d543d20SAndroid Build Coastguard Worker 
1171*2d543d20SAndroid Build Coastguard Worker 	if (cond_init_bool_indexes(p) == -1)
1172*2d543d20SAndroid Build Coastguard Worker 		return -1;
1173*2d543d20SAndroid Build Coastguard Worker 	p->p_bool_val_to_name = (char **)
1174*2d543d20SAndroid Build Coastguard Worker 	    calloc(p->p_bools.nprim, sizeof(char *));
1175*2d543d20SAndroid Build Coastguard Worker 	if (!p->p_bool_val_to_name)
1176*2d543d20SAndroid Build Coastguard Worker 		return -1;
1177*2d543d20SAndroid Build Coastguard Worker 	if (hashtab_map(p->p_bools.table, cond_index_bool, p))
1178*2d543d20SAndroid Build Coastguard Worker 		return -1;
1179*2d543d20SAndroid Build Coastguard Worker 	return 0;
1180*2d543d20SAndroid Build Coastguard Worker }
1181*2d543d20SAndroid Build Coastguard Worker 
policydb_index_decls(sepol_handle_t * handle,policydb_t * p)1182*2d543d20SAndroid Build Coastguard Worker static int policydb_index_decls(sepol_handle_t * handle, policydb_t * p)
1183*2d543d20SAndroid Build Coastguard Worker {
1184*2d543d20SAndroid Build Coastguard Worker 	avrule_block_t *curblock;
1185*2d543d20SAndroid Build Coastguard Worker 	avrule_decl_t *decl;
1186*2d543d20SAndroid Build Coastguard Worker 	unsigned int num_decls = 0;
1187*2d543d20SAndroid Build Coastguard Worker 
1188*2d543d20SAndroid Build Coastguard Worker 	free(p->decl_val_to_struct);
1189*2d543d20SAndroid Build Coastguard Worker 
1190*2d543d20SAndroid Build Coastguard Worker 	for (curblock = p->global; curblock != NULL; curblock = curblock->next) {
1191*2d543d20SAndroid Build Coastguard Worker 		for (decl = curblock->branch_list; decl != NULL;
1192*2d543d20SAndroid Build Coastguard Worker 		     decl = decl->next) {
1193*2d543d20SAndroid Build Coastguard Worker 			num_decls++;
1194*2d543d20SAndroid Build Coastguard Worker 		}
1195*2d543d20SAndroid Build Coastguard Worker 	}
1196*2d543d20SAndroid Build Coastguard Worker 
1197*2d543d20SAndroid Build Coastguard Worker 	p->decl_val_to_struct =
1198*2d543d20SAndroid Build Coastguard Worker 	    calloc(num_decls, sizeof(*(p->decl_val_to_struct)));
1199*2d543d20SAndroid Build Coastguard Worker 	if (!p->decl_val_to_struct) {
1200*2d543d20SAndroid Build Coastguard Worker 		return -1;
1201*2d543d20SAndroid Build Coastguard Worker 	}
1202*2d543d20SAndroid Build Coastguard Worker 
1203*2d543d20SAndroid Build Coastguard Worker 	for (curblock = p->global; curblock != NULL; curblock = curblock->next) {
1204*2d543d20SAndroid Build Coastguard Worker 		for (decl = curblock->branch_list; decl != NULL;
1205*2d543d20SAndroid Build Coastguard Worker 		     decl = decl->next) {
1206*2d543d20SAndroid Build Coastguard Worker 			if (!value_isvalid(decl->decl_id, num_decls)) {
1207*2d543d20SAndroid Build Coastguard Worker 				ERR(handle, "invalid decl ID %u", decl->decl_id);
1208*2d543d20SAndroid Build Coastguard Worker 				return -1;
1209*2d543d20SAndroid Build Coastguard Worker 			}
1210*2d543d20SAndroid Build Coastguard Worker 			if (p->decl_val_to_struct[decl->decl_id - 1] != NULL) {
1211*2d543d20SAndroid Build Coastguard Worker 				ERR(handle, "duplicated decl ID %u", decl->decl_id);
1212*2d543d20SAndroid Build Coastguard Worker 				return -1;
1213*2d543d20SAndroid Build Coastguard Worker 			}
1214*2d543d20SAndroid Build Coastguard Worker 			p->decl_val_to_struct[decl->decl_id - 1] = decl;
1215*2d543d20SAndroid Build Coastguard Worker 		}
1216*2d543d20SAndroid Build Coastguard Worker 	}
1217*2d543d20SAndroid Build Coastguard Worker 
1218*2d543d20SAndroid Build Coastguard Worker 	return 0;
1219*2d543d20SAndroid Build Coastguard Worker }
1220*2d543d20SAndroid Build Coastguard Worker 
1221*2d543d20SAndroid Build Coastguard Worker /*
1222*2d543d20SAndroid Build Coastguard Worker  * Define the other val_to_name and val_to_struct arrays
1223*2d543d20SAndroid Build Coastguard Worker  * in a policy database structure.
1224*2d543d20SAndroid Build Coastguard Worker  */
policydb_index_others(sepol_handle_t * handle,policydb_t * p,unsigned verbose)1225*2d543d20SAndroid Build Coastguard Worker int policydb_index_others(sepol_handle_t * handle,
1226*2d543d20SAndroid Build Coastguard Worker 			  policydb_t * p, unsigned verbose)
1227*2d543d20SAndroid Build Coastguard Worker {
1228*2d543d20SAndroid Build Coastguard Worker 	int i;
1229*2d543d20SAndroid Build Coastguard Worker 
1230*2d543d20SAndroid Build Coastguard Worker 	if (verbose) {
1231*2d543d20SAndroid Build Coastguard Worker 		INFO(handle,
1232*2d543d20SAndroid Build Coastguard Worker 		     "security:  %d users, %d roles, %d types, %d bools",
1233*2d543d20SAndroid Build Coastguard Worker 		     p->p_users.nprim, p->p_roles.nprim, p->p_types.nprim,
1234*2d543d20SAndroid Build Coastguard Worker 		     p->p_bools.nprim);
1235*2d543d20SAndroid Build Coastguard Worker 
1236*2d543d20SAndroid Build Coastguard Worker 		if (p->mls)
1237*2d543d20SAndroid Build Coastguard Worker 			INFO(handle, "security: %d sens, %d cats",
1238*2d543d20SAndroid Build Coastguard Worker 			     p->p_levels.nprim, p->p_cats.nprim);
1239*2d543d20SAndroid Build Coastguard Worker 
1240*2d543d20SAndroid Build Coastguard Worker 		INFO(handle, "security:  %d classes, %d rules, %d cond rules",
1241*2d543d20SAndroid Build Coastguard Worker 		     p->p_classes.nprim, p->te_avtab.nel, p->te_cond_avtab.nel);
1242*2d543d20SAndroid Build Coastguard Worker 	}
1243*2d543d20SAndroid Build Coastguard Worker #if 0
1244*2d543d20SAndroid Build Coastguard Worker 	avtab_hash_eval(&p->te_avtab, "rules");
1245*2d543d20SAndroid Build Coastguard Worker 	for (i = 0; i < SYM_NUM; i++)
1246*2d543d20SAndroid Build Coastguard Worker 		hashtab_hash_eval(p->symtab[i].table, symtab_name[i]);
1247*2d543d20SAndroid Build Coastguard Worker #endif
1248*2d543d20SAndroid Build Coastguard Worker 
1249*2d543d20SAndroid Build Coastguard Worker 	free(p->role_val_to_struct);
1250*2d543d20SAndroid Build Coastguard Worker 	p->role_val_to_struct = (role_datum_t **)
1251*2d543d20SAndroid Build Coastguard Worker 	    calloc(p->p_roles.nprim, sizeof(role_datum_t *));
1252*2d543d20SAndroid Build Coastguard Worker 	if (!p->role_val_to_struct)
1253*2d543d20SAndroid Build Coastguard Worker 		return -1;
1254*2d543d20SAndroid Build Coastguard Worker 
1255*2d543d20SAndroid Build Coastguard Worker 	free(p->user_val_to_struct);
1256*2d543d20SAndroid Build Coastguard Worker 	p->user_val_to_struct = (user_datum_t **)
1257*2d543d20SAndroid Build Coastguard Worker 	    calloc(p->p_users.nprim, sizeof(user_datum_t *));
1258*2d543d20SAndroid Build Coastguard Worker 	if (!p->user_val_to_struct)
1259*2d543d20SAndroid Build Coastguard Worker 		return -1;
1260*2d543d20SAndroid Build Coastguard Worker 
1261*2d543d20SAndroid Build Coastguard Worker 	free(p->type_val_to_struct);
1262*2d543d20SAndroid Build Coastguard Worker 	p->type_val_to_struct = (type_datum_t **)
1263*2d543d20SAndroid Build Coastguard Worker 	    calloc(p->p_types.nprim, sizeof(type_datum_t *));
1264*2d543d20SAndroid Build Coastguard Worker 	if (!p->type_val_to_struct)
1265*2d543d20SAndroid Build Coastguard Worker 		return -1;
1266*2d543d20SAndroid Build Coastguard Worker 
1267*2d543d20SAndroid Build Coastguard Worker 	if (cond_init_bool_indexes(p))
1268*2d543d20SAndroid Build Coastguard Worker 		return -1;
1269*2d543d20SAndroid Build Coastguard Worker 
1270*2d543d20SAndroid Build Coastguard Worker 	for (i = SYM_ROLES; i < SYM_NUM; i++) {
1271*2d543d20SAndroid Build Coastguard Worker 		free(p->sym_val_to_name[i]);
1272*2d543d20SAndroid Build Coastguard Worker 		p->sym_val_to_name[i] = NULL;
1273*2d543d20SAndroid Build Coastguard Worker 		if (p->symtab[i].nprim) {
1274*2d543d20SAndroid Build Coastguard Worker 			p->sym_val_to_name[i] = (char **)
1275*2d543d20SAndroid Build Coastguard Worker 			    calloc(p->symtab[i].nprim, sizeof(char *));
1276*2d543d20SAndroid Build Coastguard Worker 			if (!p->sym_val_to_name[i])
1277*2d543d20SAndroid Build Coastguard Worker 				return -1;
1278*2d543d20SAndroid Build Coastguard Worker 			if (hashtab_map(p->symtab[i].table, index_f[i], p))
1279*2d543d20SAndroid Build Coastguard Worker 				return -1;
1280*2d543d20SAndroid Build Coastguard Worker 		}
1281*2d543d20SAndroid Build Coastguard Worker 	}
1282*2d543d20SAndroid Build Coastguard Worker 
1283*2d543d20SAndroid Build Coastguard Worker 	/* This pre-expands the roles and users for context validity checking */
1284*2d543d20SAndroid Build Coastguard Worker 	if (hashtab_map(p->p_roles.table, policydb_role_cache, p))
1285*2d543d20SAndroid Build Coastguard Worker 		return -1;
1286*2d543d20SAndroid Build Coastguard Worker 
1287*2d543d20SAndroid Build Coastguard Worker 	if (hashtab_map(p->p_users.table, policydb_user_cache, p))
1288*2d543d20SAndroid Build Coastguard Worker 		return -1;
1289*2d543d20SAndroid Build Coastguard Worker 
1290*2d543d20SAndroid Build Coastguard Worker 	return 0;
1291*2d543d20SAndroid Build Coastguard Worker }
1292*2d543d20SAndroid Build Coastguard Worker 
1293*2d543d20SAndroid Build Coastguard Worker /*
1294*2d543d20SAndroid Build Coastguard Worker  * The following *_destroy functions are used to
1295*2d543d20SAndroid Build Coastguard Worker  * free any memory allocated for each kind of
1296*2d543d20SAndroid Build Coastguard Worker  * symbol data in the policy database.
1297*2d543d20SAndroid Build Coastguard Worker  */
1298*2d543d20SAndroid Build Coastguard Worker 
perm_destroy(hashtab_key_t key,hashtab_datum_t datum,void * p)1299*2d543d20SAndroid Build Coastguard Worker static int perm_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p
1300*2d543d20SAndroid Build Coastguard Worker 			__attribute__ ((unused)))
1301*2d543d20SAndroid Build Coastguard Worker {
1302*2d543d20SAndroid Build Coastguard Worker 	if (key)
1303*2d543d20SAndroid Build Coastguard Worker 		free(key);
1304*2d543d20SAndroid Build Coastguard Worker 	free(datum);
1305*2d543d20SAndroid Build Coastguard Worker 	return 0;
1306*2d543d20SAndroid Build Coastguard Worker }
1307*2d543d20SAndroid Build Coastguard Worker 
common_destroy(hashtab_key_t key,hashtab_datum_t datum,void * p)1308*2d543d20SAndroid Build Coastguard Worker static int common_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p
1309*2d543d20SAndroid Build Coastguard Worker 			  __attribute__ ((unused)))
1310*2d543d20SAndroid Build Coastguard Worker {
1311*2d543d20SAndroid Build Coastguard Worker 	common_datum_t *comdatum;
1312*2d543d20SAndroid Build Coastguard Worker 
1313*2d543d20SAndroid Build Coastguard Worker 	if (key)
1314*2d543d20SAndroid Build Coastguard Worker 		free(key);
1315*2d543d20SAndroid Build Coastguard Worker 	comdatum = (common_datum_t *) datum;
1316*2d543d20SAndroid Build Coastguard Worker 	(void)hashtab_map(comdatum->permissions.table, perm_destroy, 0);
1317*2d543d20SAndroid Build Coastguard Worker 	hashtab_destroy(comdatum->permissions.table);
1318*2d543d20SAndroid Build Coastguard Worker 	free(datum);
1319*2d543d20SAndroid Build Coastguard Worker 	return 0;
1320*2d543d20SAndroid Build Coastguard Worker }
1321*2d543d20SAndroid Build Coastguard Worker 
class_destroy(hashtab_key_t key,hashtab_datum_t datum,void * p)1322*2d543d20SAndroid Build Coastguard Worker static int class_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p
1323*2d543d20SAndroid Build Coastguard Worker 			 __attribute__ ((unused)))
1324*2d543d20SAndroid Build Coastguard Worker {
1325*2d543d20SAndroid Build Coastguard Worker 	class_datum_t *cladatum;
1326*2d543d20SAndroid Build Coastguard Worker 	constraint_node_t *constraint, *ctemp;
1327*2d543d20SAndroid Build Coastguard Worker 
1328*2d543d20SAndroid Build Coastguard Worker 	if (key)
1329*2d543d20SAndroid Build Coastguard Worker 		free(key);
1330*2d543d20SAndroid Build Coastguard Worker 	cladatum = (class_datum_t *) datum;
1331*2d543d20SAndroid Build Coastguard Worker 	if (cladatum == NULL) {
1332*2d543d20SAndroid Build Coastguard Worker 		return 0;
1333*2d543d20SAndroid Build Coastguard Worker 	}
1334*2d543d20SAndroid Build Coastguard Worker 	(void)hashtab_map(cladatum->permissions.table, perm_destroy, 0);
1335*2d543d20SAndroid Build Coastguard Worker 	hashtab_destroy(cladatum->permissions.table);
1336*2d543d20SAndroid Build Coastguard Worker 	constraint = cladatum->constraints;
1337*2d543d20SAndroid Build Coastguard Worker 	while (constraint) {
1338*2d543d20SAndroid Build Coastguard Worker 		constraint_expr_destroy(constraint->expr);
1339*2d543d20SAndroid Build Coastguard Worker 		ctemp = constraint;
1340*2d543d20SAndroid Build Coastguard Worker 		constraint = constraint->next;
1341*2d543d20SAndroid Build Coastguard Worker 		free(ctemp);
1342*2d543d20SAndroid Build Coastguard Worker 	}
1343*2d543d20SAndroid Build Coastguard Worker 
1344*2d543d20SAndroid Build Coastguard Worker 	constraint = cladatum->validatetrans;
1345*2d543d20SAndroid Build Coastguard Worker 	while (constraint) {
1346*2d543d20SAndroid Build Coastguard Worker 		constraint_expr_destroy(constraint->expr);
1347*2d543d20SAndroid Build Coastguard Worker 		ctemp = constraint;
1348*2d543d20SAndroid Build Coastguard Worker 		constraint = constraint->next;
1349*2d543d20SAndroid Build Coastguard Worker 		free(ctemp);
1350*2d543d20SAndroid Build Coastguard Worker 	}
1351*2d543d20SAndroid Build Coastguard Worker 
1352*2d543d20SAndroid Build Coastguard Worker 	if (cladatum->comkey)
1353*2d543d20SAndroid Build Coastguard Worker 		free(cladatum->comkey);
1354*2d543d20SAndroid Build Coastguard Worker 	free(datum);
1355*2d543d20SAndroid Build Coastguard Worker 	return 0;
1356*2d543d20SAndroid Build Coastguard Worker }
1357*2d543d20SAndroid Build Coastguard Worker 
role_destroy(hashtab_key_t key,hashtab_datum_t datum,void * p)1358*2d543d20SAndroid Build Coastguard Worker static int role_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p
1359*2d543d20SAndroid Build Coastguard Worker 			__attribute__ ((unused)))
1360*2d543d20SAndroid Build Coastguard Worker {
1361*2d543d20SAndroid Build Coastguard Worker 	free(key);
1362*2d543d20SAndroid Build Coastguard Worker 	role_datum_destroy((role_datum_t *) datum);
1363*2d543d20SAndroid Build Coastguard Worker 	free(datum);
1364*2d543d20SAndroid Build Coastguard Worker 	return 0;
1365*2d543d20SAndroid Build Coastguard Worker }
1366*2d543d20SAndroid Build Coastguard Worker 
type_destroy(hashtab_key_t key,hashtab_datum_t datum,void * p)1367*2d543d20SAndroid Build Coastguard Worker static int type_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p
1368*2d543d20SAndroid Build Coastguard Worker 			__attribute__ ((unused)))
1369*2d543d20SAndroid Build Coastguard Worker {
1370*2d543d20SAndroid Build Coastguard Worker 	free(key);
1371*2d543d20SAndroid Build Coastguard Worker 	type_datum_destroy((type_datum_t *) datum);
1372*2d543d20SAndroid Build Coastguard Worker 	free(datum);
1373*2d543d20SAndroid Build Coastguard Worker 	return 0;
1374*2d543d20SAndroid Build Coastguard Worker }
1375*2d543d20SAndroid Build Coastguard Worker 
user_destroy(hashtab_key_t key,hashtab_datum_t datum,void * p)1376*2d543d20SAndroid Build Coastguard Worker static int user_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p
1377*2d543d20SAndroid Build Coastguard Worker 			__attribute__ ((unused)))
1378*2d543d20SAndroid Build Coastguard Worker {
1379*2d543d20SAndroid Build Coastguard Worker 	free(key);
1380*2d543d20SAndroid Build Coastguard Worker 	user_datum_destroy((user_datum_t *) datum);
1381*2d543d20SAndroid Build Coastguard Worker 	free(datum);
1382*2d543d20SAndroid Build Coastguard Worker 	return 0;
1383*2d543d20SAndroid Build Coastguard Worker }
1384*2d543d20SAndroid Build Coastguard Worker 
sens_destroy(hashtab_key_t key,hashtab_datum_t datum,void * p)1385*2d543d20SAndroid Build Coastguard Worker static int sens_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p
1386*2d543d20SAndroid Build Coastguard Worker 			__attribute__ ((unused)))
1387*2d543d20SAndroid Build Coastguard Worker {
1388*2d543d20SAndroid Build Coastguard Worker 	level_datum_t *levdatum;
1389*2d543d20SAndroid Build Coastguard Worker 
1390*2d543d20SAndroid Build Coastguard Worker 	if (key)
1391*2d543d20SAndroid Build Coastguard Worker 		free(key);
1392*2d543d20SAndroid Build Coastguard Worker 	levdatum = (level_datum_t *) datum;
1393*2d543d20SAndroid Build Coastguard Worker 	if (!levdatum->isalias || !levdatum->notdefined) {
1394*2d543d20SAndroid Build Coastguard Worker 		mls_level_destroy(levdatum->level);
1395*2d543d20SAndroid Build Coastguard Worker 		free(levdatum->level);
1396*2d543d20SAndroid Build Coastguard Worker 	}
1397*2d543d20SAndroid Build Coastguard Worker 	level_datum_destroy(levdatum);
1398*2d543d20SAndroid Build Coastguard Worker 	free(levdatum);
1399*2d543d20SAndroid Build Coastguard Worker 	return 0;
1400*2d543d20SAndroid Build Coastguard Worker }
1401*2d543d20SAndroid Build Coastguard Worker 
cat_destroy(hashtab_key_t key,hashtab_datum_t datum,void * p)1402*2d543d20SAndroid Build Coastguard Worker static int cat_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p
1403*2d543d20SAndroid Build Coastguard Worker 		       __attribute__ ((unused)))
1404*2d543d20SAndroid Build Coastguard Worker {
1405*2d543d20SAndroid Build Coastguard Worker 	if (key)
1406*2d543d20SAndroid Build Coastguard Worker 		free(key);
1407*2d543d20SAndroid Build Coastguard Worker 	cat_datum_destroy((cat_datum_t *) datum);
1408*2d543d20SAndroid Build Coastguard Worker 	free(datum);
1409*2d543d20SAndroid Build Coastguard Worker 	return 0;
1410*2d543d20SAndroid Build Coastguard Worker }
1411*2d543d20SAndroid Build Coastguard Worker 
1412*2d543d20SAndroid Build Coastguard Worker static int (*const destroy_f[SYM_NUM]) (hashtab_key_t key, hashtab_datum_t datum,
1413*2d543d20SAndroid Build Coastguard Worker 				  void *datap) = {
1414*2d543d20SAndroid Build Coastguard Worker common_destroy, class_destroy, role_destroy, type_destroy, user_destroy,
1415*2d543d20SAndroid Build Coastguard Worker 	    cond_destroy_bool, sens_destroy, cat_destroy,};
1416*2d543d20SAndroid Build Coastguard Worker 
filenametr_destroy(hashtab_key_t key,hashtab_datum_t datum,void * p)1417*2d543d20SAndroid Build Coastguard Worker static int filenametr_destroy(hashtab_key_t key, hashtab_datum_t datum,
1418*2d543d20SAndroid Build Coastguard Worker 			      void *p __attribute__ ((unused)))
1419*2d543d20SAndroid Build Coastguard Worker {
1420*2d543d20SAndroid Build Coastguard Worker 	filename_trans_key_t *ft = (filename_trans_key_t *)key;
1421*2d543d20SAndroid Build Coastguard Worker 	filename_trans_datum_t *fd = datum, *next;
1422*2d543d20SAndroid Build Coastguard Worker 
1423*2d543d20SAndroid Build Coastguard Worker 	free(ft->name);
1424*2d543d20SAndroid Build Coastguard Worker 	free(key);
1425*2d543d20SAndroid Build Coastguard Worker 	do {
1426*2d543d20SAndroid Build Coastguard Worker 		next = fd->next;
1427*2d543d20SAndroid Build Coastguard Worker 		ebitmap_destroy(&fd->stypes);
1428*2d543d20SAndroid Build Coastguard Worker 		free(fd);
1429*2d543d20SAndroid Build Coastguard Worker 		fd = next;
1430*2d543d20SAndroid Build Coastguard Worker 	} while (fd);
1431*2d543d20SAndroid Build Coastguard Worker 	return 0;
1432*2d543d20SAndroid Build Coastguard Worker }
1433*2d543d20SAndroid Build Coastguard Worker 
range_tr_destroy(hashtab_key_t key,hashtab_datum_t datum,void * p)1434*2d543d20SAndroid Build Coastguard Worker static int range_tr_destroy(hashtab_key_t key, hashtab_datum_t datum,
1435*2d543d20SAndroid Build Coastguard Worker 			    void *p __attribute__ ((unused)))
1436*2d543d20SAndroid Build Coastguard Worker {
1437*2d543d20SAndroid Build Coastguard Worker 	struct mls_range *rt = (struct mls_range *)datum;
1438*2d543d20SAndroid Build Coastguard Worker 	free(key);
1439*2d543d20SAndroid Build Coastguard Worker 	ebitmap_destroy(&rt->level[0].cat);
1440*2d543d20SAndroid Build Coastguard Worker 	ebitmap_destroy(&rt->level[1].cat);
1441*2d543d20SAndroid Build Coastguard Worker 	free(datum);
1442*2d543d20SAndroid Build Coastguard Worker 	return 0;
1443*2d543d20SAndroid Build Coastguard Worker }
1444*2d543d20SAndroid Build Coastguard Worker 
ocontext_selinux_free(ocontext_t ** ocontexts)1445*2d543d20SAndroid Build Coastguard Worker static void ocontext_selinux_free(ocontext_t **ocontexts)
1446*2d543d20SAndroid Build Coastguard Worker {
1447*2d543d20SAndroid Build Coastguard Worker 	ocontext_t *c, *ctmp;
1448*2d543d20SAndroid Build Coastguard Worker 	int i;
1449*2d543d20SAndroid Build Coastguard Worker 
1450*2d543d20SAndroid Build Coastguard Worker 	for (i = 0; i < OCON_NUM; i++) {
1451*2d543d20SAndroid Build Coastguard Worker 		c = ocontexts[i];
1452*2d543d20SAndroid Build Coastguard Worker 		while (c) {
1453*2d543d20SAndroid Build Coastguard Worker 			ctmp = c;
1454*2d543d20SAndroid Build Coastguard Worker 			c = c->next;
1455*2d543d20SAndroid Build Coastguard Worker 			context_destroy(&ctmp->context[0]);
1456*2d543d20SAndroid Build Coastguard Worker 			context_destroy(&ctmp->context[1]);
1457*2d543d20SAndroid Build Coastguard Worker 			if (i == OCON_ISID || i == OCON_FS || i == OCON_NETIF
1458*2d543d20SAndroid Build Coastguard Worker 				|| i == OCON_FSUSE)
1459*2d543d20SAndroid Build Coastguard Worker 				free(ctmp->u.name);
1460*2d543d20SAndroid Build Coastguard Worker 			else if (i == OCON_IBENDPORT)
1461*2d543d20SAndroid Build Coastguard Worker 				free(ctmp->u.ibendport.dev_name);
1462*2d543d20SAndroid Build Coastguard Worker 			free(ctmp);
1463*2d543d20SAndroid Build Coastguard Worker 		}
1464*2d543d20SAndroid Build Coastguard Worker 	}
1465*2d543d20SAndroid Build Coastguard Worker }
1466*2d543d20SAndroid Build Coastguard Worker 
ocontext_xen_free(ocontext_t ** ocontexts)1467*2d543d20SAndroid Build Coastguard Worker static void ocontext_xen_free(ocontext_t **ocontexts)
1468*2d543d20SAndroid Build Coastguard Worker {
1469*2d543d20SAndroid Build Coastguard Worker 	ocontext_t *c, *ctmp;
1470*2d543d20SAndroid Build Coastguard Worker 	int i;
1471*2d543d20SAndroid Build Coastguard Worker 
1472*2d543d20SAndroid Build Coastguard Worker 	for (i = 0; i < OCON_NUM; i++) {
1473*2d543d20SAndroid Build Coastguard Worker 		c = ocontexts[i];
1474*2d543d20SAndroid Build Coastguard Worker 		while (c) {
1475*2d543d20SAndroid Build Coastguard Worker 			ctmp = c;
1476*2d543d20SAndroid Build Coastguard Worker 			c = c->next;
1477*2d543d20SAndroid Build Coastguard Worker 			context_destroy(&ctmp->context[0]);
1478*2d543d20SAndroid Build Coastguard Worker 			context_destroy(&ctmp->context[1]);
1479*2d543d20SAndroid Build Coastguard Worker 			if (i == OCON_ISID || i == OCON_XEN_DEVICETREE)
1480*2d543d20SAndroid Build Coastguard Worker 				free(ctmp->u.name);
1481*2d543d20SAndroid Build Coastguard Worker 			free(ctmp);
1482*2d543d20SAndroid Build Coastguard Worker 		}
1483*2d543d20SAndroid Build Coastguard Worker 	}
1484*2d543d20SAndroid Build Coastguard Worker }
1485*2d543d20SAndroid Build Coastguard Worker 
1486*2d543d20SAndroid Build Coastguard Worker /*
1487*2d543d20SAndroid Build Coastguard Worker  * Free any memory allocated by a policy database structure.
1488*2d543d20SAndroid Build Coastguard Worker  */
policydb_destroy(policydb_t * p)1489*2d543d20SAndroid Build Coastguard Worker void policydb_destroy(policydb_t * p)
1490*2d543d20SAndroid Build Coastguard Worker {
1491*2d543d20SAndroid Build Coastguard Worker 	ocontext_t *c, *ctmp;
1492*2d543d20SAndroid Build Coastguard Worker 	genfs_t *g, *gtmp;
1493*2d543d20SAndroid Build Coastguard Worker 	unsigned int i;
1494*2d543d20SAndroid Build Coastguard Worker 	role_allow_t *ra, *lra = NULL;
1495*2d543d20SAndroid Build Coastguard Worker 	role_trans_t *tr, *ltr = NULL;
1496*2d543d20SAndroid Build Coastguard Worker 
1497*2d543d20SAndroid Build Coastguard Worker 	if (!p)
1498*2d543d20SAndroid Build Coastguard Worker 		return;
1499*2d543d20SAndroid Build Coastguard Worker 
1500*2d543d20SAndroid Build Coastguard Worker 	ebitmap_destroy(&p->policycaps);
1501*2d543d20SAndroid Build Coastguard Worker 
1502*2d543d20SAndroid Build Coastguard Worker 	ebitmap_destroy(&p->permissive_map);
1503*2d543d20SAndroid Build Coastguard Worker 
1504*2d543d20SAndroid Build Coastguard Worker 	symtabs_destroy(p->symtab);
1505*2d543d20SAndroid Build Coastguard Worker 
1506*2d543d20SAndroid Build Coastguard Worker 	for (i = 0; i < SYM_NUM; i++) {
1507*2d543d20SAndroid Build Coastguard Worker 		if (p->sym_val_to_name[i])
1508*2d543d20SAndroid Build Coastguard Worker 			free(p->sym_val_to_name[i]);
1509*2d543d20SAndroid Build Coastguard Worker 	}
1510*2d543d20SAndroid Build Coastguard Worker 
1511*2d543d20SAndroid Build Coastguard Worker 	if (p->class_val_to_struct)
1512*2d543d20SAndroid Build Coastguard Worker 		free(p->class_val_to_struct);
1513*2d543d20SAndroid Build Coastguard Worker 	if (p->role_val_to_struct)
1514*2d543d20SAndroid Build Coastguard Worker 		free(p->role_val_to_struct);
1515*2d543d20SAndroid Build Coastguard Worker 	if (p->user_val_to_struct)
1516*2d543d20SAndroid Build Coastguard Worker 		free(p->user_val_to_struct);
1517*2d543d20SAndroid Build Coastguard Worker 	if (p->type_val_to_struct)
1518*2d543d20SAndroid Build Coastguard Worker 		free(p->type_val_to_struct);
1519*2d543d20SAndroid Build Coastguard Worker 	free(p->decl_val_to_struct);
1520*2d543d20SAndroid Build Coastguard Worker 
1521*2d543d20SAndroid Build Coastguard Worker 	for (i = 0; i < SYM_NUM; i++) {
1522*2d543d20SAndroid Build Coastguard Worker 		(void)hashtab_map(p->scope[i].table, scope_destroy, 0);
1523*2d543d20SAndroid Build Coastguard Worker 		hashtab_destroy(p->scope[i].table);
1524*2d543d20SAndroid Build Coastguard Worker 	}
1525*2d543d20SAndroid Build Coastguard Worker 	avrule_block_list_destroy(p->global);
1526*2d543d20SAndroid Build Coastguard Worker 	free(p->name);
1527*2d543d20SAndroid Build Coastguard Worker 	free(p->version);
1528*2d543d20SAndroid Build Coastguard Worker 
1529*2d543d20SAndroid Build Coastguard Worker 	avtab_destroy(&p->te_avtab);
1530*2d543d20SAndroid Build Coastguard Worker 
1531*2d543d20SAndroid Build Coastguard Worker 	if (p->target_platform == SEPOL_TARGET_SELINUX)
1532*2d543d20SAndroid Build Coastguard Worker 		ocontext_selinux_free(p->ocontexts);
1533*2d543d20SAndroid Build Coastguard Worker 	else if (p->target_platform == SEPOL_TARGET_XEN)
1534*2d543d20SAndroid Build Coastguard Worker 		ocontext_xen_free(p->ocontexts);
1535*2d543d20SAndroid Build Coastguard Worker 
1536*2d543d20SAndroid Build Coastguard Worker 	g = p->genfs;
1537*2d543d20SAndroid Build Coastguard Worker 	while (g) {
1538*2d543d20SAndroid Build Coastguard Worker 		free(g->fstype);
1539*2d543d20SAndroid Build Coastguard Worker 		c = g->head;
1540*2d543d20SAndroid Build Coastguard Worker 		while (c) {
1541*2d543d20SAndroid Build Coastguard Worker 			ctmp = c;
1542*2d543d20SAndroid Build Coastguard Worker 			c = c->next;
1543*2d543d20SAndroid Build Coastguard Worker 			context_destroy(&ctmp->context[0]);
1544*2d543d20SAndroid Build Coastguard Worker 			free(ctmp->u.name);
1545*2d543d20SAndroid Build Coastguard Worker 			free(ctmp);
1546*2d543d20SAndroid Build Coastguard Worker 		}
1547*2d543d20SAndroid Build Coastguard Worker 		gtmp = g;
1548*2d543d20SAndroid Build Coastguard Worker 		g = g->next;
1549*2d543d20SAndroid Build Coastguard Worker 		free(gtmp);
1550*2d543d20SAndroid Build Coastguard Worker 	}
1551*2d543d20SAndroid Build Coastguard Worker 	cond_policydb_destroy(p);
1552*2d543d20SAndroid Build Coastguard Worker 
1553*2d543d20SAndroid Build Coastguard Worker 	for (tr = p->role_tr; tr; tr = tr->next) {
1554*2d543d20SAndroid Build Coastguard Worker 		if (ltr)
1555*2d543d20SAndroid Build Coastguard Worker 			free(ltr);
1556*2d543d20SAndroid Build Coastguard Worker 		ltr = tr;
1557*2d543d20SAndroid Build Coastguard Worker 	}
1558*2d543d20SAndroid Build Coastguard Worker 	if (ltr)
1559*2d543d20SAndroid Build Coastguard Worker 		free(ltr);
1560*2d543d20SAndroid Build Coastguard Worker 
1561*2d543d20SAndroid Build Coastguard Worker 	for (ra = p->role_allow; ra; ra = ra->next) {
1562*2d543d20SAndroid Build Coastguard Worker 		if (lra)
1563*2d543d20SAndroid Build Coastguard Worker 			free(lra);
1564*2d543d20SAndroid Build Coastguard Worker 		lra = ra;
1565*2d543d20SAndroid Build Coastguard Worker 	}
1566*2d543d20SAndroid Build Coastguard Worker 	if (lra)
1567*2d543d20SAndroid Build Coastguard Worker 		free(lra);
1568*2d543d20SAndroid Build Coastguard Worker 
1569*2d543d20SAndroid Build Coastguard Worker 	hashtab_map(p->filename_trans, filenametr_destroy, NULL);
1570*2d543d20SAndroid Build Coastguard Worker 	hashtab_destroy(p->filename_trans);
1571*2d543d20SAndroid Build Coastguard Worker 
1572*2d543d20SAndroid Build Coastguard Worker 	hashtab_map(p->range_tr, range_tr_destroy, NULL);
1573*2d543d20SAndroid Build Coastguard Worker 	hashtab_destroy(p->range_tr);
1574*2d543d20SAndroid Build Coastguard Worker 
1575*2d543d20SAndroid Build Coastguard Worker 	if (p->type_attr_map) {
1576*2d543d20SAndroid Build Coastguard Worker 		for (i = 0; i < p->p_types.nprim; i++) {
1577*2d543d20SAndroid Build Coastguard Worker 			ebitmap_destroy(&p->type_attr_map[i]);
1578*2d543d20SAndroid Build Coastguard Worker 		}
1579*2d543d20SAndroid Build Coastguard Worker 		free(p->type_attr_map);
1580*2d543d20SAndroid Build Coastguard Worker 	}
1581*2d543d20SAndroid Build Coastguard Worker 
1582*2d543d20SAndroid Build Coastguard Worker 	if (p->attr_type_map) {
1583*2d543d20SAndroid Build Coastguard Worker 		for (i = 0; i < p->p_types.nprim; i++) {
1584*2d543d20SAndroid Build Coastguard Worker 			ebitmap_destroy(&p->attr_type_map[i]);
1585*2d543d20SAndroid Build Coastguard Worker 		}
1586*2d543d20SAndroid Build Coastguard Worker 		free(p->attr_type_map);
1587*2d543d20SAndroid Build Coastguard Worker 	}
1588*2d543d20SAndroid Build Coastguard Worker 
1589*2d543d20SAndroid Build Coastguard Worker 	return;
1590*2d543d20SAndroid Build Coastguard Worker }
1591*2d543d20SAndroid Build Coastguard Worker 
symtabs_destroy(symtab_t * symtab)1592*2d543d20SAndroid Build Coastguard Worker void symtabs_destroy(symtab_t * symtab)
1593*2d543d20SAndroid Build Coastguard Worker {
1594*2d543d20SAndroid Build Coastguard Worker 	int i;
1595*2d543d20SAndroid Build Coastguard Worker 	for (i = 0; i < SYM_NUM; i++) {
1596*2d543d20SAndroid Build Coastguard Worker 		(void)hashtab_map(symtab[i].table, destroy_f[i], 0);
1597*2d543d20SAndroid Build Coastguard Worker 		hashtab_destroy(symtab[i].table);
1598*2d543d20SAndroid Build Coastguard Worker 	}
1599*2d543d20SAndroid Build Coastguard Worker }
1600*2d543d20SAndroid Build Coastguard Worker 
scope_destroy(hashtab_key_t key,hashtab_datum_t datum,void * p)1601*2d543d20SAndroid Build Coastguard Worker int scope_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p
1602*2d543d20SAndroid Build Coastguard Worker 		  __attribute__ ((unused)))
1603*2d543d20SAndroid Build Coastguard Worker {
1604*2d543d20SAndroid Build Coastguard Worker 	scope_datum_t *cur = (scope_datum_t *) datum;
1605*2d543d20SAndroid Build Coastguard Worker 	free(key);
1606*2d543d20SAndroid Build Coastguard Worker 	if (cur != NULL) {
1607*2d543d20SAndroid Build Coastguard Worker 		free(cur->decl_ids);
1608*2d543d20SAndroid Build Coastguard Worker 	}
1609*2d543d20SAndroid Build Coastguard Worker 	free(cur);
1610*2d543d20SAndroid Build Coastguard Worker 	return 0;
1611*2d543d20SAndroid Build Coastguard Worker }
1612*2d543d20SAndroid Build Coastguard Worker 
1613*2d543d20SAndroid Build Coastguard Worker /*
1614*2d543d20SAndroid Build Coastguard Worker  * Load the initial SIDs specified in a policy database
1615*2d543d20SAndroid Build Coastguard Worker  * structure into a SID table.
1616*2d543d20SAndroid Build Coastguard Worker  */
policydb_load_isids(policydb_t * p,sidtab_t * s)1617*2d543d20SAndroid Build Coastguard Worker int policydb_load_isids(policydb_t * p, sidtab_t * s)
1618*2d543d20SAndroid Build Coastguard Worker {
1619*2d543d20SAndroid Build Coastguard Worker 	ocontext_t *head, *c;
1620*2d543d20SAndroid Build Coastguard Worker 
1621*2d543d20SAndroid Build Coastguard Worker 	if (sepol_sidtab_init(s)) {
1622*2d543d20SAndroid Build Coastguard Worker 		ERR(NULL, "out of memory on SID table init");
1623*2d543d20SAndroid Build Coastguard Worker 		return -1;
1624*2d543d20SAndroid Build Coastguard Worker 	}
1625*2d543d20SAndroid Build Coastguard Worker 
1626*2d543d20SAndroid Build Coastguard Worker 	head = p->ocontexts[OCON_ISID];
1627*2d543d20SAndroid Build Coastguard Worker 	for (c = head; c; c = c->next) {
1628*2d543d20SAndroid Build Coastguard Worker 		if (sepol_sidtab_insert(s, c->sid[0], &c->context[0])) {
1629*2d543d20SAndroid Build Coastguard Worker 			ERR(NULL, "unable to load initial SID %s", c->u.name);
1630*2d543d20SAndroid Build Coastguard Worker 			return -1;
1631*2d543d20SAndroid Build Coastguard Worker 		}
1632*2d543d20SAndroid Build Coastguard Worker 	}
1633*2d543d20SAndroid Build Coastguard Worker 
1634*2d543d20SAndroid Build Coastguard Worker 	return 0;
1635*2d543d20SAndroid Build Coastguard Worker }
1636*2d543d20SAndroid Build Coastguard Worker 
1637*2d543d20SAndroid Build Coastguard Worker /* Declare a symbol for a certain avrule_block context.  Insert it
1638*2d543d20SAndroid Build Coastguard Worker  * into a symbol table for a policy.  This function will handle
1639*2d543d20SAndroid Build Coastguard Worker  * inserting the appropriate scope information in addition to
1640*2d543d20SAndroid Build Coastguard Worker  * inserting the symbol into the hash table.
1641*2d543d20SAndroid Build Coastguard Worker  *
1642*2d543d20SAndroid Build Coastguard Worker  * arguments:
1643*2d543d20SAndroid Build Coastguard Worker  *   policydb_t *pol       module policy to modify
1644*2d543d20SAndroid Build Coastguard Worker  *   uint32_t sym          the symbole table for insertion (SYM_*)
1645*2d543d20SAndroid Build Coastguard Worker  *   hashtab_key_t key     the key for the symbol - not cloned
1646*2d543d20SAndroid Build Coastguard Worker  *   hashtab_datum_t data  the data for the symbol - not cloned
1647*2d543d20SAndroid Build Coastguard Worker  *   scope                 scope of this symbol, either SCOPE_REQ or SCOPE_DECL
1648*2d543d20SAndroid Build Coastguard Worker  *   avrule_decl_id        identifier for this symbol's encapsulating declaration
1649*2d543d20SAndroid Build Coastguard Worker  *   value (out)           assigned value to the symbol (if value is not NULL)
1650*2d543d20SAndroid Build Coastguard Worker  *
1651*2d543d20SAndroid Build Coastguard Worker  * returns:
1652*2d543d20SAndroid Build Coastguard Worker  *   0                     success
1653*2d543d20SAndroid Build Coastguard Worker  *   1                     success, but symbol already existed as a requirement
1654*2d543d20SAndroid Build Coastguard Worker  *                         (datum was not inserted and needs to be free()d)
1655*2d543d20SAndroid Build Coastguard Worker  *   -1                    general error
1656*2d543d20SAndroid Build Coastguard Worker  *   -2                    scope conflicted
1657*2d543d20SAndroid Build Coastguard Worker  *   -ENOMEM               memory error
1658*2d543d20SAndroid Build Coastguard Worker  *   error codes from hashtab_insert
1659*2d543d20SAndroid Build Coastguard Worker  */
symtab_insert(policydb_t * pol,uint32_t sym,hashtab_key_t key,hashtab_datum_t datum,uint32_t scope,uint32_t avrule_decl_id,uint32_t * value)1660*2d543d20SAndroid Build Coastguard Worker int symtab_insert(policydb_t * pol, uint32_t sym,
1661*2d543d20SAndroid Build Coastguard Worker 		  hashtab_key_t key, hashtab_datum_t datum,
1662*2d543d20SAndroid Build Coastguard Worker 		  uint32_t scope, uint32_t avrule_decl_id, uint32_t * value)
1663*2d543d20SAndroid Build Coastguard Worker {
1664*2d543d20SAndroid Build Coastguard Worker 	int rc, retval = 0;
1665*2d543d20SAndroid Build Coastguard Worker 	unsigned int i;
1666*2d543d20SAndroid Build Coastguard Worker 	scope_datum_t *scope_datum;
1667*2d543d20SAndroid Build Coastguard Worker 
1668*2d543d20SAndroid Build Coastguard Worker 	/* check if the symbol is already there.  multiple
1669*2d543d20SAndroid Build Coastguard Worker 	 * declarations of non-roles/non-users are illegal, but
1670*2d543d20SAndroid Build Coastguard Worker 	 * multiple requires are allowed. */
1671*2d543d20SAndroid Build Coastguard Worker 
1672*2d543d20SAndroid Build Coastguard Worker 	/* FIX ME - the failures after the hashtab_insert will leave
1673*2d543d20SAndroid Build Coastguard Worker 	 * the policy in a inconsistent state. */
1674*2d543d20SAndroid Build Coastguard Worker 	rc = hashtab_insert(pol->symtab[sym].table, key, datum);
1675*2d543d20SAndroid Build Coastguard Worker 	if (rc == SEPOL_OK) {
1676*2d543d20SAndroid Build Coastguard Worker 		/* if no value is passed in the symbol is not primary
1677*2d543d20SAndroid Build Coastguard Worker 		 * (i.e. aliases) */
1678*2d543d20SAndroid Build Coastguard Worker 		if (value)
1679*2d543d20SAndroid Build Coastguard Worker 			*value = ++pol->symtab[sym].nprim;
1680*2d543d20SAndroid Build Coastguard Worker 	} else if (rc == SEPOL_EEXIST) {
1681*2d543d20SAndroid Build Coastguard Worker 		retval = 1;	/* symbol not added -- need to free() later */
1682*2d543d20SAndroid Build Coastguard Worker 	} else {
1683*2d543d20SAndroid Build Coastguard Worker 		return rc;
1684*2d543d20SAndroid Build Coastguard Worker 	}
1685*2d543d20SAndroid Build Coastguard Worker 
1686*2d543d20SAndroid Build Coastguard Worker 	/* get existing scope information; if there is not one then
1687*2d543d20SAndroid Build Coastguard Worker 	 * create it */
1688*2d543d20SAndroid Build Coastguard Worker 	scope_datum =
1689*2d543d20SAndroid Build Coastguard Worker 	    (scope_datum_t *) hashtab_search(pol->scope[sym].table, key);
1690*2d543d20SAndroid Build Coastguard Worker 	if (scope_datum == NULL) {
1691*2d543d20SAndroid Build Coastguard Worker 		hashtab_key_t key2 = strdup((char *)key);
1692*2d543d20SAndroid Build Coastguard Worker 		if (!key2)
1693*2d543d20SAndroid Build Coastguard Worker 			return -ENOMEM;
1694*2d543d20SAndroid Build Coastguard Worker 		if ((scope_datum = malloc(sizeof(*scope_datum))) == NULL) {
1695*2d543d20SAndroid Build Coastguard Worker 			free(key2);
1696*2d543d20SAndroid Build Coastguard Worker 			return -ENOMEM;
1697*2d543d20SAndroid Build Coastguard Worker 		}
1698*2d543d20SAndroid Build Coastguard Worker 		scope_datum->scope = scope;
1699*2d543d20SAndroid Build Coastguard Worker 		scope_datum->decl_ids = NULL;
1700*2d543d20SAndroid Build Coastguard Worker 		scope_datum->decl_ids_len = 0;
1701*2d543d20SAndroid Build Coastguard Worker 		if ((rc =
1702*2d543d20SAndroid Build Coastguard Worker 		     hashtab_insert(pol->scope[sym].table, key2,
1703*2d543d20SAndroid Build Coastguard Worker 				    scope_datum)) != 0) {
1704*2d543d20SAndroid Build Coastguard Worker 			free(key2);
1705*2d543d20SAndroid Build Coastguard Worker 			free(scope_datum);
1706*2d543d20SAndroid Build Coastguard Worker 			return rc;
1707*2d543d20SAndroid Build Coastguard Worker 		}
1708*2d543d20SAndroid Build Coastguard Worker 	} else if (scope_datum->scope == SCOPE_DECL && scope == SCOPE_DECL) {
1709*2d543d20SAndroid Build Coastguard Worker 		/* disallow multiple declarations for non-roles/users */
1710*2d543d20SAndroid Build Coastguard Worker 		if (sym != SYM_ROLES && sym != SYM_USERS) {
1711*2d543d20SAndroid Build Coastguard Worker 			return -2;
1712*2d543d20SAndroid Build Coastguard Worker 		}
1713*2d543d20SAndroid Build Coastguard Worker 		/* Further confine that a role attribute can't have the same
1714*2d543d20SAndroid Build Coastguard Worker 		 * name as another regular role, and a role attribute can't
1715*2d543d20SAndroid Build Coastguard Worker 		 * be declared more than once. */
1716*2d543d20SAndroid Build Coastguard Worker 		if (sym == SYM_ROLES) {
1717*2d543d20SAndroid Build Coastguard Worker 			role_datum_t *base_role;
1718*2d543d20SAndroid Build Coastguard Worker 			role_datum_t *cur_role = (role_datum_t *)datum;
1719*2d543d20SAndroid Build Coastguard Worker 
1720*2d543d20SAndroid Build Coastguard Worker 			base_role = (role_datum_t *)
1721*2d543d20SAndroid Build Coastguard Worker 					hashtab_search(pol->symtab[sym].table,
1722*2d543d20SAndroid Build Coastguard Worker 						       key);
1723*2d543d20SAndroid Build Coastguard Worker 			assert(base_role != NULL);
1724*2d543d20SAndroid Build Coastguard Worker 
1725*2d543d20SAndroid Build Coastguard Worker 			if (!((base_role->flavor == ROLE_ROLE) &&
1726*2d543d20SAndroid Build Coastguard Worker 			    (cur_role->flavor == ROLE_ROLE))) {
1727*2d543d20SAndroid Build Coastguard Worker 				/* Only regular roles are allowed to have
1728*2d543d20SAndroid Build Coastguard Worker 				 * multiple declarations. */
1729*2d543d20SAndroid Build Coastguard Worker 				return -2;
1730*2d543d20SAndroid Build Coastguard Worker 			}
1731*2d543d20SAndroid Build Coastguard Worker 		}
1732*2d543d20SAndroid Build Coastguard Worker 	} else if (scope_datum->scope == SCOPE_REQ && scope == SCOPE_DECL) {
1733*2d543d20SAndroid Build Coastguard Worker 		scope_datum->scope = SCOPE_DECL;
1734*2d543d20SAndroid Build Coastguard Worker 	}
1735*2d543d20SAndroid Build Coastguard Worker 
1736*2d543d20SAndroid Build Coastguard Worker 	/* search through the pre-existing list to avoid adding duplicates */
1737*2d543d20SAndroid Build Coastguard Worker 	for (i = 0; i < scope_datum->decl_ids_len; i++) {
1738*2d543d20SAndroid Build Coastguard Worker 		if (scope_datum->decl_ids[i] == avrule_decl_id) {
1739*2d543d20SAndroid Build Coastguard Worker 			/* already there, so don't modify its scope */
1740*2d543d20SAndroid Build Coastguard Worker 			return retval;
1741*2d543d20SAndroid Build Coastguard Worker 		}
1742*2d543d20SAndroid Build Coastguard Worker 	}
1743*2d543d20SAndroid Build Coastguard Worker 
1744*2d543d20SAndroid Build Coastguard Worker 	if (add_i_to_a(avrule_decl_id,
1745*2d543d20SAndroid Build Coastguard Worker 		       &scope_datum->decl_ids_len,
1746*2d543d20SAndroid Build Coastguard Worker 		       &scope_datum->decl_ids) == -1) {
1747*2d543d20SAndroid Build Coastguard Worker 		return -ENOMEM;
1748*2d543d20SAndroid Build Coastguard Worker 	}
1749*2d543d20SAndroid Build Coastguard Worker 
1750*2d543d20SAndroid Build Coastguard Worker 	if (scope_datum->scope == SCOPE_DECL && scope == SCOPE_REQ) {
1751*2d543d20SAndroid Build Coastguard Worker 		/* Need to keep the decl at the end of the list */
1752*2d543d20SAndroid Build Coastguard Worker 		uint32_t len, tmp;
1753*2d543d20SAndroid Build Coastguard Worker 		len = scope_datum->decl_ids_len;
1754*2d543d20SAndroid Build Coastguard Worker 		if (len < 2) {
1755*2d543d20SAndroid Build Coastguard Worker 			/* This should be impossible here */
1756*2d543d20SAndroid Build Coastguard Worker 			return -1;
1757*2d543d20SAndroid Build Coastguard Worker 		}
1758*2d543d20SAndroid Build Coastguard Worker 		tmp = scope_datum->decl_ids[len-2];
1759*2d543d20SAndroid Build Coastguard Worker 		scope_datum->decl_ids[len-2] = scope_datum->decl_ids[len-1];
1760*2d543d20SAndroid Build Coastguard Worker 		scope_datum->decl_ids[len-1] = tmp;
1761*2d543d20SAndroid Build Coastguard Worker 	}
1762*2d543d20SAndroid Build Coastguard Worker 
1763*2d543d20SAndroid Build Coastguard Worker 	return retval;
1764*2d543d20SAndroid Build Coastguard Worker }
1765*2d543d20SAndroid Build Coastguard Worker 
type_set_or(type_set_t * dst,const type_set_t * a,const type_set_t * b)1766*2d543d20SAndroid Build Coastguard Worker static int type_set_or(type_set_t * dst, const type_set_t * a, const type_set_t * b)
1767*2d543d20SAndroid Build Coastguard Worker {
1768*2d543d20SAndroid Build Coastguard Worker 	type_set_init(dst);
1769*2d543d20SAndroid Build Coastguard Worker 
1770*2d543d20SAndroid Build Coastguard Worker 	if (ebitmap_or(&dst->types, &a->types, &b->types)) {
1771*2d543d20SAndroid Build Coastguard Worker 		return -1;
1772*2d543d20SAndroid Build Coastguard Worker 	}
1773*2d543d20SAndroid Build Coastguard Worker 	if (ebitmap_or(&dst->negset, &a->negset, &b->negset)) {
1774*2d543d20SAndroid Build Coastguard Worker 		return -1;
1775*2d543d20SAndroid Build Coastguard Worker 	}
1776*2d543d20SAndroid Build Coastguard Worker 
1777*2d543d20SAndroid Build Coastguard Worker 	dst->flags |= a->flags;
1778*2d543d20SAndroid Build Coastguard Worker 	dst->flags |= b->flags;
1779*2d543d20SAndroid Build Coastguard Worker 
1780*2d543d20SAndroid Build Coastguard Worker 	return 0;
1781*2d543d20SAndroid Build Coastguard Worker }
1782*2d543d20SAndroid Build Coastguard Worker 
type_set_cpy(type_set_t * dst,const type_set_t * src)1783*2d543d20SAndroid Build Coastguard Worker int type_set_cpy(type_set_t * dst, const type_set_t * src)
1784*2d543d20SAndroid Build Coastguard Worker {
1785*2d543d20SAndroid Build Coastguard Worker 	type_set_init(dst);
1786*2d543d20SAndroid Build Coastguard Worker 
1787*2d543d20SAndroid Build Coastguard Worker 	dst->flags = src->flags;
1788*2d543d20SAndroid Build Coastguard Worker 	if (ebitmap_cpy(&dst->types, &src->types))
1789*2d543d20SAndroid Build Coastguard Worker 		return -1;
1790*2d543d20SAndroid Build Coastguard Worker 	if (ebitmap_cpy(&dst->negset, &src->negset))
1791*2d543d20SAndroid Build Coastguard Worker 		return -1;
1792*2d543d20SAndroid Build Coastguard Worker 
1793*2d543d20SAndroid Build Coastguard Worker 	return 0;
1794*2d543d20SAndroid Build Coastguard Worker }
1795*2d543d20SAndroid Build Coastguard Worker 
type_set_or_eq(type_set_t * dst,const type_set_t * other)1796*2d543d20SAndroid Build Coastguard Worker int type_set_or_eq(type_set_t * dst, const type_set_t * other)
1797*2d543d20SAndroid Build Coastguard Worker {
1798*2d543d20SAndroid Build Coastguard Worker 	int ret;
1799*2d543d20SAndroid Build Coastguard Worker 	type_set_t tmp;
1800*2d543d20SAndroid Build Coastguard Worker 
1801*2d543d20SAndroid Build Coastguard Worker 	if (type_set_or(&tmp, dst, other))
1802*2d543d20SAndroid Build Coastguard Worker 		return -1;
1803*2d543d20SAndroid Build Coastguard Worker 	type_set_destroy(dst);
1804*2d543d20SAndroid Build Coastguard Worker 	ret = type_set_cpy(dst, &tmp);
1805*2d543d20SAndroid Build Coastguard Worker 	type_set_destroy(&tmp);
1806*2d543d20SAndroid Build Coastguard Worker 
1807*2d543d20SAndroid Build Coastguard Worker 	return ret;
1808*2d543d20SAndroid Build Coastguard Worker }
1809*2d543d20SAndroid Build Coastguard Worker 
1810*2d543d20SAndroid Build Coastguard Worker /***********************************************************************/
1811*2d543d20SAndroid Build Coastguard Worker /* everything below is for policy reads */
1812*2d543d20SAndroid Build Coastguard Worker 
1813*2d543d20SAndroid Build Coastguard Worker /* The following are read functions for module structures */
1814*2d543d20SAndroid Build Coastguard Worker 
role_set_read(role_set_t * r,struct policy_file * fp)1815*2d543d20SAndroid Build Coastguard Worker static int role_set_read(role_set_t * r, struct policy_file *fp)
1816*2d543d20SAndroid Build Coastguard Worker {
1817*2d543d20SAndroid Build Coastguard Worker 	uint32_t buf[1];
1818*2d543d20SAndroid Build Coastguard Worker 	int rc;
1819*2d543d20SAndroid Build Coastguard Worker 
1820*2d543d20SAndroid Build Coastguard Worker 	if (ebitmap_read(&r->roles, fp))
1821*2d543d20SAndroid Build Coastguard Worker 		return -1;
1822*2d543d20SAndroid Build Coastguard Worker 	rc = next_entry(buf, fp, sizeof(uint32_t));
1823*2d543d20SAndroid Build Coastguard Worker 	if (rc < 0)
1824*2d543d20SAndroid Build Coastguard Worker 		return -1;
1825*2d543d20SAndroid Build Coastguard Worker 	r->flags = le32_to_cpu(buf[0]);
1826*2d543d20SAndroid Build Coastguard Worker 
1827*2d543d20SAndroid Build Coastguard Worker 	return 0;
1828*2d543d20SAndroid Build Coastguard Worker }
1829*2d543d20SAndroid Build Coastguard Worker 
type_set_read(type_set_t * t,struct policy_file * fp)1830*2d543d20SAndroid Build Coastguard Worker static int type_set_read(type_set_t * t, struct policy_file *fp)
1831*2d543d20SAndroid Build Coastguard Worker {
1832*2d543d20SAndroid Build Coastguard Worker 	uint32_t buf[1];
1833*2d543d20SAndroid Build Coastguard Worker 	int rc;
1834*2d543d20SAndroid Build Coastguard Worker 
1835*2d543d20SAndroid Build Coastguard Worker 	if (ebitmap_read(&t->types, fp))
1836*2d543d20SAndroid Build Coastguard Worker 		return -1;
1837*2d543d20SAndroid Build Coastguard Worker 	if (ebitmap_read(&t->negset, fp))
1838*2d543d20SAndroid Build Coastguard Worker 		return -1;
1839*2d543d20SAndroid Build Coastguard Worker 
1840*2d543d20SAndroid Build Coastguard Worker 	rc = next_entry(buf, fp, sizeof(uint32_t));
1841*2d543d20SAndroid Build Coastguard Worker 	if (rc < 0)
1842*2d543d20SAndroid Build Coastguard Worker 		return -1;
1843*2d543d20SAndroid Build Coastguard Worker 	t->flags = le32_to_cpu(buf[0]);
1844*2d543d20SAndroid Build Coastguard Worker 
1845*2d543d20SAndroid Build Coastguard Worker 	return 0;
1846*2d543d20SAndroid Build Coastguard Worker }
1847*2d543d20SAndroid Build Coastguard Worker 
1848*2d543d20SAndroid Build Coastguard Worker /*
1849*2d543d20SAndroid Build Coastguard Worker  * Read a MLS range structure from a policydb binary
1850*2d543d20SAndroid Build Coastguard Worker  * representation file.
1851*2d543d20SAndroid Build Coastguard Worker  */
mls_read_range_helper(mls_range_t * r,struct policy_file * fp)1852*2d543d20SAndroid Build Coastguard Worker static int mls_read_range_helper(mls_range_t * r, struct policy_file *fp)
1853*2d543d20SAndroid Build Coastguard Worker {
1854*2d543d20SAndroid Build Coastguard Worker 	uint32_t buf[2], items;
1855*2d543d20SAndroid Build Coastguard Worker 	int rc;
1856*2d543d20SAndroid Build Coastguard Worker 
1857*2d543d20SAndroid Build Coastguard Worker 	rc = next_entry(buf, fp, sizeof(uint32_t));
1858*2d543d20SAndroid Build Coastguard Worker 	if (rc < 0)
1859*2d543d20SAndroid Build Coastguard Worker 		goto out;
1860*2d543d20SAndroid Build Coastguard Worker 
1861*2d543d20SAndroid Build Coastguard Worker 	items = le32_to_cpu(buf[0]);
1862*2d543d20SAndroid Build Coastguard Worker 	if (items > ARRAY_SIZE(buf)) {
1863*2d543d20SAndroid Build Coastguard Worker 		ERR(fp->handle, "range overflow");
1864*2d543d20SAndroid Build Coastguard Worker 		rc = -EINVAL;
1865*2d543d20SAndroid Build Coastguard Worker 		goto out;
1866*2d543d20SAndroid Build Coastguard Worker 	}
1867*2d543d20SAndroid Build Coastguard Worker 	rc = next_entry(buf, fp, sizeof(uint32_t) * items);
1868*2d543d20SAndroid Build Coastguard Worker 	if (rc < 0) {
1869*2d543d20SAndroid Build Coastguard Worker 		ERR(fp->handle, "truncated range");
1870*2d543d20SAndroid Build Coastguard Worker 		goto out;
1871*2d543d20SAndroid Build Coastguard Worker 	}
1872*2d543d20SAndroid Build Coastguard Worker 	r->level[0].sens = le32_to_cpu(buf[0]);
1873*2d543d20SAndroid Build Coastguard Worker 	if (items > 1)
1874*2d543d20SAndroid Build Coastguard Worker 		r->level[1].sens = le32_to_cpu(buf[1]);
1875*2d543d20SAndroid Build Coastguard Worker 	else
1876*2d543d20SAndroid Build Coastguard Worker 		r->level[1].sens = r->level[0].sens;
1877*2d543d20SAndroid Build Coastguard Worker 
1878*2d543d20SAndroid Build Coastguard Worker 	rc = ebitmap_read(&r->level[0].cat, fp);
1879*2d543d20SAndroid Build Coastguard Worker 	if (rc) {
1880*2d543d20SAndroid Build Coastguard Worker 		ERR(fp->handle, "error reading low categories");
1881*2d543d20SAndroid Build Coastguard Worker 		goto out;
1882*2d543d20SAndroid Build Coastguard Worker 	}
1883*2d543d20SAndroid Build Coastguard Worker 	if (items > 1) {
1884*2d543d20SAndroid Build Coastguard Worker 		rc = ebitmap_read(&r->level[1].cat, fp);
1885*2d543d20SAndroid Build Coastguard Worker 		if (rc) {
1886*2d543d20SAndroid Build Coastguard Worker 			ERR(fp->handle, "error reading high categories");
1887*2d543d20SAndroid Build Coastguard Worker 			goto bad_high;
1888*2d543d20SAndroid Build Coastguard Worker 		}
1889*2d543d20SAndroid Build Coastguard Worker 	} else {
1890*2d543d20SAndroid Build Coastguard Worker 		rc = ebitmap_cpy(&r->level[1].cat, &r->level[0].cat);
1891*2d543d20SAndroid Build Coastguard Worker 		if (rc) {
1892*2d543d20SAndroid Build Coastguard Worker 			ERR(fp->handle, "out of memory");
1893*2d543d20SAndroid Build Coastguard Worker 			goto bad_high;
1894*2d543d20SAndroid Build Coastguard Worker 		}
1895*2d543d20SAndroid Build Coastguard Worker 	}
1896*2d543d20SAndroid Build Coastguard Worker 
1897*2d543d20SAndroid Build Coastguard Worker 	rc = 0;
1898*2d543d20SAndroid Build Coastguard Worker       out:
1899*2d543d20SAndroid Build Coastguard Worker 	return rc;
1900*2d543d20SAndroid Build Coastguard Worker       bad_high:
1901*2d543d20SAndroid Build Coastguard Worker 	ebitmap_destroy(&r->level[0].cat);
1902*2d543d20SAndroid Build Coastguard Worker 	goto out;
1903*2d543d20SAndroid Build Coastguard Worker }
1904*2d543d20SAndroid Build Coastguard Worker 
1905*2d543d20SAndroid Build Coastguard Worker /*
1906*2d543d20SAndroid Build Coastguard Worker  * Read a semantic MLS level structure from a policydb binary
1907*2d543d20SAndroid Build Coastguard Worker  * representation file.
1908*2d543d20SAndroid Build Coastguard Worker  */
mls_read_semantic_level_helper(mls_semantic_level_t * l,struct policy_file * fp)1909*2d543d20SAndroid Build Coastguard Worker static int mls_read_semantic_level_helper(mls_semantic_level_t * l,
1910*2d543d20SAndroid Build Coastguard Worker 					  struct policy_file *fp)
1911*2d543d20SAndroid Build Coastguard Worker {
1912*2d543d20SAndroid Build Coastguard Worker 	uint32_t buf[2], ncat;
1913*2d543d20SAndroid Build Coastguard Worker 	unsigned int i;
1914*2d543d20SAndroid Build Coastguard Worker 	mls_semantic_cat_t *cat;
1915*2d543d20SAndroid Build Coastguard Worker 	int rc;
1916*2d543d20SAndroid Build Coastguard Worker 
1917*2d543d20SAndroid Build Coastguard Worker 	mls_semantic_level_init(l);
1918*2d543d20SAndroid Build Coastguard Worker 
1919*2d543d20SAndroid Build Coastguard Worker 	rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
1920*2d543d20SAndroid Build Coastguard Worker 	if (rc < 0) {
1921*2d543d20SAndroid Build Coastguard Worker 		ERR(fp->handle, "truncated level");
1922*2d543d20SAndroid Build Coastguard Worker 		goto bad;
1923*2d543d20SAndroid Build Coastguard Worker 	}
1924*2d543d20SAndroid Build Coastguard Worker 	l->sens = le32_to_cpu(buf[0]);
1925*2d543d20SAndroid Build Coastguard Worker 
1926*2d543d20SAndroid Build Coastguard Worker 	ncat = le32_to_cpu(buf[1]);
1927*2d543d20SAndroid Build Coastguard Worker 	for (i = 0; i < ncat; i++) {
1928*2d543d20SAndroid Build Coastguard Worker 		cat = (mls_semantic_cat_t *) malloc(sizeof(mls_semantic_cat_t));
1929*2d543d20SAndroid Build Coastguard Worker 		if (!cat) {
1930*2d543d20SAndroid Build Coastguard Worker 			ERR(fp->handle, "out of memory");
1931*2d543d20SAndroid Build Coastguard Worker 			goto bad;
1932*2d543d20SAndroid Build Coastguard Worker 		}
1933*2d543d20SAndroid Build Coastguard Worker 
1934*2d543d20SAndroid Build Coastguard Worker 		mls_semantic_cat_init(cat);
1935*2d543d20SAndroid Build Coastguard Worker 		cat->next = l->cat;
1936*2d543d20SAndroid Build Coastguard Worker 		l->cat = cat;
1937*2d543d20SAndroid Build Coastguard Worker 
1938*2d543d20SAndroid Build Coastguard Worker 		rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
1939*2d543d20SAndroid Build Coastguard Worker 		if (rc < 0) {
1940*2d543d20SAndroid Build Coastguard Worker 			ERR(fp->handle, "error reading level categories");
1941*2d543d20SAndroid Build Coastguard Worker 			goto bad;
1942*2d543d20SAndroid Build Coastguard Worker 		}
1943*2d543d20SAndroid Build Coastguard Worker 		cat->low = le32_to_cpu(buf[0]);
1944*2d543d20SAndroid Build Coastguard Worker 		cat->high = le32_to_cpu(buf[1]);
1945*2d543d20SAndroid Build Coastguard Worker 	}
1946*2d543d20SAndroid Build Coastguard Worker 
1947*2d543d20SAndroid Build Coastguard Worker 	return 0;
1948*2d543d20SAndroid Build Coastguard Worker 
1949*2d543d20SAndroid Build Coastguard Worker       bad:
1950*2d543d20SAndroid Build Coastguard Worker 	return -EINVAL;
1951*2d543d20SAndroid Build Coastguard Worker }
1952*2d543d20SAndroid Build Coastguard Worker 
1953*2d543d20SAndroid Build Coastguard Worker /*
1954*2d543d20SAndroid Build Coastguard Worker  * Read a semantic MLS range structure from a policydb binary
1955*2d543d20SAndroid Build Coastguard Worker  * representation file.
1956*2d543d20SAndroid Build Coastguard Worker  */
mls_read_semantic_range_helper(mls_semantic_range_t * r,struct policy_file * fp)1957*2d543d20SAndroid Build Coastguard Worker static int mls_read_semantic_range_helper(mls_semantic_range_t * r,
1958*2d543d20SAndroid Build Coastguard Worker 					  struct policy_file *fp)
1959*2d543d20SAndroid Build Coastguard Worker {
1960*2d543d20SAndroid Build Coastguard Worker 	int rc;
1961*2d543d20SAndroid Build Coastguard Worker 
1962*2d543d20SAndroid Build Coastguard Worker 	rc = mls_read_semantic_level_helper(&r->level[0], fp);
1963*2d543d20SAndroid Build Coastguard Worker 	if (rc)
1964*2d543d20SAndroid Build Coastguard Worker 		return rc;
1965*2d543d20SAndroid Build Coastguard Worker 
1966*2d543d20SAndroid Build Coastguard Worker 	rc = mls_read_semantic_level_helper(&r->level[1], fp);
1967*2d543d20SAndroid Build Coastguard Worker 
1968*2d543d20SAndroid Build Coastguard Worker 	return rc;
1969*2d543d20SAndroid Build Coastguard Worker }
1970*2d543d20SAndroid Build Coastguard Worker 
mls_level_to_semantic(mls_level_t * l,mls_semantic_level_t * sl)1971*2d543d20SAndroid Build Coastguard Worker static int mls_level_to_semantic(mls_level_t * l, mls_semantic_level_t * sl)
1972*2d543d20SAndroid Build Coastguard Worker {
1973*2d543d20SAndroid Build Coastguard Worker 	unsigned int i;
1974*2d543d20SAndroid Build Coastguard Worker 	ebitmap_node_t *cnode;
1975*2d543d20SAndroid Build Coastguard Worker 	mls_semantic_cat_t *open_cat = NULL;
1976*2d543d20SAndroid Build Coastguard Worker 
1977*2d543d20SAndroid Build Coastguard Worker 	mls_semantic_level_init(sl);
1978*2d543d20SAndroid Build Coastguard Worker 	sl->sens = l->sens;
1979*2d543d20SAndroid Build Coastguard Worker 	ebitmap_for_each_bit(&l->cat, cnode, i) {
1980*2d543d20SAndroid Build Coastguard Worker 		if (ebitmap_node_get_bit(cnode, i)) {
1981*2d543d20SAndroid Build Coastguard Worker 			if (open_cat)
1982*2d543d20SAndroid Build Coastguard Worker 				continue;
1983*2d543d20SAndroid Build Coastguard Worker 			open_cat = (mls_semantic_cat_t *)
1984*2d543d20SAndroid Build Coastguard Worker 			    malloc(sizeof(mls_semantic_cat_t));
1985*2d543d20SAndroid Build Coastguard Worker 			if (!open_cat)
1986*2d543d20SAndroid Build Coastguard Worker 				return -1;
1987*2d543d20SAndroid Build Coastguard Worker 
1988*2d543d20SAndroid Build Coastguard Worker 			mls_semantic_cat_init(open_cat);
1989*2d543d20SAndroid Build Coastguard Worker 			open_cat->low = i + 1;
1990*2d543d20SAndroid Build Coastguard Worker 			open_cat->next = sl->cat;
1991*2d543d20SAndroid Build Coastguard Worker 			sl->cat = open_cat;
1992*2d543d20SAndroid Build Coastguard Worker 		} else {
1993*2d543d20SAndroid Build Coastguard Worker 			if (!open_cat)
1994*2d543d20SAndroid Build Coastguard Worker 				continue;
1995*2d543d20SAndroid Build Coastguard Worker 			open_cat->high = i;
1996*2d543d20SAndroid Build Coastguard Worker 			open_cat = NULL;
1997*2d543d20SAndroid Build Coastguard Worker 		}
1998*2d543d20SAndroid Build Coastguard Worker 	}
1999*2d543d20SAndroid Build Coastguard Worker 	if (open_cat)
2000*2d543d20SAndroid Build Coastguard Worker 		open_cat->high = i;
2001*2d543d20SAndroid Build Coastguard Worker 
2002*2d543d20SAndroid Build Coastguard Worker 	return 0;
2003*2d543d20SAndroid Build Coastguard Worker }
2004*2d543d20SAndroid Build Coastguard Worker 
mls_range_to_semantic(mls_range_t * r,mls_semantic_range_t * sr)2005*2d543d20SAndroid Build Coastguard Worker static int mls_range_to_semantic(mls_range_t * r, mls_semantic_range_t * sr)
2006*2d543d20SAndroid Build Coastguard Worker {
2007*2d543d20SAndroid Build Coastguard Worker 	if (mls_level_to_semantic(&r->level[0], &sr->level[0]))
2008*2d543d20SAndroid Build Coastguard Worker 		return -1;
2009*2d543d20SAndroid Build Coastguard Worker 
2010*2d543d20SAndroid Build Coastguard Worker 	if (mls_level_to_semantic(&r->level[1], &sr->level[1]))
2011*2d543d20SAndroid Build Coastguard Worker 		return -1;
2012*2d543d20SAndroid Build Coastguard Worker 
2013*2d543d20SAndroid Build Coastguard Worker 	return 0;
2014*2d543d20SAndroid Build Coastguard Worker }
2015*2d543d20SAndroid Build Coastguard Worker 
2016*2d543d20SAndroid Build Coastguard Worker /*
2017*2d543d20SAndroid Build Coastguard Worker  * Read and validate a security context structure
2018*2d543d20SAndroid Build Coastguard Worker  * from a policydb binary representation file.
2019*2d543d20SAndroid Build Coastguard Worker  */
context_read_and_validate(context_struct_t * c,policydb_t * p,struct policy_file * fp)2020*2d543d20SAndroid Build Coastguard Worker static int context_read_and_validate(context_struct_t * c,
2021*2d543d20SAndroid Build Coastguard Worker 				     policydb_t * p, struct policy_file *fp)
2022*2d543d20SAndroid Build Coastguard Worker {
2023*2d543d20SAndroid Build Coastguard Worker 	uint32_t buf[3];
2024*2d543d20SAndroid Build Coastguard Worker 	int rc;
2025*2d543d20SAndroid Build Coastguard Worker 
2026*2d543d20SAndroid Build Coastguard Worker 	rc = next_entry(buf, fp, sizeof(uint32_t) * 3);
2027*2d543d20SAndroid Build Coastguard Worker 	if (rc < 0) {
2028*2d543d20SAndroid Build Coastguard Worker 		ERR(fp->handle, "context truncated");
2029*2d543d20SAndroid Build Coastguard Worker 		return -1;
2030*2d543d20SAndroid Build Coastguard Worker 	}
2031*2d543d20SAndroid Build Coastguard Worker 	c->user = le32_to_cpu(buf[0]);
2032*2d543d20SAndroid Build Coastguard Worker 	c->role = le32_to_cpu(buf[1]);
2033*2d543d20SAndroid Build Coastguard Worker 	c->type = le32_to_cpu(buf[2]);
2034*2d543d20SAndroid Build Coastguard Worker 	if ((p->policy_type == POLICY_KERN
2035*2d543d20SAndroid Build Coastguard Worker 	     && p->policyvers >= POLICYDB_VERSION_MLS)
2036*2d543d20SAndroid Build Coastguard Worker 	    || (p->policy_type == POLICY_BASE
2037*2d543d20SAndroid Build Coastguard Worker 		&& p->policyvers >= MOD_POLICYDB_VERSION_MLS)) {
2038*2d543d20SAndroid Build Coastguard Worker 		if (mls_read_range_helper(&c->range, fp)) {
2039*2d543d20SAndroid Build Coastguard Worker 			ERR(fp->handle, "error reading MLS range "
2040*2d543d20SAndroid Build Coastguard Worker 			    "of context");
2041*2d543d20SAndroid Build Coastguard Worker 			return -1;
2042*2d543d20SAndroid Build Coastguard Worker 		}
2043*2d543d20SAndroid Build Coastguard Worker 	}
2044*2d543d20SAndroid Build Coastguard Worker 
2045*2d543d20SAndroid Build Coastguard Worker 	if (!policydb_context_isvalid(p, c)) {
2046*2d543d20SAndroid Build Coastguard Worker 		ERR(fp->handle, "invalid security context");
2047*2d543d20SAndroid Build Coastguard Worker 		context_destroy(c);
2048*2d543d20SAndroid Build Coastguard Worker 		return -1;
2049*2d543d20SAndroid Build Coastguard Worker 	}
2050*2d543d20SAndroid Build Coastguard Worker 	return 0;
2051*2d543d20SAndroid Build Coastguard Worker }
2052*2d543d20SAndroid Build Coastguard Worker 
2053*2d543d20SAndroid Build Coastguard Worker /*
2054*2d543d20SAndroid Build Coastguard Worker  * The following *_read functions are used to
2055*2d543d20SAndroid Build Coastguard Worker  * read the symbol data from a policy database
2056*2d543d20SAndroid Build Coastguard Worker  * binary representation file.
2057*2d543d20SAndroid Build Coastguard Worker  */
2058*2d543d20SAndroid Build Coastguard Worker 
perm_read(policydb_t * p,hashtab_t h,struct policy_file * fp,uint32_t nprim)2059*2d543d20SAndroid Build Coastguard Worker static int perm_read(policydb_t * p
2060*2d543d20SAndroid Build Coastguard Worker 		     __attribute__ ((unused)), hashtab_t h,
2061*2d543d20SAndroid Build Coastguard Worker 		     struct policy_file *fp, uint32_t nprim)
2062*2d543d20SAndroid Build Coastguard Worker {
2063*2d543d20SAndroid Build Coastguard Worker 	char *key = 0;
2064*2d543d20SAndroid Build Coastguard Worker 	perm_datum_t *perdatum;
2065*2d543d20SAndroid Build Coastguard Worker 	uint32_t buf[2];
2066*2d543d20SAndroid Build Coastguard Worker 	size_t len;
2067*2d543d20SAndroid Build Coastguard Worker 	int rc;
2068*2d543d20SAndroid Build Coastguard Worker 
2069*2d543d20SAndroid Build Coastguard Worker 	perdatum = calloc(1, sizeof(perm_datum_t));
2070*2d543d20SAndroid Build Coastguard Worker 	if (!perdatum)
2071*2d543d20SAndroid Build Coastguard Worker 		return -1;
2072*2d543d20SAndroid Build Coastguard Worker 
2073*2d543d20SAndroid Build Coastguard Worker 	rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
2074*2d543d20SAndroid Build Coastguard Worker 	if (rc < 0)
2075*2d543d20SAndroid Build Coastguard Worker 		goto bad;
2076*2d543d20SAndroid Build Coastguard Worker 
2077*2d543d20SAndroid Build Coastguard Worker 	len = le32_to_cpu(buf[0]);
2078*2d543d20SAndroid Build Coastguard Worker 	if(str_read(&key, fp, len))
2079*2d543d20SAndroid Build Coastguard Worker 		goto bad;
2080*2d543d20SAndroid Build Coastguard Worker 
2081*2d543d20SAndroid Build Coastguard Worker 	perdatum->s.value = le32_to_cpu(buf[1]);
2082*2d543d20SAndroid Build Coastguard Worker 	if (!value_isvalid(perdatum->s.value, nprim))
2083*2d543d20SAndroid Build Coastguard Worker 		goto bad;
2084*2d543d20SAndroid Build Coastguard Worker 
2085*2d543d20SAndroid Build Coastguard Worker 	if (hashtab_insert(h, key, perdatum))
2086*2d543d20SAndroid Build Coastguard Worker 		goto bad;
2087*2d543d20SAndroid Build Coastguard Worker 
2088*2d543d20SAndroid Build Coastguard Worker 	return 0;
2089*2d543d20SAndroid Build Coastguard Worker 
2090*2d543d20SAndroid Build Coastguard Worker       bad:
2091*2d543d20SAndroid Build Coastguard Worker 	perm_destroy(key, perdatum, NULL);
2092*2d543d20SAndroid Build Coastguard Worker 	return -1;
2093*2d543d20SAndroid Build Coastguard Worker }
2094*2d543d20SAndroid Build Coastguard Worker 
common_read(policydb_t * p,hashtab_t h,struct policy_file * fp)2095*2d543d20SAndroid Build Coastguard Worker static int common_read(policydb_t * p, hashtab_t h, struct policy_file *fp)
2096*2d543d20SAndroid Build Coastguard Worker {
2097*2d543d20SAndroid Build Coastguard Worker 	char *key = 0;
2098*2d543d20SAndroid Build Coastguard Worker 	common_datum_t *comdatum;
2099*2d543d20SAndroid Build Coastguard Worker 	uint32_t buf[4];
2100*2d543d20SAndroid Build Coastguard Worker 	size_t len, nel;
2101*2d543d20SAndroid Build Coastguard Worker 	unsigned int i;
2102*2d543d20SAndroid Build Coastguard Worker 	int rc;
2103*2d543d20SAndroid Build Coastguard Worker 
2104*2d543d20SAndroid Build Coastguard Worker 	comdatum = calloc(1, sizeof(common_datum_t));
2105*2d543d20SAndroid Build Coastguard Worker 	if (!comdatum)
2106*2d543d20SAndroid Build Coastguard Worker 		return -1;
2107*2d543d20SAndroid Build Coastguard Worker 
2108*2d543d20SAndroid Build Coastguard Worker 	rc = next_entry(buf, fp, sizeof(uint32_t) * 4);
2109*2d543d20SAndroid Build Coastguard Worker 	if (rc < 0)
2110*2d543d20SAndroid Build Coastguard Worker 		goto bad;
2111*2d543d20SAndroid Build Coastguard Worker 
2112*2d543d20SAndroid Build Coastguard Worker 	len = le32_to_cpu(buf[0]);
2113*2d543d20SAndroid Build Coastguard Worker 	rc = str_read(&key, fp, len);
2114*2d543d20SAndroid Build Coastguard Worker 	if (rc < 0)
2115*2d543d20SAndroid Build Coastguard Worker 		goto bad;
2116*2d543d20SAndroid Build Coastguard Worker 
2117*2d543d20SAndroid Build Coastguard Worker 	comdatum->s.value = le32_to_cpu(buf[1]);
2118*2d543d20SAndroid Build Coastguard Worker 
2119*2d543d20SAndroid Build Coastguard Worker 	if (symtab_init(&comdatum->permissions, PERM_SYMTAB_SIZE))
2120*2d543d20SAndroid Build Coastguard Worker 		goto bad;
2121*2d543d20SAndroid Build Coastguard Worker 	comdatum->permissions.nprim = le32_to_cpu(buf[2]);
2122*2d543d20SAndroid Build Coastguard Worker 	if (comdatum->permissions.nprim > PERM_SYMTAB_SIZE)
2123*2d543d20SAndroid Build Coastguard Worker 		goto bad;
2124*2d543d20SAndroid Build Coastguard Worker 	nel = le32_to_cpu(buf[3]);
2125*2d543d20SAndroid Build Coastguard Worker 
2126*2d543d20SAndroid Build Coastguard Worker 	for (i = 0; i < nel; i++) {
2127*2d543d20SAndroid Build Coastguard Worker 		if (perm_read(p, comdatum->permissions.table, fp, comdatum->permissions.nprim))
2128*2d543d20SAndroid Build Coastguard Worker 			goto bad;
2129*2d543d20SAndroid Build Coastguard Worker 	}
2130*2d543d20SAndroid Build Coastguard Worker 
2131*2d543d20SAndroid Build Coastguard Worker 	if (hashtab_insert(h, key, comdatum))
2132*2d543d20SAndroid Build Coastguard Worker 		goto bad;
2133*2d543d20SAndroid Build Coastguard Worker 
2134*2d543d20SAndroid Build Coastguard Worker 	return 0;
2135*2d543d20SAndroid Build Coastguard Worker 
2136*2d543d20SAndroid Build Coastguard Worker       bad:
2137*2d543d20SAndroid Build Coastguard Worker 	common_destroy(key, comdatum, NULL);
2138*2d543d20SAndroid Build Coastguard Worker 	return -1;
2139*2d543d20SAndroid Build Coastguard Worker }
2140*2d543d20SAndroid Build Coastguard Worker 
read_cons_helper(policydb_t * p,constraint_node_t ** nodep,unsigned int ncons,int allowxtarget,struct policy_file * fp)2141*2d543d20SAndroid Build Coastguard Worker static int read_cons_helper(policydb_t * p, constraint_node_t ** nodep,
2142*2d543d20SAndroid Build Coastguard Worker 			    unsigned int ncons,
2143*2d543d20SAndroid Build Coastguard Worker 			    int allowxtarget, struct policy_file *fp)
2144*2d543d20SAndroid Build Coastguard Worker {
2145*2d543d20SAndroid Build Coastguard Worker 	constraint_node_t *c, *lc;
2146*2d543d20SAndroid Build Coastguard Worker 	constraint_expr_t *e, *le;
2147*2d543d20SAndroid Build Coastguard Worker 	uint32_t buf[3];
2148*2d543d20SAndroid Build Coastguard Worker 	size_t nexpr;
2149*2d543d20SAndroid Build Coastguard Worker 	unsigned int i, j;
2150*2d543d20SAndroid Build Coastguard Worker 	int rc, depth;
2151*2d543d20SAndroid Build Coastguard Worker 
2152*2d543d20SAndroid Build Coastguard Worker 	lc = NULL;
2153*2d543d20SAndroid Build Coastguard Worker 	for (i = 0; i < ncons; i++) {
2154*2d543d20SAndroid Build Coastguard Worker 		c = calloc(1, sizeof(constraint_node_t));
2155*2d543d20SAndroid Build Coastguard Worker 		if (!c)
2156*2d543d20SAndroid Build Coastguard Worker 			return -1;
2157*2d543d20SAndroid Build Coastguard Worker 
2158*2d543d20SAndroid Build Coastguard Worker 		if (lc)
2159*2d543d20SAndroid Build Coastguard Worker 			lc->next = c;
2160*2d543d20SAndroid Build Coastguard Worker 		else
2161*2d543d20SAndroid Build Coastguard Worker 			*nodep = c;
2162*2d543d20SAndroid Build Coastguard Worker 
2163*2d543d20SAndroid Build Coastguard Worker 		rc = next_entry(buf, fp, (sizeof(uint32_t) * 2));
2164*2d543d20SAndroid Build Coastguard Worker 		if (rc < 0)
2165*2d543d20SAndroid Build Coastguard Worker 			return -1;
2166*2d543d20SAndroid Build Coastguard Worker 		c->permissions = le32_to_cpu(buf[0]);
2167*2d543d20SAndroid Build Coastguard Worker 		nexpr = le32_to_cpu(buf[1]);
2168*2d543d20SAndroid Build Coastguard Worker 		le = NULL;
2169*2d543d20SAndroid Build Coastguard Worker 		depth = -1;
2170*2d543d20SAndroid Build Coastguard Worker 		for (j = 0; j < nexpr; j++) {
2171*2d543d20SAndroid Build Coastguard Worker 			e = malloc(sizeof(constraint_expr_t));
2172*2d543d20SAndroid Build Coastguard Worker 			if (!e)
2173*2d543d20SAndroid Build Coastguard Worker 				return -1;
2174*2d543d20SAndroid Build Coastguard Worker 			if (constraint_expr_init(e) == -1) {
2175*2d543d20SAndroid Build Coastguard Worker 				free(e);
2176*2d543d20SAndroid Build Coastguard Worker 				return -1;
2177*2d543d20SAndroid Build Coastguard Worker 			}
2178*2d543d20SAndroid Build Coastguard Worker 			if (le) {
2179*2d543d20SAndroid Build Coastguard Worker 				le->next = e;
2180*2d543d20SAndroid Build Coastguard Worker 			} else {
2181*2d543d20SAndroid Build Coastguard Worker 				c->expr = e;
2182*2d543d20SAndroid Build Coastguard Worker 			}
2183*2d543d20SAndroid Build Coastguard Worker 
2184*2d543d20SAndroid Build Coastguard Worker 			rc = next_entry(buf, fp, (sizeof(uint32_t) * 3));
2185*2d543d20SAndroid Build Coastguard Worker 			if (rc < 0)
2186*2d543d20SAndroid Build Coastguard Worker 				return -1;
2187*2d543d20SAndroid Build Coastguard Worker 			e->expr_type = le32_to_cpu(buf[0]);
2188*2d543d20SAndroid Build Coastguard Worker 			e->attr = le32_to_cpu(buf[1]);
2189*2d543d20SAndroid Build Coastguard Worker 			e->op = le32_to_cpu(buf[2]);
2190*2d543d20SAndroid Build Coastguard Worker 
2191*2d543d20SAndroid Build Coastguard Worker 			switch (e->expr_type) {
2192*2d543d20SAndroid Build Coastguard Worker 			case CEXPR_NOT:
2193*2d543d20SAndroid Build Coastguard Worker 				if (depth < 0)
2194*2d543d20SAndroid Build Coastguard Worker 					return -1;
2195*2d543d20SAndroid Build Coastguard Worker 				break;
2196*2d543d20SAndroid Build Coastguard Worker 			case CEXPR_AND:
2197*2d543d20SAndroid Build Coastguard Worker 			case CEXPR_OR:
2198*2d543d20SAndroid Build Coastguard Worker 				if (depth < 1)
2199*2d543d20SAndroid Build Coastguard Worker 					return -1;
2200*2d543d20SAndroid Build Coastguard Worker 				depth--;
2201*2d543d20SAndroid Build Coastguard Worker 				break;
2202*2d543d20SAndroid Build Coastguard Worker 			case CEXPR_ATTR:
2203*2d543d20SAndroid Build Coastguard Worker 				if (depth == (CEXPR_MAXDEPTH - 1))
2204*2d543d20SAndroid Build Coastguard Worker 					return -1;
2205*2d543d20SAndroid Build Coastguard Worker 				depth++;
2206*2d543d20SAndroid Build Coastguard Worker 				break;
2207*2d543d20SAndroid Build Coastguard Worker 			case CEXPR_NAMES:
2208*2d543d20SAndroid Build Coastguard Worker 				if (!allowxtarget && (e->attr & CEXPR_XTARGET))
2209*2d543d20SAndroid Build Coastguard Worker 					return -1;
2210*2d543d20SAndroid Build Coastguard Worker 				if (depth == (CEXPR_MAXDEPTH - 1))
2211*2d543d20SAndroid Build Coastguard Worker 					return -1;
2212*2d543d20SAndroid Build Coastguard Worker 				depth++;
2213*2d543d20SAndroid Build Coastguard Worker 				if (ebitmap_read(&e->names, fp))
2214*2d543d20SAndroid Build Coastguard Worker 					return -1;
2215*2d543d20SAndroid Build Coastguard Worker 				if (p->policy_type != POLICY_KERN &&
2216*2d543d20SAndroid Build Coastguard Worker 				    type_set_read(e->type_names, fp))
2217*2d543d20SAndroid Build Coastguard Worker 					return -1;
2218*2d543d20SAndroid Build Coastguard Worker 				else if (p->policy_type == POLICY_KERN &&
2219*2d543d20SAndroid Build Coastguard Worker 					 p->policyvers >= POLICYDB_VERSION_CONSTRAINT_NAMES &&
2220*2d543d20SAndroid Build Coastguard Worker 					 type_set_read(e->type_names, fp))
2221*2d543d20SAndroid Build Coastguard Worker 					return -1;
2222*2d543d20SAndroid Build Coastguard Worker 				break;
2223*2d543d20SAndroid Build Coastguard Worker 			default:
2224*2d543d20SAndroid Build Coastguard Worker 				return -1;
2225*2d543d20SAndroid Build Coastguard Worker 			}
2226*2d543d20SAndroid Build Coastguard Worker 			le = e;
2227*2d543d20SAndroid Build Coastguard Worker 		}
2228*2d543d20SAndroid Build Coastguard Worker 		if (depth != 0)
2229*2d543d20SAndroid Build Coastguard Worker 			return -1;
2230*2d543d20SAndroid Build Coastguard Worker 		lc = c;
2231*2d543d20SAndroid Build Coastguard Worker 	}
2232*2d543d20SAndroid Build Coastguard Worker 
2233*2d543d20SAndroid Build Coastguard Worker 	return 0;
2234*2d543d20SAndroid Build Coastguard Worker }
2235*2d543d20SAndroid Build Coastguard Worker 
class_read(policydb_t * p,hashtab_t h,struct policy_file * fp)2236*2d543d20SAndroid Build Coastguard Worker static int class_read(policydb_t * p, hashtab_t h, struct policy_file *fp)
2237*2d543d20SAndroid Build Coastguard Worker {
2238*2d543d20SAndroid Build Coastguard Worker 	char *key = 0;
2239*2d543d20SAndroid Build Coastguard Worker 	class_datum_t *cladatum;
2240*2d543d20SAndroid Build Coastguard Worker 	uint32_t buf[6];
2241*2d543d20SAndroid Build Coastguard Worker 	size_t len, len2, ncons, nel;
2242*2d543d20SAndroid Build Coastguard Worker 	unsigned int i;
2243*2d543d20SAndroid Build Coastguard Worker 	int rc;
2244*2d543d20SAndroid Build Coastguard Worker 
2245*2d543d20SAndroid Build Coastguard Worker 	cladatum = (class_datum_t *) calloc(1, sizeof(class_datum_t));
2246*2d543d20SAndroid Build Coastguard Worker 	if (!cladatum)
2247*2d543d20SAndroid Build Coastguard Worker 		return -1;
2248*2d543d20SAndroid Build Coastguard Worker 
2249*2d543d20SAndroid Build Coastguard Worker 	rc = next_entry(buf, fp, sizeof(uint32_t) * 6);
2250*2d543d20SAndroid Build Coastguard Worker 	if (rc < 0)
2251*2d543d20SAndroid Build Coastguard Worker 		goto bad;
2252*2d543d20SAndroid Build Coastguard Worker 
2253*2d543d20SAndroid Build Coastguard Worker 	len = le32_to_cpu(buf[0]);
2254*2d543d20SAndroid Build Coastguard Worker 	rc = str_read(&key, fp, len);
2255*2d543d20SAndroid Build Coastguard Worker 	if (rc < 0)
2256*2d543d20SAndroid Build Coastguard Worker 		goto bad;
2257*2d543d20SAndroid Build Coastguard Worker 
2258*2d543d20SAndroid Build Coastguard Worker 	len2 = le32_to_cpu(buf[1]);
2259*2d543d20SAndroid Build Coastguard Worker 	cladatum->s.value = le32_to_cpu(buf[2]);
2260*2d543d20SAndroid Build Coastguard Worker 	if (cladatum->s.value > UINT16_MAX)
2261*2d543d20SAndroid Build Coastguard Worker 		goto bad;
2262*2d543d20SAndroid Build Coastguard Worker 
2263*2d543d20SAndroid Build Coastguard Worker 	if (symtab_init(&cladatum->permissions, PERM_SYMTAB_SIZE))
2264*2d543d20SAndroid Build Coastguard Worker 		goto bad;
2265*2d543d20SAndroid Build Coastguard Worker 	cladatum->permissions.nprim = le32_to_cpu(buf[3]);
2266*2d543d20SAndroid Build Coastguard Worker 	if (cladatum->permissions.nprim > PERM_SYMTAB_SIZE)
2267*2d543d20SAndroid Build Coastguard Worker 		goto bad;
2268*2d543d20SAndroid Build Coastguard Worker 	nel = le32_to_cpu(buf[4]);
2269*2d543d20SAndroid Build Coastguard Worker 
2270*2d543d20SAndroid Build Coastguard Worker 	ncons = le32_to_cpu(buf[5]);
2271*2d543d20SAndroid Build Coastguard Worker 
2272*2d543d20SAndroid Build Coastguard Worker 	if (len2) {
2273*2d543d20SAndroid Build Coastguard Worker 		rc = str_read(&cladatum->comkey, fp, len2);
2274*2d543d20SAndroid Build Coastguard Worker 		if (rc < 0)
2275*2d543d20SAndroid Build Coastguard Worker 			goto bad;
2276*2d543d20SAndroid Build Coastguard Worker 
2277*2d543d20SAndroid Build Coastguard Worker 		cladatum->comdatum = hashtab_search(p->p_commons.table,
2278*2d543d20SAndroid Build Coastguard Worker 						    cladatum->comkey);
2279*2d543d20SAndroid Build Coastguard Worker 		if (!cladatum->comdatum) {
2280*2d543d20SAndroid Build Coastguard Worker 			ERR(fp->handle, "unknown common %s", cladatum->comkey);
2281*2d543d20SAndroid Build Coastguard Worker 			goto bad;
2282*2d543d20SAndroid Build Coastguard Worker 		}
2283*2d543d20SAndroid Build Coastguard Worker 	}
2284*2d543d20SAndroid Build Coastguard Worker 	for (i = 0; i < nel; i++) {
2285*2d543d20SAndroid Build Coastguard Worker 		if (perm_read(p, cladatum->permissions.table, fp, cladatum->permissions.nprim))
2286*2d543d20SAndroid Build Coastguard Worker 			goto bad;
2287*2d543d20SAndroid Build Coastguard Worker 	}
2288*2d543d20SAndroid Build Coastguard Worker 
2289*2d543d20SAndroid Build Coastguard Worker 	if (read_cons_helper(p, &cladatum->constraints, ncons, 0, fp))
2290*2d543d20SAndroid Build Coastguard Worker 		goto bad;
2291*2d543d20SAndroid Build Coastguard Worker 
2292*2d543d20SAndroid Build Coastguard Worker 	if ((p->policy_type == POLICY_KERN
2293*2d543d20SAndroid Build Coastguard Worker 	     && p->policyvers >= POLICYDB_VERSION_VALIDATETRANS)
2294*2d543d20SAndroid Build Coastguard Worker 	    || (p->policy_type == POLICY_BASE
2295*2d543d20SAndroid Build Coastguard Worker 		&& p->policyvers >= MOD_POLICYDB_VERSION_VALIDATETRANS)) {
2296*2d543d20SAndroid Build Coastguard Worker 		/* grab the validatetrans rules */
2297*2d543d20SAndroid Build Coastguard Worker 		rc = next_entry(buf, fp, sizeof(uint32_t));
2298*2d543d20SAndroid Build Coastguard Worker 		if (rc < 0)
2299*2d543d20SAndroid Build Coastguard Worker 			goto bad;
2300*2d543d20SAndroid Build Coastguard Worker 		ncons = le32_to_cpu(buf[0]);
2301*2d543d20SAndroid Build Coastguard Worker 		if (read_cons_helper(p, &cladatum->validatetrans, ncons, 1, fp))
2302*2d543d20SAndroid Build Coastguard Worker 			goto bad;
2303*2d543d20SAndroid Build Coastguard Worker 	}
2304*2d543d20SAndroid Build Coastguard Worker 
2305*2d543d20SAndroid Build Coastguard Worker 	if ((p->policy_type == POLICY_KERN &&
2306*2d543d20SAndroid Build Coastguard Worker 	     p->policyvers >= POLICYDB_VERSION_NEW_OBJECT_DEFAULTS) ||
2307*2d543d20SAndroid Build Coastguard Worker 	    (p->policy_type == POLICY_BASE &&
2308*2d543d20SAndroid Build Coastguard Worker 	     p->policyvers >= MOD_POLICYDB_VERSION_NEW_OBJECT_DEFAULTS)) {
2309*2d543d20SAndroid Build Coastguard Worker 		rc = next_entry(buf, fp, sizeof(uint32_t) * 3);
2310*2d543d20SAndroid Build Coastguard Worker 		if (rc < 0)
2311*2d543d20SAndroid Build Coastguard Worker 			goto bad;
2312*2d543d20SAndroid Build Coastguard Worker 		cladatum->default_user = le32_to_cpu(buf[0]);
2313*2d543d20SAndroid Build Coastguard Worker 		cladatum->default_role = le32_to_cpu(buf[1]);
2314*2d543d20SAndroid Build Coastguard Worker 		cladatum->default_range = le32_to_cpu(buf[2]);
2315*2d543d20SAndroid Build Coastguard Worker 	}
2316*2d543d20SAndroid Build Coastguard Worker 
2317*2d543d20SAndroid Build Coastguard Worker 	if ((p->policy_type == POLICY_KERN &&
2318*2d543d20SAndroid Build Coastguard Worker 	     p->policyvers >= POLICYDB_VERSION_DEFAULT_TYPE) ||
2319*2d543d20SAndroid Build Coastguard Worker 	    (p->policy_type == POLICY_BASE &&
2320*2d543d20SAndroid Build Coastguard Worker 	     p->policyvers >= MOD_POLICYDB_VERSION_DEFAULT_TYPE)) {
2321*2d543d20SAndroid Build Coastguard Worker 		rc = next_entry(buf, fp, sizeof(uint32_t));
2322*2d543d20SAndroid Build Coastguard Worker 		if (rc < 0)
2323*2d543d20SAndroid Build Coastguard Worker 			goto bad;
2324*2d543d20SAndroid Build Coastguard Worker 		cladatum->default_type = le32_to_cpu(buf[0]);
2325*2d543d20SAndroid Build Coastguard Worker 	}
2326*2d543d20SAndroid Build Coastguard Worker 
2327*2d543d20SAndroid Build Coastguard Worker 	if (hashtab_insert(h, key, cladatum))
2328*2d543d20SAndroid Build Coastguard Worker 		goto bad;
2329*2d543d20SAndroid Build Coastguard Worker 
2330*2d543d20SAndroid Build Coastguard Worker 	return 0;
2331*2d543d20SAndroid Build Coastguard Worker 
2332*2d543d20SAndroid Build Coastguard Worker       bad:
2333*2d543d20SAndroid Build Coastguard Worker 	class_destroy(key, cladatum, NULL);
2334*2d543d20SAndroid Build Coastguard Worker 	return -1;
2335*2d543d20SAndroid Build Coastguard Worker }
2336*2d543d20SAndroid Build Coastguard Worker 
role_read(policydb_t * p,hashtab_t h,struct policy_file * fp)2337*2d543d20SAndroid Build Coastguard Worker static int role_read(policydb_t * p, hashtab_t h, struct policy_file *fp)
2338*2d543d20SAndroid Build Coastguard Worker {
2339*2d543d20SAndroid Build Coastguard Worker 	char *key = 0;
2340*2d543d20SAndroid Build Coastguard Worker 	role_datum_t *role;
2341*2d543d20SAndroid Build Coastguard Worker 	uint32_t buf[3];
2342*2d543d20SAndroid Build Coastguard Worker 	size_t len;
2343*2d543d20SAndroid Build Coastguard Worker 	int rc, to_read = 2;
2344*2d543d20SAndroid Build Coastguard Worker 
2345*2d543d20SAndroid Build Coastguard Worker 	role = calloc(1, sizeof(role_datum_t));
2346*2d543d20SAndroid Build Coastguard Worker 	if (!role)
2347*2d543d20SAndroid Build Coastguard Worker 		return -1;
2348*2d543d20SAndroid Build Coastguard Worker 
2349*2d543d20SAndroid Build Coastguard Worker 	if (policydb_has_boundary_feature(p))
2350*2d543d20SAndroid Build Coastguard Worker 		to_read = 3;
2351*2d543d20SAndroid Build Coastguard Worker 
2352*2d543d20SAndroid Build Coastguard Worker 	rc = next_entry(buf, fp, sizeof(uint32_t) * to_read);
2353*2d543d20SAndroid Build Coastguard Worker 	if (rc < 0)
2354*2d543d20SAndroid Build Coastguard Worker 		goto bad;
2355*2d543d20SAndroid Build Coastguard Worker 
2356*2d543d20SAndroid Build Coastguard Worker 	len = le32_to_cpu(buf[0]);
2357*2d543d20SAndroid Build Coastguard Worker 	rc = str_read(&key, fp, len);
2358*2d543d20SAndroid Build Coastguard Worker 	if (rc < 0)
2359*2d543d20SAndroid Build Coastguard Worker 		goto bad;
2360*2d543d20SAndroid Build Coastguard Worker 
2361*2d543d20SAndroid Build Coastguard Worker 	role->s.value = le32_to_cpu(buf[1]);
2362*2d543d20SAndroid Build Coastguard Worker 	if (policydb_has_boundary_feature(p))
2363*2d543d20SAndroid Build Coastguard Worker 		role->bounds = le32_to_cpu(buf[2]);
2364*2d543d20SAndroid Build Coastguard Worker 
2365*2d543d20SAndroid Build Coastguard Worker 	if (ebitmap_read(&role->dominates, fp))
2366*2d543d20SAndroid Build Coastguard Worker 		goto bad;
2367*2d543d20SAndroid Build Coastguard Worker 
2368*2d543d20SAndroid Build Coastguard Worker 	if (p->policy_type == POLICY_KERN) {
2369*2d543d20SAndroid Build Coastguard Worker 		if (ebitmap_read(&role->types.types, fp))
2370*2d543d20SAndroid Build Coastguard Worker 			goto bad;
2371*2d543d20SAndroid Build Coastguard Worker 	} else {
2372*2d543d20SAndroid Build Coastguard Worker 		if (type_set_read(&role->types, fp))
2373*2d543d20SAndroid Build Coastguard Worker 			goto bad;
2374*2d543d20SAndroid Build Coastguard Worker 	}
2375*2d543d20SAndroid Build Coastguard Worker 
2376*2d543d20SAndroid Build Coastguard Worker 	if (p->policy_type != POLICY_KERN &&
2377*2d543d20SAndroid Build Coastguard Worker 	    p->policyvers >= MOD_POLICYDB_VERSION_ROLEATTRIB) {
2378*2d543d20SAndroid Build Coastguard Worker 		rc = next_entry(buf, fp, sizeof(uint32_t));
2379*2d543d20SAndroid Build Coastguard Worker 		if (rc < 0)
2380*2d543d20SAndroid Build Coastguard Worker 			goto bad;
2381*2d543d20SAndroid Build Coastguard Worker 
2382*2d543d20SAndroid Build Coastguard Worker 		role->flavor = le32_to_cpu(buf[0]);
2383*2d543d20SAndroid Build Coastguard Worker 
2384*2d543d20SAndroid Build Coastguard Worker 		if (ebitmap_read(&role->roles, fp))
2385*2d543d20SAndroid Build Coastguard Worker 			goto bad;
2386*2d543d20SAndroid Build Coastguard Worker 	}
2387*2d543d20SAndroid Build Coastguard Worker 
2388*2d543d20SAndroid Build Coastguard Worker 	if (strcmp(key, OBJECT_R) == 0) {
2389*2d543d20SAndroid Build Coastguard Worker 		if (role->s.value != OBJECT_R_VAL) {
2390*2d543d20SAndroid Build Coastguard Worker 			ERR(fp->handle, "role %s has wrong value %d",
2391*2d543d20SAndroid Build Coastguard Worker 			    OBJECT_R, role->s.value);
2392*2d543d20SAndroid Build Coastguard Worker 			role_destroy(key, role, NULL);
2393*2d543d20SAndroid Build Coastguard Worker 			return -1;
2394*2d543d20SAndroid Build Coastguard Worker 		}
2395*2d543d20SAndroid Build Coastguard Worker 		role_destroy(key, role, NULL);
2396*2d543d20SAndroid Build Coastguard Worker 		return 0;
2397*2d543d20SAndroid Build Coastguard Worker 	}
2398*2d543d20SAndroid Build Coastguard Worker 
2399*2d543d20SAndroid Build Coastguard Worker 	if (hashtab_insert(h, key, role))
2400*2d543d20SAndroid Build Coastguard Worker 		goto bad;
2401*2d543d20SAndroid Build Coastguard Worker 
2402*2d543d20SAndroid Build Coastguard Worker 	return 0;
2403*2d543d20SAndroid Build Coastguard Worker 
2404*2d543d20SAndroid Build Coastguard Worker       bad:
2405*2d543d20SAndroid Build Coastguard Worker 	role_destroy(key, role, NULL);
2406*2d543d20SAndroid Build Coastguard Worker 	return -1;
2407*2d543d20SAndroid Build Coastguard Worker }
2408*2d543d20SAndroid Build Coastguard Worker 
type_read(policydb_t * p,hashtab_t h,struct policy_file * fp)2409*2d543d20SAndroid Build Coastguard Worker static int type_read(policydb_t * p, hashtab_t h, struct policy_file *fp)
2410*2d543d20SAndroid Build Coastguard Worker {
2411*2d543d20SAndroid Build Coastguard Worker 	char *key = 0;
2412*2d543d20SAndroid Build Coastguard Worker 	type_datum_t *typdatum;
2413*2d543d20SAndroid Build Coastguard Worker 	uint32_t buf[5];
2414*2d543d20SAndroid Build Coastguard Worker 	size_t len;
2415*2d543d20SAndroid Build Coastguard Worker 	int rc, to_read;
2416*2d543d20SAndroid Build Coastguard Worker 	int pos = 0;
2417*2d543d20SAndroid Build Coastguard Worker 
2418*2d543d20SAndroid Build Coastguard Worker 	typdatum = calloc(1, sizeof(type_datum_t));
2419*2d543d20SAndroid Build Coastguard Worker 	if (!typdatum)
2420*2d543d20SAndroid Build Coastguard Worker 		return -1;
2421*2d543d20SAndroid Build Coastguard Worker 
2422*2d543d20SAndroid Build Coastguard Worker 	if (policydb_has_boundary_feature(p)) {
2423*2d543d20SAndroid Build Coastguard Worker 		if (p->policy_type != POLICY_KERN
2424*2d543d20SAndroid Build Coastguard Worker 		    && p->policyvers >= MOD_POLICYDB_VERSION_BOUNDARY_ALIAS)
2425*2d543d20SAndroid Build Coastguard Worker 			to_read = 5;
2426*2d543d20SAndroid Build Coastguard Worker 		else
2427*2d543d20SAndroid Build Coastguard Worker 			to_read = 4;
2428*2d543d20SAndroid Build Coastguard Worker 	}
2429*2d543d20SAndroid Build Coastguard Worker 	else if (p->policy_type == POLICY_KERN)
2430*2d543d20SAndroid Build Coastguard Worker 		to_read = 3;
2431*2d543d20SAndroid Build Coastguard Worker 	else if (p->policyvers >= MOD_POLICYDB_VERSION_PERMISSIVE)
2432*2d543d20SAndroid Build Coastguard Worker 		to_read = 5;
2433*2d543d20SAndroid Build Coastguard Worker 	else
2434*2d543d20SAndroid Build Coastguard Worker 		to_read = 4;
2435*2d543d20SAndroid Build Coastguard Worker 
2436*2d543d20SAndroid Build Coastguard Worker 	rc = next_entry(buf, fp, sizeof(uint32_t) * to_read);
2437*2d543d20SAndroid Build Coastguard Worker 	if (rc < 0)
2438*2d543d20SAndroid Build Coastguard Worker 		goto bad;
2439*2d543d20SAndroid Build Coastguard Worker 
2440*2d543d20SAndroid Build Coastguard Worker 	len = le32_to_cpu(buf[pos]);
2441*2d543d20SAndroid Build Coastguard Worker 	typdatum->s.value = le32_to_cpu(buf[++pos]);
2442*2d543d20SAndroid Build Coastguard Worker 	if (policydb_has_boundary_feature(p)) {
2443*2d543d20SAndroid Build Coastguard Worker 		uint32_t properties;
2444*2d543d20SAndroid Build Coastguard Worker 
2445*2d543d20SAndroid Build Coastguard Worker 		if (p->policy_type != POLICY_KERN
2446*2d543d20SAndroid Build Coastguard Worker 		    && p->policyvers >= MOD_POLICYDB_VERSION_BOUNDARY_ALIAS) {
2447*2d543d20SAndroid Build Coastguard Worker 			typdatum->primary = le32_to_cpu(buf[++pos]);
2448*2d543d20SAndroid Build Coastguard Worker 			properties = le32_to_cpu(buf[++pos]);
2449*2d543d20SAndroid Build Coastguard Worker 		}
2450*2d543d20SAndroid Build Coastguard Worker 		else {
2451*2d543d20SAndroid Build Coastguard Worker 			properties = le32_to_cpu(buf[++pos]);
2452*2d543d20SAndroid Build Coastguard Worker 
2453*2d543d20SAndroid Build Coastguard Worker 			if (properties & TYPEDATUM_PROPERTY_PRIMARY)
2454*2d543d20SAndroid Build Coastguard Worker 				typdatum->primary = 1;
2455*2d543d20SAndroid Build Coastguard Worker 		}
2456*2d543d20SAndroid Build Coastguard Worker 
2457*2d543d20SAndroid Build Coastguard Worker 		if (properties & TYPEDATUM_PROPERTY_ATTRIBUTE)
2458*2d543d20SAndroid Build Coastguard Worker 			typdatum->flavor = TYPE_ATTRIB;
2459*2d543d20SAndroid Build Coastguard Worker 		if (properties & TYPEDATUM_PROPERTY_ALIAS
2460*2d543d20SAndroid Build Coastguard Worker 		    && p->policy_type != POLICY_KERN)
2461*2d543d20SAndroid Build Coastguard Worker 			typdatum->flavor = TYPE_ALIAS;
2462*2d543d20SAndroid Build Coastguard Worker 		if (properties & TYPEDATUM_PROPERTY_PERMISSIVE
2463*2d543d20SAndroid Build Coastguard Worker 		    && p->policy_type != POLICY_KERN)
2464*2d543d20SAndroid Build Coastguard Worker 			typdatum->flags |= TYPE_FLAGS_PERMISSIVE;
2465*2d543d20SAndroid Build Coastguard Worker 
2466*2d543d20SAndroid Build Coastguard Worker 		typdatum->bounds = le32_to_cpu(buf[++pos]);
2467*2d543d20SAndroid Build Coastguard Worker 	} else {
2468*2d543d20SAndroid Build Coastguard Worker 		typdatum->primary = le32_to_cpu(buf[++pos]);
2469*2d543d20SAndroid Build Coastguard Worker 		if (p->policy_type != POLICY_KERN) {
2470*2d543d20SAndroid Build Coastguard Worker 			typdatum->flavor = le32_to_cpu(buf[++pos]);
2471*2d543d20SAndroid Build Coastguard Worker 			if (p->policyvers >= MOD_POLICYDB_VERSION_PERMISSIVE)
2472*2d543d20SAndroid Build Coastguard Worker 				typdatum->flags = le32_to_cpu(buf[++pos]);
2473*2d543d20SAndroid Build Coastguard Worker 		}
2474*2d543d20SAndroid Build Coastguard Worker 	}
2475*2d543d20SAndroid Build Coastguard Worker 
2476*2d543d20SAndroid Build Coastguard Worker 	if (p->policy_type != POLICY_KERN) {
2477*2d543d20SAndroid Build Coastguard Worker 		if (ebitmap_read(&typdatum->types, fp))
2478*2d543d20SAndroid Build Coastguard Worker 			goto bad;
2479*2d543d20SAndroid Build Coastguard Worker 	}
2480*2d543d20SAndroid Build Coastguard Worker 
2481*2d543d20SAndroid Build Coastguard Worker 	rc = str_read(&key, fp, len);
2482*2d543d20SAndroid Build Coastguard Worker 	if (rc < 0)
2483*2d543d20SAndroid Build Coastguard Worker 		goto bad;
2484*2d543d20SAndroid Build Coastguard Worker 
2485*2d543d20SAndroid Build Coastguard Worker 	if (hashtab_insert(h, key, typdatum))
2486*2d543d20SAndroid Build Coastguard Worker 		goto bad;
2487*2d543d20SAndroid Build Coastguard Worker 
2488*2d543d20SAndroid Build Coastguard Worker 	return 0;
2489*2d543d20SAndroid Build Coastguard Worker 
2490*2d543d20SAndroid Build Coastguard Worker       bad:
2491*2d543d20SAndroid Build Coastguard Worker 	type_destroy(key, typdatum, NULL);
2492*2d543d20SAndroid Build Coastguard Worker 	return -1;
2493*2d543d20SAndroid Build Coastguard Worker }
2494*2d543d20SAndroid Build Coastguard Worker 
role_trans_read(policydb_t * p,struct policy_file * fp)2495*2d543d20SAndroid Build Coastguard Worker static int role_trans_read(policydb_t *p, struct policy_file *fp)
2496*2d543d20SAndroid Build Coastguard Worker {
2497*2d543d20SAndroid Build Coastguard Worker 	role_trans_t **t = &p->role_tr;
2498*2d543d20SAndroid Build Coastguard Worker 	unsigned int i;
2499*2d543d20SAndroid Build Coastguard Worker 	uint32_t buf[3], nel;
2500*2d543d20SAndroid Build Coastguard Worker 	role_trans_t *tr, *ltr;
2501*2d543d20SAndroid Build Coastguard Worker 	int rc;
2502*2d543d20SAndroid Build Coastguard Worker 	int new_roletr = (p->policy_type == POLICY_KERN &&
2503*2d543d20SAndroid Build Coastguard Worker 			  p->policyvers >= POLICYDB_VERSION_ROLETRANS);
2504*2d543d20SAndroid Build Coastguard Worker 
2505*2d543d20SAndroid Build Coastguard Worker 	rc = next_entry(buf, fp, sizeof(uint32_t));
2506*2d543d20SAndroid Build Coastguard Worker 	if (rc < 0)
2507*2d543d20SAndroid Build Coastguard Worker 		return -1;
2508*2d543d20SAndroid Build Coastguard Worker 	nel = le32_to_cpu(buf[0]);
2509*2d543d20SAndroid Build Coastguard Worker 	ltr = NULL;
2510*2d543d20SAndroid Build Coastguard Worker 	for (i = 0; i < nel; i++) {
2511*2d543d20SAndroid Build Coastguard Worker 		tr = calloc(1, sizeof(struct role_trans));
2512*2d543d20SAndroid Build Coastguard Worker 		if (!tr) {
2513*2d543d20SAndroid Build Coastguard Worker 			return -1;
2514*2d543d20SAndroid Build Coastguard Worker 		}
2515*2d543d20SAndroid Build Coastguard Worker 		if (ltr) {
2516*2d543d20SAndroid Build Coastguard Worker 			ltr->next = tr;
2517*2d543d20SAndroid Build Coastguard Worker 		} else {
2518*2d543d20SAndroid Build Coastguard Worker 			*t = tr;
2519*2d543d20SAndroid Build Coastguard Worker 		}
2520*2d543d20SAndroid Build Coastguard Worker 		rc = next_entry(buf, fp, sizeof(uint32_t) * 3);
2521*2d543d20SAndroid Build Coastguard Worker 		if (rc < 0)
2522*2d543d20SAndroid Build Coastguard Worker 			return -1;
2523*2d543d20SAndroid Build Coastguard Worker 		tr->role = le32_to_cpu(buf[0]);
2524*2d543d20SAndroid Build Coastguard Worker 		tr->type = le32_to_cpu(buf[1]);
2525*2d543d20SAndroid Build Coastguard Worker 		tr->new_role = le32_to_cpu(buf[2]);
2526*2d543d20SAndroid Build Coastguard Worker 		if (new_roletr) {
2527*2d543d20SAndroid Build Coastguard Worker 			rc = next_entry(buf, fp, sizeof(uint32_t));
2528*2d543d20SAndroid Build Coastguard Worker 			if (rc < 0)
2529*2d543d20SAndroid Build Coastguard Worker 				return -1;
2530*2d543d20SAndroid Build Coastguard Worker 			tr->tclass = le32_to_cpu(buf[0]);
2531*2d543d20SAndroid Build Coastguard Worker 		} else
2532*2d543d20SAndroid Build Coastguard Worker 			tr->tclass = p->process_class;
2533*2d543d20SAndroid Build Coastguard Worker 		ltr = tr;
2534*2d543d20SAndroid Build Coastguard Worker 	}
2535*2d543d20SAndroid Build Coastguard Worker 	return 0;
2536*2d543d20SAndroid Build Coastguard Worker }
2537*2d543d20SAndroid Build Coastguard Worker 
role_allow_read(role_allow_t ** r,struct policy_file * fp)2538*2d543d20SAndroid Build Coastguard Worker static int role_allow_read(role_allow_t ** r, struct policy_file *fp)
2539*2d543d20SAndroid Build Coastguard Worker {
2540*2d543d20SAndroid Build Coastguard Worker 	unsigned int i;
2541*2d543d20SAndroid Build Coastguard Worker 	uint32_t buf[2], nel;
2542*2d543d20SAndroid Build Coastguard Worker 	role_allow_t *ra, *lra;
2543*2d543d20SAndroid Build Coastguard Worker 	int rc;
2544*2d543d20SAndroid Build Coastguard Worker 
2545*2d543d20SAndroid Build Coastguard Worker 	rc = next_entry(buf, fp, sizeof(uint32_t));
2546*2d543d20SAndroid Build Coastguard Worker 	if (rc < 0)
2547*2d543d20SAndroid Build Coastguard Worker 		return -1;
2548*2d543d20SAndroid Build Coastguard Worker 	nel = le32_to_cpu(buf[0]);
2549*2d543d20SAndroid Build Coastguard Worker 	lra = NULL;
2550*2d543d20SAndroid Build Coastguard Worker 	for (i = 0; i < nel; i++) {
2551*2d543d20SAndroid Build Coastguard Worker 		ra = calloc(1, sizeof(struct role_allow));
2552*2d543d20SAndroid Build Coastguard Worker 		if (!ra) {
2553*2d543d20SAndroid Build Coastguard Worker 			return -1;
2554*2d543d20SAndroid Build Coastguard Worker 		}
2555*2d543d20SAndroid Build Coastguard Worker 		if (lra) {
2556*2d543d20SAndroid Build Coastguard Worker 			lra->next = ra;
2557*2d543d20SAndroid Build Coastguard Worker 		} else {
2558*2d543d20SAndroid Build Coastguard Worker 			*r = ra;
2559*2d543d20SAndroid Build Coastguard Worker 		}
2560*2d543d20SAndroid Build Coastguard Worker 		rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
2561*2d543d20SAndroid Build Coastguard Worker 		if (rc < 0)
2562*2d543d20SAndroid Build Coastguard Worker 			return -1;
2563*2d543d20SAndroid Build Coastguard Worker 		ra->role = le32_to_cpu(buf[0]);
2564*2d543d20SAndroid Build Coastguard Worker 		ra->new_role = le32_to_cpu(buf[1]);
2565*2d543d20SAndroid Build Coastguard Worker 		lra = ra;
2566*2d543d20SAndroid Build Coastguard Worker 	}
2567*2d543d20SAndroid Build Coastguard Worker 	return 0;
2568*2d543d20SAndroid Build Coastguard Worker }
2569*2d543d20SAndroid Build Coastguard Worker 
policydb_filetrans_insert(policydb_t * p,uint32_t stype,uint32_t ttype,uint32_t tclass,const char * name,char ** name_alloc,uint32_t otype,uint32_t * present_otype)2570*2d543d20SAndroid Build Coastguard Worker int policydb_filetrans_insert(policydb_t *p, uint32_t stype, uint32_t ttype,
2571*2d543d20SAndroid Build Coastguard Worker 			      uint32_t tclass, const char *name,
2572*2d543d20SAndroid Build Coastguard Worker 			      char **name_alloc, uint32_t otype,
2573*2d543d20SAndroid Build Coastguard Worker 			      uint32_t *present_otype)
2574*2d543d20SAndroid Build Coastguard Worker {
2575*2d543d20SAndroid Build Coastguard Worker 	filename_trans_key_t *ft, key;
2576*2d543d20SAndroid Build Coastguard Worker 	filename_trans_datum_t *datum, *last;
2577*2d543d20SAndroid Build Coastguard Worker 
2578*2d543d20SAndroid Build Coastguard Worker 	key.ttype = ttype;
2579*2d543d20SAndroid Build Coastguard Worker 	key.tclass = tclass;
2580*2d543d20SAndroid Build Coastguard Worker 	key.name = (char *)name;
2581*2d543d20SAndroid Build Coastguard Worker 
2582*2d543d20SAndroid Build Coastguard Worker 	last = NULL;
2583*2d543d20SAndroid Build Coastguard Worker 	datum = hashtab_search(p->filename_trans, (hashtab_key_t)&key);
2584*2d543d20SAndroid Build Coastguard Worker 	while (datum) {
2585*2d543d20SAndroid Build Coastguard Worker 		if (ebitmap_get_bit(&datum->stypes, stype - 1)) {
2586*2d543d20SAndroid Build Coastguard Worker 			if (present_otype)
2587*2d543d20SAndroid Build Coastguard Worker 				*present_otype = datum->otype;
2588*2d543d20SAndroid Build Coastguard Worker 			return SEPOL_EEXIST;
2589*2d543d20SAndroid Build Coastguard Worker 		}
2590*2d543d20SAndroid Build Coastguard Worker 		if (datum->otype == otype)
2591*2d543d20SAndroid Build Coastguard Worker 			break;
2592*2d543d20SAndroid Build Coastguard Worker 		last = datum;
2593*2d543d20SAndroid Build Coastguard Worker 		datum = datum->next;
2594*2d543d20SAndroid Build Coastguard Worker 	}
2595*2d543d20SAndroid Build Coastguard Worker 	if (!datum) {
2596*2d543d20SAndroid Build Coastguard Worker 		datum = malloc(sizeof(*datum));
2597*2d543d20SAndroid Build Coastguard Worker 		if (!datum)
2598*2d543d20SAndroid Build Coastguard Worker 			return SEPOL_ENOMEM;
2599*2d543d20SAndroid Build Coastguard Worker 
2600*2d543d20SAndroid Build Coastguard Worker 		ebitmap_init(&datum->stypes);
2601*2d543d20SAndroid Build Coastguard Worker 		datum->otype = otype;
2602*2d543d20SAndroid Build Coastguard Worker 		datum->next = NULL;
2603*2d543d20SAndroid Build Coastguard Worker 
2604*2d543d20SAndroid Build Coastguard Worker 		if (last) {
2605*2d543d20SAndroid Build Coastguard Worker 			last->next = datum;
2606*2d543d20SAndroid Build Coastguard Worker 		} else {
2607*2d543d20SAndroid Build Coastguard Worker 			char *name_dup;
2608*2d543d20SAndroid Build Coastguard Worker 
2609*2d543d20SAndroid Build Coastguard Worker 			if (name_alloc) {
2610*2d543d20SAndroid Build Coastguard Worker 				name_dup = *name_alloc;
2611*2d543d20SAndroid Build Coastguard Worker 				*name_alloc = NULL;
2612*2d543d20SAndroid Build Coastguard Worker 			} else {
2613*2d543d20SAndroid Build Coastguard Worker 				name_dup = strdup(name);
2614*2d543d20SAndroid Build Coastguard Worker 				if (!name_dup) {
2615*2d543d20SAndroid Build Coastguard Worker 					free(datum);
2616*2d543d20SAndroid Build Coastguard Worker 					return SEPOL_ENOMEM;
2617*2d543d20SAndroid Build Coastguard Worker 				}
2618*2d543d20SAndroid Build Coastguard Worker 			}
2619*2d543d20SAndroid Build Coastguard Worker 
2620*2d543d20SAndroid Build Coastguard Worker 			ft = malloc(sizeof(*ft));
2621*2d543d20SAndroid Build Coastguard Worker 			if (!ft) {
2622*2d543d20SAndroid Build Coastguard Worker 				free(name_dup);
2623*2d543d20SAndroid Build Coastguard Worker 				free(datum);
2624*2d543d20SAndroid Build Coastguard Worker 				return SEPOL_ENOMEM;
2625*2d543d20SAndroid Build Coastguard Worker 			}
2626*2d543d20SAndroid Build Coastguard Worker 
2627*2d543d20SAndroid Build Coastguard Worker 			ft->ttype = ttype;
2628*2d543d20SAndroid Build Coastguard Worker 			ft->tclass = tclass;
2629*2d543d20SAndroid Build Coastguard Worker 			ft->name = name_dup;
2630*2d543d20SAndroid Build Coastguard Worker 
2631*2d543d20SAndroid Build Coastguard Worker 			if (hashtab_insert(p->filename_trans, (hashtab_key_t)ft,
2632*2d543d20SAndroid Build Coastguard Worker 					   (hashtab_datum_t)datum)) {
2633*2d543d20SAndroid Build Coastguard Worker 				free(name_dup);
2634*2d543d20SAndroid Build Coastguard Worker 				free(datum);
2635*2d543d20SAndroid Build Coastguard Worker 				free(ft);
2636*2d543d20SAndroid Build Coastguard Worker 				return SEPOL_ENOMEM;
2637*2d543d20SAndroid Build Coastguard Worker 			}
2638*2d543d20SAndroid Build Coastguard Worker 		}
2639*2d543d20SAndroid Build Coastguard Worker 	}
2640*2d543d20SAndroid Build Coastguard Worker 
2641*2d543d20SAndroid Build Coastguard Worker 	p->filename_trans_count++;
2642*2d543d20SAndroid Build Coastguard Worker 	return ebitmap_set_bit(&datum->stypes, stype - 1, 1);
2643*2d543d20SAndroid Build Coastguard Worker }
2644*2d543d20SAndroid Build Coastguard Worker 
filename_trans_read_one_compat(policydb_t * p,struct policy_file * fp)2645*2d543d20SAndroid Build Coastguard Worker static int filename_trans_read_one_compat(policydb_t *p, struct policy_file *fp)
2646*2d543d20SAndroid Build Coastguard Worker {
2647*2d543d20SAndroid Build Coastguard Worker 	uint32_t buf[4], len, stype, ttype, tclass, otype;
2648*2d543d20SAndroid Build Coastguard Worker 	char *name = NULL;
2649*2d543d20SAndroid Build Coastguard Worker 	int rc;
2650*2d543d20SAndroid Build Coastguard Worker 
2651*2d543d20SAndroid Build Coastguard Worker 	rc = next_entry(buf, fp, sizeof(uint32_t));
2652*2d543d20SAndroid Build Coastguard Worker 	if (rc < 0)
2653*2d543d20SAndroid Build Coastguard Worker 		return -1;
2654*2d543d20SAndroid Build Coastguard Worker 	len = le32_to_cpu(buf[0]);
2655*2d543d20SAndroid Build Coastguard Worker 
2656*2d543d20SAndroid Build Coastguard Worker 	rc = str_read(&name, fp, len);
2657*2d543d20SAndroid Build Coastguard Worker 	if (rc < 0)
2658*2d543d20SAndroid Build Coastguard Worker 		goto err;
2659*2d543d20SAndroid Build Coastguard Worker 
2660*2d543d20SAndroid Build Coastguard Worker 	rc = next_entry(buf, fp, sizeof(uint32_t) * 4);
2661*2d543d20SAndroid Build Coastguard Worker 	if (rc < 0)
2662*2d543d20SAndroid Build Coastguard Worker 		goto err;
2663*2d543d20SAndroid Build Coastguard Worker 
2664*2d543d20SAndroid Build Coastguard Worker 	stype = le32_to_cpu(buf[0]);
2665*2d543d20SAndroid Build Coastguard Worker 	if (stype == 0)
2666*2d543d20SAndroid Build Coastguard Worker 		goto err;
2667*2d543d20SAndroid Build Coastguard Worker 
2668*2d543d20SAndroid Build Coastguard Worker 	ttype  = le32_to_cpu(buf[1]);
2669*2d543d20SAndroid Build Coastguard Worker 	tclass = le32_to_cpu(buf[2]);
2670*2d543d20SAndroid Build Coastguard Worker 	otype  = le32_to_cpu(buf[3]);
2671*2d543d20SAndroid Build Coastguard Worker 
2672*2d543d20SAndroid Build Coastguard Worker 	rc = policydb_filetrans_insert(p, stype, ttype, tclass, name, &name,
2673*2d543d20SAndroid Build Coastguard Worker 				       otype, NULL);
2674*2d543d20SAndroid Build Coastguard Worker 	if (rc) {
2675*2d543d20SAndroid Build Coastguard Worker 		if (rc != SEPOL_EEXIST)
2676*2d543d20SAndroid Build Coastguard Worker 			goto err;
2677*2d543d20SAndroid Build Coastguard Worker 		/*
2678*2d543d20SAndroid Build Coastguard Worker 		 * Some old policies were wrongly generated with
2679*2d543d20SAndroid Build Coastguard Worker 		 * duplicate filename transition rules.  For backward
2680*2d543d20SAndroid Build Coastguard Worker 		 * compatibility, do not reject such policies, just
2681*2d543d20SAndroid Build Coastguard Worker 		 * ignore the duplicate.
2682*2d543d20SAndroid Build Coastguard Worker 		 */
2683*2d543d20SAndroid Build Coastguard Worker 	}
2684*2d543d20SAndroid Build Coastguard Worker 	free(name);
2685*2d543d20SAndroid Build Coastguard Worker 	return 0;
2686*2d543d20SAndroid Build Coastguard Worker err:
2687*2d543d20SAndroid Build Coastguard Worker 	free(name);
2688*2d543d20SAndroid Build Coastguard Worker 	return -1;
2689*2d543d20SAndroid Build Coastguard Worker }
2690*2d543d20SAndroid Build Coastguard Worker 
filename_trans_check_datum(filename_trans_datum_t * datum)2691*2d543d20SAndroid Build Coastguard Worker static int filename_trans_check_datum(filename_trans_datum_t *datum)
2692*2d543d20SAndroid Build Coastguard Worker {
2693*2d543d20SAndroid Build Coastguard Worker 	ebitmap_t stypes, otypes;
2694*2d543d20SAndroid Build Coastguard Worker 	int rc = -1;
2695*2d543d20SAndroid Build Coastguard Worker 
2696*2d543d20SAndroid Build Coastguard Worker 	ebitmap_init(&stypes);
2697*2d543d20SAndroid Build Coastguard Worker 	ebitmap_init(&otypes);
2698*2d543d20SAndroid Build Coastguard Worker 
2699*2d543d20SAndroid Build Coastguard Worker 	while (datum) {
2700*2d543d20SAndroid Build Coastguard Worker 		if (ebitmap_get_bit(&otypes, datum->otype))
2701*2d543d20SAndroid Build Coastguard Worker 			goto out;
2702*2d543d20SAndroid Build Coastguard Worker 
2703*2d543d20SAndroid Build Coastguard Worker 		if (ebitmap_set_bit(&otypes, datum->otype, 1))
2704*2d543d20SAndroid Build Coastguard Worker 			goto out;
2705*2d543d20SAndroid Build Coastguard Worker 
2706*2d543d20SAndroid Build Coastguard Worker 		if (ebitmap_match_any(&stypes, &datum->stypes))
2707*2d543d20SAndroid Build Coastguard Worker 			goto out;
2708*2d543d20SAndroid Build Coastguard Worker 
2709*2d543d20SAndroid Build Coastguard Worker 		if (ebitmap_union(&stypes, &datum->stypes))
2710*2d543d20SAndroid Build Coastguard Worker 			goto out;
2711*2d543d20SAndroid Build Coastguard Worker 
2712*2d543d20SAndroid Build Coastguard Worker 		datum = datum->next;
2713*2d543d20SAndroid Build Coastguard Worker 	}
2714*2d543d20SAndroid Build Coastguard Worker 	rc = 0;
2715*2d543d20SAndroid Build Coastguard Worker out:
2716*2d543d20SAndroid Build Coastguard Worker 	ebitmap_destroy(&stypes);
2717*2d543d20SAndroid Build Coastguard Worker 	ebitmap_destroy(&otypes);
2718*2d543d20SAndroid Build Coastguard Worker 	return rc;
2719*2d543d20SAndroid Build Coastguard Worker }
2720*2d543d20SAndroid Build Coastguard Worker 
filename_trans_read_one(policydb_t * p,struct policy_file * fp)2721*2d543d20SAndroid Build Coastguard Worker static int filename_trans_read_one(policydb_t *p, struct policy_file *fp)
2722*2d543d20SAndroid Build Coastguard Worker {
2723*2d543d20SAndroid Build Coastguard Worker 	filename_trans_key_t *ft = NULL;
2724*2d543d20SAndroid Build Coastguard Worker 	filename_trans_datum_t **dst, *datum, *first = NULL;
2725*2d543d20SAndroid Build Coastguard Worker 	unsigned int i;
2726*2d543d20SAndroid Build Coastguard Worker 	uint32_t buf[3], len, ttype, tclass, ndatum;
2727*2d543d20SAndroid Build Coastguard Worker 	char *name = NULL;
2728*2d543d20SAndroid Build Coastguard Worker 	int rc;
2729*2d543d20SAndroid Build Coastguard Worker 
2730*2d543d20SAndroid Build Coastguard Worker 	rc = next_entry(buf, fp, sizeof(uint32_t));
2731*2d543d20SAndroid Build Coastguard Worker 	if (rc < 0)
2732*2d543d20SAndroid Build Coastguard Worker 		return -1;
2733*2d543d20SAndroid Build Coastguard Worker 	len = le32_to_cpu(buf[0]);
2734*2d543d20SAndroid Build Coastguard Worker 
2735*2d543d20SAndroid Build Coastguard Worker 	rc = str_read(&name, fp, len);
2736*2d543d20SAndroid Build Coastguard Worker 	if (rc < 0)
2737*2d543d20SAndroid Build Coastguard Worker 		goto err;
2738*2d543d20SAndroid Build Coastguard Worker 
2739*2d543d20SAndroid Build Coastguard Worker 	rc = next_entry(buf, fp, sizeof(uint32_t) * 3);
2740*2d543d20SAndroid Build Coastguard Worker 	if (rc < 0)
2741*2d543d20SAndroid Build Coastguard Worker 		goto err;
2742*2d543d20SAndroid Build Coastguard Worker 
2743*2d543d20SAndroid Build Coastguard Worker 	ttype = le32_to_cpu(buf[0]);
2744*2d543d20SAndroid Build Coastguard Worker 	tclass = le32_to_cpu(buf[1]);
2745*2d543d20SAndroid Build Coastguard Worker 	ndatum = le32_to_cpu(buf[2]);
2746*2d543d20SAndroid Build Coastguard Worker 	if (ndatum == 0)
2747*2d543d20SAndroid Build Coastguard Worker 		goto err;
2748*2d543d20SAndroid Build Coastguard Worker 
2749*2d543d20SAndroid Build Coastguard Worker 	dst = &first;
2750*2d543d20SAndroid Build Coastguard Worker 	for (i = 0; i < ndatum; i++) {
2751*2d543d20SAndroid Build Coastguard Worker 		datum = malloc(sizeof(*datum));
2752*2d543d20SAndroid Build Coastguard Worker 		if (!datum)
2753*2d543d20SAndroid Build Coastguard Worker 			goto err;
2754*2d543d20SAndroid Build Coastguard Worker 
2755*2d543d20SAndroid Build Coastguard Worker 		datum->next = NULL;
2756*2d543d20SAndroid Build Coastguard Worker 		*dst = datum;
2757*2d543d20SAndroid Build Coastguard Worker 
2758*2d543d20SAndroid Build Coastguard Worker 		/* ebitmap_read() will at least init the bitmap */
2759*2d543d20SAndroid Build Coastguard Worker 		rc = ebitmap_read(&datum->stypes, fp);
2760*2d543d20SAndroid Build Coastguard Worker 		if (rc < 0)
2761*2d543d20SAndroid Build Coastguard Worker 			goto err;
2762*2d543d20SAndroid Build Coastguard Worker 
2763*2d543d20SAndroid Build Coastguard Worker 		rc = next_entry(buf, fp, sizeof(uint32_t));
2764*2d543d20SAndroid Build Coastguard Worker 		if (rc < 0)
2765*2d543d20SAndroid Build Coastguard Worker 			goto err;
2766*2d543d20SAndroid Build Coastguard Worker 
2767*2d543d20SAndroid Build Coastguard Worker 		datum->otype = le32_to_cpu(buf[0]);
2768*2d543d20SAndroid Build Coastguard Worker 
2769*2d543d20SAndroid Build Coastguard Worker 		p->filename_trans_count += ebitmap_cardinality(&datum->stypes);
2770*2d543d20SAndroid Build Coastguard Worker 
2771*2d543d20SAndroid Build Coastguard Worker 		dst = &datum->next;
2772*2d543d20SAndroid Build Coastguard Worker 	}
2773*2d543d20SAndroid Build Coastguard Worker 
2774*2d543d20SAndroid Build Coastguard Worker 	if (ndatum > 1 && filename_trans_check_datum(first))
2775*2d543d20SAndroid Build Coastguard Worker 		goto err;
2776*2d543d20SAndroid Build Coastguard Worker 
2777*2d543d20SAndroid Build Coastguard Worker 	ft = malloc(sizeof(*ft));
2778*2d543d20SAndroid Build Coastguard Worker 	if (!ft)
2779*2d543d20SAndroid Build Coastguard Worker 		goto err;
2780*2d543d20SAndroid Build Coastguard Worker 
2781*2d543d20SAndroid Build Coastguard Worker 	ft->ttype = ttype;
2782*2d543d20SAndroid Build Coastguard Worker 	ft->tclass = tclass;
2783*2d543d20SAndroid Build Coastguard Worker 	ft->name = name;
2784*2d543d20SAndroid Build Coastguard Worker 
2785*2d543d20SAndroid Build Coastguard Worker 	rc = hashtab_insert(p->filename_trans, (hashtab_key_t)ft,
2786*2d543d20SAndroid Build Coastguard Worker 			    (hashtab_datum_t)first);
2787*2d543d20SAndroid Build Coastguard Worker 	if (rc)
2788*2d543d20SAndroid Build Coastguard Worker 		goto err;
2789*2d543d20SAndroid Build Coastguard Worker 
2790*2d543d20SAndroid Build Coastguard Worker 	return 0;
2791*2d543d20SAndroid Build Coastguard Worker err:
2792*2d543d20SAndroid Build Coastguard Worker 	free(ft);
2793*2d543d20SAndroid Build Coastguard Worker 	free(name);
2794*2d543d20SAndroid Build Coastguard Worker 	while (first) {
2795*2d543d20SAndroid Build Coastguard Worker 		datum = first;
2796*2d543d20SAndroid Build Coastguard Worker 		first = first->next;
2797*2d543d20SAndroid Build Coastguard Worker 
2798*2d543d20SAndroid Build Coastguard Worker 		ebitmap_destroy(&datum->stypes);
2799*2d543d20SAndroid Build Coastguard Worker 		free(datum);
2800*2d543d20SAndroid Build Coastguard Worker 	}
2801*2d543d20SAndroid Build Coastguard Worker 	return -1;
2802*2d543d20SAndroid Build Coastguard Worker }
2803*2d543d20SAndroid Build Coastguard Worker 
filename_trans_read(policydb_t * p,struct policy_file * fp)2804*2d543d20SAndroid Build Coastguard Worker static int filename_trans_read(policydb_t *p, struct policy_file *fp)
2805*2d543d20SAndroid Build Coastguard Worker {
2806*2d543d20SAndroid Build Coastguard Worker 	unsigned int i;
2807*2d543d20SAndroid Build Coastguard Worker 	uint32_t buf[1], nel;
2808*2d543d20SAndroid Build Coastguard Worker 	int rc;
2809*2d543d20SAndroid Build Coastguard Worker 
2810*2d543d20SAndroid Build Coastguard Worker 	rc = next_entry(buf, fp, sizeof(uint32_t));
2811*2d543d20SAndroid Build Coastguard Worker 	if (rc < 0)
2812*2d543d20SAndroid Build Coastguard Worker 		return -1;
2813*2d543d20SAndroid Build Coastguard Worker 	nel = le32_to_cpu(buf[0]);
2814*2d543d20SAndroid Build Coastguard Worker 
2815*2d543d20SAndroid Build Coastguard Worker 	if (p->policyvers < POLICYDB_VERSION_COMP_FTRANS) {
2816*2d543d20SAndroid Build Coastguard Worker 		for (i = 0; i < nel; i++) {
2817*2d543d20SAndroid Build Coastguard Worker 			rc = filename_trans_read_one_compat(p, fp);
2818*2d543d20SAndroid Build Coastguard Worker 			if (rc < 0)
2819*2d543d20SAndroid Build Coastguard Worker 				return -1;
2820*2d543d20SAndroid Build Coastguard Worker 		}
2821*2d543d20SAndroid Build Coastguard Worker 	} else {
2822*2d543d20SAndroid Build Coastguard Worker 		for (i = 0; i < nel; i++) {
2823*2d543d20SAndroid Build Coastguard Worker 			rc = filename_trans_read_one(p, fp);
2824*2d543d20SAndroid Build Coastguard Worker 			if (rc < 0)
2825*2d543d20SAndroid Build Coastguard Worker 				return -1;
2826*2d543d20SAndroid Build Coastguard Worker 		}
2827*2d543d20SAndroid Build Coastguard Worker 	}
2828*2d543d20SAndroid Build Coastguard Worker 	return 0;
2829*2d543d20SAndroid Build Coastguard Worker }
2830*2d543d20SAndroid Build Coastguard Worker 
ocontext_read_xen(const struct policydb_compat_info * info,policydb_t * p,struct policy_file * fp)2831*2d543d20SAndroid Build Coastguard Worker static int ocontext_read_xen(const struct policydb_compat_info *info,
2832*2d543d20SAndroid Build Coastguard Worker 	policydb_t *p, struct policy_file *fp)
2833*2d543d20SAndroid Build Coastguard Worker {
2834*2d543d20SAndroid Build Coastguard Worker 	unsigned int i, j;
2835*2d543d20SAndroid Build Coastguard Worker 	size_t nel, len;
2836*2d543d20SAndroid Build Coastguard Worker 	ocontext_t *l, *c;
2837*2d543d20SAndroid Build Coastguard Worker 	uint32_t buf[8];
2838*2d543d20SAndroid Build Coastguard Worker 	int rc;
2839*2d543d20SAndroid Build Coastguard Worker 
2840*2d543d20SAndroid Build Coastguard Worker 	for (i = 0; i < info->ocon_num; i++) {
2841*2d543d20SAndroid Build Coastguard Worker 		rc = next_entry(buf, fp, sizeof(uint32_t));
2842*2d543d20SAndroid Build Coastguard Worker 		if (rc < 0)
2843*2d543d20SAndroid Build Coastguard Worker 			return -1;
2844*2d543d20SAndroid Build Coastguard Worker 		nel = le32_to_cpu(buf[0]);
2845*2d543d20SAndroid Build Coastguard Worker 		l = NULL;
2846*2d543d20SAndroid Build Coastguard Worker 		for (j = 0; j < nel; j++) {
2847*2d543d20SAndroid Build Coastguard Worker 			c = calloc(1, sizeof(ocontext_t));
2848*2d543d20SAndroid Build Coastguard Worker 			if (!c)
2849*2d543d20SAndroid Build Coastguard Worker 				return -1;
2850*2d543d20SAndroid Build Coastguard Worker 			if (l)
2851*2d543d20SAndroid Build Coastguard Worker 				l->next = c;
2852*2d543d20SAndroid Build Coastguard Worker 			else
2853*2d543d20SAndroid Build Coastguard Worker 				p->ocontexts[i] = c;
2854*2d543d20SAndroid Build Coastguard Worker 			l = c;
2855*2d543d20SAndroid Build Coastguard Worker 			switch (i) {
2856*2d543d20SAndroid Build Coastguard Worker 			case OCON_XEN_ISID:
2857*2d543d20SAndroid Build Coastguard Worker 				rc = next_entry(buf, fp, sizeof(uint32_t));
2858*2d543d20SAndroid Build Coastguard Worker 				if (rc < 0)
2859*2d543d20SAndroid Build Coastguard Worker 					return -1;
2860*2d543d20SAndroid Build Coastguard Worker 				c->sid[0] = le32_to_cpu(buf[0]);
2861*2d543d20SAndroid Build Coastguard Worker 				if (is_saturated(c->sid[0]))
2862*2d543d20SAndroid Build Coastguard Worker 					return -1;
2863*2d543d20SAndroid Build Coastguard Worker 				if (context_read_and_validate
2864*2d543d20SAndroid Build Coastguard Worker 				    (&c->context[0], p, fp))
2865*2d543d20SAndroid Build Coastguard Worker 					return -1;
2866*2d543d20SAndroid Build Coastguard Worker 				break;
2867*2d543d20SAndroid Build Coastguard Worker 			case OCON_XEN_PIRQ:
2868*2d543d20SAndroid Build Coastguard Worker 				rc = next_entry(buf, fp, sizeof(uint32_t));
2869*2d543d20SAndroid Build Coastguard Worker 				if (rc < 0)
2870*2d543d20SAndroid Build Coastguard Worker 					return -1;
2871*2d543d20SAndroid Build Coastguard Worker 				c->u.pirq = le32_to_cpu(buf[0]);
2872*2d543d20SAndroid Build Coastguard Worker 				if (context_read_and_validate
2873*2d543d20SAndroid Build Coastguard Worker 				    (&c->context[0], p, fp))
2874*2d543d20SAndroid Build Coastguard Worker 					return -1;
2875*2d543d20SAndroid Build Coastguard Worker 				break;
2876*2d543d20SAndroid Build Coastguard Worker 			case OCON_XEN_IOPORT:
2877*2d543d20SAndroid Build Coastguard Worker 				rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
2878*2d543d20SAndroid Build Coastguard Worker 				if (rc < 0)
2879*2d543d20SAndroid Build Coastguard Worker 					return -1;
2880*2d543d20SAndroid Build Coastguard Worker 				c->u.ioport.low_ioport = le32_to_cpu(buf[0]);
2881*2d543d20SAndroid Build Coastguard Worker 				c->u.ioport.high_ioport = le32_to_cpu(buf[1]);
2882*2d543d20SAndroid Build Coastguard Worker 				if (context_read_and_validate
2883*2d543d20SAndroid Build Coastguard Worker 				    (&c->context[0], p, fp))
2884*2d543d20SAndroid Build Coastguard Worker 					return -1;
2885*2d543d20SAndroid Build Coastguard Worker 				break;
2886*2d543d20SAndroid Build Coastguard Worker 			case OCON_XEN_IOMEM:
2887*2d543d20SAndroid Build Coastguard Worker 				if (p->policyvers >= POLICYDB_VERSION_XEN_DEVICETREE) {
2888*2d543d20SAndroid Build Coastguard Worker 					uint64_t b64[2];
2889*2d543d20SAndroid Build Coastguard Worker 					rc = next_entry(b64, fp, sizeof(uint64_t) * 2);
2890*2d543d20SAndroid Build Coastguard Worker 					if (rc < 0)
2891*2d543d20SAndroid Build Coastguard Worker 						return -1;
2892*2d543d20SAndroid Build Coastguard Worker 					c->u.iomem.low_iomem = le64_to_cpu(b64[0]);
2893*2d543d20SAndroid Build Coastguard Worker 					c->u.iomem.high_iomem = le64_to_cpu(b64[1]);
2894*2d543d20SAndroid Build Coastguard Worker 				} else {
2895*2d543d20SAndroid Build Coastguard Worker 					rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
2896*2d543d20SAndroid Build Coastguard Worker 					if (rc < 0)
2897*2d543d20SAndroid Build Coastguard Worker 						return -1;
2898*2d543d20SAndroid Build Coastguard Worker 					c->u.iomem.low_iomem = le32_to_cpu(buf[0]);
2899*2d543d20SAndroid Build Coastguard Worker 					c->u.iomem.high_iomem = le32_to_cpu(buf[1]);
2900*2d543d20SAndroid Build Coastguard Worker 				}
2901*2d543d20SAndroid Build Coastguard Worker 				if (context_read_and_validate
2902*2d543d20SAndroid Build Coastguard Worker 				    (&c->context[0], p, fp))
2903*2d543d20SAndroid Build Coastguard Worker 					return -1;
2904*2d543d20SAndroid Build Coastguard Worker 				break;
2905*2d543d20SAndroid Build Coastguard Worker 			case OCON_XEN_PCIDEVICE:
2906*2d543d20SAndroid Build Coastguard Worker 				rc = next_entry(buf, fp, sizeof(uint32_t));
2907*2d543d20SAndroid Build Coastguard Worker 				if (rc < 0)
2908*2d543d20SAndroid Build Coastguard Worker 					return -1;
2909*2d543d20SAndroid Build Coastguard Worker 				c->u.device = le32_to_cpu(buf[0]);
2910*2d543d20SAndroid Build Coastguard Worker 				if (context_read_and_validate
2911*2d543d20SAndroid Build Coastguard Worker 				    (&c->context[0], p, fp))
2912*2d543d20SAndroid Build Coastguard Worker 					return -1;
2913*2d543d20SAndroid Build Coastguard Worker 				break;
2914*2d543d20SAndroid Build Coastguard Worker 			case OCON_XEN_DEVICETREE:
2915*2d543d20SAndroid Build Coastguard Worker 				rc = next_entry(buf, fp, sizeof(uint32_t));
2916*2d543d20SAndroid Build Coastguard Worker 				if (rc < 0)
2917*2d543d20SAndroid Build Coastguard Worker 					return -1;
2918*2d543d20SAndroid Build Coastguard Worker 				len = le32_to_cpu(buf[0]);
2919*2d543d20SAndroid Build Coastguard Worker 				rc = str_read(&c->u.name, fp, len);
2920*2d543d20SAndroid Build Coastguard Worker 				if (rc < 0)
2921*2d543d20SAndroid Build Coastguard Worker 					return -1;
2922*2d543d20SAndroid Build Coastguard Worker 				if (context_read_and_validate
2923*2d543d20SAndroid Build Coastguard Worker 				    (&c->context[0], p, fp))
2924*2d543d20SAndroid Build Coastguard Worker 					return -1;
2925*2d543d20SAndroid Build Coastguard Worker 				break;
2926*2d543d20SAndroid Build Coastguard Worker 			default:
2927*2d543d20SAndroid Build Coastguard Worker 				/* should never get here */
2928*2d543d20SAndroid Build Coastguard Worker 				ERR(fp->handle, "Unknown Xen ocontext");
2929*2d543d20SAndroid Build Coastguard Worker 				return -1;
2930*2d543d20SAndroid Build Coastguard Worker 			}
2931*2d543d20SAndroid Build Coastguard Worker 		}
2932*2d543d20SAndroid Build Coastguard Worker 	}
2933*2d543d20SAndroid Build Coastguard Worker 	return 0;
2934*2d543d20SAndroid Build Coastguard Worker }
ocontext_read_selinux(const struct policydb_compat_info * info,policydb_t * p,struct policy_file * fp)2935*2d543d20SAndroid Build Coastguard Worker static int ocontext_read_selinux(const struct policydb_compat_info *info,
2936*2d543d20SAndroid Build Coastguard Worker 			 policydb_t * p, struct policy_file *fp)
2937*2d543d20SAndroid Build Coastguard Worker {
2938*2d543d20SAndroid Build Coastguard Worker 	unsigned int i, j;
2939*2d543d20SAndroid Build Coastguard Worker 	size_t nel, len;
2940*2d543d20SAndroid Build Coastguard Worker 	ocontext_t *l, *c;
2941*2d543d20SAndroid Build Coastguard Worker 	uint32_t buf[8];
2942*2d543d20SAndroid Build Coastguard Worker 	int rc;
2943*2d543d20SAndroid Build Coastguard Worker 
2944*2d543d20SAndroid Build Coastguard Worker 	for (i = 0; i < info->ocon_num; i++) {
2945*2d543d20SAndroid Build Coastguard Worker 		rc = next_entry(buf, fp, sizeof(uint32_t));
2946*2d543d20SAndroid Build Coastguard Worker 		if (rc < 0)
2947*2d543d20SAndroid Build Coastguard Worker 			return -1;
2948*2d543d20SAndroid Build Coastguard Worker 		nel = le32_to_cpu(buf[0]);
2949*2d543d20SAndroid Build Coastguard Worker 		l = NULL;
2950*2d543d20SAndroid Build Coastguard Worker 		for (j = 0; j < nel; j++) {
2951*2d543d20SAndroid Build Coastguard Worker 			c = calloc(1, sizeof(ocontext_t));
2952*2d543d20SAndroid Build Coastguard Worker 			if (!c) {
2953*2d543d20SAndroid Build Coastguard Worker 				return -1;
2954*2d543d20SAndroid Build Coastguard Worker 			}
2955*2d543d20SAndroid Build Coastguard Worker 			if (l) {
2956*2d543d20SAndroid Build Coastguard Worker 				l->next = c;
2957*2d543d20SAndroid Build Coastguard Worker 			} else {
2958*2d543d20SAndroid Build Coastguard Worker 				p->ocontexts[i] = c;
2959*2d543d20SAndroid Build Coastguard Worker 			}
2960*2d543d20SAndroid Build Coastguard Worker 			l = c;
2961*2d543d20SAndroid Build Coastguard Worker 			switch (i) {
2962*2d543d20SAndroid Build Coastguard Worker 			case OCON_ISID:
2963*2d543d20SAndroid Build Coastguard Worker 				rc = next_entry(buf, fp, sizeof(uint32_t));
2964*2d543d20SAndroid Build Coastguard Worker 				if (rc < 0)
2965*2d543d20SAndroid Build Coastguard Worker 					return -1;
2966*2d543d20SAndroid Build Coastguard Worker 				c->sid[0] = le32_to_cpu(buf[0]);
2967*2d543d20SAndroid Build Coastguard Worker 				if (is_saturated(c->sid[0]))
2968*2d543d20SAndroid Build Coastguard Worker 					return -1;
2969*2d543d20SAndroid Build Coastguard Worker 				if (context_read_and_validate
2970*2d543d20SAndroid Build Coastguard Worker 				    (&c->context[0], p, fp))
2971*2d543d20SAndroid Build Coastguard Worker 					return -1;
2972*2d543d20SAndroid Build Coastguard Worker 				break;
2973*2d543d20SAndroid Build Coastguard Worker 			case OCON_FS:
2974*2d543d20SAndroid Build Coastguard Worker 			case OCON_NETIF:
2975*2d543d20SAndroid Build Coastguard Worker 				rc = next_entry(buf, fp, sizeof(uint32_t));
2976*2d543d20SAndroid Build Coastguard Worker 				if (rc < 0)
2977*2d543d20SAndroid Build Coastguard Worker 					return -1;
2978*2d543d20SAndroid Build Coastguard Worker 				len = le32_to_cpu(buf[0]);
2979*2d543d20SAndroid Build Coastguard Worker 				if (len > 63)
2980*2d543d20SAndroid Build Coastguard Worker 					return -1;
2981*2d543d20SAndroid Build Coastguard Worker 
2982*2d543d20SAndroid Build Coastguard Worker 				rc = str_read(&c->u.name, fp, len);
2983*2d543d20SAndroid Build Coastguard Worker 				if (rc < 0)
2984*2d543d20SAndroid Build Coastguard Worker 					return -1;
2985*2d543d20SAndroid Build Coastguard Worker 
2986*2d543d20SAndroid Build Coastguard Worker 				if (context_read_and_validate
2987*2d543d20SAndroid Build Coastguard Worker 				    (&c->context[0], p, fp))
2988*2d543d20SAndroid Build Coastguard Worker 					return -1;
2989*2d543d20SAndroid Build Coastguard Worker 				if (context_read_and_validate
2990*2d543d20SAndroid Build Coastguard Worker 				    (&c->context[1], p, fp))
2991*2d543d20SAndroid Build Coastguard Worker 					return -1;
2992*2d543d20SAndroid Build Coastguard Worker 				break;
2993*2d543d20SAndroid Build Coastguard Worker 			case OCON_IBPKEY: {
2994*2d543d20SAndroid Build Coastguard Worker 				uint32_t pkey_lo, pkey_hi;
2995*2d543d20SAndroid Build Coastguard Worker 
2996*2d543d20SAndroid Build Coastguard Worker 				rc = next_entry(buf, fp, sizeof(uint32_t) * 4);
2997*2d543d20SAndroid Build Coastguard Worker 				if (rc < 0)
2998*2d543d20SAndroid Build Coastguard Worker 					return -1;
2999*2d543d20SAndroid Build Coastguard Worker 
3000*2d543d20SAndroid Build Coastguard Worker 				pkey_lo = le32_to_cpu(buf[2]);
3001*2d543d20SAndroid Build Coastguard Worker 				pkey_hi = le32_to_cpu(buf[3]);
3002*2d543d20SAndroid Build Coastguard Worker 
3003*2d543d20SAndroid Build Coastguard Worker 				if (pkey_lo > UINT16_MAX || pkey_hi > UINT16_MAX)
3004*2d543d20SAndroid Build Coastguard Worker 					return -1;
3005*2d543d20SAndroid Build Coastguard Worker 
3006*2d543d20SAndroid Build Coastguard Worker 				c->u.ibpkey.low_pkey  = pkey_lo;
3007*2d543d20SAndroid Build Coastguard Worker 				c->u.ibpkey.high_pkey = pkey_hi;
3008*2d543d20SAndroid Build Coastguard Worker 
3009*2d543d20SAndroid Build Coastguard Worker 				/* we want c->u.ibpkey.subnet_prefix in network
3010*2d543d20SAndroid Build Coastguard Worker 				 * (big-endian) order, just memcpy it */
3011*2d543d20SAndroid Build Coastguard Worker 				memcpy(&c->u.ibpkey.subnet_prefix, buf,
3012*2d543d20SAndroid Build Coastguard Worker 				       sizeof(c->u.ibpkey.subnet_prefix));
3013*2d543d20SAndroid Build Coastguard Worker 
3014*2d543d20SAndroid Build Coastguard Worker 				if (context_read_and_validate
3015*2d543d20SAndroid Build Coastguard Worker 				    (&c->context[0], p, fp))
3016*2d543d20SAndroid Build Coastguard Worker 					return -1;
3017*2d543d20SAndroid Build Coastguard Worker 				break;
3018*2d543d20SAndroid Build Coastguard Worker 			}
3019*2d543d20SAndroid Build Coastguard Worker 			case OCON_IBENDPORT: {
3020*2d543d20SAndroid Build Coastguard Worker 				uint32_t port;
3021*2d543d20SAndroid Build Coastguard Worker 
3022*2d543d20SAndroid Build Coastguard Worker 				rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
3023*2d543d20SAndroid Build Coastguard Worker 				if (rc < 0)
3024*2d543d20SAndroid Build Coastguard Worker 					return -1;
3025*2d543d20SAndroid Build Coastguard Worker 				len = le32_to_cpu(buf[0]);
3026*2d543d20SAndroid Build Coastguard Worker 				if (len == 0 || len > IB_DEVICE_NAME_MAX - 1)
3027*2d543d20SAndroid Build Coastguard Worker 					return -1;
3028*2d543d20SAndroid Build Coastguard Worker 
3029*2d543d20SAndroid Build Coastguard Worker 				port = le32_to_cpu(buf[1]);
3030*2d543d20SAndroid Build Coastguard Worker 				if (port > UINT8_MAX || port == 0)
3031*2d543d20SAndroid Build Coastguard Worker 					return -1;
3032*2d543d20SAndroid Build Coastguard Worker 
3033*2d543d20SAndroid Build Coastguard Worker 				rc = str_read(&c->u.ibendport.dev_name, fp, len);
3034*2d543d20SAndroid Build Coastguard Worker 				if (rc < 0)
3035*2d543d20SAndroid Build Coastguard Worker 					return -1;
3036*2d543d20SAndroid Build Coastguard Worker 
3037*2d543d20SAndroid Build Coastguard Worker 				c->u.ibendport.port = port;
3038*2d543d20SAndroid Build Coastguard Worker 				if (context_read_and_validate
3039*2d543d20SAndroid Build Coastguard Worker 				    (&c->context[0], p, fp))
3040*2d543d20SAndroid Build Coastguard Worker 					return -1;
3041*2d543d20SAndroid Build Coastguard Worker 				break;
3042*2d543d20SAndroid Build Coastguard Worker 			}
3043*2d543d20SAndroid Build Coastguard Worker 			case OCON_PORT:
3044*2d543d20SAndroid Build Coastguard Worker 				rc = next_entry(buf, fp, sizeof(uint32_t) * 3);
3045*2d543d20SAndroid Build Coastguard Worker 				if (rc < 0)
3046*2d543d20SAndroid Build Coastguard Worker 					return -1;
3047*2d543d20SAndroid Build Coastguard Worker 				c->u.port.protocol = le32_to_cpu(buf[0]);
3048*2d543d20SAndroid Build Coastguard Worker 				c->u.port.low_port = le32_to_cpu(buf[1]);
3049*2d543d20SAndroid Build Coastguard Worker 				c->u.port.high_port = le32_to_cpu(buf[2]);
3050*2d543d20SAndroid Build Coastguard Worker 				if (context_read_and_validate
3051*2d543d20SAndroid Build Coastguard Worker 				    (&c->context[0], p, fp))
3052*2d543d20SAndroid Build Coastguard Worker 					return -1;
3053*2d543d20SAndroid Build Coastguard Worker 				break;
3054*2d543d20SAndroid Build Coastguard Worker 			case OCON_NODE:
3055*2d543d20SAndroid Build Coastguard Worker 				rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
3056*2d543d20SAndroid Build Coastguard Worker 				if (rc < 0)
3057*2d543d20SAndroid Build Coastguard Worker 					return -1;
3058*2d543d20SAndroid Build Coastguard Worker 				c->u.node.addr = buf[0]; /* network order */
3059*2d543d20SAndroid Build Coastguard Worker 				c->u.node.mask = buf[1]; /* network order */
3060*2d543d20SAndroid Build Coastguard Worker 				if (context_read_and_validate
3061*2d543d20SAndroid Build Coastguard Worker 				    (&c->context[0], p, fp))
3062*2d543d20SAndroid Build Coastguard Worker 					return -1;
3063*2d543d20SAndroid Build Coastguard Worker 				break;
3064*2d543d20SAndroid Build Coastguard Worker 			case OCON_FSUSE:
3065*2d543d20SAndroid Build Coastguard Worker 				rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
3066*2d543d20SAndroid Build Coastguard Worker 				if (rc < 0)
3067*2d543d20SAndroid Build Coastguard Worker 					return -1;
3068*2d543d20SAndroid Build Coastguard Worker 				c->v.behavior = le32_to_cpu(buf[0]);
3069*2d543d20SAndroid Build Coastguard Worker 				len = le32_to_cpu(buf[1]);
3070*2d543d20SAndroid Build Coastguard Worker 
3071*2d543d20SAndroid Build Coastguard Worker 				rc = str_read(&c->u.name, fp, len);
3072*2d543d20SAndroid Build Coastguard Worker 				if (rc < 0)
3073*2d543d20SAndroid Build Coastguard Worker 					return -1;
3074*2d543d20SAndroid Build Coastguard Worker 
3075*2d543d20SAndroid Build Coastguard Worker 				if (context_read_and_validate
3076*2d543d20SAndroid Build Coastguard Worker 				    (&c->context[0], p, fp))
3077*2d543d20SAndroid Build Coastguard Worker 					return -1;
3078*2d543d20SAndroid Build Coastguard Worker 				break;
3079*2d543d20SAndroid Build Coastguard Worker 			case OCON_NODE6:{
3080*2d543d20SAndroid Build Coastguard Worker 				int k;
3081*2d543d20SAndroid Build Coastguard Worker 
3082*2d543d20SAndroid Build Coastguard Worker 				rc = next_entry(buf, fp, sizeof(uint32_t) * 8);
3083*2d543d20SAndroid Build Coastguard Worker 				if (rc < 0)
3084*2d543d20SAndroid Build Coastguard Worker 					return -1;
3085*2d543d20SAndroid Build Coastguard Worker 				for (k = 0; k < 4; k++)
3086*2d543d20SAndroid Build Coastguard Worker 					 /* network order */
3087*2d543d20SAndroid Build Coastguard Worker 					c->u.node6.addr[k] = buf[k];
3088*2d543d20SAndroid Build Coastguard Worker 				for (k = 0; k < 4; k++)
3089*2d543d20SAndroid Build Coastguard Worker 					/* network order */
3090*2d543d20SAndroid Build Coastguard Worker 					c->u.node6.mask[k] = buf[k + 4];
3091*2d543d20SAndroid Build Coastguard Worker 				if (context_read_and_validate
3092*2d543d20SAndroid Build Coastguard Worker 				    (&c->context[0], p, fp))
3093*2d543d20SAndroid Build Coastguard Worker 					return -1;
3094*2d543d20SAndroid Build Coastguard Worker 				break;
3095*2d543d20SAndroid Build Coastguard Worker 				}
3096*2d543d20SAndroid Build Coastguard Worker 			default:{
3097*2d543d20SAndroid Build Coastguard Worker 				ERR(fp->handle, "Unknown SELinux ocontext");
3098*2d543d20SAndroid Build Coastguard Worker 				return -1;
3099*2d543d20SAndroid Build Coastguard Worker 				}
3100*2d543d20SAndroid Build Coastguard Worker 			}
3101*2d543d20SAndroid Build Coastguard Worker 		}
3102*2d543d20SAndroid Build Coastguard Worker 	}
3103*2d543d20SAndroid Build Coastguard Worker 	return 0;
3104*2d543d20SAndroid Build Coastguard Worker }
3105*2d543d20SAndroid Build Coastguard Worker 
ocontext_read(const struct policydb_compat_info * info,policydb_t * p,struct policy_file * fp)3106*2d543d20SAndroid Build Coastguard Worker static int ocontext_read(const struct policydb_compat_info *info,
3107*2d543d20SAndroid Build Coastguard Worker 	policydb_t *p, struct policy_file *fp)
3108*2d543d20SAndroid Build Coastguard Worker {
3109*2d543d20SAndroid Build Coastguard Worker 	int rc = -1;
3110*2d543d20SAndroid Build Coastguard Worker 	switch (p->target_platform) {
3111*2d543d20SAndroid Build Coastguard Worker 	case SEPOL_TARGET_SELINUX:
3112*2d543d20SAndroid Build Coastguard Worker 		rc = ocontext_read_selinux(info, p, fp);
3113*2d543d20SAndroid Build Coastguard Worker 		break;
3114*2d543d20SAndroid Build Coastguard Worker 	case SEPOL_TARGET_XEN:
3115*2d543d20SAndroid Build Coastguard Worker 		rc = ocontext_read_xen(info, p, fp);
3116*2d543d20SAndroid Build Coastguard Worker 		break;
3117*2d543d20SAndroid Build Coastguard Worker 	default:
3118*2d543d20SAndroid Build Coastguard Worker 		ERR(fp->handle, "Unknown target");
3119*2d543d20SAndroid Build Coastguard Worker 	}
3120*2d543d20SAndroid Build Coastguard Worker 	return rc;
3121*2d543d20SAndroid Build Coastguard Worker }
3122*2d543d20SAndroid Build Coastguard Worker 
genfs_read(policydb_t * p,struct policy_file * fp)3123*2d543d20SAndroid Build Coastguard Worker static int genfs_read(policydb_t * p, struct policy_file *fp)
3124*2d543d20SAndroid Build Coastguard Worker {
3125*2d543d20SAndroid Build Coastguard Worker 	uint32_t buf[1];
3126*2d543d20SAndroid Build Coastguard Worker 	size_t nel, nel2, len, len2;
3127*2d543d20SAndroid Build Coastguard Worker 	genfs_t *genfs_p, *newgenfs, *genfs;
3128*2d543d20SAndroid Build Coastguard Worker 	size_t i, j;
3129*2d543d20SAndroid Build Coastguard Worker 	ocontext_t *l, *c, *newc = NULL;
3130*2d543d20SAndroid Build Coastguard Worker 	int rc;
3131*2d543d20SAndroid Build Coastguard Worker 
3132*2d543d20SAndroid Build Coastguard Worker 	rc = next_entry(buf, fp, sizeof(uint32_t));
3133*2d543d20SAndroid Build Coastguard Worker 	if (rc < 0)
3134*2d543d20SAndroid Build Coastguard Worker 		goto bad;
3135*2d543d20SAndroid Build Coastguard Worker 	nel = le32_to_cpu(buf[0]);
3136*2d543d20SAndroid Build Coastguard Worker 	genfs_p = NULL;
3137*2d543d20SAndroid Build Coastguard Worker 	for (i = 0; i < nel; i++) {
3138*2d543d20SAndroid Build Coastguard Worker 		rc = next_entry(buf, fp, sizeof(uint32_t));
3139*2d543d20SAndroid Build Coastguard Worker 		if (rc < 0)
3140*2d543d20SAndroid Build Coastguard Worker 			goto bad;
3141*2d543d20SAndroid Build Coastguard Worker 		len = le32_to_cpu(buf[0]);
3142*2d543d20SAndroid Build Coastguard Worker 		newgenfs = calloc(1, sizeof(genfs_t));
3143*2d543d20SAndroid Build Coastguard Worker 		if (!newgenfs)
3144*2d543d20SAndroid Build Coastguard Worker 			goto bad;
3145*2d543d20SAndroid Build Coastguard Worker 
3146*2d543d20SAndroid Build Coastguard Worker 		rc = str_read(&newgenfs->fstype, fp, len);
3147*2d543d20SAndroid Build Coastguard Worker 		if (rc < 0) {
3148*2d543d20SAndroid Build Coastguard Worker 			free(newgenfs->fstype);
3149*2d543d20SAndroid Build Coastguard Worker 			free(newgenfs);
3150*2d543d20SAndroid Build Coastguard Worker 			goto bad;
3151*2d543d20SAndroid Build Coastguard Worker 		}
3152*2d543d20SAndroid Build Coastguard Worker 
3153*2d543d20SAndroid Build Coastguard Worker 		for (genfs_p = NULL, genfs = p->genfs; genfs;
3154*2d543d20SAndroid Build Coastguard Worker 		     genfs_p = genfs, genfs = genfs->next) {
3155*2d543d20SAndroid Build Coastguard Worker 			if (strcmp(newgenfs->fstype, genfs->fstype) == 0) {
3156*2d543d20SAndroid Build Coastguard Worker 				ERR(fp->handle, "dup genfs fstype %s",
3157*2d543d20SAndroid Build Coastguard Worker 				    newgenfs->fstype);
3158*2d543d20SAndroid Build Coastguard Worker 				free(newgenfs->fstype);
3159*2d543d20SAndroid Build Coastguard Worker 				free(newgenfs);
3160*2d543d20SAndroid Build Coastguard Worker 				goto bad;
3161*2d543d20SAndroid Build Coastguard Worker 			}
3162*2d543d20SAndroid Build Coastguard Worker 			if (strcmp(newgenfs->fstype, genfs->fstype) < 0)
3163*2d543d20SAndroid Build Coastguard Worker 				break;
3164*2d543d20SAndroid Build Coastguard Worker 		}
3165*2d543d20SAndroid Build Coastguard Worker 		newgenfs->next = genfs;
3166*2d543d20SAndroid Build Coastguard Worker 		if (genfs_p)
3167*2d543d20SAndroid Build Coastguard Worker 			genfs_p->next = newgenfs;
3168*2d543d20SAndroid Build Coastguard Worker 		else
3169*2d543d20SAndroid Build Coastguard Worker 			p->genfs = newgenfs;
3170*2d543d20SAndroid Build Coastguard Worker 		rc = next_entry(buf, fp, sizeof(uint32_t));
3171*2d543d20SAndroid Build Coastguard Worker 		if (rc < 0)
3172*2d543d20SAndroid Build Coastguard Worker 			goto bad;
3173*2d543d20SAndroid Build Coastguard Worker 		nel2 = le32_to_cpu(buf[0]);
3174*2d543d20SAndroid Build Coastguard Worker 		for (j = 0; j < nel2; j++) {
3175*2d543d20SAndroid Build Coastguard Worker 			newc = calloc(1, sizeof(ocontext_t));
3176*2d543d20SAndroid Build Coastguard Worker 			if (!newc) {
3177*2d543d20SAndroid Build Coastguard Worker 				goto bad;
3178*2d543d20SAndroid Build Coastguard Worker 			}
3179*2d543d20SAndroid Build Coastguard Worker 			rc = next_entry(buf, fp, sizeof(uint32_t));
3180*2d543d20SAndroid Build Coastguard Worker 			if (rc < 0)
3181*2d543d20SAndroid Build Coastguard Worker 				goto bad;
3182*2d543d20SAndroid Build Coastguard Worker 			len = le32_to_cpu(buf[0]);
3183*2d543d20SAndroid Build Coastguard Worker 			rc = str_read(&newc->u.name, fp, len);
3184*2d543d20SAndroid Build Coastguard Worker 			if (rc < 0)
3185*2d543d20SAndroid Build Coastguard Worker 				goto bad;
3186*2d543d20SAndroid Build Coastguard Worker 
3187*2d543d20SAndroid Build Coastguard Worker 			rc = next_entry(buf, fp, sizeof(uint32_t));
3188*2d543d20SAndroid Build Coastguard Worker 			if (rc < 0)
3189*2d543d20SAndroid Build Coastguard Worker 				goto bad;
3190*2d543d20SAndroid Build Coastguard Worker 			newc->v.sclass = le32_to_cpu(buf[0]);
3191*2d543d20SAndroid Build Coastguard Worker 			if (context_read_and_validate(&newc->context[0], p, fp))
3192*2d543d20SAndroid Build Coastguard Worker 				goto bad;
3193*2d543d20SAndroid Build Coastguard Worker 			for (l = NULL, c = newgenfs->head; c;
3194*2d543d20SAndroid Build Coastguard Worker 			     l = c, c = c->next) {
3195*2d543d20SAndroid Build Coastguard Worker 				if (!strcmp(newc->u.name, c->u.name) &&
3196*2d543d20SAndroid Build Coastguard Worker 				    (!c->v.sclass || !newc->v.sclass ||
3197*2d543d20SAndroid Build Coastguard Worker 				     newc->v.sclass == c->v.sclass)) {
3198*2d543d20SAndroid Build Coastguard Worker 					ERR(fp->handle, "dup genfs entry "
3199*2d543d20SAndroid Build Coastguard Worker 					    "(%s,%s)", newgenfs->fstype,
3200*2d543d20SAndroid Build Coastguard Worker 					    c->u.name);
3201*2d543d20SAndroid Build Coastguard Worker 					goto bad;
3202*2d543d20SAndroid Build Coastguard Worker 				}
3203*2d543d20SAndroid Build Coastguard Worker 				len = strlen(newc->u.name);
3204*2d543d20SAndroid Build Coastguard Worker 				len2 = strlen(c->u.name);
3205*2d543d20SAndroid Build Coastguard Worker 				if (len > len2)
3206*2d543d20SAndroid Build Coastguard Worker 					break;
3207*2d543d20SAndroid Build Coastguard Worker 			}
3208*2d543d20SAndroid Build Coastguard Worker 			newc->next = c;
3209*2d543d20SAndroid Build Coastguard Worker 			if (l)
3210*2d543d20SAndroid Build Coastguard Worker 				l->next = newc;
3211*2d543d20SAndroid Build Coastguard Worker 			else
3212*2d543d20SAndroid Build Coastguard Worker 				newgenfs->head = newc;
3213*2d543d20SAndroid Build Coastguard Worker 			/* clear newc after a new owner has the pointer */
3214*2d543d20SAndroid Build Coastguard Worker 			newc = NULL;
3215*2d543d20SAndroid Build Coastguard Worker 		}
3216*2d543d20SAndroid Build Coastguard Worker 	}
3217*2d543d20SAndroid Build Coastguard Worker 
3218*2d543d20SAndroid Build Coastguard Worker 	return 0;
3219*2d543d20SAndroid Build Coastguard Worker 
3220*2d543d20SAndroid Build Coastguard Worker       bad:
3221*2d543d20SAndroid Build Coastguard Worker 	if (newc) {
3222*2d543d20SAndroid Build Coastguard Worker 		context_destroy(&newc->context[0]);
3223*2d543d20SAndroid Build Coastguard Worker 		context_destroy(&newc->context[1]);
3224*2d543d20SAndroid Build Coastguard Worker 		free(newc->u.name);
3225*2d543d20SAndroid Build Coastguard Worker 		free(newc);
3226*2d543d20SAndroid Build Coastguard Worker 	}
3227*2d543d20SAndroid Build Coastguard Worker 	return -1;
3228*2d543d20SAndroid Build Coastguard Worker }
3229*2d543d20SAndroid Build Coastguard Worker 
3230*2d543d20SAndroid Build Coastguard Worker /*
3231*2d543d20SAndroid Build Coastguard Worker  * Read a MLS level structure from a policydb binary
3232*2d543d20SAndroid Build Coastguard Worker  * representation file.
3233*2d543d20SAndroid Build Coastguard Worker  */
mls_read_level(mls_level_t * lp,struct policy_file * fp)3234*2d543d20SAndroid Build Coastguard Worker static int mls_read_level(mls_level_t * lp, struct policy_file *fp)
3235*2d543d20SAndroid Build Coastguard Worker {
3236*2d543d20SAndroid Build Coastguard Worker 	uint32_t buf[1];
3237*2d543d20SAndroid Build Coastguard Worker 	int rc;
3238*2d543d20SAndroid Build Coastguard Worker 
3239*2d543d20SAndroid Build Coastguard Worker 	mls_level_init(lp);
3240*2d543d20SAndroid Build Coastguard Worker 
3241*2d543d20SAndroid Build Coastguard Worker 	rc = next_entry(buf, fp, sizeof(uint32_t));
3242*2d543d20SAndroid Build Coastguard Worker 	if (rc < 0) {
3243*2d543d20SAndroid Build Coastguard Worker 		ERR(fp->handle, "truncated level");
3244*2d543d20SAndroid Build Coastguard Worker 		goto bad;
3245*2d543d20SAndroid Build Coastguard Worker 	}
3246*2d543d20SAndroid Build Coastguard Worker 	lp->sens = le32_to_cpu(buf[0]);
3247*2d543d20SAndroid Build Coastguard Worker 
3248*2d543d20SAndroid Build Coastguard Worker 	if (ebitmap_read(&lp->cat, fp)) {
3249*2d543d20SAndroid Build Coastguard Worker 		ERR(fp->handle, "error reading level categories");
3250*2d543d20SAndroid Build Coastguard Worker 		goto bad;
3251*2d543d20SAndroid Build Coastguard Worker 	}
3252*2d543d20SAndroid Build Coastguard Worker 	return 0;
3253*2d543d20SAndroid Build Coastguard Worker 
3254*2d543d20SAndroid Build Coastguard Worker       bad:
3255*2d543d20SAndroid Build Coastguard Worker 	return -EINVAL;
3256*2d543d20SAndroid Build Coastguard Worker }
3257*2d543d20SAndroid Build Coastguard Worker 
user_read(policydb_t * p,hashtab_t h,struct policy_file * fp)3258*2d543d20SAndroid Build Coastguard Worker static int user_read(policydb_t * p, hashtab_t h, struct policy_file *fp)
3259*2d543d20SAndroid Build Coastguard Worker {
3260*2d543d20SAndroid Build Coastguard Worker 	char *key = 0;
3261*2d543d20SAndroid Build Coastguard Worker 	user_datum_t *usrdatum;
3262*2d543d20SAndroid Build Coastguard Worker 	uint32_t buf[3];
3263*2d543d20SAndroid Build Coastguard Worker 	size_t len;
3264*2d543d20SAndroid Build Coastguard Worker 	int rc, to_read = 2;
3265*2d543d20SAndroid Build Coastguard Worker 
3266*2d543d20SAndroid Build Coastguard Worker 	usrdatum = calloc(1, sizeof(user_datum_t));
3267*2d543d20SAndroid Build Coastguard Worker 	if (!usrdatum)
3268*2d543d20SAndroid Build Coastguard Worker 		return -1;
3269*2d543d20SAndroid Build Coastguard Worker 
3270*2d543d20SAndroid Build Coastguard Worker 	if (policydb_has_boundary_feature(p))
3271*2d543d20SAndroid Build Coastguard Worker 		to_read = 3;
3272*2d543d20SAndroid Build Coastguard Worker 
3273*2d543d20SAndroid Build Coastguard Worker 	rc = next_entry(buf, fp, sizeof(uint32_t) * to_read);
3274*2d543d20SAndroid Build Coastguard Worker 	if (rc < 0)
3275*2d543d20SAndroid Build Coastguard Worker 		goto bad;
3276*2d543d20SAndroid Build Coastguard Worker 
3277*2d543d20SAndroid Build Coastguard Worker 	len = le32_to_cpu(buf[0]);
3278*2d543d20SAndroid Build Coastguard Worker 	rc = str_read(&key, fp, len);
3279*2d543d20SAndroid Build Coastguard Worker 	if (rc < 0)
3280*2d543d20SAndroid Build Coastguard Worker 		goto bad;
3281*2d543d20SAndroid Build Coastguard Worker 
3282*2d543d20SAndroid Build Coastguard Worker 	usrdatum->s.value = le32_to_cpu(buf[1]);
3283*2d543d20SAndroid Build Coastguard Worker 	if (policydb_has_boundary_feature(p))
3284*2d543d20SAndroid Build Coastguard Worker 		usrdatum->bounds = le32_to_cpu(buf[2]);
3285*2d543d20SAndroid Build Coastguard Worker 
3286*2d543d20SAndroid Build Coastguard Worker 	if (p->policy_type == POLICY_KERN) {
3287*2d543d20SAndroid Build Coastguard Worker 		if (ebitmap_read(&usrdatum->roles.roles, fp))
3288*2d543d20SAndroid Build Coastguard Worker 			goto bad;
3289*2d543d20SAndroid Build Coastguard Worker 	} else {
3290*2d543d20SAndroid Build Coastguard Worker 		if (role_set_read(&usrdatum->roles, fp))
3291*2d543d20SAndroid Build Coastguard Worker 			goto bad;
3292*2d543d20SAndroid Build Coastguard Worker 	}
3293*2d543d20SAndroid Build Coastguard Worker 
3294*2d543d20SAndroid Build Coastguard Worker 	/* users were not allowed in mls modules before version
3295*2d543d20SAndroid Build Coastguard Worker 	 * MOD_POLICYDB_VERSION_MLS_USERS, but they could have been
3296*2d543d20SAndroid Build Coastguard Worker 	 * required - the mls fields will be empty.  user declarations in
3297*2d543d20SAndroid Build Coastguard Worker 	 * non-mls modules will also have empty mls fields */
3298*2d543d20SAndroid Build Coastguard Worker 	if ((p->policy_type == POLICY_KERN
3299*2d543d20SAndroid Build Coastguard Worker 	     && p->policyvers >= POLICYDB_VERSION_MLS)
3300*2d543d20SAndroid Build Coastguard Worker 	    || (p->policy_type == POLICY_MOD
3301*2d543d20SAndroid Build Coastguard Worker 		&& p->policyvers >= MOD_POLICYDB_VERSION_MLS
3302*2d543d20SAndroid Build Coastguard Worker 		&& p->policyvers < MOD_POLICYDB_VERSION_MLS_USERS)
3303*2d543d20SAndroid Build Coastguard Worker 	    || (p->policy_type == POLICY_BASE
3304*2d543d20SAndroid Build Coastguard Worker 		&& p->policyvers >= MOD_POLICYDB_VERSION_MLS
3305*2d543d20SAndroid Build Coastguard Worker 		&& p->policyvers < MOD_POLICYDB_VERSION_MLS_USERS)) {
3306*2d543d20SAndroid Build Coastguard Worker 		if (mls_read_range_helper(&usrdatum->exp_range, fp))
3307*2d543d20SAndroid Build Coastguard Worker 			goto bad;
3308*2d543d20SAndroid Build Coastguard Worker 		if (mls_read_level(&usrdatum->exp_dfltlevel, fp))
3309*2d543d20SAndroid Build Coastguard Worker 			goto bad;
3310*2d543d20SAndroid Build Coastguard Worker 		if (p->policy_type != POLICY_KERN) {
3311*2d543d20SAndroid Build Coastguard Worker 			if (mls_range_to_semantic(&usrdatum->exp_range,
3312*2d543d20SAndroid Build Coastguard Worker 						  &usrdatum->range))
3313*2d543d20SAndroid Build Coastguard Worker 				goto bad;
3314*2d543d20SAndroid Build Coastguard Worker 			if (mls_level_to_semantic(&usrdatum->exp_dfltlevel,
3315*2d543d20SAndroid Build Coastguard Worker 						  &usrdatum->dfltlevel))
3316*2d543d20SAndroid Build Coastguard Worker 				goto bad;
3317*2d543d20SAndroid Build Coastguard Worker 		}
3318*2d543d20SAndroid Build Coastguard Worker 	} else if ((p->policy_type == POLICY_MOD
3319*2d543d20SAndroid Build Coastguard Worker 		    && p->policyvers >= MOD_POLICYDB_VERSION_MLS_USERS)
3320*2d543d20SAndroid Build Coastguard Worker 		   || (p->policy_type == POLICY_BASE
3321*2d543d20SAndroid Build Coastguard Worker 		       && p->policyvers >= MOD_POLICYDB_VERSION_MLS_USERS)) {
3322*2d543d20SAndroid Build Coastguard Worker 		if (mls_read_semantic_range_helper(&usrdatum->range, fp))
3323*2d543d20SAndroid Build Coastguard Worker 			goto bad;
3324*2d543d20SAndroid Build Coastguard Worker 		if (mls_read_semantic_level_helper(&usrdatum->dfltlevel, fp))
3325*2d543d20SAndroid Build Coastguard Worker 			goto bad;
3326*2d543d20SAndroid Build Coastguard Worker 	}
3327*2d543d20SAndroid Build Coastguard Worker 
3328*2d543d20SAndroid Build Coastguard Worker 	if (hashtab_insert(h, key, usrdatum))
3329*2d543d20SAndroid Build Coastguard Worker 		goto bad;
3330*2d543d20SAndroid Build Coastguard Worker 
3331*2d543d20SAndroid Build Coastguard Worker 	return 0;
3332*2d543d20SAndroid Build Coastguard Worker 
3333*2d543d20SAndroid Build Coastguard Worker       bad:
3334*2d543d20SAndroid Build Coastguard Worker 	user_destroy(key, usrdatum, NULL);
3335*2d543d20SAndroid Build Coastguard Worker 	return -1;
3336*2d543d20SAndroid Build Coastguard Worker }
3337*2d543d20SAndroid Build Coastguard Worker 
sens_read(policydb_t * p,hashtab_t h,struct policy_file * fp)3338*2d543d20SAndroid Build Coastguard Worker static int sens_read(policydb_t * p
3339*2d543d20SAndroid Build Coastguard Worker 		     __attribute__ ((unused)), hashtab_t h,
3340*2d543d20SAndroid Build Coastguard Worker 		     struct policy_file *fp)
3341*2d543d20SAndroid Build Coastguard Worker {
3342*2d543d20SAndroid Build Coastguard Worker 	char *key = 0;
3343*2d543d20SAndroid Build Coastguard Worker 	level_datum_t *levdatum;
3344*2d543d20SAndroid Build Coastguard Worker 	uint32_t buf[2], len;
3345*2d543d20SAndroid Build Coastguard Worker 	int rc;
3346*2d543d20SAndroid Build Coastguard Worker 
3347*2d543d20SAndroid Build Coastguard Worker 	levdatum = malloc(sizeof(level_datum_t));
3348*2d543d20SAndroid Build Coastguard Worker 	if (!levdatum)
3349*2d543d20SAndroid Build Coastguard Worker 		return -1;
3350*2d543d20SAndroid Build Coastguard Worker 	level_datum_init(levdatum);
3351*2d543d20SAndroid Build Coastguard Worker 
3352*2d543d20SAndroid Build Coastguard Worker 	rc = next_entry(buf, fp, (sizeof(uint32_t) * 2));
3353*2d543d20SAndroid Build Coastguard Worker 	if (rc < 0)
3354*2d543d20SAndroid Build Coastguard Worker 		goto bad;
3355*2d543d20SAndroid Build Coastguard Worker 
3356*2d543d20SAndroid Build Coastguard Worker 	len = le32_to_cpu(buf[0]);
3357*2d543d20SAndroid Build Coastguard Worker 	rc = str_read(&key, fp, len);
3358*2d543d20SAndroid Build Coastguard Worker 	if (rc < 0)
3359*2d543d20SAndroid Build Coastguard Worker 		goto bad;
3360*2d543d20SAndroid Build Coastguard Worker 
3361*2d543d20SAndroid Build Coastguard Worker 	levdatum->isalias = le32_to_cpu(buf[1]);
3362*2d543d20SAndroid Build Coastguard Worker 
3363*2d543d20SAndroid Build Coastguard Worker 	levdatum->level = malloc(sizeof(mls_level_t));
3364*2d543d20SAndroid Build Coastguard Worker 	if (!levdatum->level || mls_read_level(levdatum->level, fp))
3365*2d543d20SAndroid Build Coastguard Worker 		goto bad;
3366*2d543d20SAndroid Build Coastguard Worker 
3367*2d543d20SAndroid Build Coastguard Worker 	if (hashtab_insert(h, key, levdatum))
3368*2d543d20SAndroid Build Coastguard Worker 		goto bad;
3369*2d543d20SAndroid Build Coastguard Worker 
3370*2d543d20SAndroid Build Coastguard Worker 	return 0;
3371*2d543d20SAndroid Build Coastguard Worker 
3372*2d543d20SAndroid Build Coastguard Worker       bad:
3373*2d543d20SAndroid Build Coastguard Worker 	sens_destroy(key, levdatum, NULL);
3374*2d543d20SAndroid Build Coastguard Worker 	return -1;
3375*2d543d20SAndroid Build Coastguard Worker }
3376*2d543d20SAndroid Build Coastguard Worker 
cat_read(policydb_t * p,hashtab_t h,struct policy_file * fp)3377*2d543d20SAndroid Build Coastguard Worker static int cat_read(policydb_t * p
3378*2d543d20SAndroid Build Coastguard Worker 		    __attribute__ ((unused)), hashtab_t h,
3379*2d543d20SAndroid Build Coastguard Worker 		    struct policy_file *fp)
3380*2d543d20SAndroid Build Coastguard Worker {
3381*2d543d20SAndroid Build Coastguard Worker 	char *key = 0;
3382*2d543d20SAndroid Build Coastguard Worker 	cat_datum_t *catdatum;
3383*2d543d20SAndroid Build Coastguard Worker 	uint32_t buf[3], len;
3384*2d543d20SAndroid Build Coastguard Worker 	int rc;
3385*2d543d20SAndroid Build Coastguard Worker 
3386*2d543d20SAndroid Build Coastguard Worker 	catdatum = malloc(sizeof(cat_datum_t));
3387*2d543d20SAndroid Build Coastguard Worker 	if (!catdatum)
3388*2d543d20SAndroid Build Coastguard Worker 		return -1;
3389*2d543d20SAndroid Build Coastguard Worker 	cat_datum_init(catdatum);
3390*2d543d20SAndroid Build Coastguard Worker 
3391*2d543d20SAndroid Build Coastguard Worker 	rc = next_entry(buf, fp, (sizeof(uint32_t) * 3));
3392*2d543d20SAndroid Build Coastguard Worker 	if (rc < 0)
3393*2d543d20SAndroid Build Coastguard Worker 		goto bad;
3394*2d543d20SAndroid Build Coastguard Worker 
3395*2d543d20SAndroid Build Coastguard Worker 	len = le32_to_cpu(buf[0]);
3396*2d543d20SAndroid Build Coastguard Worker 	rc = str_read(&key, fp, len);
3397*2d543d20SAndroid Build Coastguard Worker 	if (rc < 0)
3398*2d543d20SAndroid Build Coastguard Worker 		goto bad;
3399*2d543d20SAndroid Build Coastguard Worker 
3400*2d543d20SAndroid Build Coastguard Worker 	catdatum->s.value = le32_to_cpu(buf[1]);
3401*2d543d20SAndroid Build Coastguard Worker 	catdatum->isalias = le32_to_cpu(buf[2]);
3402*2d543d20SAndroid Build Coastguard Worker 
3403*2d543d20SAndroid Build Coastguard Worker 	if (hashtab_insert(h, key, catdatum))
3404*2d543d20SAndroid Build Coastguard Worker 		goto bad;
3405*2d543d20SAndroid Build Coastguard Worker 
3406*2d543d20SAndroid Build Coastguard Worker 	return 0;
3407*2d543d20SAndroid Build Coastguard Worker 
3408*2d543d20SAndroid Build Coastguard Worker       bad:
3409*2d543d20SAndroid Build Coastguard Worker 	cat_destroy(key, catdatum, NULL);
3410*2d543d20SAndroid Build Coastguard Worker 	return -1;
3411*2d543d20SAndroid Build Coastguard Worker }
3412*2d543d20SAndroid Build Coastguard Worker 
3413*2d543d20SAndroid Build Coastguard Worker static int (*const read_f[SYM_NUM]) (policydb_t * p, hashtab_t h,
3414*2d543d20SAndroid Build Coastguard Worker 			       struct policy_file * fp) = {
3415*2d543d20SAndroid Build Coastguard Worker common_read, class_read, role_read, type_read, user_read,
3416*2d543d20SAndroid Build Coastguard Worker 	    cond_read_bool, sens_read, cat_read,};
3417*2d543d20SAndroid Build Coastguard Worker 
3418*2d543d20SAndroid Build Coastguard Worker /************** module reading functions below **************/
3419*2d543d20SAndroid Build Coastguard Worker 
avrule_read(policydb_t * p,struct policy_file * fp)3420*2d543d20SAndroid Build Coastguard Worker static avrule_t *avrule_read(policydb_t * p, struct policy_file *fp)
3421*2d543d20SAndroid Build Coastguard Worker {
3422*2d543d20SAndroid Build Coastguard Worker 	unsigned int i;
3423*2d543d20SAndroid Build Coastguard Worker 	uint32_t buf[2], len;
3424*2d543d20SAndroid Build Coastguard Worker 	class_perm_node_t *cur, *tail = NULL;
3425*2d543d20SAndroid Build Coastguard Worker 	avrule_t *avrule;
3426*2d543d20SAndroid Build Coastguard Worker 	int rc;
3427*2d543d20SAndroid Build Coastguard Worker 
3428*2d543d20SAndroid Build Coastguard Worker 	avrule = (avrule_t *) malloc(sizeof(avrule_t));
3429*2d543d20SAndroid Build Coastguard Worker 	if (!avrule)
3430*2d543d20SAndroid Build Coastguard Worker 		return NULL;
3431*2d543d20SAndroid Build Coastguard Worker 
3432*2d543d20SAndroid Build Coastguard Worker 	avrule_init(avrule);
3433*2d543d20SAndroid Build Coastguard Worker 
3434*2d543d20SAndroid Build Coastguard Worker 	rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
3435*2d543d20SAndroid Build Coastguard Worker 	if (rc < 0)
3436*2d543d20SAndroid Build Coastguard Worker 		goto bad;
3437*2d543d20SAndroid Build Coastguard Worker 
3438*2d543d20SAndroid Build Coastguard Worker 	avrule->specified = le32_to_cpu(buf[0]);
3439*2d543d20SAndroid Build Coastguard Worker 	avrule->flags = le32_to_cpu(buf[1]);
3440*2d543d20SAndroid Build Coastguard Worker 
3441*2d543d20SAndroid Build Coastguard Worker 	if (type_set_read(&avrule->stypes, fp))
3442*2d543d20SAndroid Build Coastguard Worker 		goto bad;
3443*2d543d20SAndroid Build Coastguard Worker 
3444*2d543d20SAndroid Build Coastguard Worker 	if (type_set_read(&avrule->ttypes, fp))
3445*2d543d20SAndroid Build Coastguard Worker 		goto bad;
3446*2d543d20SAndroid Build Coastguard Worker 
3447*2d543d20SAndroid Build Coastguard Worker 	rc = next_entry(buf, fp, sizeof(uint32_t));
3448*2d543d20SAndroid Build Coastguard Worker 	if (rc < 0)
3449*2d543d20SAndroid Build Coastguard Worker 		goto bad;
3450*2d543d20SAndroid Build Coastguard Worker 	len = le32_to_cpu(buf[0]);
3451*2d543d20SAndroid Build Coastguard Worker 
3452*2d543d20SAndroid Build Coastguard Worker 	for (i = 0; i < len; i++) {
3453*2d543d20SAndroid Build Coastguard Worker 		cur = (class_perm_node_t *) malloc(sizeof(class_perm_node_t));
3454*2d543d20SAndroid Build Coastguard Worker 		if (!cur)
3455*2d543d20SAndroid Build Coastguard Worker 			goto bad;
3456*2d543d20SAndroid Build Coastguard Worker 		class_perm_node_init(cur);
3457*2d543d20SAndroid Build Coastguard Worker 
3458*2d543d20SAndroid Build Coastguard Worker 		rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
3459*2d543d20SAndroid Build Coastguard Worker 		if (rc < 0) {
3460*2d543d20SAndroid Build Coastguard Worker 			free(cur);
3461*2d543d20SAndroid Build Coastguard Worker 			goto bad;
3462*2d543d20SAndroid Build Coastguard Worker 		}
3463*2d543d20SAndroid Build Coastguard Worker 
3464*2d543d20SAndroid Build Coastguard Worker 		cur->tclass = le32_to_cpu(buf[0]);
3465*2d543d20SAndroid Build Coastguard Worker 		cur->data = le32_to_cpu(buf[1]);
3466*2d543d20SAndroid Build Coastguard Worker 
3467*2d543d20SAndroid Build Coastguard Worker 		if (!tail) {
3468*2d543d20SAndroid Build Coastguard Worker 			avrule->perms = cur;
3469*2d543d20SAndroid Build Coastguard Worker 		} else {
3470*2d543d20SAndroid Build Coastguard Worker 			tail->next = cur;
3471*2d543d20SAndroid Build Coastguard Worker 		}
3472*2d543d20SAndroid Build Coastguard Worker 		tail = cur;
3473*2d543d20SAndroid Build Coastguard Worker 	}
3474*2d543d20SAndroid Build Coastguard Worker 
3475*2d543d20SAndroid Build Coastguard Worker 	if (avrule->specified & AVRULE_XPERMS) {
3476*2d543d20SAndroid Build Coastguard Worker 		uint8_t buf8;
3477*2d543d20SAndroid Build Coastguard Worker 		size_t nel = ARRAY_SIZE(avrule->xperms->perms);
3478*2d543d20SAndroid Build Coastguard Worker 		uint32_t buf32[nel];
3479*2d543d20SAndroid Build Coastguard Worker 
3480*2d543d20SAndroid Build Coastguard Worker 		if (p->policyvers < MOD_POLICYDB_VERSION_XPERMS_IOCTL) {
3481*2d543d20SAndroid Build Coastguard Worker 			ERR(fp->handle,
3482*2d543d20SAndroid Build Coastguard Worker 			    "module policy version %u does not support ioctl"
3483*2d543d20SAndroid Build Coastguard Worker 			    " extended permissions rules and one was specified",
3484*2d543d20SAndroid Build Coastguard Worker 			    p->policyvers);
3485*2d543d20SAndroid Build Coastguard Worker 			goto bad;
3486*2d543d20SAndroid Build Coastguard Worker 		}
3487*2d543d20SAndroid Build Coastguard Worker 
3488*2d543d20SAndroid Build Coastguard Worker 		if (p->target_platform != SEPOL_TARGET_SELINUX) {
3489*2d543d20SAndroid Build Coastguard Worker 			ERR(fp->handle,
3490*2d543d20SAndroid Build Coastguard Worker 			    "Target platform %s does not support ioctl"
3491*2d543d20SAndroid Build Coastguard Worker 			    " extended permissions rules and one was specified",
3492*2d543d20SAndroid Build Coastguard Worker 			    policydb_target_strings[p->target_platform]);
3493*2d543d20SAndroid Build Coastguard Worker 			goto bad;
3494*2d543d20SAndroid Build Coastguard Worker 		}
3495*2d543d20SAndroid Build Coastguard Worker 
3496*2d543d20SAndroid Build Coastguard Worker 		avrule->xperms = calloc(1, sizeof(*avrule->xperms));
3497*2d543d20SAndroid Build Coastguard Worker 		if (!avrule->xperms)
3498*2d543d20SAndroid Build Coastguard Worker 			goto bad;
3499*2d543d20SAndroid Build Coastguard Worker 
3500*2d543d20SAndroid Build Coastguard Worker 		rc = next_entry(&buf8, fp, sizeof(uint8_t));
3501*2d543d20SAndroid Build Coastguard Worker 		if (rc < 0) {
3502*2d543d20SAndroid Build Coastguard Worker 			ERR(fp->handle, "truncated entry");
3503*2d543d20SAndroid Build Coastguard Worker 			goto bad;
3504*2d543d20SAndroid Build Coastguard Worker 		}
3505*2d543d20SAndroid Build Coastguard Worker 		avrule->xperms->specified = buf8;
3506*2d543d20SAndroid Build Coastguard Worker 		rc = next_entry(&buf8, fp, sizeof(uint8_t));
3507*2d543d20SAndroid Build Coastguard Worker 		if (rc < 0) {
3508*2d543d20SAndroid Build Coastguard Worker 			ERR(fp->handle, "truncated entry");
3509*2d543d20SAndroid Build Coastguard Worker 			goto bad;
3510*2d543d20SAndroid Build Coastguard Worker 		}
3511*2d543d20SAndroid Build Coastguard Worker 		avrule->xperms->driver = buf8;
3512*2d543d20SAndroid Build Coastguard Worker 		rc = next_entry(buf32, fp, sizeof(uint32_t)*nel);
3513*2d543d20SAndroid Build Coastguard Worker 		if (rc < 0) {
3514*2d543d20SAndroid Build Coastguard Worker 			ERR(fp->handle, "truncated entry");
3515*2d543d20SAndroid Build Coastguard Worker 			goto bad;
3516*2d543d20SAndroid Build Coastguard Worker 		}
3517*2d543d20SAndroid Build Coastguard Worker 		for (i = 0; i < nel; i++)
3518*2d543d20SAndroid Build Coastguard Worker 			avrule->xperms->perms[i] = le32_to_cpu(buf32[i]);
3519*2d543d20SAndroid Build Coastguard Worker 	}
3520*2d543d20SAndroid Build Coastguard Worker 
3521*2d543d20SAndroid Build Coastguard Worker 	return avrule;
3522*2d543d20SAndroid Build Coastguard Worker       bad:
3523*2d543d20SAndroid Build Coastguard Worker 	if (avrule) {
3524*2d543d20SAndroid Build Coastguard Worker 		avrule_destroy(avrule);
3525*2d543d20SAndroid Build Coastguard Worker 		free(avrule);
3526*2d543d20SAndroid Build Coastguard Worker 	}
3527*2d543d20SAndroid Build Coastguard Worker 	return NULL;
3528*2d543d20SAndroid Build Coastguard Worker }
3529*2d543d20SAndroid Build Coastguard Worker 
range_read(policydb_t * p,struct policy_file * fp)3530*2d543d20SAndroid Build Coastguard Worker static int range_read(policydb_t * p, struct policy_file *fp)
3531*2d543d20SAndroid Build Coastguard Worker {
3532*2d543d20SAndroid Build Coastguard Worker 	uint32_t buf[2], nel;
3533*2d543d20SAndroid Build Coastguard Worker 	range_trans_t *rt = NULL;
3534*2d543d20SAndroid Build Coastguard Worker 	struct mls_range *r = NULL;
3535*2d543d20SAndroid Build Coastguard Worker 	range_trans_rule_t *rtr = NULL, *lrtr = NULL;
3536*2d543d20SAndroid Build Coastguard Worker 	unsigned int i;
3537*2d543d20SAndroid Build Coastguard Worker 	int new_rangetr = (p->policy_type == POLICY_KERN &&
3538*2d543d20SAndroid Build Coastguard Worker 			   p->policyvers >= POLICYDB_VERSION_RANGETRANS);
3539*2d543d20SAndroid Build Coastguard Worker 	int rc;
3540*2d543d20SAndroid Build Coastguard Worker 
3541*2d543d20SAndroid Build Coastguard Worker 	rc = next_entry(buf, fp, sizeof(uint32_t));
3542*2d543d20SAndroid Build Coastguard Worker 	if (rc < 0)
3543*2d543d20SAndroid Build Coastguard Worker 		return -1;
3544*2d543d20SAndroid Build Coastguard Worker 	nel = le32_to_cpu(buf[0]);
3545*2d543d20SAndroid Build Coastguard Worker 	for (i = 0; i < nel; i++) {
3546*2d543d20SAndroid Build Coastguard Worker 		rt = calloc(1, sizeof(range_trans_t));
3547*2d543d20SAndroid Build Coastguard Worker 		if (!rt)
3548*2d543d20SAndroid Build Coastguard Worker 			return -1;
3549*2d543d20SAndroid Build Coastguard Worker 		rc = next_entry(buf, fp, (sizeof(uint32_t) * 2));
3550*2d543d20SAndroid Build Coastguard Worker 		if (rc < 0)
3551*2d543d20SAndroid Build Coastguard Worker 			goto err;
3552*2d543d20SAndroid Build Coastguard Worker 		rt->source_type = le32_to_cpu(buf[0]);
3553*2d543d20SAndroid Build Coastguard Worker 		if (!value_isvalid(rt->source_type, p->p_types.nprim))
3554*2d543d20SAndroid Build Coastguard Worker 			goto err;
3555*2d543d20SAndroid Build Coastguard Worker 		rt->target_type = le32_to_cpu(buf[1]);
3556*2d543d20SAndroid Build Coastguard Worker 		if (!value_isvalid(rt->target_type, p->p_types.nprim))
3557*2d543d20SAndroid Build Coastguard Worker 			goto err;
3558*2d543d20SAndroid Build Coastguard Worker 		if (new_rangetr) {
3559*2d543d20SAndroid Build Coastguard Worker 			rc = next_entry(buf, fp, (sizeof(uint32_t)));
3560*2d543d20SAndroid Build Coastguard Worker 			if (rc < 0)
3561*2d543d20SAndroid Build Coastguard Worker 				goto err;
3562*2d543d20SAndroid Build Coastguard Worker 			rt->target_class = le32_to_cpu(buf[0]);
3563*2d543d20SAndroid Build Coastguard Worker 		} else
3564*2d543d20SAndroid Build Coastguard Worker 			rt->target_class = p->process_class;
3565*2d543d20SAndroid Build Coastguard Worker 		if (!value_isvalid(rt->target_class, p->p_classes.nprim))
3566*2d543d20SAndroid Build Coastguard Worker 			goto err;
3567*2d543d20SAndroid Build Coastguard Worker 		r = calloc(1, sizeof(*r));
3568*2d543d20SAndroid Build Coastguard Worker 		if (!r)
3569*2d543d20SAndroid Build Coastguard Worker 			goto err;
3570*2d543d20SAndroid Build Coastguard Worker 		if (mls_read_range_helper(r, fp))
3571*2d543d20SAndroid Build Coastguard Worker 			goto err;
3572*2d543d20SAndroid Build Coastguard Worker 
3573*2d543d20SAndroid Build Coastguard Worker 		if (p->policy_type == POLICY_KERN) {
3574*2d543d20SAndroid Build Coastguard Worker 			rc = hashtab_insert(p->range_tr, (hashtab_key_t)rt, r);
3575*2d543d20SAndroid Build Coastguard Worker 			if (rc)
3576*2d543d20SAndroid Build Coastguard Worker 				goto err;
3577*2d543d20SAndroid Build Coastguard Worker 			rt = NULL;
3578*2d543d20SAndroid Build Coastguard Worker 			r = NULL;
3579*2d543d20SAndroid Build Coastguard Worker 			continue;
3580*2d543d20SAndroid Build Coastguard Worker 		}
3581*2d543d20SAndroid Build Coastguard Worker 
3582*2d543d20SAndroid Build Coastguard Worker 		/* Module policy: convert to range_trans_rule and discard. */
3583*2d543d20SAndroid Build Coastguard Worker 		rtr = malloc(sizeof(range_trans_rule_t));
3584*2d543d20SAndroid Build Coastguard Worker 		if (!rtr)
3585*2d543d20SAndroid Build Coastguard Worker 			goto err;
3586*2d543d20SAndroid Build Coastguard Worker 		range_trans_rule_init(rtr);
3587*2d543d20SAndroid Build Coastguard Worker 
3588*2d543d20SAndroid Build Coastguard Worker 		if (ebitmap_set_bit(&rtr->stypes.types, rt->source_type - 1, 1))
3589*2d543d20SAndroid Build Coastguard Worker 			goto err;
3590*2d543d20SAndroid Build Coastguard Worker 
3591*2d543d20SAndroid Build Coastguard Worker 		if (ebitmap_set_bit(&rtr->ttypes.types, rt->target_type - 1, 1))
3592*2d543d20SAndroid Build Coastguard Worker 			goto err;
3593*2d543d20SAndroid Build Coastguard Worker 
3594*2d543d20SAndroid Build Coastguard Worker 		if (ebitmap_set_bit(&rtr->tclasses, rt->target_class - 1, 1))
3595*2d543d20SAndroid Build Coastguard Worker 			goto err;
3596*2d543d20SAndroid Build Coastguard Worker 
3597*2d543d20SAndroid Build Coastguard Worker 		if (mls_range_to_semantic(r, &rtr->trange))
3598*2d543d20SAndroid Build Coastguard Worker 			goto err;
3599*2d543d20SAndroid Build Coastguard Worker 
3600*2d543d20SAndroid Build Coastguard Worker 		if (lrtr)
3601*2d543d20SAndroid Build Coastguard Worker 			lrtr->next = rtr;
3602*2d543d20SAndroid Build Coastguard Worker 		else
3603*2d543d20SAndroid Build Coastguard Worker 			p->global->enabled->range_tr_rules = rtr;
3604*2d543d20SAndroid Build Coastguard Worker 
3605*2d543d20SAndroid Build Coastguard Worker 		free(rt);
3606*2d543d20SAndroid Build Coastguard Worker 		rt = NULL;
3607*2d543d20SAndroid Build Coastguard Worker 		free(r);
3608*2d543d20SAndroid Build Coastguard Worker 		r = NULL;
3609*2d543d20SAndroid Build Coastguard Worker 		lrtr = rtr;
3610*2d543d20SAndroid Build Coastguard Worker 	}
3611*2d543d20SAndroid Build Coastguard Worker 
3612*2d543d20SAndroid Build Coastguard Worker 	return 0;
3613*2d543d20SAndroid Build Coastguard Worker err:
3614*2d543d20SAndroid Build Coastguard Worker 	free(rt);
3615*2d543d20SAndroid Build Coastguard Worker 	if (r) {
3616*2d543d20SAndroid Build Coastguard Worker 		mls_range_destroy(r);
3617*2d543d20SAndroid Build Coastguard Worker 		free(r);
3618*2d543d20SAndroid Build Coastguard Worker 	}
3619*2d543d20SAndroid Build Coastguard Worker 	if (rtr) {
3620*2d543d20SAndroid Build Coastguard Worker 		range_trans_rule_destroy(rtr);
3621*2d543d20SAndroid Build Coastguard Worker 		free(rtr);
3622*2d543d20SAndroid Build Coastguard Worker 	}
3623*2d543d20SAndroid Build Coastguard Worker 	return -1;
3624*2d543d20SAndroid Build Coastguard Worker }
3625*2d543d20SAndroid Build Coastguard Worker 
avrule_read_list(policydb_t * p,avrule_t ** avrules,struct policy_file * fp)3626*2d543d20SAndroid Build Coastguard Worker int avrule_read_list(policydb_t * p, avrule_t ** avrules,
3627*2d543d20SAndroid Build Coastguard Worker 		     struct policy_file *fp)
3628*2d543d20SAndroid Build Coastguard Worker {
3629*2d543d20SAndroid Build Coastguard Worker 	unsigned int i;
3630*2d543d20SAndroid Build Coastguard Worker 	avrule_t *cur, *tail;
3631*2d543d20SAndroid Build Coastguard Worker 	uint32_t buf[1], len;
3632*2d543d20SAndroid Build Coastguard Worker 	int rc;
3633*2d543d20SAndroid Build Coastguard Worker 
3634*2d543d20SAndroid Build Coastguard Worker 	*avrules = tail = NULL;
3635*2d543d20SAndroid Build Coastguard Worker 
3636*2d543d20SAndroid Build Coastguard Worker 	rc = next_entry(buf, fp, sizeof(uint32_t));
3637*2d543d20SAndroid Build Coastguard Worker 	if (rc < 0) {
3638*2d543d20SAndroid Build Coastguard Worker 		return -1;
3639*2d543d20SAndroid Build Coastguard Worker 	}
3640*2d543d20SAndroid Build Coastguard Worker 	len = le32_to_cpu(buf[0]);
3641*2d543d20SAndroid Build Coastguard Worker 
3642*2d543d20SAndroid Build Coastguard Worker 	for (i = 0; i < len; i++) {
3643*2d543d20SAndroid Build Coastguard Worker 		cur = avrule_read(p, fp);
3644*2d543d20SAndroid Build Coastguard Worker 		if (!cur) {
3645*2d543d20SAndroid Build Coastguard Worker 			return -1;
3646*2d543d20SAndroid Build Coastguard Worker 		}
3647*2d543d20SAndroid Build Coastguard Worker 
3648*2d543d20SAndroid Build Coastguard Worker 		if (!tail) {
3649*2d543d20SAndroid Build Coastguard Worker 			*avrules = cur;
3650*2d543d20SAndroid Build Coastguard Worker 		} else {
3651*2d543d20SAndroid Build Coastguard Worker 			tail->next = cur;
3652*2d543d20SAndroid Build Coastguard Worker 		}
3653*2d543d20SAndroid Build Coastguard Worker 		tail = cur;
3654*2d543d20SAndroid Build Coastguard Worker 	}
3655*2d543d20SAndroid Build Coastguard Worker 
3656*2d543d20SAndroid Build Coastguard Worker 	return 0;
3657*2d543d20SAndroid Build Coastguard Worker }
3658*2d543d20SAndroid Build Coastguard Worker 
role_trans_rule_read(policydb_t * p,role_trans_rule_t ** r,struct policy_file * fp)3659*2d543d20SAndroid Build Coastguard Worker static int role_trans_rule_read(policydb_t *p, role_trans_rule_t ** r,
3660*2d543d20SAndroid Build Coastguard Worker 				struct policy_file *fp)
3661*2d543d20SAndroid Build Coastguard Worker {
3662*2d543d20SAndroid Build Coastguard Worker 	uint32_t buf[1], nel;
3663*2d543d20SAndroid Build Coastguard Worker 	unsigned int i;
3664*2d543d20SAndroid Build Coastguard Worker 	role_trans_rule_t *tr, *ltr;
3665*2d543d20SAndroid Build Coastguard Worker 	int rc;
3666*2d543d20SAndroid Build Coastguard Worker 
3667*2d543d20SAndroid Build Coastguard Worker 	rc = next_entry(buf, fp, sizeof(uint32_t));
3668*2d543d20SAndroid Build Coastguard Worker 	if (rc < 0)
3669*2d543d20SAndroid Build Coastguard Worker 		return -1;
3670*2d543d20SAndroid Build Coastguard Worker 	nel = le32_to_cpu(buf[0]);
3671*2d543d20SAndroid Build Coastguard Worker 	ltr = NULL;
3672*2d543d20SAndroid Build Coastguard Worker 	for (i = 0; i < nel; i++) {
3673*2d543d20SAndroid Build Coastguard Worker 		tr = malloc(sizeof(role_trans_rule_t));
3674*2d543d20SAndroid Build Coastguard Worker 		if (!tr) {
3675*2d543d20SAndroid Build Coastguard Worker 			return -1;
3676*2d543d20SAndroid Build Coastguard Worker 		}
3677*2d543d20SAndroid Build Coastguard Worker 		role_trans_rule_init(tr);
3678*2d543d20SAndroid Build Coastguard Worker 
3679*2d543d20SAndroid Build Coastguard Worker 		if (ltr) {
3680*2d543d20SAndroid Build Coastguard Worker 			ltr->next = tr;
3681*2d543d20SAndroid Build Coastguard Worker 		} else {
3682*2d543d20SAndroid Build Coastguard Worker 			*r = tr;
3683*2d543d20SAndroid Build Coastguard Worker 		}
3684*2d543d20SAndroid Build Coastguard Worker 
3685*2d543d20SAndroid Build Coastguard Worker 		if (role_set_read(&tr->roles, fp))
3686*2d543d20SAndroid Build Coastguard Worker 			return -1;
3687*2d543d20SAndroid Build Coastguard Worker 
3688*2d543d20SAndroid Build Coastguard Worker 		if (type_set_read(&tr->types, fp))
3689*2d543d20SAndroid Build Coastguard Worker 			return -1;
3690*2d543d20SAndroid Build Coastguard Worker 
3691*2d543d20SAndroid Build Coastguard Worker 		if (p->policyvers >= MOD_POLICYDB_VERSION_ROLETRANS) {
3692*2d543d20SAndroid Build Coastguard Worker 			if (ebitmap_read(&tr->classes, fp))
3693*2d543d20SAndroid Build Coastguard Worker 				return -1;
3694*2d543d20SAndroid Build Coastguard Worker 		} else {
3695*2d543d20SAndroid Build Coastguard Worker 			if (!p->process_class)
3696*2d543d20SAndroid Build Coastguard Worker 				return -1;
3697*2d543d20SAndroid Build Coastguard Worker 			if (ebitmap_set_bit(&tr->classes, p->process_class - 1, 1))
3698*2d543d20SAndroid Build Coastguard Worker 				return -1;
3699*2d543d20SAndroid Build Coastguard Worker 		}
3700*2d543d20SAndroid Build Coastguard Worker 
3701*2d543d20SAndroid Build Coastguard Worker 		rc = next_entry(buf, fp, sizeof(uint32_t));
3702*2d543d20SAndroid Build Coastguard Worker 		if (rc < 0)
3703*2d543d20SAndroid Build Coastguard Worker 			return -1;
3704*2d543d20SAndroid Build Coastguard Worker 		tr->new_role = le32_to_cpu(buf[0]);
3705*2d543d20SAndroid Build Coastguard Worker 		ltr = tr;
3706*2d543d20SAndroid Build Coastguard Worker 	}
3707*2d543d20SAndroid Build Coastguard Worker 
3708*2d543d20SAndroid Build Coastguard Worker 	return 0;
3709*2d543d20SAndroid Build Coastguard Worker }
3710*2d543d20SAndroid Build Coastguard Worker 
role_allow_rule_read(role_allow_rule_t ** r,struct policy_file * fp)3711*2d543d20SAndroid Build Coastguard Worker static int role_allow_rule_read(role_allow_rule_t ** r, struct policy_file *fp)
3712*2d543d20SAndroid Build Coastguard Worker {
3713*2d543d20SAndroid Build Coastguard Worker 	unsigned int i;
3714*2d543d20SAndroid Build Coastguard Worker 	uint32_t buf[1], nel;
3715*2d543d20SAndroid Build Coastguard Worker 	role_allow_rule_t *ra, *lra;
3716*2d543d20SAndroid Build Coastguard Worker 	int rc;
3717*2d543d20SAndroid Build Coastguard Worker 
3718*2d543d20SAndroid Build Coastguard Worker 	rc = next_entry(buf, fp, sizeof(uint32_t));
3719*2d543d20SAndroid Build Coastguard Worker 	if (rc < 0)
3720*2d543d20SAndroid Build Coastguard Worker 		return -1;
3721*2d543d20SAndroid Build Coastguard Worker 	nel = le32_to_cpu(buf[0]);
3722*2d543d20SAndroid Build Coastguard Worker 	lra = NULL;
3723*2d543d20SAndroid Build Coastguard Worker 	for (i = 0; i < nel; i++) {
3724*2d543d20SAndroid Build Coastguard Worker 		ra = malloc(sizeof(role_allow_rule_t));
3725*2d543d20SAndroid Build Coastguard Worker 		if (!ra) {
3726*2d543d20SAndroid Build Coastguard Worker 			return -1;
3727*2d543d20SAndroid Build Coastguard Worker 		}
3728*2d543d20SAndroid Build Coastguard Worker 		role_allow_rule_init(ra);
3729*2d543d20SAndroid Build Coastguard Worker 
3730*2d543d20SAndroid Build Coastguard Worker 		if (lra) {
3731*2d543d20SAndroid Build Coastguard Worker 			lra->next = ra;
3732*2d543d20SAndroid Build Coastguard Worker 		} else {
3733*2d543d20SAndroid Build Coastguard Worker 			*r = ra;
3734*2d543d20SAndroid Build Coastguard Worker 		}
3735*2d543d20SAndroid Build Coastguard Worker 
3736*2d543d20SAndroid Build Coastguard Worker 		if (role_set_read(&ra->roles, fp))
3737*2d543d20SAndroid Build Coastguard Worker 			return -1;
3738*2d543d20SAndroid Build Coastguard Worker 
3739*2d543d20SAndroid Build Coastguard Worker 		if (role_set_read(&ra->new_roles, fp))
3740*2d543d20SAndroid Build Coastguard Worker 			return -1;
3741*2d543d20SAndroid Build Coastguard Worker 
3742*2d543d20SAndroid Build Coastguard Worker 		lra = ra;
3743*2d543d20SAndroid Build Coastguard Worker 	}
3744*2d543d20SAndroid Build Coastguard Worker 	return 0;
3745*2d543d20SAndroid Build Coastguard Worker }
3746*2d543d20SAndroid Build Coastguard Worker 
filename_trans_rule_read(policydb_t * p,filename_trans_rule_t ** r,struct policy_file * fp)3747*2d543d20SAndroid Build Coastguard Worker static int filename_trans_rule_read(policydb_t *p, filename_trans_rule_t **r,
3748*2d543d20SAndroid Build Coastguard Worker 				    struct policy_file *fp)
3749*2d543d20SAndroid Build Coastguard Worker {
3750*2d543d20SAndroid Build Coastguard Worker 	uint32_t buf[3], nel, i, len;
3751*2d543d20SAndroid Build Coastguard Worker 	unsigned int entries;
3752*2d543d20SAndroid Build Coastguard Worker 	filename_trans_rule_t *ftr, *lftr;
3753*2d543d20SAndroid Build Coastguard Worker 	int rc;
3754*2d543d20SAndroid Build Coastguard Worker 
3755*2d543d20SAndroid Build Coastguard Worker 	rc = next_entry(buf, fp, sizeof(uint32_t));
3756*2d543d20SAndroid Build Coastguard Worker 	if (rc < 0)
3757*2d543d20SAndroid Build Coastguard Worker 		return -1;
3758*2d543d20SAndroid Build Coastguard Worker 	nel = le32_to_cpu(buf[0]);
3759*2d543d20SAndroid Build Coastguard Worker 	lftr = NULL;
3760*2d543d20SAndroid Build Coastguard Worker 	for (i = 0; i < nel; i++) {
3761*2d543d20SAndroid Build Coastguard Worker 		ftr = malloc(sizeof(*ftr));
3762*2d543d20SAndroid Build Coastguard Worker 		if (!ftr)
3763*2d543d20SAndroid Build Coastguard Worker 			return -1;
3764*2d543d20SAndroid Build Coastguard Worker 
3765*2d543d20SAndroid Build Coastguard Worker 		filename_trans_rule_init(ftr);
3766*2d543d20SAndroid Build Coastguard Worker 
3767*2d543d20SAndroid Build Coastguard Worker 		if (lftr)
3768*2d543d20SAndroid Build Coastguard Worker 			lftr->next = ftr;
3769*2d543d20SAndroid Build Coastguard Worker 		else
3770*2d543d20SAndroid Build Coastguard Worker 			*r = ftr;
3771*2d543d20SAndroid Build Coastguard Worker 		lftr = ftr;
3772*2d543d20SAndroid Build Coastguard Worker 
3773*2d543d20SAndroid Build Coastguard Worker 		rc = next_entry(buf, fp, sizeof(uint32_t));
3774*2d543d20SAndroid Build Coastguard Worker 		if (rc < 0)
3775*2d543d20SAndroid Build Coastguard Worker 			return -1;
3776*2d543d20SAndroid Build Coastguard Worker 
3777*2d543d20SAndroid Build Coastguard Worker 		len = le32_to_cpu(buf[0]);
3778*2d543d20SAndroid Build Coastguard Worker 
3779*2d543d20SAndroid Build Coastguard Worker 		rc = str_read(&ftr->name, fp, len);
3780*2d543d20SAndroid Build Coastguard Worker 		if (rc < 0)
3781*2d543d20SAndroid Build Coastguard Worker 			return -1;
3782*2d543d20SAndroid Build Coastguard Worker 
3783*2d543d20SAndroid Build Coastguard Worker 		if (type_set_read(&ftr->stypes, fp))
3784*2d543d20SAndroid Build Coastguard Worker 			return -1;
3785*2d543d20SAndroid Build Coastguard Worker 
3786*2d543d20SAndroid Build Coastguard Worker 		if (type_set_read(&ftr->ttypes, fp))
3787*2d543d20SAndroid Build Coastguard Worker 			return -1;
3788*2d543d20SAndroid Build Coastguard Worker 
3789*2d543d20SAndroid Build Coastguard Worker 		if (p->policyvers >= MOD_POLICYDB_VERSION_SELF_TYPETRANS)
3790*2d543d20SAndroid Build Coastguard Worker 			entries = 3;
3791*2d543d20SAndroid Build Coastguard Worker 		else
3792*2d543d20SAndroid Build Coastguard Worker 			entries = 2;
3793*2d543d20SAndroid Build Coastguard Worker 
3794*2d543d20SAndroid Build Coastguard Worker 		rc = next_entry(buf, fp, sizeof(uint32_t) * entries);
3795*2d543d20SAndroid Build Coastguard Worker 		if (rc < 0)
3796*2d543d20SAndroid Build Coastguard Worker 			return -1;
3797*2d543d20SAndroid Build Coastguard Worker 		ftr->tclass = le32_to_cpu(buf[0]);
3798*2d543d20SAndroid Build Coastguard Worker 		ftr->otype = le32_to_cpu(buf[1]);
3799*2d543d20SAndroid Build Coastguard Worker 		if (p->policyvers >= MOD_POLICYDB_VERSION_SELF_TYPETRANS)
3800*2d543d20SAndroid Build Coastguard Worker 			ftr->flags = le32_to_cpu(buf[2]);
3801*2d543d20SAndroid Build Coastguard Worker 	}
3802*2d543d20SAndroid Build Coastguard Worker 
3803*2d543d20SAndroid Build Coastguard Worker 	return 0;
3804*2d543d20SAndroid Build Coastguard Worker }
3805*2d543d20SAndroid Build Coastguard Worker 
range_trans_rule_read(range_trans_rule_t ** r,struct policy_file * fp)3806*2d543d20SAndroid Build Coastguard Worker static int range_trans_rule_read(range_trans_rule_t ** r,
3807*2d543d20SAndroid Build Coastguard Worker 				 struct policy_file *fp)
3808*2d543d20SAndroid Build Coastguard Worker {
3809*2d543d20SAndroid Build Coastguard Worker 	uint32_t buf[1], nel;
3810*2d543d20SAndroid Build Coastguard Worker 	unsigned int i;
3811*2d543d20SAndroid Build Coastguard Worker 	range_trans_rule_t *rt, *lrt = NULL;
3812*2d543d20SAndroid Build Coastguard Worker 	int rc;
3813*2d543d20SAndroid Build Coastguard Worker 
3814*2d543d20SAndroid Build Coastguard Worker 	rc = next_entry(buf, fp, sizeof(uint32_t));
3815*2d543d20SAndroid Build Coastguard Worker 	if (rc < 0)
3816*2d543d20SAndroid Build Coastguard Worker 		return -1;
3817*2d543d20SAndroid Build Coastguard Worker 	nel = le32_to_cpu(buf[0]);
3818*2d543d20SAndroid Build Coastguard Worker 	for (i = 0; i < nel; i++) {
3819*2d543d20SAndroid Build Coastguard Worker 		rt = malloc(sizeof(range_trans_rule_t));
3820*2d543d20SAndroid Build Coastguard Worker 		if (!rt) {
3821*2d543d20SAndroid Build Coastguard Worker 			return -1;
3822*2d543d20SAndroid Build Coastguard Worker 		}
3823*2d543d20SAndroid Build Coastguard Worker 		range_trans_rule_init(rt);
3824*2d543d20SAndroid Build Coastguard Worker 
3825*2d543d20SAndroid Build Coastguard Worker 		if (lrt)
3826*2d543d20SAndroid Build Coastguard Worker 			lrt->next = rt;
3827*2d543d20SAndroid Build Coastguard Worker 		else
3828*2d543d20SAndroid Build Coastguard Worker 			*r = rt;
3829*2d543d20SAndroid Build Coastguard Worker 
3830*2d543d20SAndroid Build Coastguard Worker 		if (type_set_read(&rt->stypes, fp))
3831*2d543d20SAndroid Build Coastguard Worker 			return -1;
3832*2d543d20SAndroid Build Coastguard Worker 
3833*2d543d20SAndroid Build Coastguard Worker 		if (type_set_read(&rt->ttypes, fp))
3834*2d543d20SAndroid Build Coastguard Worker 			return -1;
3835*2d543d20SAndroid Build Coastguard Worker 
3836*2d543d20SAndroid Build Coastguard Worker 		if (ebitmap_read(&rt->tclasses, fp))
3837*2d543d20SAndroid Build Coastguard Worker 			return -1;
3838*2d543d20SAndroid Build Coastguard Worker 
3839*2d543d20SAndroid Build Coastguard Worker 		if (mls_read_semantic_range_helper(&rt->trange, fp))
3840*2d543d20SAndroid Build Coastguard Worker 			return -1;
3841*2d543d20SAndroid Build Coastguard Worker 
3842*2d543d20SAndroid Build Coastguard Worker 		lrt = rt;
3843*2d543d20SAndroid Build Coastguard Worker 	}
3844*2d543d20SAndroid Build Coastguard Worker 
3845*2d543d20SAndroid Build Coastguard Worker 	return 0;
3846*2d543d20SAndroid Build Coastguard Worker }
3847*2d543d20SAndroid Build Coastguard Worker 
scope_index_read(scope_index_t * scope_index,unsigned int num_scope_syms,struct policy_file * fp)3848*2d543d20SAndroid Build Coastguard Worker static int scope_index_read(scope_index_t * scope_index,
3849*2d543d20SAndroid Build Coastguard Worker 			    unsigned int num_scope_syms, struct policy_file *fp)
3850*2d543d20SAndroid Build Coastguard Worker {
3851*2d543d20SAndroid Build Coastguard Worker 	unsigned int i;
3852*2d543d20SAndroid Build Coastguard Worker 	uint32_t buf[1];
3853*2d543d20SAndroid Build Coastguard Worker 	int rc;
3854*2d543d20SAndroid Build Coastguard Worker 
3855*2d543d20SAndroid Build Coastguard Worker 	for (i = 0; i < num_scope_syms; i++) {
3856*2d543d20SAndroid Build Coastguard Worker 		if (ebitmap_read(scope_index->scope + i, fp) < 0) {
3857*2d543d20SAndroid Build Coastguard Worker 			return -1;
3858*2d543d20SAndroid Build Coastguard Worker 		}
3859*2d543d20SAndroid Build Coastguard Worker 	}
3860*2d543d20SAndroid Build Coastguard Worker 	rc = next_entry(buf, fp, sizeof(uint32_t));
3861*2d543d20SAndroid Build Coastguard Worker 	if (rc < 0)
3862*2d543d20SAndroid Build Coastguard Worker 		return -1;
3863*2d543d20SAndroid Build Coastguard Worker 	scope_index->class_perms_len = le32_to_cpu(buf[0]);
3864*2d543d20SAndroid Build Coastguard Worker 	if (is_saturated(scope_index->class_perms_len) ||
3865*2d543d20SAndroid Build Coastguard Worker 	    exceeds_available_bytes(fp, scope_index->class_perms_len, sizeof(uint32_t) * 3))
3866*2d543d20SAndroid Build Coastguard Worker 		return -1;
3867*2d543d20SAndroid Build Coastguard Worker 	if (scope_index->class_perms_len == 0) {
3868*2d543d20SAndroid Build Coastguard Worker 		scope_index->class_perms_map = NULL;
3869*2d543d20SAndroid Build Coastguard Worker 		return 0;
3870*2d543d20SAndroid Build Coastguard Worker 	}
3871*2d543d20SAndroid Build Coastguard Worker 	if ((scope_index->class_perms_map =
3872*2d543d20SAndroid Build Coastguard Worker 	     calloc(scope_index->class_perms_len,
3873*2d543d20SAndroid Build Coastguard Worker 		    sizeof(*scope_index->class_perms_map))) == NULL) {
3874*2d543d20SAndroid Build Coastguard Worker 		return -1;
3875*2d543d20SAndroid Build Coastguard Worker 	}
3876*2d543d20SAndroid Build Coastguard Worker 	for (i = 0; i < scope_index->class_perms_len; i++) {
3877*2d543d20SAndroid Build Coastguard Worker 		if (ebitmap_read(scope_index->class_perms_map + i, fp) < 0) {
3878*2d543d20SAndroid Build Coastguard Worker 			return -1;
3879*2d543d20SAndroid Build Coastguard Worker 		}
3880*2d543d20SAndroid Build Coastguard Worker 	}
3881*2d543d20SAndroid Build Coastguard Worker 	return 0;
3882*2d543d20SAndroid Build Coastguard Worker }
3883*2d543d20SAndroid Build Coastguard Worker 
avrule_decl_read(policydb_t * p,avrule_decl_t * decl,unsigned int num_scope_syms,struct policy_file * fp)3884*2d543d20SAndroid Build Coastguard Worker static int avrule_decl_read(policydb_t * p, avrule_decl_t * decl,
3885*2d543d20SAndroid Build Coastguard Worker 			    unsigned int num_scope_syms, struct policy_file *fp)
3886*2d543d20SAndroid Build Coastguard Worker {
3887*2d543d20SAndroid Build Coastguard Worker 	uint32_t buf[2], nprim, nel;
3888*2d543d20SAndroid Build Coastguard Worker 	unsigned int i, j;
3889*2d543d20SAndroid Build Coastguard Worker 	int rc;
3890*2d543d20SAndroid Build Coastguard Worker 
3891*2d543d20SAndroid Build Coastguard Worker 	rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
3892*2d543d20SAndroid Build Coastguard Worker 	if (rc < 0)
3893*2d543d20SAndroid Build Coastguard Worker 		return -1;
3894*2d543d20SAndroid Build Coastguard Worker 	decl->decl_id = le32_to_cpu(buf[0]);
3895*2d543d20SAndroid Build Coastguard Worker 	decl->enabled = le32_to_cpu(buf[1]);
3896*2d543d20SAndroid Build Coastguard Worker 	if (cond_read_list(p, &decl->cond_list, fp) == -1 ||
3897*2d543d20SAndroid Build Coastguard Worker 	    avrule_read_list(p, &decl->avrules, fp) == -1 ||
3898*2d543d20SAndroid Build Coastguard Worker 	    role_trans_rule_read(p, &decl->role_tr_rules, fp) == -1 ||
3899*2d543d20SAndroid Build Coastguard Worker 	    role_allow_rule_read(&decl->role_allow_rules, fp) == -1) {
3900*2d543d20SAndroid Build Coastguard Worker 		return -1;
3901*2d543d20SAndroid Build Coastguard Worker 	}
3902*2d543d20SAndroid Build Coastguard Worker 
3903*2d543d20SAndroid Build Coastguard Worker 	if (p->policyvers >= MOD_POLICYDB_VERSION_FILENAME_TRANS &&
3904*2d543d20SAndroid Build Coastguard Worker 	    filename_trans_rule_read(p, &decl->filename_trans_rules, fp))
3905*2d543d20SAndroid Build Coastguard Worker 		return -1;
3906*2d543d20SAndroid Build Coastguard Worker 
3907*2d543d20SAndroid Build Coastguard Worker 	if (p->policyvers >= MOD_POLICYDB_VERSION_RANGETRANS &&
3908*2d543d20SAndroid Build Coastguard Worker 	    range_trans_rule_read(&decl->range_tr_rules, fp) == -1) {
3909*2d543d20SAndroid Build Coastguard Worker 		return -1;
3910*2d543d20SAndroid Build Coastguard Worker 	}
3911*2d543d20SAndroid Build Coastguard Worker 	if (scope_index_read(&decl->required, num_scope_syms, fp) == -1 ||
3912*2d543d20SAndroid Build Coastguard Worker 	    scope_index_read(&decl->declared, num_scope_syms, fp) == -1) {
3913*2d543d20SAndroid Build Coastguard Worker 		return -1;
3914*2d543d20SAndroid Build Coastguard Worker 	}
3915*2d543d20SAndroid Build Coastguard Worker 
3916*2d543d20SAndroid Build Coastguard Worker 	for (i = 0; i < num_scope_syms; i++) {
3917*2d543d20SAndroid Build Coastguard Worker 		rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
3918*2d543d20SAndroid Build Coastguard Worker 		if (rc < 0)
3919*2d543d20SAndroid Build Coastguard Worker 			return -1;
3920*2d543d20SAndroid Build Coastguard Worker 		nprim = le32_to_cpu(buf[0]);
3921*2d543d20SAndroid Build Coastguard Worker 		if (is_saturated(nprim))
3922*2d543d20SAndroid Build Coastguard Worker 			return -1;
3923*2d543d20SAndroid Build Coastguard Worker 		nel = le32_to_cpu(buf[1]);
3924*2d543d20SAndroid Build Coastguard Worker 		for (j = 0; j < nel; j++) {
3925*2d543d20SAndroid Build Coastguard Worker 			if (read_f[i] (p, decl->symtab[i].table, fp)) {
3926*2d543d20SAndroid Build Coastguard Worker 				return -1;
3927*2d543d20SAndroid Build Coastguard Worker 			}
3928*2d543d20SAndroid Build Coastguard Worker 		}
3929*2d543d20SAndroid Build Coastguard Worker 		decl->symtab[i].nprim = nprim;
3930*2d543d20SAndroid Build Coastguard Worker 	}
3931*2d543d20SAndroid Build Coastguard Worker 	return 0;
3932*2d543d20SAndroid Build Coastguard Worker }
3933*2d543d20SAndroid Build Coastguard Worker 
avrule_block_read(policydb_t * p,avrule_block_t ** block,unsigned int num_scope_syms,struct policy_file * fp)3934*2d543d20SAndroid Build Coastguard Worker static int avrule_block_read(policydb_t * p,
3935*2d543d20SAndroid Build Coastguard Worker 			     avrule_block_t ** block,
3936*2d543d20SAndroid Build Coastguard Worker 			     unsigned int num_scope_syms,
3937*2d543d20SAndroid Build Coastguard Worker 			     struct policy_file *fp)
3938*2d543d20SAndroid Build Coastguard Worker {
3939*2d543d20SAndroid Build Coastguard Worker 	avrule_block_t *last_block = NULL, *curblock;
3940*2d543d20SAndroid Build Coastguard Worker 	uint32_t buf[1], num_blocks, nel;
3941*2d543d20SAndroid Build Coastguard Worker 	int rc;
3942*2d543d20SAndroid Build Coastguard Worker 
3943*2d543d20SAndroid Build Coastguard Worker 	assert(*block == NULL);
3944*2d543d20SAndroid Build Coastguard Worker 
3945*2d543d20SAndroid Build Coastguard Worker 	rc = next_entry(buf, fp, sizeof(uint32_t));
3946*2d543d20SAndroid Build Coastguard Worker 	if (rc < 0)
3947*2d543d20SAndroid Build Coastguard Worker 		return -1;
3948*2d543d20SAndroid Build Coastguard Worker 	num_blocks = le32_to_cpu(buf[0]);
3949*2d543d20SAndroid Build Coastguard Worker 	nel = num_blocks;
3950*2d543d20SAndroid Build Coastguard Worker 	while (num_blocks > 0) {
3951*2d543d20SAndroid Build Coastguard Worker 		avrule_decl_t *last_decl = NULL, *curdecl;
3952*2d543d20SAndroid Build Coastguard Worker 		uint32_t num_decls;
3953*2d543d20SAndroid Build Coastguard Worker 		if ((curblock = calloc(1, sizeof(*curblock))) == NULL) {
3954*2d543d20SAndroid Build Coastguard Worker 			return -1;
3955*2d543d20SAndroid Build Coastguard Worker 		}
3956*2d543d20SAndroid Build Coastguard Worker 		rc = next_entry(buf, fp, sizeof(uint32_t));
3957*2d543d20SAndroid Build Coastguard Worker 		if (rc < 0) {
3958*2d543d20SAndroid Build Coastguard Worker 			free(curblock);
3959*2d543d20SAndroid Build Coastguard Worker 			return -1;
3960*2d543d20SAndroid Build Coastguard Worker 		}
3961*2d543d20SAndroid Build Coastguard Worker 		/* if this is the first block its non-optional, else its optional */
3962*2d543d20SAndroid Build Coastguard Worker 		if (num_blocks != nel)
3963*2d543d20SAndroid Build Coastguard Worker 			curblock->flags |= AVRULE_OPTIONAL;
3964*2d543d20SAndroid Build Coastguard Worker 
3965*2d543d20SAndroid Build Coastguard Worker 		num_decls = le32_to_cpu(buf[0]);
3966*2d543d20SAndroid Build Coastguard Worker 		while (num_decls > 0) {
3967*2d543d20SAndroid Build Coastguard Worker 			if ((curdecl = avrule_decl_create(0)) == NULL) {
3968*2d543d20SAndroid Build Coastguard Worker 				avrule_block_destroy(curblock);
3969*2d543d20SAndroid Build Coastguard Worker 				return -1;
3970*2d543d20SAndroid Build Coastguard Worker 			}
3971*2d543d20SAndroid Build Coastguard Worker 			if (avrule_decl_read(p, curdecl, num_scope_syms, fp) ==
3972*2d543d20SAndroid Build Coastguard Worker 			    -1) {
3973*2d543d20SAndroid Build Coastguard Worker 				avrule_decl_destroy(curdecl);
3974*2d543d20SAndroid Build Coastguard Worker 				avrule_block_destroy(curblock);
3975*2d543d20SAndroid Build Coastguard Worker 				return -1;
3976*2d543d20SAndroid Build Coastguard Worker 			}
3977*2d543d20SAndroid Build Coastguard Worker 			if (curdecl->enabled) {
3978*2d543d20SAndroid Build Coastguard Worker 				if (curblock->enabled != NULL) {
3979*2d543d20SAndroid Build Coastguard Worker 					/* probably a corrupt file */
3980*2d543d20SAndroid Build Coastguard Worker 					avrule_decl_destroy(curdecl);
3981*2d543d20SAndroid Build Coastguard Worker 					avrule_block_destroy(curblock);
3982*2d543d20SAndroid Build Coastguard Worker 					return -1;
3983*2d543d20SAndroid Build Coastguard Worker 				}
3984*2d543d20SAndroid Build Coastguard Worker 				curblock->enabled = curdecl;
3985*2d543d20SAndroid Build Coastguard Worker 			}
3986*2d543d20SAndroid Build Coastguard Worker 			/* one must be careful to reconstruct the
3987*2d543d20SAndroid Build Coastguard Worker 			 * decl chain in its correct order */
3988*2d543d20SAndroid Build Coastguard Worker 			if (curblock->branch_list == NULL) {
3989*2d543d20SAndroid Build Coastguard Worker 				curblock->branch_list = curdecl;
3990*2d543d20SAndroid Build Coastguard Worker 			} else {
3991*2d543d20SAndroid Build Coastguard Worker 				assert(last_decl);
3992*2d543d20SAndroid Build Coastguard Worker 				last_decl->next = curdecl;
3993*2d543d20SAndroid Build Coastguard Worker 			}
3994*2d543d20SAndroid Build Coastguard Worker 			last_decl = curdecl;
3995*2d543d20SAndroid Build Coastguard Worker 			num_decls--;
3996*2d543d20SAndroid Build Coastguard Worker 		}
3997*2d543d20SAndroid Build Coastguard Worker 
3998*2d543d20SAndroid Build Coastguard Worker 		if (*block == NULL) {
3999*2d543d20SAndroid Build Coastguard Worker 			*block = curblock;
4000*2d543d20SAndroid Build Coastguard Worker 		} else {
4001*2d543d20SAndroid Build Coastguard Worker 			assert(last_block);
4002*2d543d20SAndroid Build Coastguard Worker 			last_block->next = curblock;
4003*2d543d20SAndroid Build Coastguard Worker 		}
4004*2d543d20SAndroid Build Coastguard Worker 		last_block = curblock;
4005*2d543d20SAndroid Build Coastguard Worker 
4006*2d543d20SAndroid Build Coastguard Worker 		num_blocks--;
4007*2d543d20SAndroid Build Coastguard Worker 	}
4008*2d543d20SAndroid Build Coastguard Worker 
4009*2d543d20SAndroid Build Coastguard Worker 	return 0;
4010*2d543d20SAndroid Build Coastguard Worker }
4011*2d543d20SAndroid Build Coastguard Worker 
scope_read(policydb_t * p,int symnum,struct policy_file * fp)4012*2d543d20SAndroid Build Coastguard Worker static int scope_read(policydb_t * p, int symnum, struct policy_file *fp)
4013*2d543d20SAndroid Build Coastguard Worker {
4014*2d543d20SAndroid Build Coastguard Worker 	scope_datum_t *scope = NULL;
4015*2d543d20SAndroid Build Coastguard Worker 	uint32_t buf[2];
4016*2d543d20SAndroid Build Coastguard Worker 	char *key = NULL;
4017*2d543d20SAndroid Build Coastguard Worker 	size_t key_len;
4018*2d543d20SAndroid Build Coastguard Worker 	unsigned int i;
4019*2d543d20SAndroid Build Coastguard Worker 	hashtab_t h = p->scope[symnum].table;
4020*2d543d20SAndroid Build Coastguard Worker 	int rc;
4021*2d543d20SAndroid Build Coastguard Worker 
4022*2d543d20SAndroid Build Coastguard Worker 	rc = next_entry(buf, fp, sizeof(uint32_t));
4023*2d543d20SAndroid Build Coastguard Worker 	if (rc < 0)
4024*2d543d20SAndroid Build Coastguard Worker 		goto cleanup;
4025*2d543d20SAndroid Build Coastguard Worker 	key_len = le32_to_cpu(buf[0]);
4026*2d543d20SAndroid Build Coastguard Worker 
4027*2d543d20SAndroid Build Coastguard Worker 	rc = str_read(&key, fp, key_len);
4028*2d543d20SAndroid Build Coastguard Worker 	if (rc < 0)
4029*2d543d20SAndroid Build Coastguard Worker 		goto cleanup;
4030*2d543d20SAndroid Build Coastguard Worker 
4031*2d543d20SAndroid Build Coastguard Worker 	/* ensure that there already exists a symbol with this key */
4032*2d543d20SAndroid Build Coastguard Worker 	if (hashtab_search(p->symtab[symnum].table, key) == NULL) {
4033*2d543d20SAndroid Build Coastguard Worker 		goto cleanup;
4034*2d543d20SAndroid Build Coastguard Worker 	}
4035*2d543d20SAndroid Build Coastguard Worker 
4036*2d543d20SAndroid Build Coastguard Worker 	if ((scope = calloc(1, sizeof(*scope))) == NULL) {
4037*2d543d20SAndroid Build Coastguard Worker 		goto cleanup;
4038*2d543d20SAndroid Build Coastguard Worker 	}
4039*2d543d20SAndroid Build Coastguard Worker 	rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
4040*2d543d20SAndroid Build Coastguard Worker 	if (rc < 0)
4041*2d543d20SAndroid Build Coastguard Worker 		goto cleanup;
4042*2d543d20SAndroid Build Coastguard Worker 	scope->scope = le32_to_cpu(buf[0]);
4043*2d543d20SAndroid Build Coastguard Worker 	scope->decl_ids_len = le32_to_cpu(buf[1]);
4044*2d543d20SAndroid Build Coastguard Worker 	if (zero_or_saturated(scope->decl_ids_len) ||
4045*2d543d20SAndroid Build Coastguard Worker 	    exceeds_available_bytes(fp, scope->decl_ids_len, sizeof(uint32_t))) {
4046*2d543d20SAndroid Build Coastguard Worker 		ERR(fp->handle, "invalid scope with no declaration");
4047*2d543d20SAndroid Build Coastguard Worker 		goto cleanup;
4048*2d543d20SAndroid Build Coastguard Worker 	}
4049*2d543d20SAndroid Build Coastguard Worker 	if ((scope->decl_ids =
4050*2d543d20SAndroid Build Coastguard Worker 	     calloc(scope->decl_ids_len, sizeof(uint32_t))) == NULL) {
4051*2d543d20SAndroid Build Coastguard Worker 		goto cleanup;
4052*2d543d20SAndroid Build Coastguard Worker 	}
4053*2d543d20SAndroid Build Coastguard Worker 	rc = next_entry(scope->decl_ids, fp, sizeof(uint32_t) * scope->decl_ids_len);
4054*2d543d20SAndroid Build Coastguard Worker 	if (rc < 0)
4055*2d543d20SAndroid Build Coastguard Worker 		goto cleanup;
4056*2d543d20SAndroid Build Coastguard Worker 	for (i = 0; i < scope->decl_ids_len; i++) {
4057*2d543d20SAndroid Build Coastguard Worker 		scope->decl_ids[i] = le32_to_cpu(scope->decl_ids[i]);
4058*2d543d20SAndroid Build Coastguard Worker 	}
4059*2d543d20SAndroid Build Coastguard Worker 
4060*2d543d20SAndroid Build Coastguard Worker 	if (strcmp(key, "object_r") == 0 && h == p->p_roles_scope.table) {
4061*2d543d20SAndroid Build Coastguard Worker 		/* object_r was already added to this table in roles_init() */
4062*2d543d20SAndroid Build Coastguard Worker 		scope_destroy(key, scope, NULL);
4063*2d543d20SAndroid Build Coastguard Worker 	} else {
4064*2d543d20SAndroid Build Coastguard Worker 		if (hashtab_insert(h, key, scope)) {
4065*2d543d20SAndroid Build Coastguard Worker 			goto cleanup;
4066*2d543d20SAndroid Build Coastguard Worker 		}
4067*2d543d20SAndroid Build Coastguard Worker 	}
4068*2d543d20SAndroid Build Coastguard Worker 
4069*2d543d20SAndroid Build Coastguard Worker 	return 0;
4070*2d543d20SAndroid Build Coastguard Worker 
4071*2d543d20SAndroid Build Coastguard Worker       cleanup:
4072*2d543d20SAndroid Build Coastguard Worker 	scope_destroy(key, scope, NULL);
4073*2d543d20SAndroid Build Coastguard Worker 	return -1;
4074*2d543d20SAndroid Build Coastguard Worker }
4075*2d543d20SAndroid Build Coastguard Worker 
policydb_string_to_security_class(struct policydb * policydb,const char * class_name)4076*2d543d20SAndroid Build Coastguard Worker static sepol_security_class_t policydb_string_to_security_class(
4077*2d543d20SAndroid Build Coastguard Worker 	struct policydb *policydb,
4078*2d543d20SAndroid Build Coastguard Worker 	const char *class_name)
4079*2d543d20SAndroid Build Coastguard Worker {
4080*2d543d20SAndroid Build Coastguard Worker 	class_datum_t *tclass_datum;
4081*2d543d20SAndroid Build Coastguard Worker 
4082*2d543d20SAndroid Build Coastguard Worker 	tclass_datum = hashtab_search(policydb->p_classes.table,
4083*2d543d20SAndroid Build Coastguard Worker 				      class_name);
4084*2d543d20SAndroid Build Coastguard Worker 	if (!tclass_datum)
4085*2d543d20SAndroid Build Coastguard Worker 		return 0;
4086*2d543d20SAndroid Build Coastguard Worker 	return tclass_datum->s.value;
4087*2d543d20SAndroid Build Coastguard Worker }
4088*2d543d20SAndroid Build Coastguard Worker 
policydb_string_to_av_perm(struct policydb * policydb,sepol_security_class_t tclass,const char * perm_name)4089*2d543d20SAndroid Build Coastguard Worker static sepol_access_vector_t policydb_string_to_av_perm(
4090*2d543d20SAndroid Build Coastguard Worker 	struct policydb *policydb,
4091*2d543d20SAndroid Build Coastguard Worker 	sepol_security_class_t tclass,
4092*2d543d20SAndroid Build Coastguard Worker 	const char *perm_name)
4093*2d543d20SAndroid Build Coastguard Worker {
4094*2d543d20SAndroid Build Coastguard Worker 	class_datum_t *tclass_datum;
4095*2d543d20SAndroid Build Coastguard Worker 	perm_datum_t *perm_datum;
4096*2d543d20SAndroid Build Coastguard Worker 
4097*2d543d20SAndroid Build Coastguard Worker 	if (!tclass || tclass > policydb->p_classes.nprim)
4098*2d543d20SAndroid Build Coastguard Worker 		return 0;
4099*2d543d20SAndroid Build Coastguard Worker 	tclass_datum = policydb->class_val_to_struct[tclass - 1];
4100*2d543d20SAndroid Build Coastguard Worker 
4101*2d543d20SAndroid Build Coastguard Worker 	perm_datum = (perm_datum_t *)
4102*2d543d20SAndroid Build Coastguard Worker 			hashtab_search(tclass_datum->permissions.table,
4103*2d543d20SAndroid Build Coastguard Worker 			perm_name);
4104*2d543d20SAndroid Build Coastguard Worker 	if (perm_datum != NULL)
4105*2d543d20SAndroid Build Coastguard Worker 		return UINT32_C(1) << (perm_datum->s.value - 1);
4106*2d543d20SAndroid Build Coastguard Worker 
4107*2d543d20SAndroid Build Coastguard Worker 	if (tclass_datum->comdatum == NULL)
4108*2d543d20SAndroid Build Coastguard Worker 		return 0;
4109*2d543d20SAndroid Build Coastguard Worker 
4110*2d543d20SAndroid Build Coastguard Worker 	perm_datum = (perm_datum_t *)
4111*2d543d20SAndroid Build Coastguard Worker 			hashtab_search(tclass_datum->comdatum->permissions.table,
4112*2d543d20SAndroid Build Coastguard Worker 			perm_name);
4113*2d543d20SAndroid Build Coastguard Worker 
4114*2d543d20SAndroid Build Coastguard Worker 	if (perm_datum != NULL)
4115*2d543d20SAndroid Build Coastguard Worker 		return UINT32_C(1) << (perm_datum->s.value - 1);
4116*2d543d20SAndroid Build Coastguard Worker 
4117*2d543d20SAndroid Build Coastguard Worker 	return 0;
4118*2d543d20SAndroid Build Coastguard Worker }
4119*2d543d20SAndroid Build Coastguard Worker 
4120*2d543d20SAndroid Build Coastguard Worker 
4121*2d543d20SAndroid Build Coastguard Worker /*
4122*2d543d20SAndroid Build Coastguard Worker  * Read the configuration data from a policy database binary
4123*2d543d20SAndroid Build Coastguard Worker  * representation file into a policy database structure.
4124*2d543d20SAndroid Build Coastguard Worker  */
policydb_read(policydb_t * p,struct policy_file * fp,unsigned verbose)4125*2d543d20SAndroid Build Coastguard Worker int policydb_read(policydb_t * p, struct policy_file *fp, unsigned verbose)
4126*2d543d20SAndroid Build Coastguard Worker {
4127*2d543d20SAndroid Build Coastguard Worker 
4128*2d543d20SAndroid Build Coastguard Worker 	unsigned int i, j, r_policyvers;
4129*2d543d20SAndroid Build Coastguard Worker 	uint32_t buf[5], nprim;
4130*2d543d20SAndroid Build Coastguard Worker 	size_t len, nel;
4131*2d543d20SAndroid Build Coastguard Worker 	char *policydb_str;
4132*2d543d20SAndroid Build Coastguard Worker 	const struct policydb_compat_info *info;
4133*2d543d20SAndroid Build Coastguard Worker 	unsigned int policy_type, bufindex;
4134*2d543d20SAndroid Build Coastguard Worker 	ebitmap_node_t *tnode;
4135*2d543d20SAndroid Build Coastguard Worker 	int rc;
4136*2d543d20SAndroid Build Coastguard Worker 
4137*2d543d20SAndroid Build Coastguard Worker 	/* Read the magic number and string length. */
4138*2d543d20SAndroid Build Coastguard Worker 	rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
4139*2d543d20SAndroid Build Coastguard Worker 	if (rc < 0)
4140*2d543d20SAndroid Build Coastguard Worker 		return POLICYDB_ERROR;
4141*2d543d20SAndroid Build Coastguard Worker 	for (i = 0; i < 2; i++)
4142*2d543d20SAndroid Build Coastguard Worker 		buf[i] = le32_to_cpu(buf[i]);
4143*2d543d20SAndroid Build Coastguard Worker 
4144*2d543d20SAndroid Build Coastguard Worker 	if (buf[0] == POLICYDB_MAGIC) {
4145*2d543d20SAndroid Build Coastguard Worker 		policy_type = POLICY_KERN;
4146*2d543d20SAndroid Build Coastguard Worker 	} else if (buf[0] == POLICYDB_MOD_MAGIC) {
4147*2d543d20SAndroid Build Coastguard Worker 		policy_type = POLICY_MOD;
4148*2d543d20SAndroid Build Coastguard Worker 	} else {
4149*2d543d20SAndroid Build Coastguard Worker 		ERR(fp->handle, "policydb magic number %#08x does not "
4150*2d543d20SAndroid Build Coastguard Worker 		    "match expected magic number %#08x or %#08x",
4151*2d543d20SAndroid Build Coastguard Worker 		    buf[0], POLICYDB_MAGIC, POLICYDB_MOD_MAGIC);
4152*2d543d20SAndroid Build Coastguard Worker 		return POLICYDB_ERROR;
4153*2d543d20SAndroid Build Coastguard Worker 	}
4154*2d543d20SAndroid Build Coastguard Worker 
4155*2d543d20SAndroid Build Coastguard Worker 	len = buf[1];
4156*2d543d20SAndroid Build Coastguard Worker 	if (len == 0 || len > POLICYDB_STRING_MAX_LENGTH) {
4157*2d543d20SAndroid Build Coastguard Worker 		ERR(fp->handle, "policydb string length %s ", len ? "too long" : "zero");
4158*2d543d20SAndroid Build Coastguard Worker 		return POLICYDB_ERROR;
4159*2d543d20SAndroid Build Coastguard Worker 	}
4160*2d543d20SAndroid Build Coastguard Worker 
4161*2d543d20SAndroid Build Coastguard Worker 	policydb_str = malloc(len + 1);
4162*2d543d20SAndroid Build Coastguard Worker 	if (!policydb_str) {
4163*2d543d20SAndroid Build Coastguard Worker 		ERR(fp->handle, "unable to allocate memory for policydb "
4164*2d543d20SAndroid Build Coastguard Worker 		    "string of length %zu", len);
4165*2d543d20SAndroid Build Coastguard Worker 		return POLICYDB_ERROR;
4166*2d543d20SAndroid Build Coastguard Worker 	}
4167*2d543d20SAndroid Build Coastguard Worker 	rc = next_entry(policydb_str, fp, len);
4168*2d543d20SAndroid Build Coastguard Worker 	if (rc < 0) {
4169*2d543d20SAndroid Build Coastguard Worker 		ERR(fp->handle, "truncated policydb string identifier");
4170*2d543d20SAndroid Build Coastguard Worker 		free(policydb_str);
4171*2d543d20SAndroid Build Coastguard Worker 		return POLICYDB_ERROR;
4172*2d543d20SAndroid Build Coastguard Worker 	}
4173*2d543d20SAndroid Build Coastguard Worker 	policydb_str[len] = 0;
4174*2d543d20SAndroid Build Coastguard Worker 
4175*2d543d20SAndroid Build Coastguard Worker 	if (policy_type == POLICY_KERN) {
4176*2d543d20SAndroid Build Coastguard Worker 		for (i = 0; i < POLICYDB_TARGET_SZ; i++) {
4177*2d543d20SAndroid Build Coastguard Worker 			if ((strcmp(policydb_str, policydb_target_strings[i])
4178*2d543d20SAndroid Build Coastguard Worker 				== 0)) {
4179*2d543d20SAndroid Build Coastguard Worker 				policydb_set_target_platform(p, i);
4180*2d543d20SAndroid Build Coastguard Worker 				break;
4181*2d543d20SAndroid Build Coastguard Worker 			}
4182*2d543d20SAndroid Build Coastguard Worker 		}
4183*2d543d20SAndroid Build Coastguard Worker 
4184*2d543d20SAndroid Build Coastguard Worker 		if (i == POLICYDB_TARGET_SZ) {
4185*2d543d20SAndroid Build Coastguard Worker 			ERR(fp->handle, "cannot find a valid target for policy "
4186*2d543d20SAndroid Build Coastguard Worker 				"string %s", policydb_str);
4187*2d543d20SAndroid Build Coastguard Worker 			free(policydb_str);
4188*2d543d20SAndroid Build Coastguard Worker 			return POLICYDB_ERROR;
4189*2d543d20SAndroid Build Coastguard Worker 		}
4190*2d543d20SAndroid Build Coastguard Worker 	} else {
4191*2d543d20SAndroid Build Coastguard Worker 		if (strcmp(policydb_str, POLICYDB_MOD_STRING)) {
4192*2d543d20SAndroid Build Coastguard Worker 			ERR(fp->handle, "invalid string identifier %s",
4193*2d543d20SAndroid Build Coastguard Worker 				policydb_str);
4194*2d543d20SAndroid Build Coastguard Worker 			free(policydb_str);
4195*2d543d20SAndroid Build Coastguard Worker 			return POLICYDB_ERROR;
4196*2d543d20SAndroid Build Coastguard Worker 		}
4197*2d543d20SAndroid Build Coastguard Worker 	}
4198*2d543d20SAndroid Build Coastguard Worker 
4199*2d543d20SAndroid Build Coastguard Worker 	/* Done with policydb_str. */
4200*2d543d20SAndroid Build Coastguard Worker 	free(policydb_str);
4201*2d543d20SAndroid Build Coastguard Worker 	policydb_str = NULL;
4202*2d543d20SAndroid Build Coastguard Worker 
4203*2d543d20SAndroid Build Coastguard Worker 	/* Read the version, config, and table sizes (and policy type if it's a module). */
4204*2d543d20SAndroid Build Coastguard Worker 	if (policy_type == POLICY_KERN)
4205*2d543d20SAndroid Build Coastguard Worker 		nel = 4;
4206*2d543d20SAndroid Build Coastguard Worker 	else
4207*2d543d20SAndroid Build Coastguard Worker 		nel = 5;
4208*2d543d20SAndroid Build Coastguard Worker 
4209*2d543d20SAndroid Build Coastguard Worker 	rc = next_entry(buf, fp, sizeof(uint32_t) * nel);
4210*2d543d20SAndroid Build Coastguard Worker 	if (rc < 0)
4211*2d543d20SAndroid Build Coastguard Worker 		return POLICYDB_ERROR;
4212*2d543d20SAndroid Build Coastguard Worker 	for (i = 0; i < nel; i++)
4213*2d543d20SAndroid Build Coastguard Worker 		buf[i] = le32_to_cpu(buf[i]);
4214*2d543d20SAndroid Build Coastguard Worker 
4215*2d543d20SAndroid Build Coastguard Worker 	bufindex = 0;
4216*2d543d20SAndroid Build Coastguard Worker 
4217*2d543d20SAndroid Build Coastguard Worker 	if (policy_type == POLICY_MOD) {
4218*2d543d20SAndroid Build Coastguard Worker 		/* We know it's a module but not whether it's a base
4219*2d543d20SAndroid Build Coastguard Worker 		   module or regular binary policy module.  buf[0]
4220*2d543d20SAndroid Build Coastguard Worker 		   tells us which. */
4221*2d543d20SAndroid Build Coastguard Worker 		policy_type = buf[bufindex];
4222*2d543d20SAndroid Build Coastguard Worker 		if (policy_type != POLICY_MOD && policy_type != POLICY_BASE) {
4223*2d543d20SAndroid Build Coastguard Worker 			ERR(fp->handle, "unknown module type: %#08x",
4224*2d543d20SAndroid Build Coastguard Worker 			    policy_type);
4225*2d543d20SAndroid Build Coastguard Worker 			return POLICYDB_ERROR;
4226*2d543d20SAndroid Build Coastguard Worker 		}
4227*2d543d20SAndroid Build Coastguard Worker 		bufindex++;
4228*2d543d20SAndroid Build Coastguard Worker 	}
4229*2d543d20SAndroid Build Coastguard Worker 
4230*2d543d20SAndroid Build Coastguard Worker 	r_policyvers = buf[bufindex];
4231*2d543d20SAndroid Build Coastguard Worker 	if (policy_type == POLICY_KERN) {
4232*2d543d20SAndroid Build Coastguard Worker 		if (r_policyvers < POLICYDB_VERSION_MIN ||
4233*2d543d20SAndroid Build Coastguard Worker 		    r_policyvers > POLICYDB_VERSION_MAX) {
4234*2d543d20SAndroid Build Coastguard Worker 			ERR(fp->handle, "policydb version %d does not match "
4235*2d543d20SAndroid Build Coastguard Worker 			    "my version range %d-%d", buf[bufindex],
4236*2d543d20SAndroid Build Coastguard Worker 			    POLICYDB_VERSION_MIN, POLICYDB_VERSION_MAX);
4237*2d543d20SAndroid Build Coastguard Worker 			return POLICYDB_ERROR;
4238*2d543d20SAndroid Build Coastguard Worker 		}
4239*2d543d20SAndroid Build Coastguard Worker 	} else if (policy_type == POLICY_BASE || policy_type == POLICY_MOD) {
4240*2d543d20SAndroid Build Coastguard Worker 		if (r_policyvers < MOD_POLICYDB_VERSION_MIN ||
4241*2d543d20SAndroid Build Coastguard Worker 		    r_policyvers > MOD_POLICYDB_VERSION_MAX) {
4242*2d543d20SAndroid Build Coastguard Worker 			ERR(fp->handle, "policydb module version %d does "
4243*2d543d20SAndroid Build Coastguard Worker 			    "not match my version range %d-%d",
4244*2d543d20SAndroid Build Coastguard Worker 			    buf[bufindex], MOD_POLICYDB_VERSION_MIN,
4245*2d543d20SAndroid Build Coastguard Worker 			    MOD_POLICYDB_VERSION_MAX);
4246*2d543d20SAndroid Build Coastguard Worker 			return POLICYDB_ERROR;
4247*2d543d20SAndroid Build Coastguard Worker 		}
4248*2d543d20SAndroid Build Coastguard Worker 	} else {
4249*2d543d20SAndroid Build Coastguard Worker 		assert(0);
4250*2d543d20SAndroid Build Coastguard Worker 	}
4251*2d543d20SAndroid Build Coastguard Worker 	bufindex++;
4252*2d543d20SAndroid Build Coastguard Worker 
4253*2d543d20SAndroid Build Coastguard Worker 	/* Set the policy type and version from the read values. */
4254*2d543d20SAndroid Build Coastguard Worker 	p->policy_type = policy_type;
4255*2d543d20SAndroid Build Coastguard Worker 	p->policyvers = r_policyvers;
4256*2d543d20SAndroid Build Coastguard Worker 
4257*2d543d20SAndroid Build Coastguard Worker 	if (buf[bufindex] & POLICYDB_CONFIG_MLS) {
4258*2d543d20SAndroid Build Coastguard Worker 		p->mls = 1;
4259*2d543d20SAndroid Build Coastguard Worker 	} else {
4260*2d543d20SAndroid Build Coastguard Worker 		p->mls = 0;
4261*2d543d20SAndroid Build Coastguard Worker 	}
4262*2d543d20SAndroid Build Coastguard Worker 
4263*2d543d20SAndroid Build Coastguard Worker 	p->handle_unknown = buf[bufindex] & POLICYDB_CONFIG_UNKNOWN_MASK;
4264*2d543d20SAndroid Build Coastguard Worker 
4265*2d543d20SAndroid Build Coastguard Worker 	bufindex++;
4266*2d543d20SAndroid Build Coastguard Worker 
4267*2d543d20SAndroid Build Coastguard Worker 	info = policydb_lookup_compat(r_policyvers, policy_type,
4268*2d543d20SAndroid Build Coastguard Worker 					p->target_platform);
4269*2d543d20SAndroid Build Coastguard Worker 	if (!info) {
4270*2d543d20SAndroid Build Coastguard Worker 		ERR(fp->handle, "unable to find policy compat info "
4271*2d543d20SAndroid Build Coastguard Worker 		    "for version %d", r_policyvers);
4272*2d543d20SAndroid Build Coastguard Worker 		goto bad;
4273*2d543d20SAndroid Build Coastguard Worker 	}
4274*2d543d20SAndroid Build Coastguard Worker 
4275*2d543d20SAndroid Build Coastguard Worker 	if (buf[bufindex] != info->sym_num
4276*2d543d20SAndroid Build Coastguard Worker 	    || buf[bufindex + 1] != info->ocon_num) {
4277*2d543d20SAndroid Build Coastguard Worker 		ERR(fp->handle,
4278*2d543d20SAndroid Build Coastguard Worker 		    "policydb table sizes (%d,%d) do not " "match mine (%d,%d)",
4279*2d543d20SAndroid Build Coastguard Worker 		    buf[bufindex], buf[bufindex + 1], info->sym_num,
4280*2d543d20SAndroid Build Coastguard Worker 		    info->ocon_num);
4281*2d543d20SAndroid Build Coastguard Worker 		goto bad;
4282*2d543d20SAndroid Build Coastguard Worker 	}
4283*2d543d20SAndroid Build Coastguard Worker 
4284*2d543d20SAndroid Build Coastguard Worker 	if (p->policy_type == POLICY_MOD) {
4285*2d543d20SAndroid Build Coastguard Worker 		/* Get the module name and version */
4286*2d543d20SAndroid Build Coastguard Worker 		if ((rc = next_entry(buf, fp, sizeof(uint32_t))) < 0) {
4287*2d543d20SAndroid Build Coastguard Worker 			goto bad;
4288*2d543d20SAndroid Build Coastguard Worker 		}
4289*2d543d20SAndroid Build Coastguard Worker 		len = le32_to_cpu(buf[0]);
4290*2d543d20SAndroid Build Coastguard Worker 		rc = str_read(&p->name, fp, len);
4291*2d543d20SAndroid Build Coastguard Worker 		if (rc < 0)
4292*2d543d20SAndroid Build Coastguard Worker 			goto bad;
4293*2d543d20SAndroid Build Coastguard Worker 
4294*2d543d20SAndroid Build Coastguard Worker 		if ((rc = next_entry(buf, fp, sizeof(uint32_t))) < 0) {
4295*2d543d20SAndroid Build Coastguard Worker 			goto bad;
4296*2d543d20SAndroid Build Coastguard Worker 		}
4297*2d543d20SAndroid Build Coastguard Worker 		len = le32_to_cpu(buf[0]);
4298*2d543d20SAndroid Build Coastguard Worker 		rc = str_read(&p->version, fp, len);
4299*2d543d20SAndroid Build Coastguard Worker 		if (rc < 0)
4300*2d543d20SAndroid Build Coastguard Worker 			goto bad;
4301*2d543d20SAndroid Build Coastguard Worker 	}
4302*2d543d20SAndroid Build Coastguard Worker 
4303*2d543d20SAndroid Build Coastguard Worker 	if ((p->policyvers >= POLICYDB_VERSION_POLCAP &&
4304*2d543d20SAndroid Build Coastguard Worker 	     p->policy_type == POLICY_KERN) ||
4305*2d543d20SAndroid Build Coastguard Worker 	    (p->policyvers >= MOD_POLICYDB_VERSION_POLCAP &&
4306*2d543d20SAndroid Build Coastguard Worker 	     p->policy_type == POLICY_BASE) ||
4307*2d543d20SAndroid Build Coastguard Worker 	    (p->policyvers >= MOD_POLICYDB_VERSION_POLCAP &&
4308*2d543d20SAndroid Build Coastguard Worker 	     p->policy_type == POLICY_MOD)) {
4309*2d543d20SAndroid Build Coastguard Worker 		if (ebitmap_read(&p->policycaps, fp))
4310*2d543d20SAndroid Build Coastguard Worker 			goto bad;
4311*2d543d20SAndroid Build Coastguard Worker 	}
4312*2d543d20SAndroid Build Coastguard Worker 
4313*2d543d20SAndroid Build Coastguard Worker 	if (p->policyvers >= POLICYDB_VERSION_PERMISSIVE &&
4314*2d543d20SAndroid Build Coastguard Worker 	    p->policy_type == POLICY_KERN) {
4315*2d543d20SAndroid Build Coastguard Worker 		if (ebitmap_read(&p->permissive_map, fp))
4316*2d543d20SAndroid Build Coastguard Worker 			goto bad;
4317*2d543d20SAndroid Build Coastguard Worker 	}
4318*2d543d20SAndroid Build Coastguard Worker 
4319*2d543d20SAndroid Build Coastguard Worker 	for (i = 0; i < info->sym_num; i++) {
4320*2d543d20SAndroid Build Coastguard Worker 		rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
4321*2d543d20SAndroid Build Coastguard Worker 		if (rc < 0)
4322*2d543d20SAndroid Build Coastguard Worker 			goto bad;
4323*2d543d20SAndroid Build Coastguard Worker 		nprim = le32_to_cpu(buf[0]);
4324*2d543d20SAndroid Build Coastguard Worker 		if (is_saturated(nprim) ||
4325*2d543d20SAndroid Build Coastguard Worker 		    exceeds_available_bytes(fp, nprim, sizeof(uint32_t) * 3))
4326*2d543d20SAndroid Build Coastguard Worker 			goto bad;
4327*2d543d20SAndroid Build Coastguard Worker 		nel = le32_to_cpu(buf[1]);
4328*2d543d20SAndroid Build Coastguard Worker 		if (nel && !nprim) {
4329*2d543d20SAndroid Build Coastguard Worker 			ERR(fp->handle, "unexpected items in symbol table with no symbol");
4330*2d543d20SAndroid Build Coastguard Worker 			goto bad;
4331*2d543d20SAndroid Build Coastguard Worker 		}
4332*2d543d20SAndroid Build Coastguard Worker 		for (j = 0; j < nel; j++) {
4333*2d543d20SAndroid Build Coastguard Worker 			if (read_f[i] (p, p->symtab[i].table, fp))
4334*2d543d20SAndroid Build Coastguard Worker 				goto bad;
4335*2d543d20SAndroid Build Coastguard Worker 		}
4336*2d543d20SAndroid Build Coastguard Worker 
4337*2d543d20SAndroid Build Coastguard Worker 		p->symtab[i].nprim = nprim;
4338*2d543d20SAndroid Build Coastguard Worker 	}
4339*2d543d20SAndroid Build Coastguard Worker 
4340*2d543d20SAndroid Build Coastguard Worker 	switch (p->target_platform) {
4341*2d543d20SAndroid Build Coastguard Worker 	case SEPOL_TARGET_SELINUX:
4342*2d543d20SAndroid Build Coastguard Worker 		p->process_class = policydb_string_to_security_class(p, "process");
4343*2d543d20SAndroid Build Coastguard Worker 		p->dir_class = policydb_string_to_security_class(p, "dir");
4344*2d543d20SAndroid Build Coastguard Worker 		break;
4345*2d543d20SAndroid Build Coastguard Worker 	case SEPOL_TARGET_XEN:
4346*2d543d20SAndroid Build Coastguard Worker 		p->process_class = policydb_string_to_security_class(p, "domain");
4347*2d543d20SAndroid Build Coastguard Worker 		break;
4348*2d543d20SAndroid Build Coastguard Worker 	default:
4349*2d543d20SAndroid Build Coastguard Worker 		break;
4350*2d543d20SAndroid Build Coastguard Worker 	}
4351*2d543d20SAndroid Build Coastguard Worker 
4352*2d543d20SAndroid Build Coastguard Worker 	if (policy_type == POLICY_KERN) {
4353*2d543d20SAndroid Build Coastguard Worker 		if (avtab_read(&p->te_avtab, fp, r_policyvers))
4354*2d543d20SAndroid Build Coastguard Worker 			goto bad;
4355*2d543d20SAndroid Build Coastguard Worker 		if (r_policyvers >= POLICYDB_VERSION_BOOL)
4356*2d543d20SAndroid Build Coastguard Worker 			if (cond_read_list(p, &p->cond_list, fp))
4357*2d543d20SAndroid Build Coastguard Worker 				goto bad;
4358*2d543d20SAndroid Build Coastguard Worker 		if (role_trans_read(p, fp))
4359*2d543d20SAndroid Build Coastguard Worker 			goto bad;
4360*2d543d20SAndroid Build Coastguard Worker 		if (role_allow_read(&p->role_allow, fp))
4361*2d543d20SAndroid Build Coastguard Worker 			goto bad;
4362*2d543d20SAndroid Build Coastguard Worker 		if (r_policyvers >= POLICYDB_VERSION_FILENAME_TRANS &&
4363*2d543d20SAndroid Build Coastguard Worker 		    filename_trans_read(p, fp))
4364*2d543d20SAndroid Build Coastguard Worker 			goto bad;
4365*2d543d20SAndroid Build Coastguard Worker 	} else {
4366*2d543d20SAndroid Build Coastguard Worker 		/* first read the AV rule blocks, then the scope tables */
4367*2d543d20SAndroid Build Coastguard Worker 		avrule_block_destroy(p->global);
4368*2d543d20SAndroid Build Coastguard Worker 		p->global = NULL;
4369*2d543d20SAndroid Build Coastguard Worker 		if (avrule_block_read(p, &p->global, info->sym_num, fp) == -1) {
4370*2d543d20SAndroid Build Coastguard Worker 			goto bad;
4371*2d543d20SAndroid Build Coastguard Worker 		}
4372*2d543d20SAndroid Build Coastguard Worker 		if (p->global == NULL) {
4373*2d543d20SAndroid Build Coastguard Worker 			ERR(fp->handle, "no avrule block in policy");
4374*2d543d20SAndroid Build Coastguard Worker 			goto bad;
4375*2d543d20SAndroid Build Coastguard Worker 		}
4376*2d543d20SAndroid Build Coastguard Worker 		for (i = 0; i < info->sym_num; i++) {
4377*2d543d20SAndroid Build Coastguard Worker 			if ((rc = next_entry(buf, fp, sizeof(uint32_t))) < 0) {
4378*2d543d20SAndroid Build Coastguard Worker 				goto bad;
4379*2d543d20SAndroid Build Coastguard Worker 			}
4380*2d543d20SAndroid Build Coastguard Worker 			nel = le32_to_cpu(buf[0]);
4381*2d543d20SAndroid Build Coastguard Worker 			for (j = 0; j < nel; j++) {
4382*2d543d20SAndroid Build Coastguard Worker 				if (scope_read(p, i, fp))
4383*2d543d20SAndroid Build Coastguard Worker 					goto bad;
4384*2d543d20SAndroid Build Coastguard Worker 			}
4385*2d543d20SAndroid Build Coastguard Worker 		}
4386*2d543d20SAndroid Build Coastguard Worker 
4387*2d543d20SAndroid Build Coastguard Worker 	}
4388*2d543d20SAndroid Build Coastguard Worker 
4389*2d543d20SAndroid Build Coastguard Worker 	if (policydb_index_decls(fp->handle, p))
4390*2d543d20SAndroid Build Coastguard Worker 		goto bad;
4391*2d543d20SAndroid Build Coastguard Worker 
4392*2d543d20SAndroid Build Coastguard Worker 	if (policydb_index_classes(p))
4393*2d543d20SAndroid Build Coastguard Worker 		goto bad;
4394*2d543d20SAndroid Build Coastguard Worker 
4395*2d543d20SAndroid Build Coastguard Worker 	switch (p->target_platform) {
4396*2d543d20SAndroid Build Coastguard Worker 	case SEPOL_TARGET_SELINUX:
4397*2d543d20SAndroid Build Coastguard Worker 		/* fall through */
4398*2d543d20SAndroid Build Coastguard Worker 	case SEPOL_TARGET_XEN:
4399*2d543d20SAndroid Build Coastguard Worker 		p->process_trans = policydb_string_to_av_perm(p, p->process_class,
4400*2d543d20SAndroid Build Coastguard Worker 							      "transition");
4401*2d543d20SAndroid Build Coastguard Worker 		p->process_trans_dyntrans = p->process_trans |
4402*2d543d20SAndroid Build Coastguard Worker 			policydb_string_to_av_perm(p, p->process_class,
4403*2d543d20SAndroid Build Coastguard Worker 						   "dyntransition");
4404*2d543d20SAndroid Build Coastguard Worker 		break;
4405*2d543d20SAndroid Build Coastguard Worker 	default:
4406*2d543d20SAndroid Build Coastguard Worker 		break;
4407*2d543d20SAndroid Build Coastguard Worker 	}
4408*2d543d20SAndroid Build Coastguard Worker 
4409*2d543d20SAndroid Build Coastguard Worker 	if (policydb_index_others(fp->handle, p, verbose))
4410*2d543d20SAndroid Build Coastguard Worker 		goto bad;
4411*2d543d20SAndroid Build Coastguard Worker 
4412*2d543d20SAndroid Build Coastguard Worker 	if (ocontext_read(info, p, fp) == -1) {
4413*2d543d20SAndroid Build Coastguard Worker 		goto bad;
4414*2d543d20SAndroid Build Coastguard Worker 	}
4415*2d543d20SAndroid Build Coastguard Worker 
4416*2d543d20SAndroid Build Coastguard Worker 	if (genfs_read(p, fp) == -1) {
4417*2d543d20SAndroid Build Coastguard Worker 		goto bad;
4418*2d543d20SAndroid Build Coastguard Worker 	}
4419*2d543d20SAndroid Build Coastguard Worker 
4420*2d543d20SAndroid Build Coastguard Worker 	if ((p->policy_type == POLICY_KERN
4421*2d543d20SAndroid Build Coastguard Worker 	     && p->policyvers >= POLICYDB_VERSION_MLS)
4422*2d543d20SAndroid Build Coastguard Worker 	    || (p->policy_type == POLICY_BASE
4423*2d543d20SAndroid Build Coastguard Worker 		&& p->policyvers >= MOD_POLICYDB_VERSION_MLS
4424*2d543d20SAndroid Build Coastguard Worker 		&& p->policyvers < MOD_POLICYDB_VERSION_RANGETRANS)) {
4425*2d543d20SAndroid Build Coastguard Worker 		if (range_read(p, fp)) {
4426*2d543d20SAndroid Build Coastguard Worker 			goto bad;
4427*2d543d20SAndroid Build Coastguard Worker 		}
4428*2d543d20SAndroid Build Coastguard Worker 	}
4429*2d543d20SAndroid Build Coastguard Worker 
4430*2d543d20SAndroid Build Coastguard Worker 	if (policy_type == POLICY_KERN) {
4431*2d543d20SAndroid Build Coastguard Worker 		p->type_attr_map = calloc(p->p_types.nprim, sizeof(ebitmap_t));
4432*2d543d20SAndroid Build Coastguard Worker 		p->attr_type_map = calloc(p->p_types.nprim, sizeof(ebitmap_t));
4433*2d543d20SAndroid Build Coastguard Worker 		if (!p->type_attr_map || !p->attr_type_map)
4434*2d543d20SAndroid Build Coastguard Worker 			goto bad;
4435*2d543d20SAndroid Build Coastguard Worker 		for (i = 0; i < p->p_types.nprim; i++) {
4436*2d543d20SAndroid Build Coastguard Worker 			if (r_policyvers >= POLICYDB_VERSION_AVTAB) {
4437*2d543d20SAndroid Build Coastguard Worker 				if (ebitmap_read(&p->type_attr_map[i], fp))
4438*2d543d20SAndroid Build Coastguard Worker 					goto bad;
4439*2d543d20SAndroid Build Coastguard Worker 				ebitmap_for_each_positive_bit(&p->type_attr_map[i],
4440*2d543d20SAndroid Build Coastguard Worker 							 tnode, j) {
4441*2d543d20SAndroid Build Coastguard Worker 					if (i == j)
4442*2d543d20SAndroid Build Coastguard Worker 						continue;
4443*2d543d20SAndroid Build Coastguard Worker 
4444*2d543d20SAndroid Build Coastguard Worker 					if (j >= p->p_types.nprim)
4445*2d543d20SAndroid Build Coastguard Worker 						goto bad;
4446*2d543d20SAndroid Build Coastguard Worker 
4447*2d543d20SAndroid Build Coastguard Worker 					if (ebitmap_set_bit
4448*2d543d20SAndroid Build Coastguard Worker 					    (&p->attr_type_map[j], i, 1))
4449*2d543d20SAndroid Build Coastguard Worker 						goto bad;
4450*2d543d20SAndroid Build Coastguard Worker 				}
4451*2d543d20SAndroid Build Coastguard Worker 			}
4452*2d543d20SAndroid Build Coastguard Worker 			/* add the type itself as the degenerate case */
4453*2d543d20SAndroid Build Coastguard Worker 			if (p->type_val_to_struct[i] && ebitmap_set_bit(&p->type_attr_map[i], i, 1))
4454*2d543d20SAndroid Build Coastguard Worker 				goto bad;
4455*2d543d20SAndroid Build Coastguard Worker 			if (p->type_val_to_struct[i] && p->type_val_to_struct[i]->flavor != TYPE_ATTRIB) {
4456*2d543d20SAndroid Build Coastguard Worker 				if (ebitmap_set_bit(&p->attr_type_map[i], i, 1))
4457*2d543d20SAndroid Build Coastguard Worker 					goto bad;
4458*2d543d20SAndroid Build Coastguard Worker 			}
4459*2d543d20SAndroid Build Coastguard Worker 		}
4460*2d543d20SAndroid Build Coastguard Worker 	}
4461*2d543d20SAndroid Build Coastguard Worker 
4462*2d543d20SAndroid Build Coastguard Worker 	if (policydb_validate(fp->handle, p))
4463*2d543d20SAndroid Build Coastguard Worker 		goto bad;
4464*2d543d20SAndroid Build Coastguard Worker 
4465*2d543d20SAndroid Build Coastguard Worker 	return POLICYDB_SUCCESS;
4466*2d543d20SAndroid Build Coastguard Worker       bad:
4467*2d543d20SAndroid Build Coastguard Worker 	return POLICYDB_ERROR;
4468*2d543d20SAndroid Build Coastguard Worker }
4469*2d543d20SAndroid Build Coastguard Worker 
policydb_reindex_users(policydb_t * p)4470*2d543d20SAndroid Build Coastguard Worker int policydb_reindex_users(policydb_t * p)
4471*2d543d20SAndroid Build Coastguard Worker {
4472*2d543d20SAndroid Build Coastguard Worker 	unsigned int i = SYM_USERS;
4473*2d543d20SAndroid Build Coastguard Worker 
4474*2d543d20SAndroid Build Coastguard Worker 	if (p->user_val_to_struct)
4475*2d543d20SAndroid Build Coastguard Worker 		free(p->user_val_to_struct);
4476*2d543d20SAndroid Build Coastguard Worker 	if (p->sym_val_to_name[i])
4477*2d543d20SAndroid Build Coastguard Worker 		free(p->sym_val_to_name[i]);
4478*2d543d20SAndroid Build Coastguard Worker 
4479*2d543d20SAndroid Build Coastguard Worker 	p->user_val_to_struct = (user_datum_t **)
4480*2d543d20SAndroid Build Coastguard Worker 	    calloc(p->p_users.nprim, sizeof(user_datum_t *));
4481*2d543d20SAndroid Build Coastguard Worker 	if (!p->user_val_to_struct)
4482*2d543d20SAndroid Build Coastguard Worker 		return -1;
4483*2d543d20SAndroid Build Coastguard Worker 
4484*2d543d20SAndroid Build Coastguard Worker 	p->sym_val_to_name[i] = (char **)
4485*2d543d20SAndroid Build Coastguard Worker 	    calloc(p->symtab[i].nprim, sizeof(char *));
4486*2d543d20SAndroid Build Coastguard Worker 	if (!p->sym_val_to_name[i])
4487*2d543d20SAndroid Build Coastguard Worker 		return -1;
4488*2d543d20SAndroid Build Coastguard Worker 
4489*2d543d20SAndroid Build Coastguard Worker 	if (hashtab_map(p->symtab[i].table, index_f[i], p))
4490*2d543d20SAndroid Build Coastguard Worker 		return -1;
4491*2d543d20SAndroid Build Coastguard Worker 
4492*2d543d20SAndroid Build Coastguard Worker 	/* Expand user roles for context validity checking */
4493*2d543d20SAndroid Build Coastguard Worker 	if (hashtab_map(p->p_users.table, policydb_user_cache, p))
4494*2d543d20SAndroid Build Coastguard Worker 		return -1;
4495*2d543d20SAndroid Build Coastguard Worker 
4496*2d543d20SAndroid Build Coastguard Worker 	return 0;
4497*2d543d20SAndroid Build Coastguard Worker }
4498*2d543d20SAndroid Build Coastguard Worker 
policy_file_init(policy_file_t * pf)4499*2d543d20SAndroid Build Coastguard Worker void policy_file_init(policy_file_t *pf)
4500*2d543d20SAndroid Build Coastguard Worker {
4501*2d543d20SAndroid Build Coastguard Worker 	memset(pf, 0, sizeof(policy_file_t));
4502*2d543d20SAndroid Build Coastguard Worker }
4503*2d543d20SAndroid Build Coastguard Worker 
policydb_set_target_platform(policydb_t * p,int platform)4504*2d543d20SAndroid Build Coastguard Worker int policydb_set_target_platform(policydb_t *p, int platform)
4505*2d543d20SAndroid Build Coastguard Worker {
4506*2d543d20SAndroid Build Coastguard Worker 	if (platform == SEPOL_TARGET_SELINUX)
4507*2d543d20SAndroid Build Coastguard Worker 		p->target_platform = SEPOL_TARGET_SELINUX;
4508*2d543d20SAndroid Build Coastguard Worker 	else if (platform == SEPOL_TARGET_XEN)
4509*2d543d20SAndroid Build Coastguard Worker 		p->target_platform = SEPOL_TARGET_XEN;
4510*2d543d20SAndroid Build Coastguard Worker 	else
4511*2d543d20SAndroid Build Coastguard Worker 		return -1;
4512*2d543d20SAndroid Build Coastguard Worker 
4513*2d543d20SAndroid Build Coastguard Worker 	return 0;
4514*2d543d20SAndroid Build Coastguard Worker }
4515*2d543d20SAndroid Build Coastguard Worker 
policydb_sort_ocontexts(policydb_t * p)4516*2d543d20SAndroid Build Coastguard Worker int policydb_sort_ocontexts(policydb_t *p)
4517*2d543d20SAndroid Build Coastguard Worker {
4518*2d543d20SAndroid Build Coastguard Worker 	return sort_ocontexts(p);
4519*2d543d20SAndroid Build Coastguard Worker }
4520