1*2d543d20SAndroid Build Coastguard Worker /* Author: Jason Tang <[email protected]>
2*2d543d20SAndroid Build Coastguard Worker * Christopher Ashworth <[email protected]>
3*2d543d20SAndroid Build Coastguard Worker *
4*2d543d20SAndroid Build Coastguard Worker * Copyright (C) 2004-2006 Tresys Technology, LLC
5*2d543d20SAndroid Build Coastguard Worker * Copyright (C) 2005 Red Hat, Inc.
6*2d543d20SAndroid Build Coastguard Worker *
7*2d543d20SAndroid Build Coastguard Worker * This library is free software; you can redistribute it and/or
8*2d543d20SAndroid Build Coastguard Worker * modify it under the terms of the GNU Lesser General Public
9*2d543d20SAndroid Build Coastguard Worker * License as published by the Free Software Foundation; either
10*2d543d20SAndroid Build Coastguard Worker * version 2.1 of the License, or (at your option) any later version.
11*2d543d20SAndroid Build Coastguard Worker *
12*2d543d20SAndroid Build Coastguard Worker * This library is distributed in the hope that it will be useful,
13*2d543d20SAndroid Build Coastguard Worker * but WITHOUT ANY WARRANTY; without even the implied warranty of
14*2d543d20SAndroid Build Coastguard Worker * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15*2d543d20SAndroid Build Coastguard Worker * Lesser General Public License for more details.
16*2d543d20SAndroid Build Coastguard Worker *
17*2d543d20SAndroid Build Coastguard Worker * You should have received a copy of the GNU Lesser General Public
18*2d543d20SAndroid Build Coastguard Worker * License along with this library; if not, write to the Free Software
19*2d543d20SAndroid Build Coastguard Worker * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20*2d543d20SAndroid Build Coastguard Worker */
21*2d543d20SAndroid Build Coastguard Worker
22*2d543d20SAndroid Build Coastguard Worker #include <sepol/module.h>
23*2d543d20SAndroid Build Coastguard Worker #include <sepol/handle.h>
24*2d543d20SAndroid Build Coastguard Worker #include <sepol/cil/cil.h>
25*2d543d20SAndroid Build Coastguard Worker #include <selinux/selinux.h>
26*2d543d20SAndroid Build Coastguard Worker
27*2d543d20SAndroid Build Coastguard Worker #include <assert.h>
28*2d543d20SAndroid Build Coastguard Worker #include <fcntl.h>
29*2d543d20SAndroid Build Coastguard Worker #include <stdio.h>
30*2d543d20SAndroid Build Coastguard Worker #include <stdio_ext.h>
31*2d543d20SAndroid Build Coastguard Worker #include <stdlib.h>
32*2d543d20SAndroid Build Coastguard Worker #include <string.h>
33*2d543d20SAndroid Build Coastguard Worker #include <unistd.h>
34*2d543d20SAndroid Build Coastguard Worker #include <sys/stat.h>
35*2d543d20SAndroid Build Coastguard Worker #include <sys/types.h>
36*2d543d20SAndroid Build Coastguard Worker #include <sys/mman.h>
37*2d543d20SAndroid Build Coastguard Worker #include <sys/wait.h>
38*2d543d20SAndroid Build Coastguard Worker #include <limits.h>
39*2d543d20SAndroid Build Coastguard Worker #include <errno.h>
40*2d543d20SAndroid Build Coastguard Worker #include <dirent.h>
41*2d543d20SAndroid Build Coastguard Worker
42*2d543d20SAndroid Build Coastguard Worker #include "user_internal.h"
43*2d543d20SAndroid Build Coastguard Worker #include "seuser_internal.h"
44*2d543d20SAndroid Build Coastguard Worker #include "port_internal.h"
45*2d543d20SAndroid Build Coastguard Worker #include "ibpkey_internal.h"
46*2d543d20SAndroid Build Coastguard Worker #include "ibendport_internal.h"
47*2d543d20SAndroid Build Coastguard Worker #include "iface_internal.h"
48*2d543d20SAndroid Build Coastguard Worker #include "boolean_internal.h"
49*2d543d20SAndroid Build Coastguard Worker #include "fcontext_internal.h"
50*2d543d20SAndroid Build Coastguard Worker #include "node_internal.h"
51*2d543d20SAndroid Build Coastguard Worker #include "genhomedircon.h"
52*2d543d20SAndroid Build Coastguard Worker
53*2d543d20SAndroid Build Coastguard Worker #include "debug.h"
54*2d543d20SAndroid Build Coastguard Worker #include "handle.h"
55*2d543d20SAndroid Build Coastguard Worker #include "compressed_file.h"
56*2d543d20SAndroid Build Coastguard Worker #include "modules.h"
57*2d543d20SAndroid Build Coastguard Worker #include "direct_api.h"
58*2d543d20SAndroid Build Coastguard Worker #include "semanage_store.h"
59*2d543d20SAndroid Build Coastguard Worker #include "database_policydb.h"
60*2d543d20SAndroid Build Coastguard Worker #include "policy.h"
61*2d543d20SAndroid Build Coastguard Worker #include "sha256.h"
62*2d543d20SAndroid Build Coastguard Worker
63*2d543d20SAndroid Build Coastguard Worker #define PIPE_READ 0
64*2d543d20SAndroid Build Coastguard Worker #define PIPE_WRITE 1
65*2d543d20SAndroid Build Coastguard Worker #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
66*2d543d20SAndroid Build Coastguard Worker
67*2d543d20SAndroid Build Coastguard Worker static void semanage_direct_destroy(semanage_handle_t * sh);
68*2d543d20SAndroid Build Coastguard Worker static int semanage_direct_disconnect(semanage_handle_t * sh);
69*2d543d20SAndroid Build Coastguard Worker static int semanage_direct_begintrans(semanage_handle_t * sh);
70*2d543d20SAndroid Build Coastguard Worker static int semanage_direct_commit(semanage_handle_t * sh);
71*2d543d20SAndroid Build Coastguard Worker static int semanage_direct_install(semanage_handle_t * sh, char *data,
72*2d543d20SAndroid Build Coastguard Worker size_t data_len, const char *module_name, const char *lang_ext);
73*2d543d20SAndroid Build Coastguard Worker static int semanage_direct_install_file(semanage_handle_t * sh, const char *module_name);
74*2d543d20SAndroid Build Coastguard Worker static int semanage_direct_extract(semanage_handle_t * sh,
75*2d543d20SAndroid Build Coastguard Worker semanage_module_key_t *modkey,
76*2d543d20SAndroid Build Coastguard Worker int extract_cil,
77*2d543d20SAndroid Build Coastguard Worker void **mapped_data,
78*2d543d20SAndroid Build Coastguard Worker size_t *data_len,
79*2d543d20SAndroid Build Coastguard Worker semanage_module_info_t **modinfo);
80*2d543d20SAndroid Build Coastguard Worker static int semanage_direct_remove(semanage_handle_t * sh, char *module_name);
81*2d543d20SAndroid Build Coastguard Worker static int semanage_direct_list(semanage_handle_t * sh,
82*2d543d20SAndroid Build Coastguard Worker semanage_module_info_t ** modinfo,
83*2d543d20SAndroid Build Coastguard Worker int *num_modules);
84*2d543d20SAndroid Build Coastguard Worker static int semanage_direct_get_enabled(semanage_handle_t *sh,
85*2d543d20SAndroid Build Coastguard Worker const semanage_module_key_t *modkey,
86*2d543d20SAndroid Build Coastguard Worker int *enabled);
87*2d543d20SAndroid Build Coastguard Worker static int semanage_direct_set_enabled(semanage_handle_t *sh,
88*2d543d20SAndroid Build Coastguard Worker const semanage_module_key_t *modkey,
89*2d543d20SAndroid Build Coastguard Worker int enabled);
90*2d543d20SAndroid Build Coastguard Worker
91*2d543d20SAndroid Build Coastguard Worker static int semanage_direct_get_module_info(semanage_handle_t *sh,
92*2d543d20SAndroid Build Coastguard Worker const semanage_module_key_t *modkey,
93*2d543d20SAndroid Build Coastguard Worker semanage_module_info_t **modinfo);
94*2d543d20SAndroid Build Coastguard Worker
95*2d543d20SAndroid Build Coastguard Worker static int semanage_direct_list_all(semanage_handle_t *sh,
96*2d543d20SAndroid Build Coastguard Worker semanage_module_info_t **modinfo,
97*2d543d20SAndroid Build Coastguard Worker int *num_modules);
98*2d543d20SAndroid Build Coastguard Worker
99*2d543d20SAndroid Build Coastguard Worker static int semanage_direct_install_info(semanage_handle_t *sh,
100*2d543d20SAndroid Build Coastguard Worker const semanage_module_info_t *modinfo,
101*2d543d20SAndroid Build Coastguard Worker char *data,
102*2d543d20SAndroid Build Coastguard Worker size_t data_len);
103*2d543d20SAndroid Build Coastguard Worker
104*2d543d20SAndroid Build Coastguard Worker static int semanage_direct_remove_key(semanage_handle_t *sh,
105*2d543d20SAndroid Build Coastguard Worker const semanage_module_key_t *modkey);
106*2d543d20SAndroid Build Coastguard Worker
107*2d543d20SAndroid Build Coastguard Worker static struct semanage_policy_table direct_funcs = {
108*2d543d20SAndroid Build Coastguard Worker .get_serial = semanage_direct_get_serial,
109*2d543d20SAndroid Build Coastguard Worker .destroy = semanage_direct_destroy,
110*2d543d20SAndroid Build Coastguard Worker .disconnect = semanage_direct_disconnect,
111*2d543d20SAndroid Build Coastguard Worker .begin_trans = semanage_direct_begintrans,
112*2d543d20SAndroid Build Coastguard Worker .commit = semanage_direct_commit,
113*2d543d20SAndroid Build Coastguard Worker .install = semanage_direct_install,
114*2d543d20SAndroid Build Coastguard Worker .extract = semanage_direct_extract,
115*2d543d20SAndroid Build Coastguard Worker .install_file = semanage_direct_install_file,
116*2d543d20SAndroid Build Coastguard Worker .remove = semanage_direct_remove,
117*2d543d20SAndroid Build Coastguard Worker .list = semanage_direct_list,
118*2d543d20SAndroid Build Coastguard Worker .get_enabled = semanage_direct_get_enabled,
119*2d543d20SAndroid Build Coastguard Worker .set_enabled = semanage_direct_set_enabled,
120*2d543d20SAndroid Build Coastguard Worker .get_module_info = semanage_direct_get_module_info,
121*2d543d20SAndroid Build Coastguard Worker .list_all = semanage_direct_list_all,
122*2d543d20SAndroid Build Coastguard Worker .install_info = semanage_direct_install_info,
123*2d543d20SAndroid Build Coastguard Worker .remove_key = semanage_direct_remove_key,
124*2d543d20SAndroid Build Coastguard Worker };
125*2d543d20SAndroid Build Coastguard Worker
semanage_direct_is_managed(semanage_handle_t * sh)126*2d543d20SAndroid Build Coastguard Worker int semanage_direct_is_managed(semanage_handle_t * sh)
127*2d543d20SAndroid Build Coastguard Worker {
128*2d543d20SAndroid Build Coastguard Worker if (semanage_check_init(sh, sh->conf->store_root_path))
129*2d543d20SAndroid Build Coastguard Worker goto err;
130*2d543d20SAndroid Build Coastguard Worker
131*2d543d20SAndroid Build Coastguard Worker if (semanage_access_check(sh) < 0)
132*2d543d20SAndroid Build Coastguard Worker return 0;
133*2d543d20SAndroid Build Coastguard Worker
134*2d543d20SAndroid Build Coastguard Worker return 1;
135*2d543d20SAndroid Build Coastguard Worker
136*2d543d20SAndroid Build Coastguard Worker err:
137*2d543d20SAndroid Build Coastguard Worker ERR(sh, "could not check whether policy is managed");
138*2d543d20SAndroid Build Coastguard Worker return STATUS_ERR;
139*2d543d20SAndroid Build Coastguard Worker }
140*2d543d20SAndroid Build Coastguard Worker
141*2d543d20SAndroid Build Coastguard Worker /* Check that the module store exists, creating it if necessary.
142*2d543d20SAndroid Build Coastguard Worker */
semanage_direct_connect(semanage_handle_t * sh)143*2d543d20SAndroid Build Coastguard Worker int semanage_direct_connect(semanage_handle_t * sh)
144*2d543d20SAndroid Build Coastguard Worker {
145*2d543d20SAndroid Build Coastguard Worker const char *path;
146*2d543d20SAndroid Build Coastguard Worker struct stat sb;
147*2d543d20SAndroid Build Coastguard Worker
148*2d543d20SAndroid Build Coastguard Worker if (semanage_check_init(sh, sh->conf->store_root_path))
149*2d543d20SAndroid Build Coastguard Worker goto err;
150*2d543d20SAndroid Build Coastguard Worker
151*2d543d20SAndroid Build Coastguard Worker if (sh->create_store)
152*2d543d20SAndroid Build Coastguard Worker if (semanage_create_store(sh, 1))
153*2d543d20SAndroid Build Coastguard Worker goto err;
154*2d543d20SAndroid Build Coastguard Worker
155*2d543d20SAndroid Build Coastguard Worker sh->u.direct.translock_file_fd = -1;
156*2d543d20SAndroid Build Coastguard Worker sh->u.direct.activelock_file_fd = -1;
157*2d543d20SAndroid Build Coastguard Worker
158*2d543d20SAndroid Build Coastguard Worker /* set up function pointers */
159*2d543d20SAndroid Build Coastguard Worker sh->funcs = &direct_funcs;
160*2d543d20SAndroid Build Coastguard Worker
161*2d543d20SAndroid Build Coastguard Worker /* Object databases: local modifications */
162*2d543d20SAndroid Build Coastguard Worker if (user_base_file_dbase_init(sh,
163*2d543d20SAndroid Build Coastguard Worker semanage_path(SEMANAGE_ACTIVE,
164*2d543d20SAndroid Build Coastguard Worker SEMANAGE_USERS_BASE_LOCAL),
165*2d543d20SAndroid Build Coastguard Worker semanage_path(SEMANAGE_TMP,
166*2d543d20SAndroid Build Coastguard Worker SEMANAGE_USERS_BASE_LOCAL),
167*2d543d20SAndroid Build Coastguard Worker semanage_user_base_dbase_local(sh)) < 0)
168*2d543d20SAndroid Build Coastguard Worker goto err;
169*2d543d20SAndroid Build Coastguard Worker
170*2d543d20SAndroid Build Coastguard Worker if (user_extra_file_dbase_init(sh,
171*2d543d20SAndroid Build Coastguard Worker semanage_path(SEMANAGE_ACTIVE,
172*2d543d20SAndroid Build Coastguard Worker SEMANAGE_USERS_EXTRA_LOCAL),
173*2d543d20SAndroid Build Coastguard Worker semanage_path(SEMANAGE_TMP,
174*2d543d20SAndroid Build Coastguard Worker SEMANAGE_USERS_EXTRA_LOCAL),
175*2d543d20SAndroid Build Coastguard Worker semanage_user_extra_dbase_local(sh)) < 0)
176*2d543d20SAndroid Build Coastguard Worker goto err;
177*2d543d20SAndroid Build Coastguard Worker
178*2d543d20SAndroid Build Coastguard Worker if (user_join_dbase_init(sh,
179*2d543d20SAndroid Build Coastguard Worker semanage_user_base_dbase_local(sh),
180*2d543d20SAndroid Build Coastguard Worker semanage_user_extra_dbase_local(sh),
181*2d543d20SAndroid Build Coastguard Worker semanage_user_dbase_local(sh)) < 0)
182*2d543d20SAndroid Build Coastguard Worker goto err;
183*2d543d20SAndroid Build Coastguard Worker
184*2d543d20SAndroid Build Coastguard Worker if (port_file_dbase_init(sh,
185*2d543d20SAndroid Build Coastguard Worker semanage_path(SEMANAGE_ACTIVE,
186*2d543d20SAndroid Build Coastguard Worker SEMANAGE_PORTS_LOCAL),
187*2d543d20SAndroid Build Coastguard Worker semanage_path(SEMANAGE_TMP,
188*2d543d20SAndroid Build Coastguard Worker SEMANAGE_PORTS_LOCAL),
189*2d543d20SAndroid Build Coastguard Worker semanage_port_dbase_local(sh)) < 0)
190*2d543d20SAndroid Build Coastguard Worker goto err;
191*2d543d20SAndroid Build Coastguard Worker
192*2d543d20SAndroid Build Coastguard Worker if (iface_file_dbase_init(sh,
193*2d543d20SAndroid Build Coastguard Worker semanage_path(SEMANAGE_ACTIVE,
194*2d543d20SAndroid Build Coastguard Worker SEMANAGE_INTERFACES_LOCAL),
195*2d543d20SAndroid Build Coastguard Worker semanage_path(SEMANAGE_TMP,
196*2d543d20SAndroid Build Coastguard Worker SEMANAGE_INTERFACES_LOCAL),
197*2d543d20SAndroid Build Coastguard Worker semanage_iface_dbase_local(sh)) < 0)
198*2d543d20SAndroid Build Coastguard Worker goto err;
199*2d543d20SAndroid Build Coastguard Worker
200*2d543d20SAndroid Build Coastguard Worker if (bool_file_dbase_init(sh,
201*2d543d20SAndroid Build Coastguard Worker semanage_path(SEMANAGE_ACTIVE,
202*2d543d20SAndroid Build Coastguard Worker SEMANAGE_BOOLEANS_LOCAL),
203*2d543d20SAndroid Build Coastguard Worker semanage_path(SEMANAGE_TMP,
204*2d543d20SAndroid Build Coastguard Worker SEMANAGE_BOOLEANS_LOCAL),
205*2d543d20SAndroid Build Coastguard Worker semanage_bool_dbase_local(sh)) < 0)
206*2d543d20SAndroid Build Coastguard Worker goto err;
207*2d543d20SAndroid Build Coastguard Worker
208*2d543d20SAndroid Build Coastguard Worker if (fcontext_file_dbase_init(sh,
209*2d543d20SAndroid Build Coastguard Worker semanage_path(SEMANAGE_ACTIVE, SEMANAGE_STORE_FC_LOCAL),
210*2d543d20SAndroid Build Coastguard Worker semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC_LOCAL),
211*2d543d20SAndroid Build Coastguard Worker semanage_fcontext_dbase_local(sh)) < 0)
212*2d543d20SAndroid Build Coastguard Worker goto err;
213*2d543d20SAndroid Build Coastguard Worker
214*2d543d20SAndroid Build Coastguard Worker if (fcontext_file_dbase_init(sh,
215*2d543d20SAndroid Build Coastguard Worker semanage_path(SEMANAGE_ACTIVE, SEMANAGE_STORE_FC_HOMEDIRS),
216*2d543d20SAndroid Build Coastguard Worker semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC_HOMEDIRS),
217*2d543d20SAndroid Build Coastguard Worker semanage_fcontext_dbase_homedirs(sh)) < 0)
218*2d543d20SAndroid Build Coastguard Worker goto err;
219*2d543d20SAndroid Build Coastguard Worker
220*2d543d20SAndroid Build Coastguard Worker if (seuser_file_dbase_init(sh,
221*2d543d20SAndroid Build Coastguard Worker semanage_path(SEMANAGE_ACTIVE,
222*2d543d20SAndroid Build Coastguard Worker SEMANAGE_SEUSERS_LOCAL),
223*2d543d20SAndroid Build Coastguard Worker semanage_path(SEMANAGE_TMP,
224*2d543d20SAndroid Build Coastguard Worker SEMANAGE_SEUSERS_LOCAL),
225*2d543d20SAndroid Build Coastguard Worker semanage_seuser_dbase_local(sh)) < 0)
226*2d543d20SAndroid Build Coastguard Worker goto err;
227*2d543d20SAndroid Build Coastguard Worker
228*2d543d20SAndroid Build Coastguard Worker if (node_file_dbase_init(sh,
229*2d543d20SAndroid Build Coastguard Worker semanage_path(SEMANAGE_ACTIVE,
230*2d543d20SAndroid Build Coastguard Worker SEMANAGE_NODES_LOCAL),
231*2d543d20SAndroid Build Coastguard Worker semanage_path(SEMANAGE_TMP,
232*2d543d20SAndroid Build Coastguard Worker SEMANAGE_NODES_LOCAL),
233*2d543d20SAndroid Build Coastguard Worker semanage_node_dbase_local(sh)) < 0)
234*2d543d20SAndroid Build Coastguard Worker goto err;
235*2d543d20SAndroid Build Coastguard Worker
236*2d543d20SAndroid Build Coastguard Worker if (ibpkey_file_dbase_init(sh,
237*2d543d20SAndroid Build Coastguard Worker semanage_path(SEMANAGE_ACTIVE,
238*2d543d20SAndroid Build Coastguard Worker SEMANAGE_IBPKEYS_LOCAL),
239*2d543d20SAndroid Build Coastguard Worker semanage_path(SEMANAGE_TMP,
240*2d543d20SAndroid Build Coastguard Worker SEMANAGE_IBPKEYS_LOCAL),
241*2d543d20SAndroid Build Coastguard Worker semanage_ibpkey_dbase_local(sh)) < 0)
242*2d543d20SAndroid Build Coastguard Worker goto err;
243*2d543d20SAndroid Build Coastguard Worker
244*2d543d20SAndroid Build Coastguard Worker if (ibendport_file_dbase_init(sh,
245*2d543d20SAndroid Build Coastguard Worker semanage_path(SEMANAGE_ACTIVE,
246*2d543d20SAndroid Build Coastguard Worker SEMANAGE_IBENDPORTS_LOCAL),
247*2d543d20SAndroid Build Coastguard Worker semanage_path(SEMANAGE_TMP,
248*2d543d20SAndroid Build Coastguard Worker SEMANAGE_IBENDPORTS_LOCAL),
249*2d543d20SAndroid Build Coastguard Worker semanage_ibendport_dbase_local(sh)) < 0)
250*2d543d20SAndroid Build Coastguard Worker goto err;
251*2d543d20SAndroid Build Coastguard Worker
252*2d543d20SAndroid Build Coastguard Worker /* Object databases: local modifications + policy */
253*2d543d20SAndroid Build Coastguard Worker if (user_base_policydb_dbase_init(sh,
254*2d543d20SAndroid Build Coastguard Worker semanage_user_base_dbase_policy(sh)) <
255*2d543d20SAndroid Build Coastguard Worker 0)
256*2d543d20SAndroid Build Coastguard Worker goto err;
257*2d543d20SAndroid Build Coastguard Worker
258*2d543d20SAndroid Build Coastguard Worker if (user_extra_file_dbase_init(sh,
259*2d543d20SAndroid Build Coastguard Worker semanage_path(SEMANAGE_ACTIVE,
260*2d543d20SAndroid Build Coastguard Worker SEMANAGE_USERS_EXTRA),
261*2d543d20SAndroid Build Coastguard Worker semanage_path(SEMANAGE_TMP,
262*2d543d20SAndroid Build Coastguard Worker SEMANAGE_USERS_EXTRA),
263*2d543d20SAndroid Build Coastguard Worker semanage_user_extra_dbase_policy(sh)) <
264*2d543d20SAndroid Build Coastguard Worker 0)
265*2d543d20SAndroid Build Coastguard Worker goto err;
266*2d543d20SAndroid Build Coastguard Worker
267*2d543d20SAndroid Build Coastguard Worker if (user_join_dbase_init(sh,
268*2d543d20SAndroid Build Coastguard Worker semanage_user_base_dbase_policy(sh),
269*2d543d20SAndroid Build Coastguard Worker semanage_user_extra_dbase_policy(sh),
270*2d543d20SAndroid Build Coastguard Worker semanage_user_dbase_policy(sh)) < 0)
271*2d543d20SAndroid Build Coastguard Worker goto err;
272*2d543d20SAndroid Build Coastguard Worker
273*2d543d20SAndroid Build Coastguard Worker if (port_policydb_dbase_init(sh, semanage_port_dbase_policy(sh)) < 0)
274*2d543d20SAndroid Build Coastguard Worker goto err;
275*2d543d20SAndroid Build Coastguard Worker
276*2d543d20SAndroid Build Coastguard Worker if (ibpkey_policydb_dbase_init(sh, semanage_ibpkey_dbase_policy(sh)) < 0)
277*2d543d20SAndroid Build Coastguard Worker goto err;
278*2d543d20SAndroid Build Coastguard Worker
279*2d543d20SAndroid Build Coastguard Worker if (ibendport_policydb_dbase_init(sh, semanage_ibendport_dbase_policy(sh)) < 0)
280*2d543d20SAndroid Build Coastguard Worker goto err;
281*2d543d20SAndroid Build Coastguard Worker
282*2d543d20SAndroid Build Coastguard Worker if (iface_policydb_dbase_init(sh, semanage_iface_dbase_policy(sh)) < 0)
283*2d543d20SAndroid Build Coastguard Worker goto err;
284*2d543d20SAndroid Build Coastguard Worker
285*2d543d20SAndroid Build Coastguard Worker if (bool_policydb_dbase_init(sh, semanage_bool_dbase_policy(sh)) < 0)
286*2d543d20SAndroid Build Coastguard Worker goto err;
287*2d543d20SAndroid Build Coastguard Worker
288*2d543d20SAndroid Build Coastguard Worker if (fcontext_file_dbase_init(sh,
289*2d543d20SAndroid Build Coastguard Worker semanage_path(SEMANAGE_ACTIVE, SEMANAGE_STORE_FC),
290*2d543d20SAndroid Build Coastguard Worker semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC),
291*2d543d20SAndroid Build Coastguard Worker semanage_fcontext_dbase_policy(sh)) < 0)
292*2d543d20SAndroid Build Coastguard Worker goto err;
293*2d543d20SAndroid Build Coastguard Worker
294*2d543d20SAndroid Build Coastguard Worker if (seuser_file_dbase_init(sh,
295*2d543d20SAndroid Build Coastguard Worker semanage_path(SEMANAGE_ACTIVE, SEMANAGE_STORE_SEUSERS),
296*2d543d20SAndroid Build Coastguard Worker semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_SEUSERS),
297*2d543d20SAndroid Build Coastguard Worker semanage_seuser_dbase_policy(sh)) < 0)
298*2d543d20SAndroid Build Coastguard Worker goto err;
299*2d543d20SAndroid Build Coastguard Worker
300*2d543d20SAndroid Build Coastguard Worker if (node_policydb_dbase_init(sh, semanage_node_dbase_policy(sh)) < 0)
301*2d543d20SAndroid Build Coastguard Worker goto err;
302*2d543d20SAndroid Build Coastguard Worker
303*2d543d20SAndroid Build Coastguard Worker /* Active kernel policy */
304*2d543d20SAndroid Build Coastguard Worker if (bool_activedb_dbase_init(sh, semanage_bool_dbase_active(sh)) < 0)
305*2d543d20SAndroid Build Coastguard Worker goto err;
306*2d543d20SAndroid Build Coastguard Worker
307*2d543d20SAndroid Build Coastguard Worker /* set the disable dontaudit value */
308*2d543d20SAndroid Build Coastguard Worker path = semanage_path(SEMANAGE_ACTIVE, SEMANAGE_DISABLE_DONTAUDIT);
309*2d543d20SAndroid Build Coastguard Worker
310*2d543d20SAndroid Build Coastguard Worker if (stat(path, &sb) == 0)
311*2d543d20SAndroid Build Coastguard Worker sepol_set_disable_dontaudit(sh->sepolh, 1);
312*2d543d20SAndroid Build Coastguard Worker else if (errno == ENOENT) {
313*2d543d20SAndroid Build Coastguard Worker /* The file does not exist */
314*2d543d20SAndroid Build Coastguard Worker sepol_set_disable_dontaudit(sh->sepolh, 0);
315*2d543d20SAndroid Build Coastguard Worker } else {
316*2d543d20SAndroid Build Coastguard Worker ERR(sh, "Unable to access %s: %s\n", path, strerror(errno));
317*2d543d20SAndroid Build Coastguard Worker goto err;
318*2d543d20SAndroid Build Coastguard Worker }
319*2d543d20SAndroid Build Coastguard Worker
320*2d543d20SAndroid Build Coastguard Worker return STATUS_SUCCESS;
321*2d543d20SAndroid Build Coastguard Worker
322*2d543d20SAndroid Build Coastguard Worker err:
323*2d543d20SAndroid Build Coastguard Worker ERR(sh, "could not establish direct connection");
324*2d543d20SAndroid Build Coastguard Worker return STATUS_ERR;
325*2d543d20SAndroid Build Coastguard Worker }
326*2d543d20SAndroid Build Coastguard Worker
semanage_direct_destroy(semanage_handle_t * sh)327*2d543d20SAndroid Build Coastguard Worker static void semanage_direct_destroy(semanage_handle_t * sh
328*2d543d20SAndroid Build Coastguard Worker __attribute__ ((unused)))
329*2d543d20SAndroid Build Coastguard Worker {
330*2d543d20SAndroid Build Coastguard Worker /* do nothing */
331*2d543d20SAndroid Build Coastguard Worker }
332*2d543d20SAndroid Build Coastguard Worker
semanage_remove_tmps(semanage_handle_t * sh)333*2d543d20SAndroid Build Coastguard Worker static int semanage_remove_tmps(semanage_handle_t *sh)
334*2d543d20SAndroid Build Coastguard Worker {
335*2d543d20SAndroid Build Coastguard Worker if (sh->commit_err)
336*2d543d20SAndroid Build Coastguard Worker return 0;
337*2d543d20SAndroid Build Coastguard Worker
338*2d543d20SAndroid Build Coastguard Worker /* destroy sandbox if it exists */
339*2d543d20SAndroid Build Coastguard Worker if (semanage_remove_directory
340*2d543d20SAndroid Build Coastguard Worker (semanage_path(SEMANAGE_TMP, SEMANAGE_TOPLEVEL)) < 0) {
341*2d543d20SAndroid Build Coastguard Worker if (errno != ENOENT) {
342*2d543d20SAndroid Build Coastguard Worker ERR(sh, "Could not cleanly remove sandbox %s.",
343*2d543d20SAndroid Build Coastguard Worker semanage_path(SEMANAGE_TMP, SEMANAGE_TOPLEVEL));
344*2d543d20SAndroid Build Coastguard Worker return -1;
345*2d543d20SAndroid Build Coastguard Worker }
346*2d543d20SAndroid Build Coastguard Worker }
347*2d543d20SAndroid Build Coastguard Worker
348*2d543d20SAndroid Build Coastguard Worker /* destroy tmp policy if it exists */
349*2d543d20SAndroid Build Coastguard Worker if (semanage_remove_directory
350*2d543d20SAndroid Build Coastguard Worker (semanage_final_path(SEMANAGE_FINAL_TMP,
351*2d543d20SAndroid Build Coastguard Worker SEMANAGE_FINAL_TOPLEVEL)) < 0) {
352*2d543d20SAndroid Build Coastguard Worker if (errno != ENOENT) {
353*2d543d20SAndroid Build Coastguard Worker ERR(sh, "Could not cleanly remove tmp %s.",
354*2d543d20SAndroid Build Coastguard Worker semanage_final_path(SEMANAGE_FINAL_TMP,
355*2d543d20SAndroid Build Coastguard Worker SEMANAGE_FINAL_TOPLEVEL));
356*2d543d20SAndroid Build Coastguard Worker return -1;
357*2d543d20SAndroid Build Coastguard Worker }
358*2d543d20SAndroid Build Coastguard Worker }
359*2d543d20SAndroid Build Coastguard Worker
360*2d543d20SAndroid Build Coastguard Worker return 0;
361*2d543d20SAndroid Build Coastguard Worker }
362*2d543d20SAndroid Build Coastguard Worker
semanage_direct_disconnect(semanage_handle_t * sh)363*2d543d20SAndroid Build Coastguard Worker static int semanage_direct_disconnect(semanage_handle_t *sh)
364*2d543d20SAndroid Build Coastguard Worker {
365*2d543d20SAndroid Build Coastguard Worker int retval = 0;
366*2d543d20SAndroid Build Coastguard Worker
367*2d543d20SAndroid Build Coastguard Worker /* destroy transaction and remove tmp files if no commit error */
368*2d543d20SAndroid Build Coastguard Worker if (sh->is_in_transaction) {
369*2d543d20SAndroid Build Coastguard Worker retval = semanage_remove_tmps(sh);
370*2d543d20SAndroid Build Coastguard Worker semanage_release_trans_lock(sh);
371*2d543d20SAndroid Build Coastguard Worker }
372*2d543d20SAndroid Build Coastguard Worker
373*2d543d20SAndroid Build Coastguard Worker /* Release object databases: local modifications */
374*2d543d20SAndroid Build Coastguard Worker user_base_file_dbase_release(semanage_user_base_dbase_local(sh));
375*2d543d20SAndroid Build Coastguard Worker user_extra_file_dbase_release(semanage_user_extra_dbase_local(sh));
376*2d543d20SAndroid Build Coastguard Worker user_join_dbase_release(semanage_user_dbase_local(sh));
377*2d543d20SAndroid Build Coastguard Worker port_file_dbase_release(semanage_port_dbase_local(sh));
378*2d543d20SAndroid Build Coastguard Worker ibpkey_file_dbase_release(semanage_ibpkey_dbase_local(sh));
379*2d543d20SAndroid Build Coastguard Worker ibendport_file_dbase_release(semanage_ibendport_dbase_local(sh));
380*2d543d20SAndroid Build Coastguard Worker iface_file_dbase_release(semanage_iface_dbase_local(sh));
381*2d543d20SAndroid Build Coastguard Worker bool_file_dbase_release(semanage_bool_dbase_local(sh));
382*2d543d20SAndroid Build Coastguard Worker fcontext_file_dbase_release(semanage_fcontext_dbase_local(sh));
383*2d543d20SAndroid Build Coastguard Worker fcontext_file_dbase_release(semanage_fcontext_dbase_homedirs(sh));
384*2d543d20SAndroid Build Coastguard Worker seuser_file_dbase_release(semanage_seuser_dbase_local(sh));
385*2d543d20SAndroid Build Coastguard Worker node_file_dbase_release(semanage_node_dbase_local(sh));
386*2d543d20SAndroid Build Coastguard Worker
387*2d543d20SAndroid Build Coastguard Worker /* Release object databases: local modifications + policy */
388*2d543d20SAndroid Build Coastguard Worker user_base_policydb_dbase_release(semanage_user_base_dbase_policy(sh));
389*2d543d20SAndroid Build Coastguard Worker user_extra_file_dbase_release(semanage_user_extra_dbase_policy(sh));
390*2d543d20SAndroid Build Coastguard Worker user_join_dbase_release(semanage_user_dbase_policy(sh));
391*2d543d20SAndroid Build Coastguard Worker port_policydb_dbase_release(semanage_port_dbase_policy(sh));
392*2d543d20SAndroid Build Coastguard Worker ibpkey_policydb_dbase_release(semanage_ibpkey_dbase_policy(sh));
393*2d543d20SAndroid Build Coastguard Worker ibendport_policydb_dbase_release(semanage_ibendport_dbase_policy(sh));
394*2d543d20SAndroid Build Coastguard Worker iface_policydb_dbase_release(semanage_iface_dbase_policy(sh));
395*2d543d20SAndroid Build Coastguard Worker bool_policydb_dbase_release(semanage_bool_dbase_policy(sh));
396*2d543d20SAndroid Build Coastguard Worker fcontext_file_dbase_release(semanage_fcontext_dbase_policy(sh));
397*2d543d20SAndroid Build Coastguard Worker seuser_file_dbase_release(semanage_seuser_dbase_policy(sh));
398*2d543d20SAndroid Build Coastguard Worker node_policydb_dbase_release(semanage_node_dbase_policy(sh));
399*2d543d20SAndroid Build Coastguard Worker
400*2d543d20SAndroid Build Coastguard Worker /* Release object databases: active kernel policy */
401*2d543d20SAndroid Build Coastguard Worker bool_activedb_dbase_release(semanage_bool_dbase_active(sh));
402*2d543d20SAndroid Build Coastguard Worker
403*2d543d20SAndroid Build Coastguard Worker return retval;
404*2d543d20SAndroid Build Coastguard Worker }
405*2d543d20SAndroid Build Coastguard Worker
semanage_direct_begintrans(semanage_handle_t * sh)406*2d543d20SAndroid Build Coastguard Worker static int semanage_direct_begintrans(semanage_handle_t * sh)
407*2d543d20SAndroid Build Coastguard Worker {
408*2d543d20SAndroid Build Coastguard Worker if (semanage_get_trans_lock(sh) < 0) {
409*2d543d20SAndroid Build Coastguard Worker return -1;
410*2d543d20SAndroid Build Coastguard Worker }
411*2d543d20SAndroid Build Coastguard Worker if ((semanage_make_sandbox(sh)) < 0) {
412*2d543d20SAndroid Build Coastguard Worker return -1;
413*2d543d20SAndroid Build Coastguard Worker }
414*2d543d20SAndroid Build Coastguard Worker if ((semanage_make_final(sh)) < 0) {
415*2d543d20SAndroid Build Coastguard Worker return -1;
416*2d543d20SAndroid Build Coastguard Worker }
417*2d543d20SAndroid Build Coastguard Worker return 0;
418*2d543d20SAndroid Build Coastguard Worker }
419*2d543d20SAndroid Build Coastguard Worker
420*2d543d20SAndroid Build Coastguard Worker /********************* utility functions *********************/
421*2d543d20SAndroid Build Coastguard Worker
422*2d543d20SAndroid Build Coastguard Worker /* Takes a module stored in 'module_data' and parses its headers.
423*2d543d20SAndroid Build Coastguard Worker * Sets reference variables 'module_name' to module's name, and
424*2d543d20SAndroid Build Coastguard Worker * 'version' to module's version. The caller is responsible for
425*2d543d20SAndroid Build Coastguard Worker * free()ing 'module_name', and 'version'; they will be
426*2d543d20SAndroid Build Coastguard Worker * set to NULL upon entering this function. Returns 0 on success, -1
427*2d543d20SAndroid Build Coastguard Worker * if out of memory.
428*2d543d20SAndroid Build Coastguard Worker */
parse_module_headers(semanage_handle_t * sh,char * module_data,size_t data_len,char ** module_name,char ** version)429*2d543d20SAndroid Build Coastguard Worker static int parse_module_headers(semanage_handle_t * sh, char *module_data,
430*2d543d20SAndroid Build Coastguard Worker size_t data_len, char **module_name,
431*2d543d20SAndroid Build Coastguard Worker char **version)
432*2d543d20SAndroid Build Coastguard Worker {
433*2d543d20SAndroid Build Coastguard Worker struct sepol_policy_file *pf;
434*2d543d20SAndroid Build Coastguard Worker int file_type;
435*2d543d20SAndroid Build Coastguard Worker *module_name = *version = NULL;
436*2d543d20SAndroid Build Coastguard Worker
437*2d543d20SAndroid Build Coastguard Worker if (sepol_policy_file_create(&pf)) {
438*2d543d20SAndroid Build Coastguard Worker ERR(sh, "Out of memory!");
439*2d543d20SAndroid Build Coastguard Worker return -1;
440*2d543d20SAndroid Build Coastguard Worker }
441*2d543d20SAndroid Build Coastguard Worker sepol_policy_file_set_mem(pf, module_data, data_len);
442*2d543d20SAndroid Build Coastguard Worker sepol_policy_file_set_handle(pf, sh->sepolh);
443*2d543d20SAndroid Build Coastguard Worker if (module_data != NULL && data_len > 0)
444*2d543d20SAndroid Build Coastguard Worker sepol_module_package_info(pf, &file_type, module_name,
445*2d543d20SAndroid Build Coastguard Worker version);
446*2d543d20SAndroid Build Coastguard Worker sepol_policy_file_free(pf);
447*2d543d20SAndroid Build Coastguard Worker
448*2d543d20SAndroid Build Coastguard Worker return 0;
449*2d543d20SAndroid Build Coastguard Worker }
450*2d543d20SAndroid Build Coastguard Worker
451*2d543d20SAndroid Build Coastguard Worker /* Writes a block of data to a file. Returns 0 on success, -1 on
452*2d543d20SAndroid Build Coastguard Worker * error. */
write_file(semanage_handle_t * sh,const char * filename,const char * data,size_t num_bytes)453*2d543d20SAndroid Build Coastguard Worker static int write_file(semanage_handle_t * sh,
454*2d543d20SAndroid Build Coastguard Worker const char *filename, const char *data, size_t num_bytes)
455*2d543d20SAndroid Build Coastguard Worker {
456*2d543d20SAndroid Build Coastguard Worker int out;
457*2d543d20SAndroid Build Coastguard Worker
458*2d543d20SAndroid Build Coastguard Worker if ((out =
459*2d543d20SAndroid Build Coastguard Worker open(filename, O_WRONLY | O_CREAT | O_TRUNC,
460*2d543d20SAndroid Build Coastguard Worker S_IRUSR | S_IWUSR)) == -1) {
461*2d543d20SAndroid Build Coastguard Worker ERR(sh, "Could not open %s for writing.", filename);
462*2d543d20SAndroid Build Coastguard Worker return -1;
463*2d543d20SAndroid Build Coastguard Worker }
464*2d543d20SAndroid Build Coastguard Worker if (write(out, data, num_bytes) == -1) {
465*2d543d20SAndroid Build Coastguard Worker ERR(sh, "Error while writing to %s.", filename);
466*2d543d20SAndroid Build Coastguard Worker close(out);
467*2d543d20SAndroid Build Coastguard Worker return -1;
468*2d543d20SAndroid Build Coastguard Worker }
469*2d543d20SAndroid Build Coastguard Worker close(out);
470*2d543d20SAndroid Build Coastguard Worker return 0;
471*2d543d20SAndroid Build Coastguard Worker }
472*2d543d20SAndroid Build Coastguard Worker
semanage_direct_update_user_extra(semanage_handle_t * sh,cil_db_t * cildb)473*2d543d20SAndroid Build Coastguard Worker static int semanage_direct_update_user_extra(semanage_handle_t * sh, cil_db_t *cildb)
474*2d543d20SAndroid Build Coastguard Worker {
475*2d543d20SAndroid Build Coastguard Worker const char *ofilename = NULL;
476*2d543d20SAndroid Build Coastguard Worker int retval = -1;
477*2d543d20SAndroid Build Coastguard Worker char *data = NULL;
478*2d543d20SAndroid Build Coastguard Worker size_t size = 0;
479*2d543d20SAndroid Build Coastguard Worker
480*2d543d20SAndroid Build Coastguard Worker dbase_config_t *pusers_extra = semanage_user_extra_dbase_policy(sh);
481*2d543d20SAndroid Build Coastguard Worker
482*2d543d20SAndroid Build Coastguard Worker retval = cil_userprefixes_to_string(cildb, &data, &size);
483*2d543d20SAndroid Build Coastguard Worker if (retval != SEPOL_OK) {
484*2d543d20SAndroid Build Coastguard Worker goto cleanup;
485*2d543d20SAndroid Build Coastguard Worker }
486*2d543d20SAndroid Build Coastguard Worker
487*2d543d20SAndroid Build Coastguard Worker if (size > 0) {
488*2d543d20SAndroid Build Coastguard Worker /*
489*2d543d20SAndroid Build Coastguard Worker * Write the users_extra entries from CIL modules.
490*2d543d20SAndroid Build Coastguard Worker * This file is used as our baseline when we do not require
491*2d543d20SAndroid Build Coastguard Worker * re-linking.
492*2d543d20SAndroid Build Coastguard Worker */
493*2d543d20SAndroid Build Coastguard Worker ofilename = semanage_path(SEMANAGE_TMP,
494*2d543d20SAndroid Build Coastguard Worker SEMANAGE_USERS_EXTRA_LINKED);
495*2d543d20SAndroid Build Coastguard Worker if (ofilename == NULL) {
496*2d543d20SAndroid Build Coastguard Worker retval = -1;
497*2d543d20SAndroid Build Coastguard Worker goto cleanup;
498*2d543d20SAndroid Build Coastguard Worker }
499*2d543d20SAndroid Build Coastguard Worker retval = write_file(sh, ofilename, data, size);
500*2d543d20SAndroid Build Coastguard Worker if (retval < 0)
501*2d543d20SAndroid Build Coastguard Worker goto cleanup;
502*2d543d20SAndroid Build Coastguard Worker
503*2d543d20SAndroid Build Coastguard Worker /*
504*2d543d20SAndroid Build Coastguard Worker * Write the users_extra file; users_extra.local
505*2d543d20SAndroid Build Coastguard Worker * will be merged into this file.
506*2d543d20SAndroid Build Coastguard Worker */
507*2d543d20SAndroid Build Coastguard Worker ofilename = semanage_path(SEMANAGE_TMP, SEMANAGE_USERS_EXTRA);
508*2d543d20SAndroid Build Coastguard Worker if (ofilename == NULL) {
509*2d543d20SAndroid Build Coastguard Worker retval = -1;
510*2d543d20SAndroid Build Coastguard Worker goto cleanup;
511*2d543d20SAndroid Build Coastguard Worker }
512*2d543d20SAndroid Build Coastguard Worker retval = write_file(sh, ofilename, data, size);
513*2d543d20SAndroid Build Coastguard Worker if (retval < 0)
514*2d543d20SAndroid Build Coastguard Worker goto cleanup;
515*2d543d20SAndroid Build Coastguard Worker
516*2d543d20SAndroid Build Coastguard Worker pusers_extra->dtable->drop_cache(pusers_extra->dbase);
517*2d543d20SAndroid Build Coastguard Worker
518*2d543d20SAndroid Build Coastguard Worker } else {
519*2d543d20SAndroid Build Coastguard Worker retval = pusers_extra->dtable->clear(sh, pusers_extra->dbase);
520*2d543d20SAndroid Build Coastguard Worker }
521*2d543d20SAndroid Build Coastguard Worker
522*2d543d20SAndroid Build Coastguard Worker cleanup:
523*2d543d20SAndroid Build Coastguard Worker free(data);
524*2d543d20SAndroid Build Coastguard Worker
525*2d543d20SAndroid Build Coastguard Worker return retval;
526*2d543d20SAndroid Build Coastguard Worker }
527*2d543d20SAndroid Build Coastguard Worker
semanage_direct_update_seuser(semanage_handle_t * sh,cil_db_t * cildb)528*2d543d20SAndroid Build Coastguard Worker static int semanage_direct_update_seuser(semanage_handle_t * sh, cil_db_t *cildb)
529*2d543d20SAndroid Build Coastguard Worker {
530*2d543d20SAndroid Build Coastguard Worker const char *ofilename = NULL;
531*2d543d20SAndroid Build Coastguard Worker int retval = -1;
532*2d543d20SAndroid Build Coastguard Worker char *data = NULL;
533*2d543d20SAndroid Build Coastguard Worker size_t size = 0;
534*2d543d20SAndroid Build Coastguard Worker
535*2d543d20SAndroid Build Coastguard Worker dbase_config_t *pseusers = semanage_seuser_dbase_policy(sh);
536*2d543d20SAndroid Build Coastguard Worker
537*2d543d20SAndroid Build Coastguard Worker retval = cil_selinuxusers_to_string(cildb, &data, &size);
538*2d543d20SAndroid Build Coastguard Worker if (retval != SEPOL_OK) {
539*2d543d20SAndroid Build Coastguard Worker goto cleanup;
540*2d543d20SAndroid Build Coastguard Worker }
541*2d543d20SAndroid Build Coastguard Worker
542*2d543d20SAndroid Build Coastguard Worker if (size > 0) {
543*2d543d20SAndroid Build Coastguard Worker /*
544*2d543d20SAndroid Build Coastguard Worker * Write the seusers entries from CIL modules.
545*2d543d20SAndroid Build Coastguard Worker * This file is used as our baseline when we do not require
546*2d543d20SAndroid Build Coastguard Worker * re-linking.
547*2d543d20SAndroid Build Coastguard Worker */
548*2d543d20SAndroid Build Coastguard Worker ofilename = semanage_path(SEMANAGE_TMP,
549*2d543d20SAndroid Build Coastguard Worker SEMANAGE_SEUSERS_LINKED);
550*2d543d20SAndroid Build Coastguard Worker if (ofilename == NULL) {
551*2d543d20SAndroid Build Coastguard Worker retval = -1;
552*2d543d20SAndroid Build Coastguard Worker goto cleanup;
553*2d543d20SAndroid Build Coastguard Worker }
554*2d543d20SAndroid Build Coastguard Worker retval = write_file(sh, ofilename, data, size);
555*2d543d20SAndroid Build Coastguard Worker if (retval < 0)
556*2d543d20SAndroid Build Coastguard Worker goto cleanup;
557*2d543d20SAndroid Build Coastguard Worker
558*2d543d20SAndroid Build Coastguard Worker /*
559*2d543d20SAndroid Build Coastguard Worker * Write the seusers file; seusers.local will be merged into
560*2d543d20SAndroid Build Coastguard Worker * this file.
561*2d543d20SAndroid Build Coastguard Worker */
562*2d543d20SAndroid Build Coastguard Worker ofilename = semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_SEUSERS);
563*2d543d20SAndroid Build Coastguard Worker if (ofilename == NULL) {
564*2d543d20SAndroid Build Coastguard Worker retval = -1;
565*2d543d20SAndroid Build Coastguard Worker goto cleanup;
566*2d543d20SAndroid Build Coastguard Worker }
567*2d543d20SAndroid Build Coastguard Worker retval = write_file(sh, ofilename, data, size);
568*2d543d20SAndroid Build Coastguard Worker if (retval < 0)
569*2d543d20SAndroid Build Coastguard Worker goto cleanup;
570*2d543d20SAndroid Build Coastguard Worker
571*2d543d20SAndroid Build Coastguard Worker pseusers->dtable->drop_cache(pseusers->dbase);
572*2d543d20SAndroid Build Coastguard Worker } else {
573*2d543d20SAndroid Build Coastguard Worker retval = pseusers->dtable->clear(sh, pseusers->dbase);
574*2d543d20SAndroid Build Coastguard Worker }
575*2d543d20SAndroid Build Coastguard Worker
576*2d543d20SAndroid Build Coastguard Worker cleanup:
577*2d543d20SAndroid Build Coastguard Worker free(data);
578*2d543d20SAndroid Build Coastguard Worker
579*2d543d20SAndroid Build Coastguard Worker return retval;
580*2d543d20SAndroid Build Coastguard Worker }
581*2d543d20SAndroid Build Coastguard Worker
read_from_pipe_to_data(semanage_handle_t * sh,size_t initial_len,int fd,char ** out_data_read,size_t * out_read_len)582*2d543d20SAndroid Build Coastguard Worker static int read_from_pipe_to_data(semanage_handle_t *sh, size_t initial_len, int fd, char **out_data_read, size_t *out_read_len)
583*2d543d20SAndroid Build Coastguard Worker {
584*2d543d20SAndroid Build Coastguard Worker size_t max_len = initial_len;
585*2d543d20SAndroid Build Coastguard Worker ssize_t read_len = 0;
586*2d543d20SAndroid Build Coastguard Worker size_t data_read_len = 0;
587*2d543d20SAndroid Build Coastguard Worker char *data_read = NULL;
588*2d543d20SAndroid Build Coastguard Worker
589*2d543d20SAndroid Build Coastguard Worker if (max_len <= 0) {
590*2d543d20SAndroid Build Coastguard Worker max_len = 1;
591*2d543d20SAndroid Build Coastguard Worker }
592*2d543d20SAndroid Build Coastguard Worker data_read = malloc(max_len * sizeof(*data_read));
593*2d543d20SAndroid Build Coastguard Worker if (data_read == NULL) {
594*2d543d20SAndroid Build Coastguard Worker ERR(sh, "Failed to malloc, out of memory.\n");
595*2d543d20SAndroid Build Coastguard Worker return -1;
596*2d543d20SAndroid Build Coastguard Worker }
597*2d543d20SAndroid Build Coastguard Worker
598*2d543d20SAndroid Build Coastguard Worker while ((read_len = read(fd, data_read + data_read_len, max_len - data_read_len)) > 0) {
599*2d543d20SAndroid Build Coastguard Worker data_read_len += read_len;
600*2d543d20SAndroid Build Coastguard Worker if (data_read_len == max_len) {
601*2d543d20SAndroid Build Coastguard Worker max_len *= 2;
602*2d543d20SAndroid Build Coastguard Worker data_read = realloc(data_read, max_len);
603*2d543d20SAndroid Build Coastguard Worker if (data_read == NULL) {
604*2d543d20SAndroid Build Coastguard Worker ERR(sh, "Failed to realloc, out of memory.\n");
605*2d543d20SAndroid Build Coastguard Worker return -1;
606*2d543d20SAndroid Build Coastguard Worker }
607*2d543d20SAndroid Build Coastguard Worker }
608*2d543d20SAndroid Build Coastguard Worker }
609*2d543d20SAndroid Build Coastguard Worker
610*2d543d20SAndroid Build Coastguard Worker *out_read_len = data_read_len;
611*2d543d20SAndroid Build Coastguard Worker *out_data_read = data_read;
612*2d543d20SAndroid Build Coastguard Worker
613*2d543d20SAndroid Build Coastguard Worker return 0;
614*2d543d20SAndroid Build Coastguard Worker }
615*2d543d20SAndroid Build Coastguard Worker
semanage_pipe_data(semanage_handle_t * sh,char * path,char * in_data,size_t in_data_len,char ** out_data,size_t * out_data_len,char ** err_data,size_t * err_data_len)616*2d543d20SAndroid Build Coastguard Worker static int semanage_pipe_data(semanage_handle_t *sh, char *path, char *in_data, size_t in_data_len, char **out_data, size_t *out_data_len, char **err_data, size_t *err_data_len)
617*2d543d20SAndroid Build Coastguard Worker {
618*2d543d20SAndroid Build Coastguard Worker int input_fd[2] = {-1, -1};
619*2d543d20SAndroid Build Coastguard Worker int output_fd[2] = {-1, -1};
620*2d543d20SAndroid Build Coastguard Worker int err_fd[2] = {-1, -1};
621*2d543d20SAndroid Build Coastguard Worker pid_t pid;
622*2d543d20SAndroid Build Coastguard Worker char *data_read = NULL;
623*2d543d20SAndroid Build Coastguard Worker char *err_data_read = NULL;
624*2d543d20SAndroid Build Coastguard Worker int retval;
625*2d543d20SAndroid Build Coastguard Worker int status = 0;
626*2d543d20SAndroid Build Coastguard Worker size_t initial_len;
627*2d543d20SAndroid Build Coastguard Worker size_t data_read_len = 0;
628*2d543d20SAndroid Build Coastguard Worker size_t err_data_read_len = 0;
629*2d543d20SAndroid Build Coastguard Worker struct sigaction old_signal;
630*2d543d20SAndroid Build Coastguard Worker struct sigaction new_signal;
631*2d543d20SAndroid Build Coastguard Worker new_signal.sa_handler = SIG_IGN;
632*2d543d20SAndroid Build Coastguard Worker sigemptyset(&new_signal.sa_mask);
633*2d543d20SAndroid Build Coastguard Worker new_signal.sa_flags = 0;
634*2d543d20SAndroid Build Coastguard Worker /* This is needed in case the read end of input_fd is closed causing a SIGPIPE signal to be sent.
635*2d543d20SAndroid Build Coastguard Worker * If SIGPIPE is not caught, the signal will cause semanage to terminate immediately. The sigaction below
636*2d543d20SAndroid Build Coastguard Worker * creates a new_signal that ignores SIGPIPE allowing the write to exit cleanly.
637*2d543d20SAndroid Build Coastguard Worker *
638*2d543d20SAndroid Build Coastguard Worker * Another sigaction is called in cleanup to restore the original behavior when a SIGPIPE is received.
639*2d543d20SAndroid Build Coastguard Worker */
640*2d543d20SAndroid Build Coastguard Worker sigaction(SIGPIPE, &new_signal, &old_signal);
641*2d543d20SAndroid Build Coastguard Worker
642*2d543d20SAndroid Build Coastguard Worker retval = pipe(input_fd);
643*2d543d20SAndroid Build Coastguard Worker if (retval == -1) {
644*2d543d20SAndroid Build Coastguard Worker ERR(sh, "Unable to create pipe for input pipe: %s\n", strerror(errno));
645*2d543d20SAndroid Build Coastguard Worker goto cleanup;
646*2d543d20SAndroid Build Coastguard Worker }
647*2d543d20SAndroid Build Coastguard Worker retval = pipe(output_fd);
648*2d543d20SAndroid Build Coastguard Worker if (retval == -1) {
649*2d543d20SAndroid Build Coastguard Worker ERR(sh, "Unable to create pipe for output pipe: %s\n", strerror(errno));
650*2d543d20SAndroid Build Coastguard Worker goto cleanup;
651*2d543d20SAndroid Build Coastguard Worker }
652*2d543d20SAndroid Build Coastguard Worker retval = pipe(err_fd);
653*2d543d20SAndroid Build Coastguard Worker if (retval == -1) {
654*2d543d20SAndroid Build Coastguard Worker ERR(sh, "Unable to create pipe for error pipe: %s\n", strerror(errno));
655*2d543d20SAndroid Build Coastguard Worker goto cleanup;
656*2d543d20SAndroid Build Coastguard Worker }
657*2d543d20SAndroid Build Coastguard Worker
658*2d543d20SAndroid Build Coastguard Worker pid = fork();
659*2d543d20SAndroid Build Coastguard Worker if (pid == -1) {
660*2d543d20SAndroid Build Coastguard Worker ERR(sh, "Unable to fork from parent: %s.", strerror(errno));
661*2d543d20SAndroid Build Coastguard Worker retval = -1;
662*2d543d20SAndroid Build Coastguard Worker goto cleanup;
663*2d543d20SAndroid Build Coastguard Worker } else if (pid == 0) {
664*2d543d20SAndroid Build Coastguard Worker retval = dup2(input_fd[PIPE_READ], STDIN_FILENO);
665*2d543d20SAndroid Build Coastguard Worker if (retval == -1) {
666*2d543d20SAndroid Build Coastguard Worker ERR(sh, "Unable to dup2 input pipe: %s\n", strerror(errno));
667*2d543d20SAndroid Build Coastguard Worker goto cleanup;
668*2d543d20SAndroid Build Coastguard Worker }
669*2d543d20SAndroid Build Coastguard Worker retval = dup2(output_fd[PIPE_WRITE], STDOUT_FILENO);
670*2d543d20SAndroid Build Coastguard Worker if (retval == -1) {
671*2d543d20SAndroid Build Coastguard Worker ERR(sh, "Unable to dup2 output pipe: %s\n", strerror(errno));
672*2d543d20SAndroid Build Coastguard Worker goto cleanup;
673*2d543d20SAndroid Build Coastguard Worker }
674*2d543d20SAndroid Build Coastguard Worker retval = dup2(err_fd[PIPE_WRITE], STDERR_FILENO);
675*2d543d20SAndroid Build Coastguard Worker if (retval == -1) {
676*2d543d20SAndroid Build Coastguard Worker ERR(sh, "Unable to dup2 error pipe: %s\n", strerror(errno));
677*2d543d20SAndroid Build Coastguard Worker goto cleanup;
678*2d543d20SAndroid Build Coastguard Worker }
679*2d543d20SAndroid Build Coastguard Worker
680*2d543d20SAndroid Build Coastguard Worker retval = close(input_fd[PIPE_WRITE]);
681*2d543d20SAndroid Build Coastguard Worker if (retval == -1) {
682*2d543d20SAndroid Build Coastguard Worker ERR(sh, "Unable to close input pipe: %s\n", strerror(errno));
683*2d543d20SAndroid Build Coastguard Worker goto cleanup;
684*2d543d20SAndroid Build Coastguard Worker }
685*2d543d20SAndroid Build Coastguard Worker retval = close(output_fd[PIPE_READ]);
686*2d543d20SAndroid Build Coastguard Worker if (retval == -1) {
687*2d543d20SAndroid Build Coastguard Worker ERR(sh, "Unable to close output pipe: %s\n", strerror(errno));
688*2d543d20SAndroid Build Coastguard Worker goto cleanup;
689*2d543d20SAndroid Build Coastguard Worker }
690*2d543d20SAndroid Build Coastguard Worker retval = close(err_fd[PIPE_READ]);
691*2d543d20SAndroid Build Coastguard Worker if (retval == -1) {
692*2d543d20SAndroid Build Coastguard Worker ERR(sh, "Unable to close error pipe: %s\n", strerror(errno));
693*2d543d20SAndroid Build Coastguard Worker goto cleanup;
694*2d543d20SAndroid Build Coastguard Worker }
695*2d543d20SAndroid Build Coastguard Worker retval = execl(path, path, NULL);
696*2d543d20SAndroid Build Coastguard Worker if (retval == -1) {
697*2d543d20SAndroid Build Coastguard Worker ERR(sh, "Unable to execute %s : %s\n", path, strerror(errno));
698*2d543d20SAndroid Build Coastguard Worker _exit(EXIT_FAILURE);
699*2d543d20SAndroid Build Coastguard Worker }
700*2d543d20SAndroid Build Coastguard Worker } else {
701*2d543d20SAndroid Build Coastguard Worker retval = close(input_fd[PIPE_READ]);
702*2d543d20SAndroid Build Coastguard Worker input_fd[PIPE_READ] = -1;
703*2d543d20SAndroid Build Coastguard Worker if (retval == -1) {
704*2d543d20SAndroid Build Coastguard Worker ERR(sh, "Unable to close read end of input pipe: %s\n", strerror(errno));
705*2d543d20SAndroid Build Coastguard Worker goto cleanup;
706*2d543d20SAndroid Build Coastguard Worker }
707*2d543d20SAndroid Build Coastguard Worker
708*2d543d20SAndroid Build Coastguard Worker retval = close(output_fd[PIPE_WRITE]);
709*2d543d20SAndroid Build Coastguard Worker output_fd[PIPE_WRITE] = -1;
710*2d543d20SAndroid Build Coastguard Worker if (retval == -1) {
711*2d543d20SAndroid Build Coastguard Worker ERR(sh, "Unable to close write end of output pipe: %s\n", strerror(errno));
712*2d543d20SAndroid Build Coastguard Worker goto cleanup;
713*2d543d20SAndroid Build Coastguard Worker }
714*2d543d20SAndroid Build Coastguard Worker
715*2d543d20SAndroid Build Coastguard Worker retval = close(err_fd[PIPE_WRITE]);
716*2d543d20SAndroid Build Coastguard Worker err_fd[PIPE_WRITE] = -1;
717*2d543d20SAndroid Build Coastguard Worker if (retval == -1) {
718*2d543d20SAndroid Build Coastguard Worker ERR(sh, "Unable to close write end of error pipe: %s\n", strerror(errno));
719*2d543d20SAndroid Build Coastguard Worker goto cleanup;
720*2d543d20SAndroid Build Coastguard Worker }
721*2d543d20SAndroid Build Coastguard Worker
722*2d543d20SAndroid Build Coastguard Worker retval = write(input_fd[PIPE_WRITE], in_data, in_data_len);
723*2d543d20SAndroid Build Coastguard Worker if (retval == -1) {
724*2d543d20SAndroid Build Coastguard Worker ERR(sh, "Failed to write data to input pipe: %s\n", strerror(errno));
725*2d543d20SAndroid Build Coastguard Worker goto cleanup;
726*2d543d20SAndroid Build Coastguard Worker }
727*2d543d20SAndroid Build Coastguard Worker retval = close(input_fd[PIPE_WRITE]);
728*2d543d20SAndroid Build Coastguard Worker input_fd[PIPE_WRITE] = -1;
729*2d543d20SAndroid Build Coastguard Worker if (retval == -1) {
730*2d543d20SAndroid Build Coastguard Worker ERR(sh, "Unable to close write end of input pipe: %s\n", strerror(errno));
731*2d543d20SAndroid Build Coastguard Worker goto cleanup;
732*2d543d20SAndroid Build Coastguard Worker }
733*2d543d20SAndroid Build Coastguard Worker
734*2d543d20SAndroid Build Coastguard Worker initial_len = 1 << 17;
735*2d543d20SAndroid Build Coastguard Worker retval = read_from_pipe_to_data(sh, initial_len, output_fd[PIPE_READ], &data_read, &data_read_len);
736*2d543d20SAndroid Build Coastguard Worker if (retval != 0) {
737*2d543d20SAndroid Build Coastguard Worker goto cleanup;
738*2d543d20SAndroid Build Coastguard Worker }
739*2d543d20SAndroid Build Coastguard Worker retval = close(output_fd[PIPE_READ]);
740*2d543d20SAndroid Build Coastguard Worker output_fd[PIPE_READ] = -1;
741*2d543d20SAndroid Build Coastguard Worker if (retval == -1) {
742*2d543d20SAndroid Build Coastguard Worker ERR(sh, "Unable to close read end of output pipe: %s\n", strerror(errno));
743*2d543d20SAndroid Build Coastguard Worker goto cleanup;
744*2d543d20SAndroid Build Coastguard Worker }
745*2d543d20SAndroid Build Coastguard Worker
746*2d543d20SAndroid Build Coastguard Worker initial_len = 1 << 9;
747*2d543d20SAndroid Build Coastguard Worker retval = read_from_pipe_to_data(sh, initial_len, err_fd[PIPE_READ], &err_data_read, &err_data_read_len);
748*2d543d20SAndroid Build Coastguard Worker if (retval != 0) {
749*2d543d20SAndroid Build Coastguard Worker goto cleanup;
750*2d543d20SAndroid Build Coastguard Worker }
751*2d543d20SAndroid Build Coastguard Worker retval = close(err_fd[PIPE_READ]);
752*2d543d20SAndroid Build Coastguard Worker err_fd[PIPE_READ] = -1;
753*2d543d20SAndroid Build Coastguard Worker if (retval == -1) {
754*2d543d20SAndroid Build Coastguard Worker ERR(sh, "Unable to close read end of error pipe: %s\n", strerror(errno));
755*2d543d20SAndroid Build Coastguard Worker goto cleanup;
756*2d543d20SAndroid Build Coastguard Worker }
757*2d543d20SAndroid Build Coastguard Worker
758*2d543d20SAndroid Build Coastguard Worker if (waitpid(pid, &status, 0) == -1 || !WIFEXITED(status)) {
759*2d543d20SAndroid Build Coastguard Worker ERR(sh, "Child process %s did not exit cleanly.", path);
760*2d543d20SAndroid Build Coastguard Worker retval = -1;
761*2d543d20SAndroid Build Coastguard Worker goto cleanup;
762*2d543d20SAndroid Build Coastguard Worker }
763*2d543d20SAndroid Build Coastguard Worker if (WEXITSTATUS(status) != 0) {
764*2d543d20SAndroid Build Coastguard Worker ERR(sh, "Child process %s failed with code: %d.", path, WEXITSTATUS(status));
765*2d543d20SAndroid Build Coastguard Worker retval = -1;
766*2d543d20SAndroid Build Coastguard Worker goto cleanup;
767*2d543d20SAndroid Build Coastguard Worker }
768*2d543d20SAndroid Build Coastguard Worker }
769*2d543d20SAndroid Build Coastguard Worker
770*2d543d20SAndroid Build Coastguard Worker retval = 0;
771*2d543d20SAndroid Build Coastguard Worker
772*2d543d20SAndroid Build Coastguard Worker cleanup:
773*2d543d20SAndroid Build Coastguard Worker sigaction(SIGPIPE, &old_signal, NULL);
774*2d543d20SAndroid Build Coastguard Worker
775*2d543d20SAndroid Build Coastguard Worker if (data_read != NULL) {
776*2d543d20SAndroid Build Coastguard Worker *out_data = data_read;
777*2d543d20SAndroid Build Coastguard Worker *out_data_len = data_read_len;
778*2d543d20SAndroid Build Coastguard Worker }
779*2d543d20SAndroid Build Coastguard Worker
780*2d543d20SAndroid Build Coastguard Worker if (err_data_read != NULL) {
781*2d543d20SAndroid Build Coastguard Worker *err_data = err_data_read;
782*2d543d20SAndroid Build Coastguard Worker *err_data_len = err_data_read_len;
783*2d543d20SAndroid Build Coastguard Worker }
784*2d543d20SAndroid Build Coastguard Worker
785*2d543d20SAndroid Build Coastguard Worker if (output_fd[PIPE_READ] != -1) {
786*2d543d20SAndroid Build Coastguard Worker close(output_fd[PIPE_READ]);
787*2d543d20SAndroid Build Coastguard Worker }
788*2d543d20SAndroid Build Coastguard Worker if (output_fd[PIPE_WRITE] != -1) {
789*2d543d20SAndroid Build Coastguard Worker close(output_fd[PIPE_WRITE]);
790*2d543d20SAndroid Build Coastguard Worker }
791*2d543d20SAndroid Build Coastguard Worker if (err_fd[PIPE_READ] != -1) {
792*2d543d20SAndroid Build Coastguard Worker close(err_fd[PIPE_READ]);
793*2d543d20SAndroid Build Coastguard Worker }
794*2d543d20SAndroid Build Coastguard Worker if (err_fd[PIPE_WRITE] != -1) {
795*2d543d20SAndroid Build Coastguard Worker close(err_fd[PIPE_WRITE]);
796*2d543d20SAndroid Build Coastguard Worker }
797*2d543d20SAndroid Build Coastguard Worker if (input_fd[PIPE_READ] != -1) {
798*2d543d20SAndroid Build Coastguard Worker close(input_fd[PIPE_READ]);
799*2d543d20SAndroid Build Coastguard Worker }
800*2d543d20SAndroid Build Coastguard Worker if (input_fd[PIPE_WRITE] != -1) {
801*2d543d20SAndroid Build Coastguard Worker close(input_fd[PIPE_WRITE]);
802*2d543d20SAndroid Build Coastguard Worker }
803*2d543d20SAndroid Build Coastguard Worker
804*2d543d20SAndroid Build Coastguard Worker return retval;
805*2d543d20SAndroid Build Coastguard Worker }
806*2d543d20SAndroid Build Coastguard Worker
semanage_direct_write_langext(semanage_handle_t * sh,const char * lang_ext,const semanage_module_info_t * modinfo)807*2d543d20SAndroid Build Coastguard Worker static int semanage_direct_write_langext(semanage_handle_t *sh,
808*2d543d20SAndroid Build Coastguard Worker const char *lang_ext,
809*2d543d20SAndroid Build Coastguard Worker const semanage_module_info_t *modinfo)
810*2d543d20SAndroid Build Coastguard Worker {
811*2d543d20SAndroid Build Coastguard Worker int ret = -1;
812*2d543d20SAndroid Build Coastguard Worker char fn[PATH_MAX];
813*2d543d20SAndroid Build Coastguard Worker FILE *fp = NULL;
814*2d543d20SAndroid Build Coastguard Worker
815*2d543d20SAndroid Build Coastguard Worker ret = semanage_module_get_path(sh,
816*2d543d20SAndroid Build Coastguard Worker modinfo,
817*2d543d20SAndroid Build Coastguard Worker SEMANAGE_MODULE_PATH_LANG_EXT,
818*2d543d20SAndroid Build Coastguard Worker fn,
819*2d543d20SAndroid Build Coastguard Worker sizeof(fn));
820*2d543d20SAndroid Build Coastguard Worker if (ret != 0) {
821*2d543d20SAndroid Build Coastguard Worker goto cleanup;
822*2d543d20SAndroid Build Coastguard Worker }
823*2d543d20SAndroid Build Coastguard Worker
824*2d543d20SAndroid Build Coastguard Worker fp = fopen(fn, "w");
825*2d543d20SAndroid Build Coastguard Worker if (fp == NULL) {
826*2d543d20SAndroid Build Coastguard Worker ERR(sh, "Unable to open %s module ext file.", modinfo->name);
827*2d543d20SAndroid Build Coastguard Worker ret = -1;
828*2d543d20SAndroid Build Coastguard Worker goto cleanup;
829*2d543d20SAndroid Build Coastguard Worker }
830*2d543d20SAndroid Build Coastguard Worker
831*2d543d20SAndroid Build Coastguard Worker if (fputs(lang_ext, fp) < 0) {
832*2d543d20SAndroid Build Coastguard Worker ERR(sh, "Unable to write %s module ext file.", modinfo->name);
833*2d543d20SAndroid Build Coastguard Worker ret = -1;
834*2d543d20SAndroid Build Coastguard Worker goto cleanup;
835*2d543d20SAndroid Build Coastguard Worker }
836*2d543d20SAndroid Build Coastguard Worker
837*2d543d20SAndroid Build Coastguard Worker if (fclose(fp) != 0) {
838*2d543d20SAndroid Build Coastguard Worker ERR(sh, "Unable to close %s module ext file.", modinfo->name);
839*2d543d20SAndroid Build Coastguard Worker fp = NULL;
840*2d543d20SAndroid Build Coastguard Worker ret = -1;
841*2d543d20SAndroid Build Coastguard Worker goto cleanup;
842*2d543d20SAndroid Build Coastguard Worker }
843*2d543d20SAndroid Build Coastguard Worker
844*2d543d20SAndroid Build Coastguard Worker fp = NULL;
845*2d543d20SAndroid Build Coastguard Worker
846*2d543d20SAndroid Build Coastguard Worker ret = 0;
847*2d543d20SAndroid Build Coastguard Worker
848*2d543d20SAndroid Build Coastguard Worker cleanup:
849*2d543d20SAndroid Build Coastguard Worker if (fp != NULL) fclose(fp);
850*2d543d20SAndroid Build Coastguard Worker
851*2d543d20SAndroid Build Coastguard Worker return ret;
852*2d543d20SAndroid Build Coastguard Worker }
853*2d543d20SAndroid Build Coastguard Worker
update_checksum_with_len(Sha256Context * context,size_t s)854*2d543d20SAndroid Build Coastguard Worker static void update_checksum_with_len(Sha256Context *context, size_t s)
855*2d543d20SAndroid Build Coastguard Worker {
856*2d543d20SAndroid Build Coastguard Worker int i;
857*2d543d20SAndroid Build Coastguard Worker uint8_t buffer[8];
858*2d543d20SAndroid Build Coastguard Worker
859*2d543d20SAndroid Build Coastguard Worker for (i = 0; i < 8; i++) {
860*2d543d20SAndroid Build Coastguard Worker buffer[i] = s & 0xff;
861*2d543d20SAndroid Build Coastguard Worker s >>= 8;
862*2d543d20SAndroid Build Coastguard Worker }
863*2d543d20SAndroid Build Coastguard Worker Sha256Update(context, buffer, 8);
864*2d543d20SAndroid Build Coastguard Worker }
865*2d543d20SAndroid Build Coastguard Worker
update_checksum_with_bool(Sha256Context * context,bool b)866*2d543d20SAndroid Build Coastguard Worker static void update_checksum_with_bool(Sha256Context *context, bool b)
867*2d543d20SAndroid Build Coastguard Worker {
868*2d543d20SAndroid Build Coastguard Worker uint8_t byte;
869*2d543d20SAndroid Build Coastguard Worker
870*2d543d20SAndroid Build Coastguard Worker byte = b ? UINT8_C(1) : UINT8_C(0);
871*2d543d20SAndroid Build Coastguard Worker Sha256Update(context, &byte, 1);
872*2d543d20SAndroid Build Coastguard Worker }
873*2d543d20SAndroid Build Coastguard Worker
semanage_compile_module(semanage_handle_t * sh,semanage_module_info_t * modinfo,Sha256Context * context)874*2d543d20SAndroid Build Coastguard Worker static int semanage_compile_module(semanage_handle_t *sh,
875*2d543d20SAndroid Build Coastguard Worker semanage_module_info_t *modinfo,
876*2d543d20SAndroid Build Coastguard Worker Sha256Context *context)
877*2d543d20SAndroid Build Coastguard Worker {
878*2d543d20SAndroid Build Coastguard Worker char cil_path[PATH_MAX];
879*2d543d20SAndroid Build Coastguard Worker char hll_path[PATH_MAX];
880*2d543d20SAndroid Build Coastguard Worker char *compiler_path = NULL;
881*2d543d20SAndroid Build Coastguard Worker char *cil_data = NULL;
882*2d543d20SAndroid Build Coastguard Worker char *err_data = NULL;
883*2d543d20SAndroid Build Coastguard Worker char *start = NULL;
884*2d543d20SAndroid Build Coastguard Worker char *end = NULL;
885*2d543d20SAndroid Build Coastguard Worker int status = 0;
886*2d543d20SAndroid Build Coastguard Worker size_t cil_data_len = 0;
887*2d543d20SAndroid Build Coastguard Worker size_t err_data_len = 0;
888*2d543d20SAndroid Build Coastguard Worker struct file_contents hll_contents = {};
889*2d543d20SAndroid Build Coastguard Worker
890*2d543d20SAndroid Build Coastguard Worker if (!strcasecmp(modinfo->lang_ext, "cil")) {
891*2d543d20SAndroid Build Coastguard Worker goto cleanup;
892*2d543d20SAndroid Build Coastguard Worker }
893*2d543d20SAndroid Build Coastguard Worker
894*2d543d20SAndroid Build Coastguard Worker status = semanage_get_hll_compiler_path(sh, modinfo->lang_ext, &compiler_path);
895*2d543d20SAndroid Build Coastguard Worker if (status != 0) {
896*2d543d20SAndroid Build Coastguard Worker goto cleanup;
897*2d543d20SAndroid Build Coastguard Worker }
898*2d543d20SAndroid Build Coastguard Worker
899*2d543d20SAndroid Build Coastguard Worker status = semanage_module_get_path(
900*2d543d20SAndroid Build Coastguard Worker sh,
901*2d543d20SAndroid Build Coastguard Worker modinfo,
902*2d543d20SAndroid Build Coastguard Worker SEMANAGE_MODULE_PATH_CIL,
903*2d543d20SAndroid Build Coastguard Worker cil_path,
904*2d543d20SAndroid Build Coastguard Worker sizeof(cil_path));
905*2d543d20SAndroid Build Coastguard Worker if (status != 0) {
906*2d543d20SAndroid Build Coastguard Worker goto cleanup;
907*2d543d20SAndroid Build Coastguard Worker }
908*2d543d20SAndroid Build Coastguard Worker
909*2d543d20SAndroid Build Coastguard Worker status = semanage_module_get_path(
910*2d543d20SAndroid Build Coastguard Worker sh,
911*2d543d20SAndroid Build Coastguard Worker modinfo,
912*2d543d20SAndroid Build Coastguard Worker SEMANAGE_MODULE_PATH_HLL,
913*2d543d20SAndroid Build Coastguard Worker hll_path,
914*2d543d20SAndroid Build Coastguard Worker sizeof(hll_path));
915*2d543d20SAndroid Build Coastguard Worker if (status != 0) {
916*2d543d20SAndroid Build Coastguard Worker goto cleanup;
917*2d543d20SAndroid Build Coastguard Worker }
918*2d543d20SAndroid Build Coastguard Worker
919*2d543d20SAndroid Build Coastguard Worker status = map_compressed_file(sh, hll_path, &hll_contents);
920*2d543d20SAndroid Build Coastguard Worker if (status < 0) {
921*2d543d20SAndroid Build Coastguard Worker ERR(sh, "Unable to read file %s\n", hll_path);
922*2d543d20SAndroid Build Coastguard Worker goto cleanup;
923*2d543d20SAndroid Build Coastguard Worker }
924*2d543d20SAndroid Build Coastguard Worker
925*2d543d20SAndroid Build Coastguard Worker status = semanage_pipe_data(sh, compiler_path, hll_contents.data,
926*2d543d20SAndroid Build Coastguard Worker hll_contents.len, &cil_data, &cil_data_len,
927*2d543d20SAndroid Build Coastguard Worker &err_data, &err_data_len);
928*2d543d20SAndroid Build Coastguard Worker if (err_data_len > 0) {
929*2d543d20SAndroid Build Coastguard Worker for (start = end = err_data; end < err_data + err_data_len; end++) {
930*2d543d20SAndroid Build Coastguard Worker if (*end == '\n') {
931*2d543d20SAndroid Build Coastguard Worker fprintf(stderr, "%s: ", modinfo->name);
932*2d543d20SAndroid Build Coastguard Worker fwrite(start, 1, end - start + 1, stderr);
933*2d543d20SAndroid Build Coastguard Worker start = end + 1;
934*2d543d20SAndroid Build Coastguard Worker }
935*2d543d20SAndroid Build Coastguard Worker }
936*2d543d20SAndroid Build Coastguard Worker
937*2d543d20SAndroid Build Coastguard Worker if (end != start) {
938*2d543d20SAndroid Build Coastguard Worker fprintf(stderr, "%s: ", modinfo->name);
939*2d543d20SAndroid Build Coastguard Worker fwrite(start, 1, end - start, stderr);
940*2d543d20SAndroid Build Coastguard Worker fprintf(stderr, "\n");
941*2d543d20SAndroid Build Coastguard Worker }
942*2d543d20SAndroid Build Coastguard Worker }
943*2d543d20SAndroid Build Coastguard Worker if (status != 0) {
944*2d543d20SAndroid Build Coastguard Worker goto cleanup;
945*2d543d20SAndroid Build Coastguard Worker }
946*2d543d20SAndroid Build Coastguard Worker
947*2d543d20SAndroid Build Coastguard Worker if (context) {
948*2d543d20SAndroid Build Coastguard Worker update_checksum_with_len(context, cil_data_len);
949*2d543d20SAndroid Build Coastguard Worker Sha256Update(context, cil_data, cil_data_len);
950*2d543d20SAndroid Build Coastguard Worker }
951*2d543d20SAndroid Build Coastguard Worker
952*2d543d20SAndroid Build Coastguard Worker status = write_compressed_file(sh, cil_path, cil_data, cil_data_len);
953*2d543d20SAndroid Build Coastguard Worker if (status == -1) {
954*2d543d20SAndroid Build Coastguard Worker ERR(sh, "Failed to write %s\n", cil_path);
955*2d543d20SAndroid Build Coastguard Worker goto cleanup;
956*2d543d20SAndroid Build Coastguard Worker }
957*2d543d20SAndroid Build Coastguard Worker
958*2d543d20SAndroid Build Coastguard Worker if (sh->conf->remove_hll == 1) {
959*2d543d20SAndroid Build Coastguard Worker status = unlink(hll_path);
960*2d543d20SAndroid Build Coastguard Worker if (status != 0) {
961*2d543d20SAndroid Build Coastguard Worker ERR(sh, "Error while removing HLL file %s: %s", hll_path, strerror(errno));
962*2d543d20SAndroid Build Coastguard Worker goto cleanup;
963*2d543d20SAndroid Build Coastguard Worker }
964*2d543d20SAndroid Build Coastguard Worker
965*2d543d20SAndroid Build Coastguard Worker status = semanage_direct_write_langext(sh, "cil", modinfo);
966*2d543d20SAndroid Build Coastguard Worker if (status != 0) {
967*2d543d20SAndroid Build Coastguard Worker goto cleanup;
968*2d543d20SAndroid Build Coastguard Worker }
969*2d543d20SAndroid Build Coastguard Worker }
970*2d543d20SAndroid Build Coastguard Worker
971*2d543d20SAndroid Build Coastguard Worker cleanup:
972*2d543d20SAndroid Build Coastguard Worker unmap_compressed_file(&hll_contents);
973*2d543d20SAndroid Build Coastguard Worker free(cil_data);
974*2d543d20SAndroid Build Coastguard Worker free(err_data);
975*2d543d20SAndroid Build Coastguard Worker free(compiler_path);
976*2d543d20SAndroid Build Coastguard Worker
977*2d543d20SAndroid Build Coastguard Worker return status;
978*2d543d20SAndroid Build Coastguard Worker }
979*2d543d20SAndroid Build Coastguard Worker
modinfo_cmp(const void * a,const void * b)980*2d543d20SAndroid Build Coastguard Worker static int modinfo_cmp(const void *a, const void *b)
981*2d543d20SAndroid Build Coastguard Worker {
982*2d543d20SAndroid Build Coastguard Worker const semanage_module_info_t *ma = a;
983*2d543d20SAndroid Build Coastguard Worker const semanage_module_info_t *mb = b;
984*2d543d20SAndroid Build Coastguard Worker
985*2d543d20SAndroid Build Coastguard Worker return strcmp(ma->name, mb->name);
986*2d543d20SAndroid Build Coastguard Worker }
987*2d543d20SAndroid Build Coastguard Worker
988*2d543d20SAndroid Build Coastguard Worker struct extra_checksum_params {
989*2d543d20SAndroid Build Coastguard Worker int disable_dontaudit;
990*2d543d20SAndroid Build Coastguard Worker int preserve_tunables;
991*2d543d20SAndroid Build Coastguard Worker int target_platform;
992*2d543d20SAndroid Build Coastguard Worker int policyvers;
993*2d543d20SAndroid Build Coastguard Worker };
994*2d543d20SAndroid Build Coastguard Worker
semanage_compile_hll_modules(semanage_handle_t * sh,semanage_module_info_t * modinfos,int num_modinfos,const struct extra_checksum_params * extra,char * cil_checksum)995*2d543d20SAndroid Build Coastguard Worker static int semanage_compile_hll_modules(semanage_handle_t *sh,
996*2d543d20SAndroid Build Coastguard Worker semanage_module_info_t *modinfos,
997*2d543d20SAndroid Build Coastguard Worker int num_modinfos,
998*2d543d20SAndroid Build Coastguard Worker const struct extra_checksum_params *extra,
999*2d543d20SAndroid Build Coastguard Worker char *cil_checksum)
1000*2d543d20SAndroid Build Coastguard Worker {
1001*2d543d20SAndroid Build Coastguard Worker /* to be incremented when checksum input data format changes */
1002*2d543d20SAndroid Build Coastguard Worker static const size_t CHECKSUM_EPOCH = 2;
1003*2d543d20SAndroid Build Coastguard Worker
1004*2d543d20SAndroid Build Coastguard Worker int i, status = 0;
1005*2d543d20SAndroid Build Coastguard Worker char cil_path[PATH_MAX];
1006*2d543d20SAndroid Build Coastguard Worker struct stat sb;
1007*2d543d20SAndroid Build Coastguard Worker Sha256Context context;
1008*2d543d20SAndroid Build Coastguard Worker SHA256_HASH hash;
1009*2d543d20SAndroid Build Coastguard Worker struct file_contents contents = {};
1010*2d543d20SAndroid Build Coastguard Worker
1011*2d543d20SAndroid Build Coastguard Worker assert(sh);
1012*2d543d20SAndroid Build Coastguard Worker assert(modinfos);
1013*2d543d20SAndroid Build Coastguard Worker
1014*2d543d20SAndroid Build Coastguard Worker /* Sort modules by name to get consistent ordering. */
1015*2d543d20SAndroid Build Coastguard Worker qsort(modinfos, num_modinfos, sizeof(*modinfos), &modinfo_cmp);
1016*2d543d20SAndroid Build Coastguard Worker
1017*2d543d20SAndroid Build Coastguard Worker Sha256Initialise(&context);
1018*2d543d20SAndroid Build Coastguard Worker update_checksum_with_len(&context, CHECKSUM_EPOCH);
1019*2d543d20SAndroid Build Coastguard Worker update_checksum_with_bool(&context, !!extra->disable_dontaudit);
1020*2d543d20SAndroid Build Coastguard Worker update_checksum_with_bool(&context, !!extra->preserve_tunables);
1021*2d543d20SAndroid Build Coastguard Worker update_checksum_with_len(&context, (size_t)extra->target_platform);
1022*2d543d20SAndroid Build Coastguard Worker update_checksum_with_len(&context, (size_t)extra->policyvers);
1023*2d543d20SAndroid Build Coastguard Worker
1024*2d543d20SAndroid Build Coastguard Worker /* prefix with module count to avoid collisions */
1025*2d543d20SAndroid Build Coastguard Worker update_checksum_with_len(&context, num_modinfos);
1026*2d543d20SAndroid Build Coastguard Worker for (i = 0; i < num_modinfos; i++) {
1027*2d543d20SAndroid Build Coastguard Worker status = semanage_module_get_path(
1028*2d543d20SAndroid Build Coastguard Worker sh,
1029*2d543d20SAndroid Build Coastguard Worker &modinfos[i],
1030*2d543d20SAndroid Build Coastguard Worker SEMANAGE_MODULE_PATH_CIL,
1031*2d543d20SAndroid Build Coastguard Worker cil_path,
1032*2d543d20SAndroid Build Coastguard Worker sizeof(cil_path));
1033*2d543d20SAndroid Build Coastguard Worker if (status != 0)
1034*2d543d20SAndroid Build Coastguard Worker return -1;
1035*2d543d20SAndroid Build Coastguard Worker
1036*2d543d20SAndroid Build Coastguard Worker if (!semanage_get_ignore_module_cache(sh)) {
1037*2d543d20SAndroid Build Coastguard Worker status = stat(cil_path, &sb);
1038*2d543d20SAndroid Build Coastguard Worker if (status == 0) {
1039*2d543d20SAndroid Build Coastguard Worker status = map_compressed_file(sh, cil_path, &contents);
1040*2d543d20SAndroid Build Coastguard Worker if (status < 0) {
1041*2d543d20SAndroid Build Coastguard Worker ERR(sh, "Error mapping file: %s", cil_path);
1042*2d543d20SAndroid Build Coastguard Worker return -1;
1043*2d543d20SAndroid Build Coastguard Worker }
1044*2d543d20SAndroid Build Coastguard Worker
1045*2d543d20SAndroid Build Coastguard Worker /* prefix with length to avoid collisions */
1046*2d543d20SAndroid Build Coastguard Worker update_checksum_with_len(&context, contents.len);
1047*2d543d20SAndroid Build Coastguard Worker Sha256Update(&context, contents.data, contents.len);
1048*2d543d20SAndroid Build Coastguard Worker
1049*2d543d20SAndroid Build Coastguard Worker unmap_compressed_file(&contents);
1050*2d543d20SAndroid Build Coastguard Worker continue;
1051*2d543d20SAndroid Build Coastguard Worker } else if (errno != ENOENT) {
1052*2d543d20SAndroid Build Coastguard Worker ERR(sh, "Unable to access %s: %s\n", cil_path,
1053*2d543d20SAndroid Build Coastguard Worker strerror(errno));
1054*2d543d20SAndroid Build Coastguard Worker return -1; //an error in the "stat" call
1055*2d543d20SAndroid Build Coastguard Worker }
1056*2d543d20SAndroid Build Coastguard Worker }
1057*2d543d20SAndroid Build Coastguard Worker
1058*2d543d20SAndroid Build Coastguard Worker status = semanage_compile_module(sh, &modinfos[i], &context);
1059*2d543d20SAndroid Build Coastguard Worker if (status < 0)
1060*2d543d20SAndroid Build Coastguard Worker return -1;
1061*2d543d20SAndroid Build Coastguard Worker }
1062*2d543d20SAndroid Build Coastguard Worker Sha256Finalise(&context, &hash);
1063*2d543d20SAndroid Build Coastguard Worker
1064*2d543d20SAndroid Build Coastguard Worker semanage_hash_to_checksum_string(hash.bytes, cil_checksum);
1065*2d543d20SAndroid Build Coastguard Worker return 0;
1066*2d543d20SAndroid Build Coastguard Worker }
1067*2d543d20SAndroid Build Coastguard Worker
semanage_compare_checksum(semanage_handle_t * sh,const char * reference)1068*2d543d20SAndroid Build Coastguard Worker static int semanage_compare_checksum(semanage_handle_t *sh, const char *reference)
1069*2d543d20SAndroid Build Coastguard Worker {
1070*2d543d20SAndroid Build Coastguard Worker const char *path = semanage_path(SEMANAGE_TMP, SEMANAGE_MODULES_CHECKSUM);
1071*2d543d20SAndroid Build Coastguard Worker struct stat sb;
1072*2d543d20SAndroid Build Coastguard Worker int fd, retval;
1073*2d543d20SAndroid Build Coastguard Worker char *data;
1074*2d543d20SAndroid Build Coastguard Worker
1075*2d543d20SAndroid Build Coastguard Worker fd = open(path, O_RDONLY);
1076*2d543d20SAndroid Build Coastguard Worker if (fd == -1) {
1077*2d543d20SAndroid Build Coastguard Worker if (errno != ENOENT) {
1078*2d543d20SAndroid Build Coastguard Worker ERR(sh, "Unable to open %s: %s\n", path, strerror(errno));
1079*2d543d20SAndroid Build Coastguard Worker return -1;
1080*2d543d20SAndroid Build Coastguard Worker }
1081*2d543d20SAndroid Build Coastguard Worker /* Checksum file not present - force a rebuild. */
1082*2d543d20SAndroid Build Coastguard Worker return 1;
1083*2d543d20SAndroid Build Coastguard Worker }
1084*2d543d20SAndroid Build Coastguard Worker
1085*2d543d20SAndroid Build Coastguard Worker if (fstat(fd, &sb) == -1) {
1086*2d543d20SAndroid Build Coastguard Worker ERR(sh, "Unable to stat %s\n", path);
1087*2d543d20SAndroid Build Coastguard Worker retval = -1;
1088*2d543d20SAndroid Build Coastguard Worker goto out_close;
1089*2d543d20SAndroid Build Coastguard Worker }
1090*2d543d20SAndroid Build Coastguard Worker
1091*2d543d20SAndroid Build Coastguard Worker if (sb.st_size != (off_t)CHECKSUM_CONTENT_SIZE) {
1092*2d543d20SAndroid Build Coastguard Worker /* Incompatible/invalid hash type - just force a rebuild. */
1093*2d543d20SAndroid Build Coastguard Worker WARN(sh, "Module checksum invalid - forcing a rebuild\n");
1094*2d543d20SAndroid Build Coastguard Worker retval = 1;
1095*2d543d20SAndroid Build Coastguard Worker goto out_close;
1096*2d543d20SAndroid Build Coastguard Worker }
1097*2d543d20SAndroid Build Coastguard Worker
1098*2d543d20SAndroid Build Coastguard Worker data = mmap(NULL, CHECKSUM_CONTENT_SIZE, PROT_READ, MAP_PRIVATE, fd, 0);
1099*2d543d20SAndroid Build Coastguard Worker if (data == MAP_FAILED) {
1100*2d543d20SAndroid Build Coastguard Worker ERR(sh, "Unable to mmap %s\n", path);
1101*2d543d20SAndroid Build Coastguard Worker retval = -1;
1102*2d543d20SAndroid Build Coastguard Worker goto out_close;
1103*2d543d20SAndroid Build Coastguard Worker }
1104*2d543d20SAndroid Build Coastguard Worker
1105*2d543d20SAndroid Build Coastguard Worker retval = memcmp(data, reference, CHECKSUM_CONTENT_SIZE) != 0;
1106*2d543d20SAndroid Build Coastguard Worker munmap(data, sb.st_size);
1107*2d543d20SAndroid Build Coastguard Worker out_close:
1108*2d543d20SAndroid Build Coastguard Worker close(fd);
1109*2d543d20SAndroid Build Coastguard Worker return retval;
1110*2d543d20SAndroid Build Coastguard Worker }
1111*2d543d20SAndroid Build Coastguard Worker
semanage_write_modules_checksum(semanage_handle_t * sh,const char * checksum)1112*2d543d20SAndroid Build Coastguard Worker static int semanage_write_modules_checksum(semanage_handle_t *sh,
1113*2d543d20SAndroid Build Coastguard Worker const char *checksum)
1114*2d543d20SAndroid Build Coastguard Worker {
1115*2d543d20SAndroid Build Coastguard Worker const char *path = semanage_path(SEMANAGE_TMP, SEMANAGE_MODULES_CHECKSUM);
1116*2d543d20SAndroid Build Coastguard Worker
1117*2d543d20SAndroid Build Coastguard Worker return write_file(sh, path, checksum, CHECKSUM_CONTENT_SIZE);
1118*2d543d20SAndroid Build Coastguard Worker }
1119*2d543d20SAndroid Build Coastguard Worker
1120*2d543d20SAndroid Build Coastguard Worker /* Files that must exist in order to skip policy rebuild. */
1121*2d543d20SAndroid Build Coastguard Worker static const int semanage_computed_files[] = {
1122*2d543d20SAndroid Build Coastguard Worker SEMANAGE_STORE_KERNEL,
1123*2d543d20SAndroid Build Coastguard Worker SEMANAGE_STORE_FC,
1124*2d543d20SAndroid Build Coastguard Worker SEMANAGE_STORE_SEUSERS,
1125*2d543d20SAndroid Build Coastguard Worker SEMANAGE_LINKED,
1126*2d543d20SAndroid Build Coastguard Worker SEMANAGE_SEUSERS_LINKED,
1127*2d543d20SAndroid Build Coastguard Worker SEMANAGE_USERS_EXTRA_LINKED
1128*2d543d20SAndroid Build Coastguard Worker };
1129*2d543d20SAndroid Build Coastguard Worker
1130*2d543d20SAndroid Build Coastguard Worker /* Copies a file from src to dst. If dst already exists then
1131*2d543d20SAndroid Build Coastguard Worker * overwrite it. If source doesn't exist then return success.
1132*2d543d20SAndroid Build Coastguard Worker * Returns 0 on success, -1 on error. */
copy_file_if_exists(const char * src,const char * dst,mode_t mode)1133*2d543d20SAndroid Build Coastguard Worker static int copy_file_if_exists(const char *src, const char *dst, mode_t mode){
1134*2d543d20SAndroid Build Coastguard Worker int rc = semanage_copy_file(src, dst, mode, false);
1135*2d543d20SAndroid Build Coastguard Worker return (rc < 0 && errno != ENOENT) ? rc : 0;
1136*2d543d20SAndroid Build Coastguard Worker }
1137*2d543d20SAndroid Build Coastguard Worker
1138*2d543d20SAndroid Build Coastguard Worker /********************* direct API functions ********************/
1139*2d543d20SAndroid Build Coastguard Worker
1140*2d543d20SAndroid Build Coastguard Worker /* Commits all changes in sandbox to the actual kernel policy.
1141*2d543d20SAndroid Build Coastguard Worker * Returns commit number on success, -1 on error.
1142*2d543d20SAndroid Build Coastguard Worker */
semanage_direct_commit(semanage_handle_t * sh)1143*2d543d20SAndroid Build Coastguard Worker static int semanage_direct_commit(semanage_handle_t * sh)
1144*2d543d20SAndroid Build Coastguard Worker {
1145*2d543d20SAndroid Build Coastguard Worker char **mod_filenames = NULL;
1146*2d543d20SAndroid Build Coastguard Worker char *fc_buffer = NULL;
1147*2d543d20SAndroid Build Coastguard Worker size_t fc_buffer_len = 0;
1148*2d543d20SAndroid Build Coastguard Worker const char *ofilename = NULL;
1149*2d543d20SAndroid Build Coastguard Worker const char *path;
1150*2d543d20SAndroid Build Coastguard Worker int retval = -1, num_modinfos = 0, i;
1151*2d543d20SAndroid Build Coastguard Worker sepol_policydb_t *out = NULL;
1152*2d543d20SAndroid Build Coastguard Worker struct cil_db *cildb = NULL;
1153*2d543d20SAndroid Build Coastguard Worker semanage_module_info_t *modinfos = NULL;
1154*2d543d20SAndroid Build Coastguard Worker mode_t mask = umask(0077);
1155*2d543d20SAndroid Build Coastguard Worker struct stat sb;
1156*2d543d20SAndroid Build Coastguard Worker char modules_checksum[CHECKSUM_CONTENT_SIZE + 1 /* '\0' */];
1157*2d543d20SAndroid Build Coastguard Worker struct extra_checksum_params extra;
1158*2d543d20SAndroid Build Coastguard Worker
1159*2d543d20SAndroid Build Coastguard Worker int do_rebuild, do_write_kernel, do_install;
1160*2d543d20SAndroid Build Coastguard Worker int fcontexts_modified, ports_modified, seusers_modified,
1161*2d543d20SAndroid Build Coastguard Worker disable_dontaudit, preserve_tunables, ibpkeys_modified,
1162*2d543d20SAndroid Build Coastguard Worker ibendports_modified;
1163*2d543d20SAndroid Build Coastguard Worker dbase_config_t *users = semanage_user_dbase_local(sh);
1164*2d543d20SAndroid Build Coastguard Worker dbase_config_t *users_base = semanage_user_base_dbase_local(sh);
1165*2d543d20SAndroid Build Coastguard Worker dbase_config_t *pusers_base = semanage_user_base_dbase_policy(sh);
1166*2d543d20SAndroid Build Coastguard Worker dbase_config_t *pusers_extra = semanage_user_extra_dbase_policy(sh);
1167*2d543d20SAndroid Build Coastguard Worker dbase_config_t *ports = semanage_port_dbase_local(sh);
1168*2d543d20SAndroid Build Coastguard Worker dbase_config_t *pports = semanage_port_dbase_policy(sh);
1169*2d543d20SAndroid Build Coastguard Worker dbase_config_t *ibpkeys = semanage_ibpkey_dbase_local(sh);
1170*2d543d20SAndroid Build Coastguard Worker dbase_config_t *pibpkeys = semanage_ibpkey_dbase_policy(sh);
1171*2d543d20SAndroid Build Coastguard Worker dbase_config_t *ibendports = semanage_ibendport_dbase_local(sh);
1172*2d543d20SAndroid Build Coastguard Worker dbase_config_t *pibendports = semanage_ibendport_dbase_policy(sh);
1173*2d543d20SAndroid Build Coastguard Worker dbase_config_t *bools = semanage_bool_dbase_local(sh);
1174*2d543d20SAndroid Build Coastguard Worker dbase_config_t *pbools = semanage_bool_dbase_policy(sh);
1175*2d543d20SAndroid Build Coastguard Worker dbase_config_t *ifaces = semanage_iface_dbase_local(sh);
1176*2d543d20SAndroid Build Coastguard Worker dbase_config_t *pifaces = semanage_iface_dbase_policy(sh);
1177*2d543d20SAndroid Build Coastguard Worker dbase_config_t *nodes = semanage_node_dbase_local(sh);
1178*2d543d20SAndroid Build Coastguard Worker dbase_config_t *pnodes = semanage_node_dbase_policy(sh);
1179*2d543d20SAndroid Build Coastguard Worker dbase_config_t *fcontexts = semanage_fcontext_dbase_local(sh);
1180*2d543d20SAndroid Build Coastguard Worker dbase_config_t *pfcontexts = semanage_fcontext_dbase_policy(sh);
1181*2d543d20SAndroid Build Coastguard Worker dbase_config_t *seusers = semanage_seuser_dbase_local(sh);
1182*2d543d20SAndroid Build Coastguard Worker dbase_config_t *pseusers = semanage_seuser_dbase_policy(sh);
1183*2d543d20SAndroid Build Coastguard Worker
1184*2d543d20SAndroid Build Coastguard Worker /* Modified flags that we need to use more than once. */
1185*2d543d20SAndroid Build Coastguard Worker ports_modified = ports->dtable->is_modified(ports->dbase);
1186*2d543d20SAndroid Build Coastguard Worker ibpkeys_modified = ibpkeys->dtable->is_modified(ibpkeys->dbase);
1187*2d543d20SAndroid Build Coastguard Worker ibendports_modified = ibendports->dtable->is_modified(ibendports->dbase);
1188*2d543d20SAndroid Build Coastguard Worker seusers_modified = seusers->dtable->is_modified(seusers->dbase);
1189*2d543d20SAndroid Build Coastguard Worker fcontexts_modified = fcontexts->dtable->is_modified(fcontexts->dbase);
1190*2d543d20SAndroid Build Coastguard Worker
1191*2d543d20SAndroid Build Coastguard Worker /* Before we do anything else, flush the join to its component parts.
1192*2d543d20SAndroid Build Coastguard Worker * This *does not* flush to disk automatically */
1193*2d543d20SAndroid Build Coastguard Worker if (users->dtable->is_modified(users->dbase)) {
1194*2d543d20SAndroid Build Coastguard Worker retval = users->dtable->flush(sh, users->dbase);
1195*2d543d20SAndroid Build Coastguard Worker if (retval < 0)
1196*2d543d20SAndroid Build Coastguard Worker goto cleanup;
1197*2d543d20SAndroid Build Coastguard Worker }
1198*2d543d20SAndroid Build Coastguard Worker
1199*2d543d20SAndroid Build Coastguard Worker /* Rebuild if explicitly requested or any module changes occurred. */
1200*2d543d20SAndroid Build Coastguard Worker do_rebuild = sh->do_rebuild | sh->modules_modified;
1201*2d543d20SAndroid Build Coastguard Worker
1202*2d543d20SAndroid Build Coastguard Worker /* Create or remove the disable_dontaudit flag file. */
1203*2d543d20SAndroid Build Coastguard Worker path = semanage_path(SEMANAGE_TMP, SEMANAGE_DISABLE_DONTAUDIT);
1204*2d543d20SAndroid Build Coastguard Worker if (stat(path, &sb) == 0)
1205*2d543d20SAndroid Build Coastguard Worker do_rebuild |= !(sepol_get_disable_dontaudit(sh->sepolh) == 1);
1206*2d543d20SAndroid Build Coastguard Worker else if (errno == ENOENT) {
1207*2d543d20SAndroid Build Coastguard Worker /* The file does not exist */
1208*2d543d20SAndroid Build Coastguard Worker do_rebuild |= (sepol_get_disable_dontaudit(sh->sepolh) == 1);
1209*2d543d20SAndroid Build Coastguard Worker } else {
1210*2d543d20SAndroid Build Coastguard Worker ERR(sh, "Unable to access %s: %s\n", path, strerror(errno));
1211*2d543d20SAndroid Build Coastguard Worker retval = -1;
1212*2d543d20SAndroid Build Coastguard Worker goto cleanup;
1213*2d543d20SAndroid Build Coastguard Worker }
1214*2d543d20SAndroid Build Coastguard Worker if (sepol_get_disable_dontaudit(sh->sepolh) == 1) {
1215*2d543d20SAndroid Build Coastguard Worker FILE *touch;
1216*2d543d20SAndroid Build Coastguard Worker touch = fopen(path, "w");
1217*2d543d20SAndroid Build Coastguard Worker if (touch != NULL) {
1218*2d543d20SAndroid Build Coastguard Worker if (fclose(touch) != 0) {
1219*2d543d20SAndroid Build Coastguard Worker ERR(sh, "Error attempting to create disable_dontaudit flag.");
1220*2d543d20SAndroid Build Coastguard Worker goto cleanup;
1221*2d543d20SAndroid Build Coastguard Worker }
1222*2d543d20SAndroid Build Coastguard Worker } else {
1223*2d543d20SAndroid Build Coastguard Worker ERR(sh, "Error attempting to create disable_dontaudit flag.");
1224*2d543d20SAndroid Build Coastguard Worker goto cleanup;
1225*2d543d20SAndroid Build Coastguard Worker }
1226*2d543d20SAndroid Build Coastguard Worker } else {
1227*2d543d20SAndroid Build Coastguard Worker if (remove(path) == -1 && errno != ENOENT) {
1228*2d543d20SAndroid Build Coastguard Worker ERR(sh, "Error removing the disable_dontaudit flag.");
1229*2d543d20SAndroid Build Coastguard Worker goto cleanup;
1230*2d543d20SAndroid Build Coastguard Worker }
1231*2d543d20SAndroid Build Coastguard Worker }
1232*2d543d20SAndroid Build Coastguard Worker
1233*2d543d20SAndroid Build Coastguard Worker /* Create or remove the preserve_tunables flag file. */
1234*2d543d20SAndroid Build Coastguard Worker path = semanage_path(SEMANAGE_TMP, SEMANAGE_PRESERVE_TUNABLES);
1235*2d543d20SAndroid Build Coastguard Worker if (stat(path, &sb) == 0)
1236*2d543d20SAndroid Build Coastguard Worker do_rebuild |= !(sepol_get_preserve_tunables(sh->sepolh) == 1);
1237*2d543d20SAndroid Build Coastguard Worker else if (errno == ENOENT) {
1238*2d543d20SAndroid Build Coastguard Worker /* The file does not exist */
1239*2d543d20SAndroid Build Coastguard Worker do_rebuild |= (sepol_get_preserve_tunables(sh->sepolh) == 1);
1240*2d543d20SAndroid Build Coastguard Worker } else {
1241*2d543d20SAndroid Build Coastguard Worker ERR(sh, "Unable to access %s: %s\n", path, strerror(errno));
1242*2d543d20SAndroid Build Coastguard Worker retval = -1;
1243*2d543d20SAndroid Build Coastguard Worker goto cleanup;
1244*2d543d20SAndroid Build Coastguard Worker }
1245*2d543d20SAndroid Build Coastguard Worker
1246*2d543d20SAndroid Build Coastguard Worker if (sepol_get_preserve_tunables(sh->sepolh) == 1) {
1247*2d543d20SAndroid Build Coastguard Worker FILE *touch;
1248*2d543d20SAndroid Build Coastguard Worker touch = fopen(path, "w");
1249*2d543d20SAndroid Build Coastguard Worker if (touch != NULL) {
1250*2d543d20SAndroid Build Coastguard Worker if (fclose(touch) != 0) {
1251*2d543d20SAndroid Build Coastguard Worker ERR(sh, "Error attempting to create preserve_tunable flag.");
1252*2d543d20SAndroid Build Coastguard Worker goto cleanup;
1253*2d543d20SAndroid Build Coastguard Worker }
1254*2d543d20SAndroid Build Coastguard Worker } else {
1255*2d543d20SAndroid Build Coastguard Worker ERR(sh, "Error attempting to create preserve_tunable flag.");
1256*2d543d20SAndroid Build Coastguard Worker goto cleanup;
1257*2d543d20SAndroid Build Coastguard Worker }
1258*2d543d20SAndroid Build Coastguard Worker } else {
1259*2d543d20SAndroid Build Coastguard Worker if (remove(path) == -1 && errno != ENOENT) {
1260*2d543d20SAndroid Build Coastguard Worker ERR(sh, "Error removing the preserve_tunables flag.");
1261*2d543d20SAndroid Build Coastguard Worker goto cleanup;
1262*2d543d20SAndroid Build Coastguard Worker }
1263*2d543d20SAndroid Build Coastguard Worker }
1264*2d543d20SAndroid Build Coastguard Worker
1265*2d543d20SAndroid Build Coastguard Worker /*
1266*2d543d20SAndroid Build Coastguard Worker * This is for systems that have already migrated with an older version
1267*2d543d20SAndroid Build Coastguard Worker * of semanage_migrate_store. The older version did not copy
1268*2d543d20SAndroid Build Coastguard Worker * policy.kern so the policy binary must be rebuilt here.
1269*2d543d20SAndroid Build Coastguard Worker * This also ensures that any linked files that are required
1270*2d543d20SAndroid Build Coastguard Worker * in order to skip re-linking are present; otherwise, we force
1271*2d543d20SAndroid Build Coastguard Worker * a rebuild.
1272*2d543d20SAndroid Build Coastguard Worker */
1273*2d543d20SAndroid Build Coastguard Worker for (i = 0; !do_rebuild && i < (int)ARRAY_SIZE(semanage_computed_files); i++) {
1274*2d543d20SAndroid Build Coastguard Worker path = semanage_path(SEMANAGE_TMP, semanage_computed_files[i]);
1275*2d543d20SAndroid Build Coastguard Worker if (stat(path, &sb) != 0) {
1276*2d543d20SAndroid Build Coastguard Worker if (errno != ENOENT) {
1277*2d543d20SAndroid Build Coastguard Worker ERR(sh, "Unable to access %s: %s\n", path, strerror(errno));
1278*2d543d20SAndroid Build Coastguard Worker retval = -1;
1279*2d543d20SAndroid Build Coastguard Worker goto cleanup;
1280*2d543d20SAndroid Build Coastguard Worker }
1281*2d543d20SAndroid Build Coastguard Worker
1282*2d543d20SAndroid Build Coastguard Worker do_rebuild = 1;
1283*2d543d20SAndroid Build Coastguard Worker break;
1284*2d543d20SAndroid Build Coastguard Worker }
1285*2d543d20SAndroid Build Coastguard Worker }
1286*2d543d20SAndroid Build Coastguard Worker
1287*2d543d20SAndroid Build Coastguard Worker if (do_rebuild || sh->check_ext_changes) {
1288*2d543d20SAndroid Build Coastguard Worker retval = semanage_get_active_modules(sh, &modinfos, &num_modinfos);
1289*2d543d20SAndroid Build Coastguard Worker if (retval < 0) {
1290*2d543d20SAndroid Build Coastguard Worker goto cleanup;
1291*2d543d20SAndroid Build Coastguard Worker }
1292*2d543d20SAndroid Build Coastguard Worker
1293*2d543d20SAndroid Build Coastguard Worker /* No modules - nothing to rebuild. */
1294*2d543d20SAndroid Build Coastguard Worker if (num_modinfos == 0) {
1295*2d543d20SAndroid Build Coastguard Worker goto cleanup;
1296*2d543d20SAndroid Build Coastguard Worker }
1297*2d543d20SAndroid Build Coastguard Worker
1298*2d543d20SAndroid Build Coastguard Worker extra = (struct extra_checksum_params){
1299*2d543d20SAndroid Build Coastguard Worker .disable_dontaudit = sepol_get_disable_dontaudit(sh->sepolh),
1300*2d543d20SAndroid Build Coastguard Worker .preserve_tunables = sepol_get_preserve_tunables(sh->sepolh),
1301*2d543d20SAndroid Build Coastguard Worker .target_platform = sh->conf->target_platform,
1302*2d543d20SAndroid Build Coastguard Worker .policyvers = sh->conf->policyvers,
1303*2d543d20SAndroid Build Coastguard Worker };
1304*2d543d20SAndroid Build Coastguard Worker retval = semanage_compile_hll_modules(sh, modinfos, num_modinfos,
1305*2d543d20SAndroid Build Coastguard Worker &extra, modules_checksum);
1306*2d543d20SAndroid Build Coastguard Worker if (retval < 0) {
1307*2d543d20SAndroid Build Coastguard Worker ERR(sh, "Failed to compile hll files into cil files.\n");
1308*2d543d20SAndroid Build Coastguard Worker goto cleanup;
1309*2d543d20SAndroid Build Coastguard Worker }
1310*2d543d20SAndroid Build Coastguard Worker
1311*2d543d20SAndroid Build Coastguard Worker if (!do_rebuild && sh->check_ext_changes) {
1312*2d543d20SAndroid Build Coastguard Worker retval = semanage_compare_checksum(sh, modules_checksum);
1313*2d543d20SAndroid Build Coastguard Worker if (retval < 0)
1314*2d543d20SAndroid Build Coastguard Worker goto cleanup;
1315*2d543d20SAndroid Build Coastguard Worker do_rebuild = retval;
1316*2d543d20SAndroid Build Coastguard Worker }
1317*2d543d20SAndroid Build Coastguard Worker
1318*2d543d20SAndroid Build Coastguard Worker retval = semanage_write_modules_checksum(sh, modules_checksum);
1319*2d543d20SAndroid Build Coastguard Worker if (retval < 0) {
1320*2d543d20SAndroid Build Coastguard Worker ERR(sh, "Failed to write module checksum file.\n");
1321*2d543d20SAndroid Build Coastguard Worker goto cleanup;
1322*2d543d20SAndroid Build Coastguard Worker }
1323*2d543d20SAndroid Build Coastguard Worker }
1324*2d543d20SAndroid Build Coastguard Worker
1325*2d543d20SAndroid Build Coastguard Worker /*
1326*2d543d20SAndroid Build Coastguard Worker * If there were policy changes, or explicitly requested, or
1327*2d543d20SAndroid Build Coastguard Worker * any required files are missing, rebuild the policy.
1328*2d543d20SAndroid Build Coastguard Worker */
1329*2d543d20SAndroid Build Coastguard Worker if (do_rebuild) {
1330*2d543d20SAndroid Build Coastguard Worker /* =================== Module expansion =============== */
1331*2d543d20SAndroid Build Coastguard Worker
1332*2d543d20SAndroid Build Coastguard Worker retval = semanage_get_cil_paths(sh, modinfos, num_modinfos, &mod_filenames);
1333*2d543d20SAndroid Build Coastguard Worker if (retval < 0)
1334*2d543d20SAndroid Build Coastguard Worker goto cleanup;
1335*2d543d20SAndroid Build Coastguard Worker
1336*2d543d20SAndroid Build Coastguard Worker retval = semanage_verify_modules(sh, mod_filenames, num_modinfos);
1337*2d543d20SAndroid Build Coastguard Worker if (retval < 0)
1338*2d543d20SAndroid Build Coastguard Worker goto cleanup;
1339*2d543d20SAndroid Build Coastguard Worker
1340*2d543d20SAndroid Build Coastguard Worker cil_db_init(&cildb);
1341*2d543d20SAndroid Build Coastguard Worker
1342*2d543d20SAndroid Build Coastguard Worker disable_dontaudit = sepol_get_disable_dontaudit(sh->sepolh);
1343*2d543d20SAndroid Build Coastguard Worker preserve_tunables = sepol_get_preserve_tunables(sh->sepolh);
1344*2d543d20SAndroid Build Coastguard Worker cil_set_disable_dontaudit(cildb, disable_dontaudit);
1345*2d543d20SAndroid Build Coastguard Worker cil_set_disable_neverallow(cildb, !(sh->conf->expand_check));
1346*2d543d20SAndroid Build Coastguard Worker cil_set_preserve_tunables(cildb, preserve_tunables);
1347*2d543d20SAndroid Build Coastguard Worker cil_set_target_platform(cildb, sh->conf->target_platform);
1348*2d543d20SAndroid Build Coastguard Worker cil_set_policy_version(cildb, sh->conf->policyvers);
1349*2d543d20SAndroid Build Coastguard Worker
1350*2d543d20SAndroid Build Coastguard Worker if (sh->conf->handle_unknown != -1) {
1351*2d543d20SAndroid Build Coastguard Worker cil_set_handle_unknown(cildb, sh->conf->handle_unknown);
1352*2d543d20SAndroid Build Coastguard Worker }
1353*2d543d20SAndroid Build Coastguard Worker
1354*2d543d20SAndroid Build Coastguard Worker retval = semanage_load_files(sh, cildb, mod_filenames, num_modinfos);
1355*2d543d20SAndroid Build Coastguard Worker if (retval < 0) {
1356*2d543d20SAndroid Build Coastguard Worker goto cleanup;
1357*2d543d20SAndroid Build Coastguard Worker }
1358*2d543d20SAndroid Build Coastguard Worker
1359*2d543d20SAndroid Build Coastguard Worker retval = cil_compile(cildb);
1360*2d543d20SAndroid Build Coastguard Worker if (retval < 0)
1361*2d543d20SAndroid Build Coastguard Worker goto cleanup;
1362*2d543d20SAndroid Build Coastguard Worker
1363*2d543d20SAndroid Build Coastguard Worker retval = cil_build_policydb(cildb, &out);
1364*2d543d20SAndroid Build Coastguard Worker if (retval < 0)
1365*2d543d20SAndroid Build Coastguard Worker goto cleanup;
1366*2d543d20SAndroid Build Coastguard Worker
1367*2d543d20SAndroid Build Coastguard Worker /* File Contexts */
1368*2d543d20SAndroid Build Coastguard Worker retval = cil_filecons_to_string(cildb, &fc_buffer, &fc_buffer_len);
1369*2d543d20SAndroid Build Coastguard Worker if (retval < 0)
1370*2d543d20SAndroid Build Coastguard Worker goto cleanup;
1371*2d543d20SAndroid Build Coastguard Worker
1372*2d543d20SAndroid Build Coastguard Worker /* Write the contexts (including template contexts) to a single file. */
1373*2d543d20SAndroid Build Coastguard Worker ofilename = semanage_path(SEMANAGE_TMP, SEMANAGE_FC_TMPL);
1374*2d543d20SAndroid Build Coastguard Worker if (ofilename == NULL) {
1375*2d543d20SAndroid Build Coastguard Worker retval = -1;
1376*2d543d20SAndroid Build Coastguard Worker goto cleanup;
1377*2d543d20SAndroid Build Coastguard Worker }
1378*2d543d20SAndroid Build Coastguard Worker retval = write_file(sh, ofilename, fc_buffer, fc_buffer_len);
1379*2d543d20SAndroid Build Coastguard Worker if (retval < 0)
1380*2d543d20SAndroid Build Coastguard Worker goto cleanup;
1381*2d543d20SAndroid Build Coastguard Worker
1382*2d543d20SAndroid Build Coastguard Worker /* Split complete and template file contexts into their separate files. */
1383*2d543d20SAndroid Build Coastguard Worker retval = semanage_split_fc(sh);
1384*2d543d20SAndroid Build Coastguard Worker if (retval < 0)
1385*2d543d20SAndroid Build Coastguard Worker goto cleanup;
1386*2d543d20SAndroid Build Coastguard Worker
1387*2d543d20SAndroid Build Coastguard Worker /* remove FC_TMPL now that it is now longer needed */
1388*2d543d20SAndroid Build Coastguard Worker unlink(semanage_path(SEMANAGE_TMP, SEMANAGE_FC_TMPL));
1389*2d543d20SAndroid Build Coastguard Worker
1390*2d543d20SAndroid Build Coastguard Worker pfcontexts->dtable->drop_cache(pfcontexts->dbase);
1391*2d543d20SAndroid Build Coastguard Worker
1392*2d543d20SAndroid Build Coastguard Worker /* SEUsers */
1393*2d543d20SAndroid Build Coastguard Worker retval = semanage_direct_update_seuser(sh, cildb);
1394*2d543d20SAndroid Build Coastguard Worker if (retval < 0)
1395*2d543d20SAndroid Build Coastguard Worker goto cleanup;
1396*2d543d20SAndroid Build Coastguard Worker
1397*2d543d20SAndroid Build Coastguard Worker /* User Extra */
1398*2d543d20SAndroid Build Coastguard Worker retval = semanage_direct_update_user_extra(sh, cildb);
1399*2d543d20SAndroid Build Coastguard Worker if (retval < 0)
1400*2d543d20SAndroid Build Coastguard Worker goto cleanup;
1401*2d543d20SAndroid Build Coastguard Worker
1402*2d543d20SAndroid Build Coastguard Worker cil_db_destroy(&cildb);
1403*2d543d20SAndroid Build Coastguard Worker
1404*2d543d20SAndroid Build Coastguard Worker /* Remove redundancies in binary policy if requested. */
1405*2d543d20SAndroid Build Coastguard Worker if (sh->conf->optimize_policy) {
1406*2d543d20SAndroid Build Coastguard Worker retval = sepol_policydb_optimize(out);
1407*2d543d20SAndroid Build Coastguard Worker if (retval < 0)
1408*2d543d20SAndroid Build Coastguard Worker goto cleanup;
1409*2d543d20SAndroid Build Coastguard Worker }
1410*2d543d20SAndroid Build Coastguard Worker
1411*2d543d20SAndroid Build Coastguard Worker /* Write the linked policy before merging local changes. */
1412*2d543d20SAndroid Build Coastguard Worker retval = semanage_write_policydb(sh, out,
1413*2d543d20SAndroid Build Coastguard Worker SEMANAGE_LINKED);
1414*2d543d20SAndroid Build Coastguard Worker if (retval < 0)
1415*2d543d20SAndroid Build Coastguard Worker goto cleanup;
1416*2d543d20SAndroid Build Coastguard Worker } else {
1417*2d543d20SAndroid Build Coastguard Worker /* Load the existing linked policy, w/o local changes */
1418*2d543d20SAndroid Build Coastguard Worker retval = sepol_policydb_create(&out);
1419*2d543d20SAndroid Build Coastguard Worker if (retval < 0)
1420*2d543d20SAndroid Build Coastguard Worker goto cleanup;
1421*2d543d20SAndroid Build Coastguard Worker
1422*2d543d20SAndroid Build Coastguard Worker retval = semanage_read_policydb(sh, out, SEMANAGE_LINKED);
1423*2d543d20SAndroid Build Coastguard Worker if (retval < 0)
1424*2d543d20SAndroid Build Coastguard Worker goto cleanup;
1425*2d543d20SAndroid Build Coastguard Worker
1426*2d543d20SAndroid Build Coastguard Worker path = semanage_path(SEMANAGE_TMP, SEMANAGE_SEUSERS_LINKED);
1427*2d543d20SAndroid Build Coastguard Worker if (stat(path, &sb) == 0) {
1428*2d543d20SAndroid Build Coastguard Worker retval = semanage_copy_file(path,
1429*2d543d20SAndroid Build Coastguard Worker semanage_path(SEMANAGE_TMP,
1430*2d543d20SAndroid Build Coastguard Worker SEMANAGE_STORE_SEUSERS),
1431*2d543d20SAndroid Build Coastguard Worker 0, false);
1432*2d543d20SAndroid Build Coastguard Worker if (retval < 0)
1433*2d543d20SAndroid Build Coastguard Worker goto cleanup;
1434*2d543d20SAndroid Build Coastguard Worker pseusers->dtable->drop_cache(pseusers->dbase);
1435*2d543d20SAndroid Build Coastguard Worker } else if (errno == ENOENT) {
1436*2d543d20SAndroid Build Coastguard Worker /* The file does not exist */
1437*2d543d20SAndroid Build Coastguard Worker pseusers->dtable->clear(sh, pseusers->dbase);
1438*2d543d20SAndroid Build Coastguard Worker } else {
1439*2d543d20SAndroid Build Coastguard Worker ERR(sh, "Unable to access %s: %s\n", path, strerror(errno));
1440*2d543d20SAndroid Build Coastguard Worker retval = -1;
1441*2d543d20SAndroid Build Coastguard Worker goto cleanup;
1442*2d543d20SAndroid Build Coastguard Worker }
1443*2d543d20SAndroid Build Coastguard Worker
1444*2d543d20SAndroid Build Coastguard Worker path = semanage_path(SEMANAGE_TMP, SEMANAGE_USERS_EXTRA_LINKED);
1445*2d543d20SAndroid Build Coastguard Worker if (stat(path, &sb) == 0) {
1446*2d543d20SAndroid Build Coastguard Worker retval = semanage_copy_file(path,
1447*2d543d20SAndroid Build Coastguard Worker semanage_path(SEMANAGE_TMP,
1448*2d543d20SAndroid Build Coastguard Worker SEMANAGE_USERS_EXTRA),
1449*2d543d20SAndroid Build Coastguard Worker 0, false);
1450*2d543d20SAndroid Build Coastguard Worker if (retval < 0)
1451*2d543d20SAndroid Build Coastguard Worker goto cleanup;
1452*2d543d20SAndroid Build Coastguard Worker pusers_extra->dtable->drop_cache(pusers_extra->dbase);
1453*2d543d20SAndroid Build Coastguard Worker } else if (errno == ENOENT) {
1454*2d543d20SAndroid Build Coastguard Worker /* The file does not exist */
1455*2d543d20SAndroid Build Coastguard Worker pusers_extra->dtable->clear(sh, pusers_extra->dbase);
1456*2d543d20SAndroid Build Coastguard Worker } else {
1457*2d543d20SAndroid Build Coastguard Worker ERR(sh, "Unable to access %s: %s\n", path, strerror(errno));
1458*2d543d20SAndroid Build Coastguard Worker retval = -1;
1459*2d543d20SAndroid Build Coastguard Worker goto cleanup;
1460*2d543d20SAndroid Build Coastguard Worker }
1461*2d543d20SAndroid Build Coastguard Worker }
1462*2d543d20SAndroid Build Coastguard Worker
1463*2d543d20SAndroid Build Coastguard Worker /*
1464*2d543d20SAndroid Build Coastguard Worker * Determine what else needs to be done.
1465*2d543d20SAndroid Build Coastguard Worker * We need to write the kernel policy if we are rebuilding
1466*2d543d20SAndroid Build Coastguard Worker * or if any other policy component that lives in the kernel
1467*2d543d20SAndroid Build Coastguard Worker * policy has been modified. We also want to force it when
1468*2d543d20SAndroid Build Coastguard Worker * check_ext_changes was specified as the various dbases may have
1469*2d543d20SAndroid Build Coastguard Worker * changes as well.
1470*2d543d20SAndroid Build Coastguard Worker * We need to install the policy files if any of the managed files
1471*2d543d20SAndroid Build Coastguard Worker * that live under /etc/selinux (kernel policy, seusers, file contexts)
1472*2d543d20SAndroid Build Coastguard Worker * will be modified.
1473*2d543d20SAndroid Build Coastguard Worker */
1474*2d543d20SAndroid Build Coastguard Worker do_write_kernel = do_rebuild | sh->check_ext_changes |
1475*2d543d20SAndroid Build Coastguard Worker ports_modified | ibpkeys_modified | ibendports_modified |
1476*2d543d20SAndroid Build Coastguard Worker bools->dtable->is_modified(bools->dbase) |
1477*2d543d20SAndroid Build Coastguard Worker ifaces->dtable->is_modified(ifaces->dbase) |
1478*2d543d20SAndroid Build Coastguard Worker nodes->dtable->is_modified(nodes->dbase) |
1479*2d543d20SAndroid Build Coastguard Worker users->dtable->is_modified(users_base->dbase);
1480*2d543d20SAndroid Build Coastguard Worker do_install = do_write_kernel | seusers_modified | fcontexts_modified;
1481*2d543d20SAndroid Build Coastguard Worker
1482*2d543d20SAndroid Build Coastguard Worker /* Attach our databases to the policydb we just created or loaded. */
1483*2d543d20SAndroid Build Coastguard Worker dbase_policydb_attach((dbase_policydb_t *) pusers_base->dbase, out);
1484*2d543d20SAndroid Build Coastguard Worker dbase_policydb_attach((dbase_policydb_t *) pports->dbase, out);
1485*2d543d20SAndroid Build Coastguard Worker dbase_policydb_attach((dbase_policydb_t *) pibpkeys->dbase, out);
1486*2d543d20SAndroid Build Coastguard Worker dbase_policydb_attach((dbase_policydb_t *) pibendports->dbase, out);
1487*2d543d20SAndroid Build Coastguard Worker dbase_policydb_attach((dbase_policydb_t *) pifaces->dbase, out);
1488*2d543d20SAndroid Build Coastguard Worker dbase_policydb_attach((dbase_policydb_t *) pbools->dbase, out);
1489*2d543d20SAndroid Build Coastguard Worker dbase_policydb_attach((dbase_policydb_t *) pnodes->dbase, out);
1490*2d543d20SAndroid Build Coastguard Worker
1491*2d543d20SAndroid Build Coastguard Worker /* Merge local changes */
1492*2d543d20SAndroid Build Coastguard Worker retval = semanage_base_merge_components(sh);
1493*2d543d20SAndroid Build Coastguard Worker if (retval < 0)
1494*2d543d20SAndroid Build Coastguard Worker goto cleanup;
1495*2d543d20SAndroid Build Coastguard Worker
1496*2d543d20SAndroid Build Coastguard Worker if (do_write_kernel) {
1497*2d543d20SAndroid Build Coastguard Worker /* Write new kernel policy. */
1498*2d543d20SAndroid Build Coastguard Worker retval = semanage_write_policydb(sh, out,
1499*2d543d20SAndroid Build Coastguard Worker SEMANAGE_STORE_KERNEL);
1500*2d543d20SAndroid Build Coastguard Worker if (retval < 0)
1501*2d543d20SAndroid Build Coastguard Worker goto cleanup;
1502*2d543d20SAndroid Build Coastguard Worker
1503*2d543d20SAndroid Build Coastguard Worker /* Run the kernel policy verifier, if any. */
1504*2d543d20SAndroid Build Coastguard Worker retval = semanage_verify_kernel(sh);
1505*2d543d20SAndroid Build Coastguard Worker if (retval < 0)
1506*2d543d20SAndroid Build Coastguard Worker goto cleanup;
1507*2d543d20SAndroid Build Coastguard Worker }
1508*2d543d20SAndroid Build Coastguard Worker
1509*2d543d20SAndroid Build Coastguard Worker /* ======= Post-process: Validate non-policydb components ===== */
1510*2d543d20SAndroid Build Coastguard Worker
1511*2d543d20SAndroid Build Coastguard Worker /* Validate local modifications to file contexts.
1512*2d543d20SAndroid Build Coastguard Worker * Note: those are still cached, even though they've been
1513*2d543d20SAndroid Build Coastguard Worker * merged into the main file_contexts. We won't check the
1514*2d543d20SAndroid Build Coastguard Worker * large file_contexts - checked at compile time */
1515*2d543d20SAndroid Build Coastguard Worker if (do_rebuild || fcontexts_modified) {
1516*2d543d20SAndroid Build Coastguard Worker retval = semanage_fcontext_validate_local(sh, out);
1517*2d543d20SAndroid Build Coastguard Worker if (retval < 0)
1518*2d543d20SAndroid Build Coastguard Worker goto cleanup;
1519*2d543d20SAndroid Build Coastguard Worker }
1520*2d543d20SAndroid Build Coastguard Worker
1521*2d543d20SAndroid Build Coastguard Worker /* Validate local seusers against policy */
1522*2d543d20SAndroid Build Coastguard Worker if (do_rebuild || seusers_modified) {
1523*2d543d20SAndroid Build Coastguard Worker retval = semanage_seuser_validate_local(sh, out);
1524*2d543d20SAndroid Build Coastguard Worker if (retval < 0)
1525*2d543d20SAndroid Build Coastguard Worker goto cleanup;
1526*2d543d20SAndroid Build Coastguard Worker }
1527*2d543d20SAndroid Build Coastguard Worker
1528*2d543d20SAndroid Build Coastguard Worker /* Validate local ports for overlap */
1529*2d543d20SAndroid Build Coastguard Worker if (do_rebuild || ports_modified) {
1530*2d543d20SAndroid Build Coastguard Worker retval = semanage_port_validate_local(sh);
1531*2d543d20SAndroid Build Coastguard Worker if (retval < 0)
1532*2d543d20SAndroid Build Coastguard Worker goto cleanup;
1533*2d543d20SAndroid Build Coastguard Worker }
1534*2d543d20SAndroid Build Coastguard Worker
1535*2d543d20SAndroid Build Coastguard Worker /* Validate local ibpkeys for overlap */
1536*2d543d20SAndroid Build Coastguard Worker if (do_rebuild || ibpkeys_modified) {
1537*2d543d20SAndroid Build Coastguard Worker retval = semanage_ibpkey_validate_local(sh);
1538*2d543d20SAndroid Build Coastguard Worker if (retval < 0)
1539*2d543d20SAndroid Build Coastguard Worker goto cleanup;
1540*2d543d20SAndroid Build Coastguard Worker }
1541*2d543d20SAndroid Build Coastguard Worker
1542*2d543d20SAndroid Build Coastguard Worker /* Validate local ibendports */
1543*2d543d20SAndroid Build Coastguard Worker if (do_rebuild || ibendports_modified) {
1544*2d543d20SAndroid Build Coastguard Worker retval = semanage_ibendport_validate_local(sh);
1545*2d543d20SAndroid Build Coastguard Worker if (retval < 0)
1546*2d543d20SAndroid Build Coastguard Worker goto cleanup;
1547*2d543d20SAndroid Build Coastguard Worker }
1548*2d543d20SAndroid Build Coastguard Worker /* ================== Write non-policydb components ========= */
1549*2d543d20SAndroid Build Coastguard Worker
1550*2d543d20SAndroid Build Coastguard Worker /* Commit changes to components */
1551*2d543d20SAndroid Build Coastguard Worker retval = semanage_commit_components(sh);
1552*2d543d20SAndroid Build Coastguard Worker if (retval < 0)
1553*2d543d20SAndroid Build Coastguard Worker goto cleanup;
1554*2d543d20SAndroid Build Coastguard Worker
1555*2d543d20SAndroid Build Coastguard Worker retval = semanage_copy_file(semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_KERNEL),
1556*2d543d20SAndroid Build Coastguard Worker semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_KERNEL),
1557*2d543d20SAndroid Build Coastguard Worker sh->conf->file_mode, false);
1558*2d543d20SAndroid Build Coastguard Worker if (retval < 0) {
1559*2d543d20SAndroid Build Coastguard Worker goto cleanup;
1560*2d543d20SAndroid Build Coastguard Worker }
1561*2d543d20SAndroid Build Coastguard Worker
1562*2d543d20SAndroid Build Coastguard Worker retval = copy_file_if_exists(semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC_LOCAL),
1563*2d543d20SAndroid Build Coastguard Worker semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_FC_LOCAL),
1564*2d543d20SAndroid Build Coastguard Worker sh->conf->file_mode);
1565*2d543d20SAndroid Build Coastguard Worker if (retval < 0) {
1566*2d543d20SAndroid Build Coastguard Worker goto cleanup;
1567*2d543d20SAndroid Build Coastguard Worker }
1568*2d543d20SAndroid Build Coastguard Worker
1569*2d543d20SAndroid Build Coastguard Worker retval = copy_file_if_exists(semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC),
1570*2d543d20SAndroid Build Coastguard Worker semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_FC),
1571*2d543d20SAndroid Build Coastguard Worker sh->conf->file_mode);
1572*2d543d20SAndroid Build Coastguard Worker if (retval < 0) {
1573*2d543d20SAndroid Build Coastguard Worker goto cleanup;
1574*2d543d20SAndroid Build Coastguard Worker }
1575*2d543d20SAndroid Build Coastguard Worker
1576*2d543d20SAndroid Build Coastguard Worker retval = copy_file_if_exists(semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_SEUSERS),
1577*2d543d20SAndroid Build Coastguard Worker semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_SEUSERS),
1578*2d543d20SAndroid Build Coastguard Worker sh->conf->file_mode);
1579*2d543d20SAndroid Build Coastguard Worker if (retval < 0) {
1580*2d543d20SAndroid Build Coastguard Worker goto cleanup;
1581*2d543d20SAndroid Build Coastguard Worker }
1582*2d543d20SAndroid Build Coastguard Worker
1583*2d543d20SAndroid Build Coastguard Worker /* run genhomedircon if its enabled, this should be the last operation
1584*2d543d20SAndroid Build Coastguard Worker * which requires the out policydb */
1585*2d543d20SAndroid Build Coastguard Worker if (!sh->conf->disable_genhomedircon) {
1586*2d543d20SAndroid Build Coastguard Worker if (out){
1587*2d543d20SAndroid Build Coastguard Worker if ((retval = semanage_genhomedircon(sh, out, sh->conf->usepasswd,
1588*2d543d20SAndroid Build Coastguard Worker sh->conf->ignoredirs)) != 0) {
1589*2d543d20SAndroid Build Coastguard Worker ERR(sh, "semanage_genhomedircon returned error code %d.", retval);
1590*2d543d20SAndroid Build Coastguard Worker goto cleanup;
1591*2d543d20SAndroid Build Coastguard Worker }
1592*2d543d20SAndroid Build Coastguard Worker /* file_contexts.homedirs was created in SEMANAGE_TMP store */
1593*2d543d20SAndroid Build Coastguard Worker retval = semanage_copy_file(
1594*2d543d20SAndroid Build Coastguard Worker semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC_HOMEDIRS),
1595*2d543d20SAndroid Build Coastguard Worker semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_FC_HOMEDIRS),
1596*2d543d20SAndroid Build Coastguard Worker sh->conf->file_mode, false);
1597*2d543d20SAndroid Build Coastguard Worker if (retval < 0) {
1598*2d543d20SAndroid Build Coastguard Worker goto cleanup;
1599*2d543d20SAndroid Build Coastguard Worker }
1600*2d543d20SAndroid Build Coastguard Worker }
1601*2d543d20SAndroid Build Coastguard Worker } else {
1602*2d543d20SAndroid Build Coastguard Worker WARN(sh, "WARNING: genhomedircon is disabled. \
1603*2d543d20SAndroid Build Coastguard Worker See /etc/selinux/semanage.conf if you need to enable it.");
1604*2d543d20SAndroid Build Coastguard Worker }
1605*2d543d20SAndroid Build Coastguard Worker
1606*2d543d20SAndroid Build Coastguard Worker /* free out, if we don't free it before calling semanage_install_sandbox
1607*2d543d20SAndroid Build Coastguard Worker * then fork() may fail on low memory machines */
1608*2d543d20SAndroid Build Coastguard Worker sepol_policydb_free(out);
1609*2d543d20SAndroid Build Coastguard Worker out = NULL;
1610*2d543d20SAndroid Build Coastguard Worker
1611*2d543d20SAndroid Build Coastguard Worker if (do_install)
1612*2d543d20SAndroid Build Coastguard Worker retval = semanage_install_sandbox(sh);
1613*2d543d20SAndroid Build Coastguard Worker
1614*2d543d20SAndroid Build Coastguard Worker cleanup:
1615*2d543d20SAndroid Build Coastguard Worker for (i = 0; i < num_modinfos; i++) {
1616*2d543d20SAndroid Build Coastguard Worker semanage_module_info_destroy(sh, &modinfos[i]);
1617*2d543d20SAndroid Build Coastguard Worker }
1618*2d543d20SAndroid Build Coastguard Worker free(modinfos);
1619*2d543d20SAndroid Build Coastguard Worker
1620*2d543d20SAndroid Build Coastguard Worker for (i = 0; mod_filenames != NULL && i < num_modinfos; i++) {
1621*2d543d20SAndroid Build Coastguard Worker free(mod_filenames[i]);
1622*2d543d20SAndroid Build Coastguard Worker }
1623*2d543d20SAndroid Build Coastguard Worker
1624*2d543d20SAndroid Build Coastguard Worker /* Detach from policydb, so it can be freed */
1625*2d543d20SAndroid Build Coastguard Worker dbase_policydb_detach((dbase_policydb_t *) pusers_base->dbase);
1626*2d543d20SAndroid Build Coastguard Worker dbase_policydb_detach((dbase_policydb_t *) pports->dbase);
1627*2d543d20SAndroid Build Coastguard Worker dbase_policydb_detach((dbase_policydb_t *) pibpkeys->dbase);
1628*2d543d20SAndroid Build Coastguard Worker dbase_policydb_detach((dbase_policydb_t *) pibendports->dbase);
1629*2d543d20SAndroid Build Coastguard Worker dbase_policydb_detach((dbase_policydb_t *) pifaces->dbase);
1630*2d543d20SAndroid Build Coastguard Worker dbase_policydb_detach((dbase_policydb_t *) pnodes->dbase);
1631*2d543d20SAndroid Build Coastguard Worker dbase_policydb_detach((dbase_policydb_t *) pbools->dbase);
1632*2d543d20SAndroid Build Coastguard Worker
1633*2d543d20SAndroid Build Coastguard Worker free(mod_filenames);
1634*2d543d20SAndroid Build Coastguard Worker sepol_policydb_free(out);
1635*2d543d20SAndroid Build Coastguard Worker cil_db_destroy(&cildb);
1636*2d543d20SAndroid Build Coastguard Worker
1637*2d543d20SAndroid Build Coastguard Worker free(fc_buffer);
1638*2d543d20SAndroid Build Coastguard Worker
1639*2d543d20SAndroid Build Coastguard Worker /* Set commit_err so other functions can detect any errors. Note that
1640*2d543d20SAndroid Build Coastguard Worker * retval > 0 will be the commit number.
1641*2d543d20SAndroid Build Coastguard Worker */
1642*2d543d20SAndroid Build Coastguard Worker if (retval < 0)
1643*2d543d20SAndroid Build Coastguard Worker sh->commit_err = retval;
1644*2d543d20SAndroid Build Coastguard Worker
1645*2d543d20SAndroid Build Coastguard Worker if (semanage_remove_tmps(sh) != 0)
1646*2d543d20SAndroid Build Coastguard Worker retval = -1;
1647*2d543d20SAndroid Build Coastguard Worker
1648*2d543d20SAndroid Build Coastguard Worker semanage_release_trans_lock(sh);
1649*2d543d20SAndroid Build Coastguard Worker umask(mask);
1650*2d543d20SAndroid Build Coastguard Worker
1651*2d543d20SAndroid Build Coastguard Worker return retval;
1652*2d543d20SAndroid Build Coastguard Worker }
1653*2d543d20SAndroid Build Coastguard Worker
1654*2d543d20SAndroid Build Coastguard Worker /* Writes a module to the sandbox's module directory, overwriting any
1655*2d543d20SAndroid Build Coastguard Worker * previous module stored within. Note that module data are not
1656*2d543d20SAndroid Build Coastguard Worker * free()d by this function; caller is responsible for deallocating it
1657*2d543d20SAndroid Build Coastguard Worker * if necessary. Returns 0 on success, -1 if out of memory, -2 if the
1658*2d543d20SAndroid Build Coastguard Worker * data does not represent a valid module file, -3 if error while
1659*2d543d20SAndroid Build Coastguard Worker * writing file. */
semanage_direct_install(semanage_handle_t * sh,char * data,size_t data_len,const char * module_name,const char * lang_ext)1660*2d543d20SAndroid Build Coastguard Worker static int semanage_direct_install(semanage_handle_t * sh,
1661*2d543d20SAndroid Build Coastguard Worker char *data, size_t data_len,
1662*2d543d20SAndroid Build Coastguard Worker const char *module_name, const char *lang_ext)
1663*2d543d20SAndroid Build Coastguard Worker {
1664*2d543d20SAndroid Build Coastguard Worker int status = 0;
1665*2d543d20SAndroid Build Coastguard Worker int ret = 0;
1666*2d543d20SAndroid Build Coastguard Worker
1667*2d543d20SAndroid Build Coastguard Worker semanage_module_info_t modinfo;
1668*2d543d20SAndroid Build Coastguard Worker ret = semanage_module_info_init(sh, &modinfo);
1669*2d543d20SAndroid Build Coastguard Worker if (ret != 0) {
1670*2d543d20SAndroid Build Coastguard Worker status = -1;
1671*2d543d20SAndroid Build Coastguard Worker goto cleanup;
1672*2d543d20SAndroid Build Coastguard Worker }
1673*2d543d20SAndroid Build Coastguard Worker
1674*2d543d20SAndroid Build Coastguard Worker ret = semanage_module_info_set_priority(sh, &modinfo, sh->priority);
1675*2d543d20SAndroid Build Coastguard Worker if (ret != 0) {
1676*2d543d20SAndroid Build Coastguard Worker status = -1;
1677*2d543d20SAndroid Build Coastguard Worker goto cleanup;
1678*2d543d20SAndroid Build Coastguard Worker }
1679*2d543d20SAndroid Build Coastguard Worker
1680*2d543d20SAndroid Build Coastguard Worker ret = semanage_module_info_set_name(sh, &modinfo, module_name);
1681*2d543d20SAndroid Build Coastguard Worker if (ret != 0) {
1682*2d543d20SAndroid Build Coastguard Worker status = -1;
1683*2d543d20SAndroid Build Coastguard Worker goto cleanup;
1684*2d543d20SAndroid Build Coastguard Worker }
1685*2d543d20SAndroid Build Coastguard Worker
1686*2d543d20SAndroid Build Coastguard Worker ret = semanage_module_info_set_lang_ext(sh, &modinfo, lang_ext);
1687*2d543d20SAndroid Build Coastguard Worker if (ret != 0) {
1688*2d543d20SAndroid Build Coastguard Worker status = -1;
1689*2d543d20SAndroid Build Coastguard Worker goto cleanup;
1690*2d543d20SAndroid Build Coastguard Worker }
1691*2d543d20SAndroid Build Coastguard Worker
1692*2d543d20SAndroid Build Coastguard Worker ret = semanage_module_info_set_enabled(sh, &modinfo, -1);
1693*2d543d20SAndroid Build Coastguard Worker if (ret != 0) {
1694*2d543d20SAndroid Build Coastguard Worker status = -1;
1695*2d543d20SAndroid Build Coastguard Worker goto cleanup;
1696*2d543d20SAndroid Build Coastguard Worker }
1697*2d543d20SAndroid Build Coastguard Worker
1698*2d543d20SAndroid Build Coastguard Worker status = semanage_direct_install_info(sh, &modinfo, data, data_len);
1699*2d543d20SAndroid Build Coastguard Worker
1700*2d543d20SAndroid Build Coastguard Worker cleanup:
1701*2d543d20SAndroid Build Coastguard Worker
1702*2d543d20SAndroid Build Coastguard Worker semanage_module_info_destroy(sh, &modinfo);
1703*2d543d20SAndroid Build Coastguard Worker
1704*2d543d20SAndroid Build Coastguard Worker return status;
1705*2d543d20SAndroid Build Coastguard Worker }
1706*2d543d20SAndroid Build Coastguard Worker
1707*2d543d20SAndroid Build Coastguard Worker /* Attempts to link a module to the sandbox's module directory, unlinking any
1708*2d543d20SAndroid Build Coastguard Worker * previous module stored within. Returns 0 on success, -1 if out of memory, -2 if the
1709*2d543d20SAndroid Build Coastguard Worker * data does not represent a valid module file, -3 if error while
1710*2d543d20SAndroid Build Coastguard Worker * writing file. */
1711*2d543d20SAndroid Build Coastguard Worker
semanage_direct_install_file(semanage_handle_t * sh,const char * install_filename)1712*2d543d20SAndroid Build Coastguard Worker static int semanage_direct_install_file(semanage_handle_t * sh,
1713*2d543d20SAndroid Build Coastguard Worker const char *install_filename)
1714*2d543d20SAndroid Build Coastguard Worker {
1715*2d543d20SAndroid Build Coastguard Worker
1716*2d543d20SAndroid Build Coastguard Worker int retval = -1;
1717*2d543d20SAndroid Build Coastguard Worker char *path = NULL;
1718*2d543d20SAndroid Build Coastguard Worker char *filename;
1719*2d543d20SAndroid Build Coastguard Worker char *lang_ext = NULL;
1720*2d543d20SAndroid Build Coastguard Worker char *module_name = NULL;
1721*2d543d20SAndroid Build Coastguard Worker char *separator;
1722*2d543d20SAndroid Build Coastguard Worker char *version = NULL;
1723*2d543d20SAndroid Build Coastguard Worker struct file_contents contents = {};
1724*2d543d20SAndroid Build Coastguard Worker
1725*2d543d20SAndroid Build Coastguard Worker retval = map_compressed_file(sh, install_filename, &contents);
1726*2d543d20SAndroid Build Coastguard Worker if (retval < 0) {
1727*2d543d20SAndroid Build Coastguard Worker ERR(sh, "Unable to read file %s\n", install_filename);
1728*2d543d20SAndroid Build Coastguard Worker goto cleanup;
1729*2d543d20SAndroid Build Coastguard Worker }
1730*2d543d20SAndroid Build Coastguard Worker
1731*2d543d20SAndroid Build Coastguard Worker path = strdup(install_filename);
1732*2d543d20SAndroid Build Coastguard Worker if (path == NULL) {
1733*2d543d20SAndroid Build Coastguard Worker ERR(sh, "No memory available for strdup.\n");
1734*2d543d20SAndroid Build Coastguard Worker retval = -1;
1735*2d543d20SAndroid Build Coastguard Worker goto cleanup;
1736*2d543d20SAndroid Build Coastguard Worker }
1737*2d543d20SAndroid Build Coastguard Worker
1738*2d543d20SAndroid Build Coastguard Worker filename = basename(path);
1739*2d543d20SAndroid Build Coastguard Worker
1740*2d543d20SAndroid Build Coastguard Worker if (contents.compressed) {
1741*2d543d20SAndroid Build Coastguard Worker separator = strrchr(filename, '.');
1742*2d543d20SAndroid Build Coastguard Worker if (separator == NULL) {
1743*2d543d20SAndroid Build Coastguard Worker ERR(sh, "Compressed module does not have a valid extension.");
1744*2d543d20SAndroid Build Coastguard Worker retval = -1;
1745*2d543d20SAndroid Build Coastguard Worker goto cleanup;
1746*2d543d20SAndroid Build Coastguard Worker }
1747*2d543d20SAndroid Build Coastguard Worker *separator = '\0';
1748*2d543d20SAndroid Build Coastguard Worker lang_ext = separator + 1;
1749*2d543d20SAndroid Build Coastguard Worker }
1750*2d543d20SAndroid Build Coastguard Worker
1751*2d543d20SAndroid Build Coastguard Worker separator = strrchr(filename, '.');
1752*2d543d20SAndroid Build Coastguard Worker if (separator == NULL) {
1753*2d543d20SAndroid Build Coastguard Worker if (lang_ext == NULL) {
1754*2d543d20SAndroid Build Coastguard Worker ERR(sh, "Module does not have a valid extension.");
1755*2d543d20SAndroid Build Coastguard Worker retval = -1;
1756*2d543d20SAndroid Build Coastguard Worker goto cleanup;
1757*2d543d20SAndroid Build Coastguard Worker }
1758*2d543d20SAndroid Build Coastguard Worker } else {
1759*2d543d20SAndroid Build Coastguard Worker *separator = '\0';
1760*2d543d20SAndroid Build Coastguard Worker lang_ext = separator + 1;
1761*2d543d20SAndroid Build Coastguard Worker }
1762*2d543d20SAndroid Build Coastguard Worker
1763*2d543d20SAndroid Build Coastguard Worker if (strcmp(lang_ext, "pp") == 0) {
1764*2d543d20SAndroid Build Coastguard Worker retval = parse_module_headers(sh, contents.data, contents.len,
1765*2d543d20SAndroid Build Coastguard Worker &module_name, &version);
1766*2d543d20SAndroid Build Coastguard Worker free(version);
1767*2d543d20SAndroid Build Coastguard Worker if (retval != 0)
1768*2d543d20SAndroid Build Coastguard Worker goto cleanup;
1769*2d543d20SAndroid Build Coastguard Worker }
1770*2d543d20SAndroid Build Coastguard Worker
1771*2d543d20SAndroid Build Coastguard Worker if (module_name == NULL) {
1772*2d543d20SAndroid Build Coastguard Worker module_name = strdup(filename);
1773*2d543d20SAndroid Build Coastguard Worker if (module_name == NULL) {
1774*2d543d20SAndroid Build Coastguard Worker ERR(sh, "No memory available for module_name.\n");
1775*2d543d20SAndroid Build Coastguard Worker retval = -1;
1776*2d543d20SAndroid Build Coastguard Worker goto cleanup;
1777*2d543d20SAndroid Build Coastguard Worker }
1778*2d543d20SAndroid Build Coastguard Worker } else if (strcmp(module_name, filename) != 0) {
1779*2d543d20SAndroid Build Coastguard Worker fprintf(stderr, "Warning: SELinux userspace will refer to the module from %s as %s rather than %s\n", install_filename, module_name, filename);
1780*2d543d20SAndroid Build Coastguard Worker }
1781*2d543d20SAndroid Build Coastguard Worker
1782*2d543d20SAndroid Build Coastguard Worker retval = semanage_direct_install(sh, contents.data, contents.len,
1783*2d543d20SAndroid Build Coastguard Worker module_name, lang_ext);
1784*2d543d20SAndroid Build Coastguard Worker
1785*2d543d20SAndroid Build Coastguard Worker cleanup:
1786*2d543d20SAndroid Build Coastguard Worker unmap_compressed_file(&contents);
1787*2d543d20SAndroid Build Coastguard Worker free(module_name);
1788*2d543d20SAndroid Build Coastguard Worker free(path);
1789*2d543d20SAndroid Build Coastguard Worker
1790*2d543d20SAndroid Build Coastguard Worker return retval;
1791*2d543d20SAndroid Build Coastguard Worker }
1792*2d543d20SAndroid Build Coastguard Worker
semanage_direct_extract(semanage_handle_t * sh,semanage_module_key_t * modkey,int extract_cil,void ** mapped_data,size_t * data_len,semanage_module_info_t ** modinfo)1793*2d543d20SAndroid Build Coastguard Worker static int semanage_direct_extract(semanage_handle_t * sh,
1794*2d543d20SAndroid Build Coastguard Worker semanage_module_key_t *modkey,
1795*2d543d20SAndroid Build Coastguard Worker int extract_cil,
1796*2d543d20SAndroid Build Coastguard Worker void **mapped_data,
1797*2d543d20SAndroid Build Coastguard Worker size_t *data_len,
1798*2d543d20SAndroid Build Coastguard Worker semanage_module_info_t **modinfo)
1799*2d543d20SAndroid Build Coastguard Worker {
1800*2d543d20SAndroid Build Coastguard Worker char module_path[PATH_MAX];
1801*2d543d20SAndroid Build Coastguard Worker char input_file[PATH_MAX];
1802*2d543d20SAndroid Build Coastguard Worker enum semanage_module_path_type file_type;
1803*2d543d20SAndroid Build Coastguard Worker int rc = -1;
1804*2d543d20SAndroid Build Coastguard Worker semanage_module_info_t *_modinfo = NULL;
1805*2d543d20SAndroid Build Coastguard Worker struct stat sb;
1806*2d543d20SAndroid Build Coastguard Worker struct file_contents contents = {};
1807*2d543d20SAndroid Build Coastguard Worker
1808*2d543d20SAndroid Build Coastguard Worker /* get path of module */
1809*2d543d20SAndroid Build Coastguard Worker rc = semanage_module_get_path(
1810*2d543d20SAndroid Build Coastguard Worker sh,
1811*2d543d20SAndroid Build Coastguard Worker (const semanage_module_info_t *)modkey,
1812*2d543d20SAndroid Build Coastguard Worker SEMANAGE_MODULE_PATH_NAME,
1813*2d543d20SAndroid Build Coastguard Worker module_path,
1814*2d543d20SAndroid Build Coastguard Worker sizeof(module_path));
1815*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
1816*2d543d20SAndroid Build Coastguard Worker goto cleanup;
1817*2d543d20SAndroid Build Coastguard Worker }
1818*2d543d20SAndroid Build Coastguard Worker
1819*2d543d20SAndroid Build Coastguard Worker if (stat(module_path, &sb) != 0) {
1820*2d543d20SAndroid Build Coastguard Worker ERR(sh, "Unable to access %s: %s\n", module_path, strerror(errno));
1821*2d543d20SAndroid Build Coastguard Worker rc = -1;
1822*2d543d20SAndroid Build Coastguard Worker goto cleanup;
1823*2d543d20SAndroid Build Coastguard Worker }
1824*2d543d20SAndroid Build Coastguard Worker
1825*2d543d20SAndroid Build Coastguard Worker rc = semanage_module_get_module_info(sh,
1826*2d543d20SAndroid Build Coastguard Worker modkey,
1827*2d543d20SAndroid Build Coastguard Worker &_modinfo);
1828*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
1829*2d543d20SAndroid Build Coastguard Worker goto cleanup;
1830*2d543d20SAndroid Build Coastguard Worker }
1831*2d543d20SAndroid Build Coastguard Worker
1832*2d543d20SAndroid Build Coastguard Worker if (extract_cil || strcmp(_modinfo->lang_ext, "cil") == 0) {
1833*2d543d20SAndroid Build Coastguard Worker file_type = SEMANAGE_MODULE_PATH_CIL;
1834*2d543d20SAndroid Build Coastguard Worker } else {
1835*2d543d20SAndroid Build Coastguard Worker file_type = SEMANAGE_MODULE_PATH_HLL;
1836*2d543d20SAndroid Build Coastguard Worker }
1837*2d543d20SAndroid Build Coastguard Worker
1838*2d543d20SAndroid Build Coastguard Worker /* get path of what to extract */
1839*2d543d20SAndroid Build Coastguard Worker rc = semanage_module_get_path(
1840*2d543d20SAndroid Build Coastguard Worker sh,
1841*2d543d20SAndroid Build Coastguard Worker _modinfo,
1842*2d543d20SAndroid Build Coastguard Worker file_type,
1843*2d543d20SAndroid Build Coastguard Worker input_file,
1844*2d543d20SAndroid Build Coastguard Worker sizeof(input_file));
1845*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
1846*2d543d20SAndroid Build Coastguard Worker goto cleanup;
1847*2d543d20SAndroid Build Coastguard Worker }
1848*2d543d20SAndroid Build Coastguard Worker
1849*2d543d20SAndroid Build Coastguard Worker if (extract_cil == 1 && strcmp(_modinfo->lang_ext, "cil") && stat(input_file, &sb) != 0) {
1850*2d543d20SAndroid Build Coastguard Worker if (errno != ENOENT) {
1851*2d543d20SAndroid Build Coastguard Worker ERR(sh, "Unable to access %s: %s\n", input_file, strerror(errno));
1852*2d543d20SAndroid Build Coastguard Worker rc = -1;
1853*2d543d20SAndroid Build Coastguard Worker goto cleanup;
1854*2d543d20SAndroid Build Coastguard Worker }
1855*2d543d20SAndroid Build Coastguard Worker
1856*2d543d20SAndroid Build Coastguard Worker rc = semanage_compile_module(sh, _modinfo, NULL);
1857*2d543d20SAndroid Build Coastguard Worker if (rc < 0) {
1858*2d543d20SAndroid Build Coastguard Worker goto cleanup;
1859*2d543d20SAndroid Build Coastguard Worker }
1860*2d543d20SAndroid Build Coastguard Worker }
1861*2d543d20SAndroid Build Coastguard Worker
1862*2d543d20SAndroid Build Coastguard Worker rc = map_compressed_file(sh, input_file, &contents);
1863*2d543d20SAndroid Build Coastguard Worker if (rc < 0) {
1864*2d543d20SAndroid Build Coastguard Worker ERR(sh, "Error mapping file: %s", input_file);
1865*2d543d20SAndroid Build Coastguard Worker goto cleanup;
1866*2d543d20SAndroid Build Coastguard Worker }
1867*2d543d20SAndroid Build Coastguard Worker
1868*2d543d20SAndroid Build Coastguard Worker /* The API promises an mmap'ed pointer */
1869*2d543d20SAndroid Build Coastguard Worker if (contents.compressed) {
1870*2d543d20SAndroid Build Coastguard Worker *mapped_data = mmap(NULL, contents.len, PROT_READ|PROT_WRITE,
1871*2d543d20SAndroid Build Coastguard Worker MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
1872*2d543d20SAndroid Build Coastguard Worker if (*mapped_data == MAP_FAILED) {
1873*2d543d20SAndroid Build Coastguard Worker ERR(sh, "Unable to map memory");
1874*2d543d20SAndroid Build Coastguard Worker rc = -1;
1875*2d543d20SAndroid Build Coastguard Worker goto cleanup;
1876*2d543d20SAndroid Build Coastguard Worker }
1877*2d543d20SAndroid Build Coastguard Worker memcpy(*mapped_data, contents.data, contents.len);
1878*2d543d20SAndroid Build Coastguard Worker free(contents.data);
1879*2d543d20SAndroid Build Coastguard Worker } else {
1880*2d543d20SAndroid Build Coastguard Worker *mapped_data = contents.data;
1881*2d543d20SAndroid Build Coastguard Worker }
1882*2d543d20SAndroid Build Coastguard Worker
1883*2d543d20SAndroid Build Coastguard Worker *modinfo = _modinfo;
1884*2d543d20SAndroid Build Coastguard Worker *data_len = contents.len;
1885*2d543d20SAndroid Build Coastguard Worker
1886*2d543d20SAndroid Build Coastguard Worker cleanup:
1887*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
1888*2d543d20SAndroid Build Coastguard Worker unmap_compressed_file(&contents);
1889*2d543d20SAndroid Build Coastguard Worker semanage_module_info_destroy(sh, _modinfo);
1890*2d543d20SAndroid Build Coastguard Worker free(_modinfo);
1891*2d543d20SAndroid Build Coastguard Worker }
1892*2d543d20SAndroid Build Coastguard Worker
1893*2d543d20SAndroid Build Coastguard Worker return rc;
1894*2d543d20SAndroid Build Coastguard Worker }
1895*2d543d20SAndroid Build Coastguard Worker
1896*2d543d20SAndroid Build Coastguard Worker /* Removes a module from the sandbox. Returns 0 on success, -1 if out
1897*2d543d20SAndroid Build Coastguard Worker * of memory, -2 if module not found or could not be removed. */
semanage_direct_remove(semanage_handle_t * sh,char * module_name)1898*2d543d20SAndroid Build Coastguard Worker static int semanage_direct_remove(semanage_handle_t * sh, char *module_name)
1899*2d543d20SAndroid Build Coastguard Worker {
1900*2d543d20SAndroid Build Coastguard Worker int status = 0;
1901*2d543d20SAndroid Build Coastguard Worker int ret = 0;
1902*2d543d20SAndroid Build Coastguard Worker
1903*2d543d20SAndroid Build Coastguard Worker semanage_module_key_t modkey;
1904*2d543d20SAndroid Build Coastguard Worker ret = semanage_module_key_init(sh, &modkey);
1905*2d543d20SAndroid Build Coastguard Worker if (ret != 0) {
1906*2d543d20SAndroid Build Coastguard Worker status = -1;
1907*2d543d20SAndroid Build Coastguard Worker goto cleanup;
1908*2d543d20SAndroid Build Coastguard Worker }
1909*2d543d20SAndroid Build Coastguard Worker
1910*2d543d20SAndroid Build Coastguard Worker ret = semanage_module_key_set_priority(sh, &modkey, sh->priority);
1911*2d543d20SAndroid Build Coastguard Worker if (ret != 0) {
1912*2d543d20SAndroid Build Coastguard Worker status = -1;
1913*2d543d20SAndroid Build Coastguard Worker goto cleanup;
1914*2d543d20SAndroid Build Coastguard Worker }
1915*2d543d20SAndroid Build Coastguard Worker
1916*2d543d20SAndroid Build Coastguard Worker ret = semanage_module_key_set_name(sh, &modkey, module_name);
1917*2d543d20SAndroid Build Coastguard Worker if (ret != 0) {
1918*2d543d20SAndroid Build Coastguard Worker status = -1;
1919*2d543d20SAndroid Build Coastguard Worker goto cleanup;
1920*2d543d20SAndroid Build Coastguard Worker }
1921*2d543d20SAndroid Build Coastguard Worker
1922*2d543d20SAndroid Build Coastguard Worker status = semanage_direct_remove_key(sh, &modkey);
1923*2d543d20SAndroid Build Coastguard Worker
1924*2d543d20SAndroid Build Coastguard Worker cleanup:
1925*2d543d20SAndroid Build Coastguard Worker semanage_module_key_destroy(sh, &modkey);
1926*2d543d20SAndroid Build Coastguard Worker return status;
1927*2d543d20SAndroid Build Coastguard Worker }
1928*2d543d20SAndroid Build Coastguard Worker
1929*2d543d20SAndroid Build Coastguard Worker /* Allocate an array of module_info structures for each readable
1930*2d543d20SAndroid Build Coastguard Worker * module within the store. Note that if the calling program has
1931*2d543d20SAndroid Build Coastguard Worker * already begun a transaction then this function will get a list of
1932*2d543d20SAndroid Build Coastguard Worker * modules within the sandbox. The caller is responsible for calling
1933*2d543d20SAndroid Build Coastguard Worker * semanage_module_info_datum_destroy() on each element of the array
1934*2d543d20SAndroid Build Coastguard Worker * as well as free()ing the entire list.
1935*2d543d20SAndroid Build Coastguard Worker */
semanage_direct_list(semanage_handle_t * sh,semanage_module_info_t ** modinfo,int * num_modules)1936*2d543d20SAndroid Build Coastguard Worker static int semanage_direct_list(semanage_handle_t * sh,
1937*2d543d20SAndroid Build Coastguard Worker semanage_module_info_t ** modinfo,
1938*2d543d20SAndroid Build Coastguard Worker int *num_modules)
1939*2d543d20SAndroid Build Coastguard Worker {
1940*2d543d20SAndroid Build Coastguard Worker int i, retval = -1;
1941*2d543d20SAndroid Build Coastguard Worker *modinfo = NULL;
1942*2d543d20SAndroid Build Coastguard Worker *num_modules = 0;
1943*2d543d20SAndroid Build Coastguard Worker
1944*2d543d20SAndroid Build Coastguard Worker /* get the read lock when reading from the active
1945*2d543d20SAndroid Build Coastguard Worker (non-transaction) directory */
1946*2d543d20SAndroid Build Coastguard Worker if (!sh->is_in_transaction)
1947*2d543d20SAndroid Build Coastguard Worker if (semanage_get_active_lock(sh) < 0)
1948*2d543d20SAndroid Build Coastguard Worker return -1;
1949*2d543d20SAndroid Build Coastguard Worker
1950*2d543d20SAndroid Build Coastguard Worker if (semanage_get_active_modules(sh, modinfo, num_modules) == -1) {
1951*2d543d20SAndroid Build Coastguard Worker goto cleanup;
1952*2d543d20SAndroid Build Coastguard Worker }
1953*2d543d20SAndroid Build Coastguard Worker
1954*2d543d20SAndroid Build Coastguard Worker if (num_modules == 0) {
1955*2d543d20SAndroid Build Coastguard Worker retval = semanage_direct_get_serial(sh);
1956*2d543d20SAndroid Build Coastguard Worker goto cleanup;
1957*2d543d20SAndroid Build Coastguard Worker }
1958*2d543d20SAndroid Build Coastguard Worker
1959*2d543d20SAndroid Build Coastguard Worker retval = semanage_direct_get_serial(sh);
1960*2d543d20SAndroid Build Coastguard Worker
1961*2d543d20SAndroid Build Coastguard Worker cleanup:
1962*2d543d20SAndroid Build Coastguard Worker if (retval < 0) {
1963*2d543d20SAndroid Build Coastguard Worker for (i = 0; i < *num_modules; i++) {
1964*2d543d20SAndroid Build Coastguard Worker semanage_module_info_destroy(sh, &(*modinfo[i]));
1965*2d543d20SAndroid Build Coastguard Worker modinfo[i] = NULL;
1966*2d543d20SAndroid Build Coastguard Worker }
1967*2d543d20SAndroid Build Coastguard Worker free(*modinfo);
1968*2d543d20SAndroid Build Coastguard Worker *modinfo = NULL;
1969*2d543d20SAndroid Build Coastguard Worker }
1970*2d543d20SAndroid Build Coastguard Worker
1971*2d543d20SAndroid Build Coastguard Worker if (!sh->is_in_transaction) {
1972*2d543d20SAndroid Build Coastguard Worker semanage_release_active_lock(sh);
1973*2d543d20SAndroid Build Coastguard Worker }
1974*2d543d20SAndroid Build Coastguard Worker return retval;
1975*2d543d20SAndroid Build Coastguard Worker }
1976*2d543d20SAndroid Build Coastguard Worker
semanage_direct_get_enabled(semanage_handle_t * sh,const semanage_module_key_t * modkey,int * enabled)1977*2d543d20SAndroid Build Coastguard Worker static int semanage_direct_get_enabled(semanage_handle_t *sh,
1978*2d543d20SAndroid Build Coastguard Worker const semanage_module_key_t *modkey,
1979*2d543d20SAndroid Build Coastguard Worker int *enabled)
1980*2d543d20SAndroid Build Coastguard Worker {
1981*2d543d20SAndroid Build Coastguard Worker assert(sh);
1982*2d543d20SAndroid Build Coastguard Worker assert(modkey);
1983*2d543d20SAndroid Build Coastguard Worker assert(enabled);
1984*2d543d20SAndroid Build Coastguard Worker
1985*2d543d20SAndroid Build Coastguard Worker int status = 0;
1986*2d543d20SAndroid Build Coastguard Worker int ret = 0;
1987*2d543d20SAndroid Build Coastguard Worker
1988*2d543d20SAndroid Build Coastguard Worker char path[PATH_MAX];
1989*2d543d20SAndroid Build Coastguard Worker struct stat sb;
1990*2d543d20SAndroid Build Coastguard Worker semanage_module_info_t *modinfo = NULL;
1991*2d543d20SAndroid Build Coastguard Worker
1992*2d543d20SAndroid Build Coastguard Worker /* get module info */
1993*2d543d20SAndroid Build Coastguard Worker ret = semanage_module_get_module_info(
1994*2d543d20SAndroid Build Coastguard Worker sh,
1995*2d543d20SAndroid Build Coastguard Worker modkey,
1996*2d543d20SAndroid Build Coastguard Worker &modinfo);
1997*2d543d20SAndroid Build Coastguard Worker if (ret != 0) {
1998*2d543d20SAndroid Build Coastguard Worker status = -1;
1999*2d543d20SAndroid Build Coastguard Worker goto cleanup;
2000*2d543d20SAndroid Build Coastguard Worker }
2001*2d543d20SAndroid Build Coastguard Worker
2002*2d543d20SAndroid Build Coastguard Worker /* get disabled file path */
2003*2d543d20SAndroid Build Coastguard Worker ret = semanage_module_get_path(
2004*2d543d20SAndroid Build Coastguard Worker sh,
2005*2d543d20SAndroid Build Coastguard Worker modinfo,
2006*2d543d20SAndroid Build Coastguard Worker SEMANAGE_MODULE_PATH_DISABLED,
2007*2d543d20SAndroid Build Coastguard Worker path,
2008*2d543d20SAndroid Build Coastguard Worker sizeof(path));
2009*2d543d20SAndroid Build Coastguard Worker if (ret != 0) {
2010*2d543d20SAndroid Build Coastguard Worker status = -1;
2011*2d543d20SAndroid Build Coastguard Worker goto cleanup;
2012*2d543d20SAndroid Build Coastguard Worker }
2013*2d543d20SAndroid Build Coastguard Worker
2014*2d543d20SAndroid Build Coastguard Worker if (stat(path, &sb) < 0) {
2015*2d543d20SAndroid Build Coastguard Worker if (errno != ENOENT) {
2016*2d543d20SAndroid Build Coastguard Worker ERR(sh, "Unable to access %s: %s\n", path, strerror(errno));
2017*2d543d20SAndroid Build Coastguard Worker status = -1;
2018*2d543d20SAndroid Build Coastguard Worker goto cleanup;
2019*2d543d20SAndroid Build Coastguard Worker }
2020*2d543d20SAndroid Build Coastguard Worker
2021*2d543d20SAndroid Build Coastguard Worker *enabled = 1;
2022*2d543d20SAndroid Build Coastguard Worker }
2023*2d543d20SAndroid Build Coastguard Worker else {
2024*2d543d20SAndroid Build Coastguard Worker *enabled = 0;
2025*2d543d20SAndroid Build Coastguard Worker }
2026*2d543d20SAndroid Build Coastguard Worker
2027*2d543d20SAndroid Build Coastguard Worker cleanup:
2028*2d543d20SAndroid Build Coastguard Worker semanage_module_info_destroy(sh, modinfo);
2029*2d543d20SAndroid Build Coastguard Worker free(modinfo);
2030*2d543d20SAndroid Build Coastguard Worker
2031*2d543d20SAndroid Build Coastguard Worker return status;
2032*2d543d20SAndroid Build Coastguard Worker }
2033*2d543d20SAndroid Build Coastguard Worker
semanage_direct_set_enabled(semanage_handle_t * sh,const semanage_module_key_t * modkey,int enabled)2034*2d543d20SAndroid Build Coastguard Worker static int semanage_direct_set_enabled(semanage_handle_t *sh,
2035*2d543d20SAndroid Build Coastguard Worker const semanage_module_key_t *modkey,
2036*2d543d20SAndroid Build Coastguard Worker int enabled)
2037*2d543d20SAndroid Build Coastguard Worker {
2038*2d543d20SAndroid Build Coastguard Worker assert(sh);
2039*2d543d20SAndroid Build Coastguard Worker assert(modkey);
2040*2d543d20SAndroid Build Coastguard Worker
2041*2d543d20SAndroid Build Coastguard Worker int status = 0;
2042*2d543d20SAndroid Build Coastguard Worker int ret = 0;
2043*2d543d20SAndroid Build Coastguard Worker
2044*2d543d20SAndroid Build Coastguard Worker char fn[PATH_MAX];
2045*2d543d20SAndroid Build Coastguard Worker const char *path = NULL;
2046*2d543d20SAndroid Build Coastguard Worker FILE *fp = NULL;
2047*2d543d20SAndroid Build Coastguard Worker semanage_module_info_t *modinfo = NULL;
2048*2d543d20SAndroid Build Coastguard Worker mode_t mask;
2049*2d543d20SAndroid Build Coastguard Worker
2050*2d543d20SAndroid Build Coastguard Worker /* check transaction */
2051*2d543d20SAndroid Build Coastguard Worker if (!sh->is_in_transaction) {
2052*2d543d20SAndroid Build Coastguard Worker if (semanage_begin_transaction(sh) < 0) {
2053*2d543d20SAndroid Build Coastguard Worker status = -1;
2054*2d543d20SAndroid Build Coastguard Worker goto cleanup;
2055*2d543d20SAndroid Build Coastguard Worker }
2056*2d543d20SAndroid Build Coastguard Worker }
2057*2d543d20SAndroid Build Coastguard Worker
2058*2d543d20SAndroid Build Coastguard Worker /* validate name */
2059*2d543d20SAndroid Build Coastguard Worker ret = semanage_module_validate_name(modkey->name);
2060*2d543d20SAndroid Build Coastguard Worker if (ret != 0) {
2061*2d543d20SAndroid Build Coastguard Worker errno = 0;
2062*2d543d20SAndroid Build Coastguard Worker ERR(sh, "Name %s is invalid.", modkey->name);
2063*2d543d20SAndroid Build Coastguard Worker status = -1;
2064*2d543d20SAndroid Build Coastguard Worker goto cleanup;
2065*2d543d20SAndroid Build Coastguard Worker }
2066*2d543d20SAndroid Build Coastguard Worker
2067*2d543d20SAndroid Build Coastguard Worker /* validate enabled */
2068*2d543d20SAndroid Build Coastguard Worker ret = semanage_module_validate_enabled(enabled);
2069*2d543d20SAndroid Build Coastguard Worker if (ret != 0) {
2070*2d543d20SAndroid Build Coastguard Worker errno = 0;
2071*2d543d20SAndroid Build Coastguard Worker ERR(sh, "Enabled status %d is invalid.", enabled);
2072*2d543d20SAndroid Build Coastguard Worker status = -1;
2073*2d543d20SAndroid Build Coastguard Worker goto cleanup;
2074*2d543d20SAndroid Build Coastguard Worker }
2075*2d543d20SAndroid Build Coastguard Worker
2076*2d543d20SAndroid Build Coastguard Worker /* check for disabled path, create if missing */
2077*2d543d20SAndroid Build Coastguard Worker path = semanage_path(SEMANAGE_TMP, SEMANAGE_MODULES_DISABLED);
2078*2d543d20SAndroid Build Coastguard Worker
2079*2d543d20SAndroid Build Coastguard Worker ret = semanage_mkdir(sh, path);
2080*2d543d20SAndroid Build Coastguard Worker if (ret != 0) {
2081*2d543d20SAndroid Build Coastguard Worker status = -1;
2082*2d543d20SAndroid Build Coastguard Worker goto cleanup;
2083*2d543d20SAndroid Build Coastguard Worker }
2084*2d543d20SAndroid Build Coastguard Worker
2085*2d543d20SAndroid Build Coastguard Worker /* get module info */
2086*2d543d20SAndroid Build Coastguard Worker ret = semanage_module_get_module_info(
2087*2d543d20SAndroid Build Coastguard Worker sh,
2088*2d543d20SAndroid Build Coastguard Worker modkey,
2089*2d543d20SAndroid Build Coastguard Worker &modinfo);
2090*2d543d20SAndroid Build Coastguard Worker if (ret != 0) {
2091*2d543d20SAndroid Build Coastguard Worker status = -1;
2092*2d543d20SAndroid Build Coastguard Worker goto cleanup;
2093*2d543d20SAndroid Build Coastguard Worker }
2094*2d543d20SAndroid Build Coastguard Worker
2095*2d543d20SAndroid Build Coastguard Worker /* get module disabled file */
2096*2d543d20SAndroid Build Coastguard Worker ret = semanage_module_get_path(
2097*2d543d20SAndroid Build Coastguard Worker sh,
2098*2d543d20SAndroid Build Coastguard Worker modinfo,
2099*2d543d20SAndroid Build Coastguard Worker SEMANAGE_MODULE_PATH_DISABLED,
2100*2d543d20SAndroid Build Coastguard Worker fn,
2101*2d543d20SAndroid Build Coastguard Worker sizeof(fn));
2102*2d543d20SAndroid Build Coastguard Worker if (ret != 0) {
2103*2d543d20SAndroid Build Coastguard Worker status = -1;
2104*2d543d20SAndroid Build Coastguard Worker goto cleanup;
2105*2d543d20SAndroid Build Coastguard Worker }
2106*2d543d20SAndroid Build Coastguard Worker
2107*2d543d20SAndroid Build Coastguard Worker switch (enabled) {
2108*2d543d20SAndroid Build Coastguard Worker case 0: /* disable the module */
2109*2d543d20SAndroid Build Coastguard Worker mask = umask(0077);
2110*2d543d20SAndroid Build Coastguard Worker fp = fopen(fn, "w");
2111*2d543d20SAndroid Build Coastguard Worker umask(mask);
2112*2d543d20SAndroid Build Coastguard Worker
2113*2d543d20SAndroid Build Coastguard Worker if (fp == NULL) {
2114*2d543d20SAndroid Build Coastguard Worker ERR(sh,
2115*2d543d20SAndroid Build Coastguard Worker "Unable to disable module %s",
2116*2d543d20SAndroid Build Coastguard Worker modkey->name);
2117*2d543d20SAndroid Build Coastguard Worker status = -1;
2118*2d543d20SAndroid Build Coastguard Worker goto cleanup;
2119*2d543d20SAndroid Build Coastguard Worker }
2120*2d543d20SAndroid Build Coastguard Worker
2121*2d543d20SAndroid Build Coastguard Worker ret = fclose(fp);
2122*2d543d20SAndroid Build Coastguard Worker fp = NULL;
2123*2d543d20SAndroid Build Coastguard Worker if (ret != 0) {
2124*2d543d20SAndroid Build Coastguard Worker ERR(sh,
2125*2d543d20SAndroid Build Coastguard Worker "Unable to close disabled file for module %s",
2126*2d543d20SAndroid Build Coastguard Worker modkey->name);
2127*2d543d20SAndroid Build Coastguard Worker status = -1;
2128*2d543d20SAndroid Build Coastguard Worker goto cleanup;
2129*2d543d20SAndroid Build Coastguard Worker }
2130*2d543d20SAndroid Build Coastguard Worker
2131*2d543d20SAndroid Build Coastguard Worker break;
2132*2d543d20SAndroid Build Coastguard Worker case 1: /* enable the module */
2133*2d543d20SAndroid Build Coastguard Worker if (unlink(fn) < 0) {
2134*2d543d20SAndroid Build Coastguard Worker if (errno != ENOENT) {
2135*2d543d20SAndroid Build Coastguard Worker ERR(sh,
2136*2d543d20SAndroid Build Coastguard Worker "Unable to enable module %s",
2137*2d543d20SAndroid Build Coastguard Worker modkey->name);
2138*2d543d20SAndroid Build Coastguard Worker status = -1;
2139*2d543d20SAndroid Build Coastguard Worker goto cleanup;
2140*2d543d20SAndroid Build Coastguard Worker }
2141*2d543d20SAndroid Build Coastguard Worker else {
2142*2d543d20SAndroid Build Coastguard Worker /* module already enabled */
2143*2d543d20SAndroid Build Coastguard Worker errno = 0;
2144*2d543d20SAndroid Build Coastguard Worker }
2145*2d543d20SAndroid Build Coastguard Worker }
2146*2d543d20SAndroid Build Coastguard Worker
2147*2d543d20SAndroid Build Coastguard Worker break;
2148*2d543d20SAndroid Build Coastguard Worker case -1: /* warn about ignored setting to default */
2149*2d543d20SAndroid Build Coastguard Worker WARN(sh,
2150*2d543d20SAndroid Build Coastguard Worker "Setting module %s to 'default' state has no effect",
2151*2d543d20SAndroid Build Coastguard Worker modkey->name);
2152*2d543d20SAndroid Build Coastguard Worker break;
2153*2d543d20SAndroid Build Coastguard Worker }
2154*2d543d20SAndroid Build Coastguard Worker
2155*2d543d20SAndroid Build Coastguard Worker cleanup:
2156*2d543d20SAndroid Build Coastguard Worker semanage_module_info_destroy(sh, modinfo);
2157*2d543d20SAndroid Build Coastguard Worker free(modinfo);
2158*2d543d20SAndroid Build Coastguard Worker
2159*2d543d20SAndroid Build Coastguard Worker if (fp != NULL) fclose(fp);
2160*2d543d20SAndroid Build Coastguard Worker return status;
2161*2d543d20SAndroid Build Coastguard Worker }
2162*2d543d20SAndroid Build Coastguard Worker
semanage_direct_access_check(semanage_handle_t * sh)2163*2d543d20SAndroid Build Coastguard Worker int semanage_direct_access_check(semanage_handle_t * sh)
2164*2d543d20SAndroid Build Coastguard Worker {
2165*2d543d20SAndroid Build Coastguard Worker if (semanage_check_init(sh, sh->conf->store_root_path))
2166*2d543d20SAndroid Build Coastguard Worker return -1;
2167*2d543d20SAndroid Build Coastguard Worker
2168*2d543d20SAndroid Build Coastguard Worker return semanage_store_access_check();
2169*2d543d20SAndroid Build Coastguard Worker }
2170*2d543d20SAndroid Build Coastguard Worker
semanage_direct_mls_enabled(semanage_handle_t * sh)2171*2d543d20SAndroid Build Coastguard Worker int semanage_direct_mls_enabled(semanage_handle_t * sh)
2172*2d543d20SAndroid Build Coastguard Worker {
2173*2d543d20SAndroid Build Coastguard Worker sepol_policydb_t *p = NULL;
2174*2d543d20SAndroid Build Coastguard Worker int retval;
2175*2d543d20SAndroid Build Coastguard Worker
2176*2d543d20SAndroid Build Coastguard Worker retval = sepol_policydb_create(&p);
2177*2d543d20SAndroid Build Coastguard Worker if (retval < 0)
2178*2d543d20SAndroid Build Coastguard Worker goto cleanup;
2179*2d543d20SAndroid Build Coastguard Worker
2180*2d543d20SAndroid Build Coastguard Worker retval = semanage_read_policydb(sh, p, SEMANAGE_STORE_KERNEL);
2181*2d543d20SAndroid Build Coastguard Worker if (retval < 0)
2182*2d543d20SAndroid Build Coastguard Worker goto cleanup;
2183*2d543d20SAndroid Build Coastguard Worker
2184*2d543d20SAndroid Build Coastguard Worker retval = sepol_policydb_mls_enabled(p);
2185*2d543d20SAndroid Build Coastguard Worker cleanup:
2186*2d543d20SAndroid Build Coastguard Worker sepol_policydb_free(p);
2187*2d543d20SAndroid Build Coastguard Worker return retval;
2188*2d543d20SAndroid Build Coastguard Worker }
2189*2d543d20SAndroid Build Coastguard Worker
semanage_direct_get_module_info(semanage_handle_t * sh,const semanage_module_key_t * modkey,semanage_module_info_t ** modinfo)2190*2d543d20SAndroid Build Coastguard Worker static int semanage_direct_get_module_info(semanage_handle_t *sh,
2191*2d543d20SAndroid Build Coastguard Worker const semanage_module_key_t *modkey,
2192*2d543d20SAndroid Build Coastguard Worker semanage_module_info_t **modinfo)
2193*2d543d20SAndroid Build Coastguard Worker {
2194*2d543d20SAndroid Build Coastguard Worker assert(sh);
2195*2d543d20SAndroid Build Coastguard Worker assert(modkey);
2196*2d543d20SAndroid Build Coastguard Worker assert(modinfo);
2197*2d543d20SAndroid Build Coastguard Worker
2198*2d543d20SAndroid Build Coastguard Worker int status = 0;
2199*2d543d20SAndroid Build Coastguard Worker int ret = 0;
2200*2d543d20SAndroid Build Coastguard Worker
2201*2d543d20SAndroid Build Coastguard Worker char fn[PATH_MAX];
2202*2d543d20SAndroid Build Coastguard Worker FILE *fp = NULL;
2203*2d543d20SAndroid Build Coastguard Worker size_t size = 0;
2204*2d543d20SAndroid Build Coastguard Worker struct stat sb;
2205*2d543d20SAndroid Build Coastguard Worker char *tmp = NULL;
2206*2d543d20SAndroid Build Coastguard Worker
2207*2d543d20SAndroid Build Coastguard Worker int i = 0;
2208*2d543d20SAndroid Build Coastguard Worker
2209*2d543d20SAndroid Build Coastguard Worker semanage_module_info_t *modinfos = NULL;
2210*2d543d20SAndroid Build Coastguard Worker int modinfos_len = 0;
2211*2d543d20SAndroid Build Coastguard Worker semanage_module_info_t *highest = NULL;
2212*2d543d20SAndroid Build Coastguard Worker
2213*2d543d20SAndroid Build Coastguard Worker /* check module name */
2214*2d543d20SAndroid Build Coastguard Worker ret = semanage_module_validate_name(modkey->name);
2215*2d543d20SAndroid Build Coastguard Worker if (ret < 0) {
2216*2d543d20SAndroid Build Coastguard Worker errno = 0;
2217*2d543d20SAndroid Build Coastguard Worker ERR(sh, "Name %s is invalid.", modkey->name);
2218*2d543d20SAndroid Build Coastguard Worker status = -1;
2219*2d543d20SAndroid Build Coastguard Worker goto cleanup;
2220*2d543d20SAndroid Build Coastguard Worker }
2221*2d543d20SAndroid Build Coastguard Worker
2222*2d543d20SAndroid Build Coastguard Worker /* if priority == 0, then find the highest priority available */
2223*2d543d20SAndroid Build Coastguard Worker if (modkey->priority == 0) {
2224*2d543d20SAndroid Build Coastguard Worker ret = semanage_direct_list_all(sh, &modinfos, &modinfos_len);
2225*2d543d20SAndroid Build Coastguard Worker if (ret != 0) {
2226*2d543d20SAndroid Build Coastguard Worker status = -1;
2227*2d543d20SAndroid Build Coastguard Worker goto cleanup;
2228*2d543d20SAndroid Build Coastguard Worker }
2229*2d543d20SAndroid Build Coastguard Worker
2230*2d543d20SAndroid Build Coastguard Worker for (i = 0; i < modinfos_len; i++) {
2231*2d543d20SAndroid Build Coastguard Worker ret = strcmp(modinfos[i].name, modkey->name);
2232*2d543d20SAndroid Build Coastguard Worker if (ret == 0) {
2233*2d543d20SAndroid Build Coastguard Worker highest = &modinfos[i];
2234*2d543d20SAndroid Build Coastguard Worker break;
2235*2d543d20SAndroid Build Coastguard Worker }
2236*2d543d20SAndroid Build Coastguard Worker }
2237*2d543d20SAndroid Build Coastguard Worker
2238*2d543d20SAndroid Build Coastguard Worker if (highest == NULL) {
2239*2d543d20SAndroid Build Coastguard Worker status = -1;
2240*2d543d20SAndroid Build Coastguard Worker goto cleanup;
2241*2d543d20SAndroid Build Coastguard Worker }
2242*2d543d20SAndroid Build Coastguard Worker
2243*2d543d20SAndroid Build Coastguard Worker ret = semanage_module_info_create(sh, modinfo);
2244*2d543d20SAndroid Build Coastguard Worker if (ret != 0) {
2245*2d543d20SAndroid Build Coastguard Worker status = -1;
2246*2d543d20SAndroid Build Coastguard Worker goto cleanup;
2247*2d543d20SAndroid Build Coastguard Worker }
2248*2d543d20SAndroid Build Coastguard Worker
2249*2d543d20SAndroid Build Coastguard Worker ret = semanage_module_info_clone(sh, highest, *modinfo);
2250*2d543d20SAndroid Build Coastguard Worker if (ret != 0) {
2251*2d543d20SAndroid Build Coastguard Worker status = -1;
2252*2d543d20SAndroid Build Coastguard Worker }
2253*2d543d20SAndroid Build Coastguard Worker
2254*2d543d20SAndroid Build Coastguard Worker /* skip to cleanup, module was found */
2255*2d543d20SAndroid Build Coastguard Worker goto cleanup;
2256*2d543d20SAndroid Build Coastguard Worker }
2257*2d543d20SAndroid Build Coastguard Worker
2258*2d543d20SAndroid Build Coastguard Worker /* check module priority */
2259*2d543d20SAndroid Build Coastguard Worker ret = semanage_module_validate_priority(modkey->priority);
2260*2d543d20SAndroid Build Coastguard Worker if (ret != 0) {
2261*2d543d20SAndroid Build Coastguard Worker errno = 0;
2262*2d543d20SAndroid Build Coastguard Worker ERR(sh, "Priority %d is invalid.", modkey->priority);
2263*2d543d20SAndroid Build Coastguard Worker status = -1;
2264*2d543d20SAndroid Build Coastguard Worker goto cleanup;
2265*2d543d20SAndroid Build Coastguard Worker }
2266*2d543d20SAndroid Build Coastguard Worker
2267*2d543d20SAndroid Build Coastguard Worker /* copy in key values */
2268*2d543d20SAndroid Build Coastguard Worker ret = semanage_module_info_create(sh, modinfo);
2269*2d543d20SAndroid Build Coastguard Worker if (ret != 0) {
2270*2d543d20SAndroid Build Coastguard Worker status = -1;
2271*2d543d20SAndroid Build Coastguard Worker goto cleanup;
2272*2d543d20SAndroid Build Coastguard Worker }
2273*2d543d20SAndroid Build Coastguard Worker
2274*2d543d20SAndroid Build Coastguard Worker ret = semanage_module_info_set_priority(sh, *modinfo, modkey->priority);
2275*2d543d20SAndroid Build Coastguard Worker if (ret != 0) {
2276*2d543d20SAndroid Build Coastguard Worker status = -1;
2277*2d543d20SAndroid Build Coastguard Worker goto cleanup;
2278*2d543d20SAndroid Build Coastguard Worker }
2279*2d543d20SAndroid Build Coastguard Worker
2280*2d543d20SAndroid Build Coastguard Worker ret = semanage_module_info_set_name(sh, *modinfo, modkey->name);
2281*2d543d20SAndroid Build Coastguard Worker if (ret != 0) {
2282*2d543d20SAndroid Build Coastguard Worker status = -1;
2283*2d543d20SAndroid Build Coastguard Worker goto cleanup;
2284*2d543d20SAndroid Build Coastguard Worker }
2285*2d543d20SAndroid Build Coastguard Worker
2286*2d543d20SAndroid Build Coastguard Worker /* lookup module ext */
2287*2d543d20SAndroid Build Coastguard Worker ret = semanage_module_get_path(sh,
2288*2d543d20SAndroid Build Coastguard Worker *modinfo,
2289*2d543d20SAndroid Build Coastguard Worker SEMANAGE_MODULE_PATH_LANG_EXT,
2290*2d543d20SAndroid Build Coastguard Worker fn,
2291*2d543d20SAndroid Build Coastguard Worker sizeof(fn));
2292*2d543d20SAndroid Build Coastguard Worker if (ret != 0) {
2293*2d543d20SAndroid Build Coastguard Worker status = -1;
2294*2d543d20SAndroid Build Coastguard Worker goto cleanup;
2295*2d543d20SAndroid Build Coastguard Worker }
2296*2d543d20SAndroid Build Coastguard Worker
2297*2d543d20SAndroid Build Coastguard Worker fp = fopen(fn, "r");
2298*2d543d20SAndroid Build Coastguard Worker
2299*2d543d20SAndroid Build Coastguard Worker if (fp == NULL) {
2300*2d543d20SAndroid Build Coastguard Worker ERR(sh,
2301*2d543d20SAndroid Build Coastguard Worker "Unable to open %s module lang ext file at %s.",
2302*2d543d20SAndroid Build Coastguard Worker (*modinfo)->name, fn);
2303*2d543d20SAndroid Build Coastguard Worker status = -1;
2304*2d543d20SAndroid Build Coastguard Worker goto cleanup;
2305*2d543d20SAndroid Build Coastguard Worker }
2306*2d543d20SAndroid Build Coastguard Worker
2307*2d543d20SAndroid Build Coastguard Worker /* set module ext */
2308*2d543d20SAndroid Build Coastguard Worker if (getline(&tmp, &size, fp) < 0) {
2309*2d543d20SAndroid Build Coastguard Worker ERR(sh,
2310*2d543d20SAndroid Build Coastguard Worker "Unable to read %s module lang ext file.",
2311*2d543d20SAndroid Build Coastguard Worker (*modinfo)->name);
2312*2d543d20SAndroid Build Coastguard Worker status = -1;
2313*2d543d20SAndroid Build Coastguard Worker goto cleanup;
2314*2d543d20SAndroid Build Coastguard Worker }
2315*2d543d20SAndroid Build Coastguard Worker
2316*2d543d20SAndroid Build Coastguard Worker ret = semanage_module_info_set_lang_ext(sh, *modinfo, tmp);
2317*2d543d20SAndroid Build Coastguard Worker if (ret != 0) {
2318*2d543d20SAndroid Build Coastguard Worker status = -1;
2319*2d543d20SAndroid Build Coastguard Worker goto cleanup;
2320*2d543d20SAndroid Build Coastguard Worker }
2321*2d543d20SAndroid Build Coastguard Worker free(tmp);
2322*2d543d20SAndroid Build Coastguard Worker tmp = NULL;
2323*2d543d20SAndroid Build Coastguard Worker
2324*2d543d20SAndroid Build Coastguard Worker if (fclose(fp) != 0) {
2325*2d543d20SAndroid Build Coastguard Worker fp = NULL;
2326*2d543d20SAndroid Build Coastguard Worker ERR(sh,
2327*2d543d20SAndroid Build Coastguard Worker "Unable to close %s module lang ext file.",
2328*2d543d20SAndroid Build Coastguard Worker (*modinfo)->name);
2329*2d543d20SAndroid Build Coastguard Worker status = -1;
2330*2d543d20SAndroid Build Coastguard Worker goto cleanup;
2331*2d543d20SAndroid Build Coastguard Worker }
2332*2d543d20SAndroid Build Coastguard Worker
2333*2d543d20SAndroid Build Coastguard Worker fp = NULL;
2334*2d543d20SAndroid Build Coastguard Worker
2335*2d543d20SAndroid Build Coastguard Worker /* lookup enabled/disabled status */
2336*2d543d20SAndroid Build Coastguard Worker ret = semanage_module_get_path(sh,
2337*2d543d20SAndroid Build Coastguard Worker *modinfo,
2338*2d543d20SAndroid Build Coastguard Worker SEMANAGE_MODULE_PATH_DISABLED,
2339*2d543d20SAndroid Build Coastguard Worker fn,
2340*2d543d20SAndroid Build Coastguard Worker sizeof(fn));
2341*2d543d20SAndroid Build Coastguard Worker if (ret != 0) {
2342*2d543d20SAndroid Build Coastguard Worker status = -1;
2343*2d543d20SAndroid Build Coastguard Worker goto cleanup;
2344*2d543d20SAndroid Build Coastguard Worker }
2345*2d543d20SAndroid Build Coastguard Worker
2346*2d543d20SAndroid Build Coastguard Worker /* set enabled/disabled status */
2347*2d543d20SAndroid Build Coastguard Worker if (stat(fn, &sb) < 0) {
2348*2d543d20SAndroid Build Coastguard Worker if (errno != ENOENT) {
2349*2d543d20SAndroid Build Coastguard Worker ERR(sh, "Unable to access %s: %s\n", fn, strerror(errno));
2350*2d543d20SAndroid Build Coastguard Worker status = -1;
2351*2d543d20SAndroid Build Coastguard Worker goto cleanup;
2352*2d543d20SAndroid Build Coastguard Worker }
2353*2d543d20SAndroid Build Coastguard Worker
2354*2d543d20SAndroid Build Coastguard Worker ret = semanage_module_info_set_enabled(sh, *modinfo, 1);
2355*2d543d20SAndroid Build Coastguard Worker if (ret != 0) {
2356*2d543d20SAndroid Build Coastguard Worker status = -1;
2357*2d543d20SAndroid Build Coastguard Worker goto cleanup;
2358*2d543d20SAndroid Build Coastguard Worker }
2359*2d543d20SAndroid Build Coastguard Worker }
2360*2d543d20SAndroid Build Coastguard Worker else {
2361*2d543d20SAndroid Build Coastguard Worker ret = semanage_module_info_set_enabled(sh, *modinfo, 0);
2362*2d543d20SAndroid Build Coastguard Worker if (ret != 0) {
2363*2d543d20SAndroid Build Coastguard Worker status = -1;
2364*2d543d20SAndroid Build Coastguard Worker goto cleanup;
2365*2d543d20SAndroid Build Coastguard Worker }
2366*2d543d20SAndroid Build Coastguard Worker }
2367*2d543d20SAndroid Build Coastguard Worker
2368*2d543d20SAndroid Build Coastguard Worker cleanup:
2369*2d543d20SAndroid Build Coastguard Worker free(tmp);
2370*2d543d20SAndroid Build Coastguard Worker
2371*2d543d20SAndroid Build Coastguard Worker if (modinfos != NULL) {
2372*2d543d20SAndroid Build Coastguard Worker for (i = 0; i < modinfos_len; i++) {
2373*2d543d20SAndroid Build Coastguard Worker semanage_module_info_destroy(sh, &modinfos[i]);
2374*2d543d20SAndroid Build Coastguard Worker }
2375*2d543d20SAndroid Build Coastguard Worker free(modinfos);
2376*2d543d20SAndroid Build Coastguard Worker }
2377*2d543d20SAndroid Build Coastguard Worker
2378*2d543d20SAndroid Build Coastguard Worker if (fp != NULL) fclose(fp);
2379*2d543d20SAndroid Build Coastguard Worker return status;
2380*2d543d20SAndroid Build Coastguard Worker }
2381*2d543d20SAndroid Build Coastguard Worker
semanage_direct_set_module_info(semanage_handle_t * sh,const semanage_module_info_t * modinfo)2382*2d543d20SAndroid Build Coastguard Worker static int semanage_direct_set_module_info(semanage_handle_t *sh,
2383*2d543d20SAndroid Build Coastguard Worker const semanage_module_info_t *modinfo)
2384*2d543d20SAndroid Build Coastguard Worker {
2385*2d543d20SAndroid Build Coastguard Worker int status = 0;
2386*2d543d20SAndroid Build Coastguard Worker int ret = 0;
2387*2d543d20SAndroid Build Coastguard Worker
2388*2d543d20SAndroid Build Coastguard Worker char fn[PATH_MAX];
2389*2d543d20SAndroid Build Coastguard Worker const char *path = NULL;
2390*2d543d20SAndroid Build Coastguard Worker int enabled = 0;
2391*2d543d20SAndroid Build Coastguard Worker semanage_module_info_t *modinfo_tmp = NULL;
2392*2d543d20SAndroid Build Coastguard Worker
2393*2d543d20SAndroid Build Coastguard Worker semanage_module_key_t modkey;
2394*2d543d20SAndroid Build Coastguard Worker ret = semanage_module_key_init(sh, &modkey);
2395*2d543d20SAndroid Build Coastguard Worker if (ret != 0) {
2396*2d543d20SAndroid Build Coastguard Worker status = -1;
2397*2d543d20SAndroid Build Coastguard Worker goto cleanup;
2398*2d543d20SAndroid Build Coastguard Worker }
2399*2d543d20SAndroid Build Coastguard Worker
2400*2d543d20SAndroid Build Coastguard Worker /* check transaction */
2401*2d543d20SAndroid Build Coastguard Worker if (!sh->is_in_transaction) {
2402*2d543d20SAndroid Build Coastguard Worker if (semanage_begin_transaction(sh) < 0) {
2403*2d543d20SAndroid Build Coastguard Worker status = -1;
2404*2d543d20SAndroid Build Coastguard Worker goto cleanup;
2405*2d543d20SAndroid Build Coastguard Worker }
2406*2d543d20SAndroid Build Coastguard Worker }
2407*2d543d20SAndroid Build Coastguard Worker
2408*2d543d20SAndroid Build Coastguard Worker /* validate module */
2409*2d543d20SAndroid Build Coastguard Worker ret = semanage_module_info_validate(modinfo);
2410*2d543d20SAndroid Build Coastguard Worker if (ret != 0) {
2411*2d543d20SAndroid Build Coastguard Worker status = -1;
2412*2d543d20SAndroid Build Coastguard Worker goto cleanup;
2413*2d543d20SAndroid Build Coastguard Worker }
2414*2d543d20SAndroid Build Coastguard Worker
2415*2d543d20SAndroid Build Coastguard Worker sh->modules_modified = 1;
2416*2d543d20SAndroid Build Coastguard Worker
2417*2d543d20SAndroid Build Coastguard Worker /* check for modules path, create if missing */
2418*2d543d20SAndroid Build Coastguard Worker path = semanage_path(SEMANAGE_TMP, SEMANAGE_MODULES);
2419*2d543d20SAndroid Build Coastguard Worker
2420*2d543d20SAndroid Build Coastguard Worker ret = semanage_mkdir(sh, path);
2421*2d543d20SAndroid Build Coastguard Worker if (ret != 0) {
2422*2d543d20SAndroid Build Coastguard Worker status = -1;
2423*2d543d20SAndroid Build Coastguard Worker goto cleanup;
2424*2d543d20SAndroid Build Coastguard Worker }
2425*2d543d20SAndroid Build Coastguard Worker
2426*2d543d20SAndroid Build Coastguard Worker /* write priority */
2427*2d543d20SAndroid Build Coastguard Worker ret = semanage_module_get_path(sh,
2428*2d543d20SAndroid Build Coastguard Worker modinfo,
2429*2d543d20SAndroid Build Coastguard Worker SEMANAGE_MODULE_PATH_PRIORITY,
2430*2d543d20SAndroid Build Coastguard Worker fn,
2431*2d543d20SAndroid Build Coastguard Worker sizeof(fn));
2432*2d543d20SAndroid Build Coastguard Worker if (ret != 0) {
2433*2d543d20SAndroid Build Coastguard Worker status = -1;
2434*2d543d20SAndroid Build Coastguard Worker goto cleanup;
2435*2d543d20SAndroid Build Coastguard Worker }
2436*2d543d20SAndroid Build Coastguard Worker
2437*2d543d20SAndroid Build Coastguard Worker ret = semanage_mkdir(sh, fn);
2438*2d543d20SAndroid Build Coastguard Worker if (ret != 0) {
2439*2d543d20SAndroid Build Coastguard Worker status = -1;
2440*2d543d20SAndroid Build Coastguard Worker goto cleanup;
2441*2d543d20SAndroid Build Coastguard Worker }
2442*2d543d20SAndroid Build Coastguard Worker
2443*2d543d20SAndroid Build Coastguard Worker /* write name */
2444*2d543d20SAndroid Build Coastguard Worker ret = semanage_module_get_path(sh,
2445*2d543d20SAndroid Build Coastguard Worker modinfo,
2446*2d543d20SAndroid Build Coastguard Worker SEMANAGE_MODULE_PATH_NAME,
2447*2d543d20SAndroid Build Coastguard Worker fn,
2448*2d543d20SAndroid Build Coastguard Worker sizeof(fn));
2449*2d543d20SAndroid Build Coastguard Worker if (ret != 0) {
2450*2d543d20SAndroid Build Coastguard Worker status = -1;
2451*2d543d20SAndroid Build Coastguard Worker goto cleanup;
2452*2d543d20SAndroid Build Coastguard Worker }
2453*2d543d20SAndroid Build Coastguard Worker
2454*2d543d20SAndroid Build Coastguard Worker ret = semanage_mkdir(sh, fn);
2455*2d543d20SAndroid Build Coastguard Worker if (ret != 0) {
2456*2d543d20SAndroid Build Coastguard Worker status = -1;
2457*2d543d20SAndroid Build Coastguard Worker goto cleanup;
2458*2d543d20SAndroid Build Coastguard Worker }
2459*2d543d20SAndroid Build Coastguard Worker
2460*2d543d20SAndroid Build Coastguard Worker /* write ext */
2461*2d543d20SAndroid Build Coastguard Worker ret = semanage_direct_write_langext(sh, modinfo->lang_ext, modinfo);
2462*2d543d20SAndroid Build Coastguard Worker if (ret != 0) {
2463*2d543d20SAndroid Build Coastguard Worker status = -1;
2464*2d543d20SAndroid Build Coastguard Worker goto cleanup;
2465*2d543d20SAndroid Build Coastguard Worker }
2466*2d543d20SAndroid Build Coastguard Worker
2467*2d543d20SAndroid Build Coastguard Worker /* write enabled/disabled status */
2468*2d543d20SAndroid Build Coastguard Worker
2469*2d543d20SAndroid Build Coastguard Worker /* check for disabled path, create if missing */
2470*2d543d20SAndroid Build Coastguard Worker path = semanage_path(SEMANAGE_TMP, SEMANAGE_MODULES_DISABLED);
2471*2d543d20SAndroid Build Coastguard Worker
2472*2d543d20SAndroid Build Coastguard Worker ret = semanage_mkdir(sh, path);
2473*2d543d20SAndroid Build Coastguard Worker if (ret != 0) {
2474*2d543d20SAndroid Build Coastguard Worker status = -1;
2475*2d543d20SAndroid Build Coastguard Worker goto cleanup;
2476*2d543d20SAndroid Build Coastguard Worker }
2477*2d543d20SAndroid Build Coastguard Worker
2478*2d543d20SAndroid Build Coastguard Worker ret = semanage_module_get_path(sh,
2479*2d543d20SAndroid Build Coastguard Worker modinfo,
2480*2d543d20SAndroid Build Coastguard Worker SEMANAGE_MODULE_PATH_DISABLED,
2481*2d543d20SAndroid Build Coastguard Worker fn,
2482*2d543d20SAndroid Build Coastguard Worker sizeof(fn));
2483*2d543d20SAndroid Build Coastguard Worker if (ret != 0) {
2484*2d543d20SAndroid Build Coastguard Worker status = -1;
2485*2d543d20SAndroid Build Coastguard Worker goto cleanup;
2486*2d543d20SAndroid Build Coastguard Worker }
2487*2d543d20SAndroid Build Coastguard Worker
2488*2d543d20SAndroid Build Coastguard Worker ret = semanage_module_key_set_name(sh, &modkey, modinfo->name);
2489*2d543d20SAndroid Build Coastguard Worker if (ret != 0) {
2490*2d543d20SAndroid Build Coastguard Worker status = -1;
2491*2d543d20SAndroid Build Coastguard Worker goto cleanup;
2492*2d543d20SAndroid Build Coastguard Worker }
2493*2d543d20SAndroid Build Coastguard Worker
2494*2d543d20SAndroid Build Coastguard Worker if (modinfo->enabled == -1) {
2495*2d543d20SAndroid Build Coastguard Worker /* default to enabled */
2496*2d543d20SAndroid Build Coastguard Worker enabled = 1;
2497*2d543d20SAndroid Build Coastguard Worker
2498*2d543d20SAndroid Build Coastguard Worker /* check if a module is already installed */
2499*2d543d20SAndroid Build Coastguard Worker ret = semanage_module_get_module_info(sh,
2500*2d543d20SAndroid Build Coastguard Worker &modkey,
2501*2d543d20SAndroid Build Coastguard Worker &modinfo_tmp);
2502*2d543d20SAndroid Build Coastguard Worker if (ret == 0) {
2503*2d543d20SAndroid Build Coastguard Worker /* set enabled status to current one */
2504*2d543d20SAndroid Build Coastguard Worker enabled = modinfo_tmp->enabled;
2505*2d543d20SAndroid Build Coastguard Worker }
2506*2d543d20SAndroid Build Coastguard Worker }
2507*2d543d20SAndroid Build Coastguard Worker else {
2508*2d543d20SAndroid Build Coastguard Worker enabled = modinfo->enabled;
2509*2d543d20SAndroid Build Coastguard Worker }
2510*2d543d20SAndroid Build Coastguard Worker
2511*2d543d20SAndroid Build Coastguard Worker ret = semanage_module_set_enabled(sh, &modkey, enabled);
2512*2d543d20SAndroid Build Coastguard Worker if (ret != 0) {
2513*2d543d20SAndroid Build Coastguard Worker status = -1;
2514*2d543d20SAndroid Build Coastguard Worker goto cleanup;
2515*2d543d20SAndroid Build Coastguard Worker }
2516*2d543d20SAndroid Build Coastguard Worker
2517*2d543d20SAndroid Build Coastguard Worker cleanup:
2518*2d543d20SAndroid Build Coastguard Worker semanage_module_key_destroy(sh, &modkey);
2519*2d543d20SAndroid Build Coastguard Worker
2520*2d543d20SAndroid Build Coastguard Worker semanage_module_info_destroy(sh, modinfo_tmp);
2521*2d543d20SAndroid Build Coastguard Worker free(modinfo_tmp);
2522*2d543d20SAndroid Build Coastguard Worker
2523*2d543d20SAndroid Build Coastguard Worker return status;
2524*2d543d20SAndroid Build Coastguard Worker }
2525*2d543d20SAndroid Build Coastguard Worker
semanage_priorities_filename_select(const struct dirent * d)2526*2d543d20SAndroid Build Coastguard Worker static int semanage_priorities_filename_select(const struct dirent *d)
2527*2d543d20SAndroid Build Coastguard Worker {
2528*2d543d20SAndroid Build Coastguard Worker if (d->d_name[0] == '.' ||
2529*2d543d20SAndroid Build Coastguard Worker strcmp(d->d_name, "disabled") == 0)
2530*2d543d20SAndroid Build Coastguard Worker return 0;
2531*2d543d20SAndroid Build Coastguard Worker return 1;
2532*2d543d20SAndroid Build Coastguard Worker }
2533*2d543d20SAndroid Build Coastguard Worker
semanage_modules_filename_select(const struct dirent * d)2534*2d543d20SAndroid Build Coastguard Worker static int semanage_modules_filename_select(const struct dirent *d)
2535*2d543d20SAndroid Build Coastguard Worker {
2536*2d543d20SAndroid Build Coastguard Worker if (d->d_name[0] == '.')
2537*2d543d20SAndroid Build Coastguard Worker return 0;
2538*2d543d20SAndroid Build Coastguard Worker return 1;
2539*2d543d20SAndroid Build Coastguard Worker }
2540*2d543d20SAndroid Build Coastguard Worker
semanage_direct_list_all(semanage_handle_t * sh,semanage_module_info_t ** modinfos,int * modinfos_len)2541*2d543d20SAndroid Build Coastguard Worker static int semanage_direct_list_all(semanage_handle_t *sh,
2542*2d543d20SAndroid Build Coastguard Worker semanage_module_info_t **modinfos,
2543*2d543d20SAndroid Build Coastguard Worker int *modinfos_len)
2544*2d543d20SAndroid Build Coastguard Worker {
2545*2d543d20SAndroid Build Coastguard Worker assert(sh);
2546*2d543d20SAndroid Build Coastguard Worker assert(modinfos);
2547*2d543d20SAndroid Build Coastguard Worker assert(modinfos_len);
2548*2d543d20SAndroid Build Coastguard Worker
2549*2d543d20SAndroid Build Coastguard Worker int status = 0;
2550*2d543d20SAndroid Build Coastguard Worker int ret = 0;
2551*2d543d20SAndroid Build Coastguard Worker
2552*2d543d20SAndroid Build Coastguard Worker int i = 0;
2553*2d543d20SAndroid Build Coastguard Worker int j = 0;
2554*2d543d20SAndroid Build Coastguard Worker
2555*2d543d20SAndroid Build Coastguard Worker *modinfos = NULL;
2556*2d543d20SAndroid Build Coastguard Worker *modinfos_len = 0;
2557*2d543d20SAndroid Build Coastguard Worker void *tmp = NULL;
2558*2d543d20SAndroid Build Coastguard Worker
2559*2d543d20SAndroid Build Coastguard Worker const char *toplevel = NULL;
2560*2d543d20SAndroid Build Coastguard Worker
2561*2d543d20SAndroid Build Coastguard Worker struct dirent **priorities = NULL;
2562*2d543d20SAndroid Build Coastguard Worker int priorities_len = 0;
2563*2d543d20SAndroid Build Coastguard Worker char priority_path[PATH_MAX];
2564*2d543d20SAndroid Build Coastguard Worker
2565*2d543d20SAndroid Build Coastguard Worker struct dirent **modules = NULL;
2566*2d543d20SAndroid Build Coastguard Worker int modules_len = 0;
2567*2d543d20SAndroid Build Coastguard Worker
2568*2d543d20SAndroid Build Coastguard Worker uint16_t priority = 0;
2569*2d543d20SAndroid Build Coastguard Worker
2570*2d543d20SAndroid Build Coastguard Worker semanage_module_info_t *modinfo_tmp = NULL;
2571*2d543d20SAndroid Build Coastguard Worker
2572*2d543d20SAndroid Build Coastguard Worker semanage_module_info_t modinfo;
2573*2d543d20SAndroid Build Coastguard Worker ret = semanage_module_info_init(sh, &modinfo);
2574*2d543d20SAndroid Build Coastguard Worker if (ret != 0) {
2575*2d543d20SAndroid Build Coastguard Worker status = -1;
2576*2d543d20SAndroid Build Coastguard Worker goto cleanup;
2577*2d543d20SAndroid Build Coastguard Worker }
2578*2d543d20SAndroid Build Coastguard Worker
2579*2d543d20SAndroid Build Coastguard Worker if (sh->is_in_transaction) {
2580*2d543d20SAndroid Build Coastguard Worker toplevel = semanage_path(SEMANAGE_TMP, SEMANAGE_MODULES);
2581*2d543d20SAndroid Build Coastguard Worker } else {
2582*2d543d20SAndroid Build Coastguard Worker toplevel = semanage_path(SEMANAGE_ACTIVE, SEMANAGE_MODULES);
2583*2d543d20SAndroid Build Coastguard Worker }
2584*2d543d20SAndroid Build Coastguard Worker
2585*2d543d20SAndroid Build Coastguard Worker /* find priorities */
2586*2d543d20SAndroid Build Coastguard Worker priorities_len = scandir(toplevel,
2587*2d543d20SAndroid Build Coastguard Worker &priorities,
2588*2d543d20SAndroid Build Coastguard Worker semanage_priorities_filename_select,
2589*2d543d20SAndroid Build Coastguard Worker versionsort);
2590*2d543d20SAndroid Build Coastguard Worker if (priorities_len == -1) {
2591*2d543d20SAndroid Build Coastguard Worker ERR(sh, "Error while scanning directory %s.", toplevel);
2592*2d543d20SAndroid Build Coastguard Worker status = -1;
2593*2d543d20SAndroid Build Coastguard Worker goto cleanup;
2594*2d543d20SAndroid Build Coastguard Worker }
2595*2d543d20SAndroid Build Coastguard Worker
2596*2d543d20SAndroid Build Coastguard Worker /* for each priority directory */
2597*2d543d20SAndroid Build Coastguard Worker /* loop through in reverse so that highest priority is first */
2598*2d543d20SAndroid Build Coastguard Worker for (i = priorities_len - 1; i >= 0; i--) {
2599*2d543d20SAndroid Build Coastguard Worker /* convert priority string to uint16_t */
2600*2d543d20SAndroid Build Coastguard Worker ret = semanage_string_to_priority(priorities[i]->d_name,
2601*2d543d20SAndroid Build Coastguard Worker &priority);
2602*2d543d20SAndroid Build Coastguard Worker if (ret != 0) {
2603*2d543d20SAndroid Build Coastguard Worker status = -1;
2604*2d543d20SAndroid Build Coastguard Worker goto cleanup;
2605*2d543d20SAndroid Build Coastguard Worker }
2606*2d543d20SAndroid Build Coastguard Worker
2607*2d543d20SAndroid Build Coastguard Worker /* set our priority */
2608*2d543d20SAndroid Build Coastguard Worker ret = semanage_module_info_set_priority(sh,
2609*2d543d20SAndroid Build Coastguard Worker &modinfo,
2610*2d543d20SAndroid Build Coastguard Worker priority);
2611*2d543d20SAndroid Build Coastguard Worker if (ret != 0) {
2612*2d543d20SAndroid Build Coastguard Worker status = -1;
2613*2d543d20SAndroid Build Coastguard Worker goto cleanup;
2614*2d543d20SAndroid Build Coastguard Worker }
2615*2d543d20SAndroid Build Coastguard Worker
2616*2d543d20SAndroid Build Coastguard Worker /* get the priority path */
2617*2d543d20SAndroid Build Coastguard Worker ret = semanage_module_get_path(sh,
2618*2d543d20SAndroid Build Coastguard Worker &modinfo,
2619*2d543d20SAndroid Build Coastguard Worker SEMANAGE_MODULE_PATH_PRIORITY,
2620*2d543d20SAndroid Build Coastguard Worker priority_path,
2621*2d543d20SAndroid Build Coastguard Worker sizeof(priority_path));
2622*2d543d20SAndroid Build Coastguard Worker if (ret != 0) {
2623*2d543d20SAndroid Build Coastguard Worker status = -1;
2624*2d543d20SAndroid Build Coastguard Worker goto cleanup;
2625*2d543d20SAndroid Build Coastguard Worker }
2626*2d543d20SAndroid Build Coastguard Worker
2627*2d543d20SAndroid Build Coastguard Worker /* cleanup old modules */
2628*2d543d20SAndroid Build Coastguard Worker if (modules != NULL) {
2629*2d543d20SAndroid Build Coastguard Worker for (j = 0; j < modules_len; j++) {
2630*2d543d20SAndroid Build Coastguard Worker free(modules[j]);
2631*2d543d20SAndroid Build Coastguard Worker modules[j] = NULL;
2632*2d543d20SAndroid Build Coastguard Worker }
2633*2d543d20SAndroid Build Coastguard Worker free(modules);
2634*2d543d20SAndroid Build Coastguard Worker modules = NULL;
2635*2d543d20SAndroid Build Coastguard Worker modules_len = 0;
2636*2d543d20SAndroid Build Coastguard Worker }
2637*2d543d20SAndroid Build Coastguard Worker
2638*2d543d20SAndroid Build Coastguard Worker /* find modules at this priority */
2639*2d543d20SAndroid Build Coastguard Worker modules_len = scandir(priority_path,
2640*2d543d20SAndroid Build Coastguard Worker &modules,
2641*2d543d20SAndroid Build Coastguard Worker semanage_modules_filename_select,
2642*2d543d20SAndroid Build Coastguard Worker versionsort);
2643*2d543d20SAndroid Build Coastguard Worker if (modules_len == -1) {
2644*2d543d20SAndroid Build Coastguard Worker ERR(sh,
2645*2d543d20SAndroid Build Coastguard Worker "Error while scanning directory %s.",
2646*2d543d20SAndroid Build Coastguard Worker priority_path);
2647*2d543d20SAndroid Build Coastguard Worker status = -1;
2648*2d543d20SAndroid Build Coastguard Worker goto cleanup;
2649*2d543d20SAndroid Build Coastguard Worker }
2650*2d543d20SAndroid Build Coastguard Worker
2651*2d543d20SAndroid Build Coastguard Worker if (modules_len == 0) continue;
2652*2d543d20SAndroid Build Coastguard Worker
2653*2d543d20SAndroid Build Coastguard Worker /* add space for modules */
2654*2d543d20SAndroid Build Coastguard Worker tmp = realloc(*modinfos,
2655*2d543d20SAndroid Build Coastguard Worker sizeof(semanage_module_info_t) *
2656*2d543d20SAndroid Build Coastguard Worker (*modinfos_len + modules_len));
2657*2d543d20SAndroid Build Coastguard Worker if (tmp == NULL) {
2658*2d543d20SAndroid Build Coastguard Worker ERR(sh, "Error allocating memory for module array.");
2659*2d543d20SAndroid Build Coastguard Worker status = -1;
2660*2d543d20SAndroid Build Coastguard Worker goto cleanup;
2661*2d543d20SAndroid Build Coastguard Worker }
2662*2d543d20SAndroid Build Coastguard Worker *modinfos = tmp;
2663*2d543d20SAndroid Build Coastguard Worker
2664*2d543d20SAndroid Build Coastguard Worker /* for each module directory */
2665*2d543d20SAndroid Build Coastguard Worker for(j = 0; j < modules_len; j++) {
2666*2d543d20SAndroid Build Coastguard Worker /* set module name */
2667*2d543d20SAndroid Build Coastguard Worker ret = semanage_module_info_set_name(
2668*2d543d20SAndroid Build Coastguard Worker sh,
2669*2d543d20SAndroid Build Coastguard Worker &modinfo,
2670*2d543d20SAndroid Build Coastguard Worker modules[j]->d_name);
2671*2d543d20SAndroid Build Coastguard Worker if (ret != 0) {
2672*2d543d20SAndroid Build Coastguard Worker status = -1;
2673*2d543d20SAndroid Build Coastguard Worker goto cleanup;
2674*2d543d20SAndroid Build Coastguard Worker }
2675*2d543d20SAndroid Build Coastguard Worker
2676*2d543d20SAndroid Build Coastguard Worker /* get module values */
2677*2d543d20SAndroid Build Coastguard Worker ret = semanage_direct_get_module_info(
2678*2d543d20SAndroid Build Coastguard Worker sh,
2679*2d543d20SAndroid Build Coastguard Worker (const semanage_module_key_t *)
2680*2d543d20SAndroid Build Coastguard Worker (&modinfo),
2681*2d543d20SAndroid Build Coastguard Worker &modinfo_tmp);
2682*2d543d20SAndroid Build Coastguard Worker if (ret != 0) {
2683*2d543d20SAndroid Build Coastguard Worker status = -1;
2684*2d543d20SAndroid Build Coastguard Worker goto cleanup;
2685*2d543d20SAndroid Build Coastguard Worker }
2686*2d543d20SAndroid Build Coastguard Worker
2687*2d543d20SAndroid Build Coastguard Worker /* copy into array */
2688*2d543d20SAndroid Build Coastguard Worker ret = semanage_module_info_init(
2689*2d543d20SAndroid Build Coastguard Worker sh,
2690*2d543d20SAndroid Build Coastguard Worker &((*modinfos)[*modinfos_len]));
2691*2d543d20SAndroid Build Coastguard Worker if (ret != 0) {
2692*2d543d20SAndroid Build Coastguard Worker status = -1;
2693*2d543d20SAndroid Build Coastguard Worker goto cleanup;
2694*2d543d20SAndroid Build Coastguard Worker }
2695*2d543d20SAndroid Build Coastguard Worker
2696*2d543d20SAndroid Build Coastguard Worker ret = semanage_module_info_clone(
2697*2d543d20SAndroid Build Coastguard Worker sh,
2698*2d543d20SAndroid Build Coastguard Worker modinfo_tmp,
2699*2d543d20SAndroid Build Coastguard Worker &((*modinfos)[*modinfos_len]));
2700*2d543d20SAndroid Build Coastguard Worker if (ret != 0) {
2701*2d543d20SAndroid Build Coastguard Worker status = -1;
2702*2d543d20SAndroid Build Coastguard Worker goto cleanup;
2703*2d543d20SAndroid Build Coastguard Worker }
2704*2d543d20SAndroid Build Coastguard Worker
2705*2d543d20SAndroid Build Coastguard Worker semanage_module_info_destroy(sh, modinfo_tmp);
2706*2d543d20SAndroid Build Coastguard Worker free(modinfo_tmp);
2707*2d543d20SAndroid Build Coastguard Worker modinfo_tmp = NULL;
2708*2d543d20SAndroid Build Coastguard Worker
2709*2d543d20SAndroid Build Coastguard Worker *modinfos_len += 1;
2710*2d543d20SAndroid Build Coastguard Worker }
2711*2d543d20SAndroid Build Coastguard Worker }
2712*2d543d20SAndroid Build Coastguard Worker
2713*2d543d20SAndroid Build Coastguard Worker cleanup:
2714*2d543d20SAndroid Build Coastguard Worker semanage_module_info_destroy(sh, &modinfo);
2715*2d543d20SAndroid Build Coastguard Worker
2716*2d543d20SAndroid Build Coastguard Worker if (priorities != NULL) {
2717*2d543d20SAndroid Build Coastguard Worker for (i = 0; i < priorities_len; i++) {
2718*2d543d20SAndroid Build Coastguard Worker free(priorities[i]);
2719*2d543d20SAndroid Build Coastguard Worker }
2720*2d543d20SAndroid Build Coastguard Worker free(priorities);
2721*2d543d20SAndroid Build Coastguard Worker }
2722*2d543d20SAndroid Build Coastguard Worker
2723*2d543d20SAndroid Build Coastguard Worker if (modules != NULL) {
2724*2d543d20SAndroid Build Coastguard Worker for (i = 0; i < modules_len; i++) {
2725*2d543d20SAndroid Build Coastguard Worker free(modules[i]);
2726*2d543d20SAndroid Build Coastguard Worker }
2727*2d543d20SAndroid Build Coastguard Worker free(modules);
2728*2d543d20SAndroid Build Coastguard Worker }
2729*2d543d20SAndroid Build Coastguard Worker
2730*2d543d20SAndroid Build Coastguard Worker semanage_module_info_destroy(sh, modinfo_tmp);
2731*2d543d20SAndroid Build Coastguard Worker free(modinfo_tmp);
2732*2d543d20SAndroid Build Coastguard Worker modinfo_tmp = NULL;
2733*2d543d20SAndroid Build Coastguard Worker
2734*2d543d20SAndroid Build Coastguard Worker if (status != 0) {
2735*2d543d20SAndroid Build Coastguard Worker if (modinfos != NULL) {
2736*2d543d20SAndroid Build Coastguard Worker for (i = 0; i < *modinfos_len; i++) {
2737*2d543d20SAndroid Build Coastguard Worker semanage_module_info_destroy(
2738*2d543d20SAndroid Build Coastguard Worker sh,
2739*2d543d20SAndroid Build Coastguard Worker &(*modinfos)[i]);
2740*2d543d20SAndroid Build Coastguard Worker }
2741*2d543d20SAndroid Build Coastguard Worker free(*modinfos);
2742*2d543d20SAndroid Build Coastguard Worker *modinfos = NULL;
2743*2d543d20SAndroid Build Coastguard Worker *modinfos_len = 0;
2744*2d543d20SAndroid Build Coastguard Worker }
2745*2d543d20SAndroid Build Coastguard Worker }
2746*2d543d20SAndroid Build Coastguard Worker
2747*2d543d20SAndroid Build Coastguard Worker return status;
2748*2d543d20SAndroid Build Coastguard Worker }
2749*2d543d20SAndroid Build Coastguard Worker
semanage_direct_install_info(semanage_handle_t * sh,const semanage_module_info_t * modinfo,char * data,size_t data_len)2750*2d543d20SAndroid Build Coastguard Worker static int semanage_direct_install_info(semanage_handle_t *sh,
2751*2d543d20SAndroid Build Coastguard Worker const semanage_module_info_t *modinfo,
2752*2d543d20SAndroid Build Coastguard Worker char *data,
2753*2d543d20SAndroid Build Coastguard Worker size_t data_len)
2754*2d543d20SAndroid Build Coastguard Worker {
2755*2d543d20SAndroid Build Coastguard Worker assert(sh);
2756*2d543d20SAndroid Build Coastguard Worker assert(modinfo);
2757*2d543d20SAndroid Build Coastguard Worker assert(data);
2758*2d543d20SAndroid Build Coastguard Worker
2759*2d543d20SAndroid Build Coastguard Worker int status = 0;
2760*2d543d20SAndroid Build Coastguard Worker int ret = 0;
2761*2d543d20SAndroid Build Coastguard Worker int type;
2762*2d543d20SAndroid Build Coastguard Worker struct stat sb;
2763*2d543d20SAndroid Build Coastguard Worker
2764*2d543d20SAndroid Build Coastguard Worker char path[PATH_MAX];
2765*2d543d20SAndroid Build Coastguard Worker mode_t mask = umask(0077);
2766*2d543d20SAndroid Build Coastguard Worker
2767*2d543d20SAndroid Build Coastguard Worker semanage_module_info_t *higher_info = NULL;
2768*2d543d20SAndroid Build Coastguard Worker semanage_module_key_t higher_key;
2769*2d543d20SAndroid Build Coastguard Worker ret = semanage_module_key_init(sh, &higher_key);
2770*2d543d20SAndroid Build Coastguard Worker if (ret != 0) {
2771*2d543d20SAndroid Build Coastguard Worker status = -1;
2772*2d543d20SAndroid Build Coastguard Worker goto cleanup;
2773*2d543d20SAndroid Build Coastguard Worker }
2774*2d543d20SAndroid Build Coastguard Worker
2775*2d543d20SAndroid Build Coastguard Worker /* validate module info */
2776*2d543d20SAndroid Build Coastguard Worker ret = semanage_module_info_validate(modinfo);
2777*2d543d20SAndroid Build Coastguard Worker if (ret != 0) {
2778*2d543d20SAndroid Build Coastguard Worker ERR(sh, "%s failed module validation.\n", modinfo->name);
2779*2d543d20SAndroid Build Coastguard Worker status = -2;
2780*2d543d20SAndroid Build Coastguard Worker goto cleanup;
2781*2d543d20SAndroid Build Coastguard Worker }
2782*2d543d20SAndroid Build Coastguard Worker
2783*2d543d20SAndroid Build Coastguard Worker /* Check for higher priority module and warn if there is one as
2784*2d543d20SAndroid Build Coastguard Worker * it will override the module currently being installed.
2785*2d543d20SAndroid Build Coastguard Worker */
2786*2d543d20SAndroid Build Coastguard Worker ret = semanage_module_key_set_name(sh, &higher_key, modinfo->name);
2787*2d543d20SAndroid Build Coastguard Worker if (ret != 0) {
2788*2d543d20SAndroid Build Coastguard Worker status = -1;
2789*2d543d20SAndroid Build Coastguard Worker goto cleanup;
2790*2d543d20SAndroid Build Coastguard Worker }
2791*2d543d20SAndroid Build Coastguard Worker
2792*2d543d20SAndroid Build Coastguard Worker ret = semanage_direct_get_module_info(sh, &higher_key, &higher_info);
2793*2d543d20SAndroid Build Coastguard Worker if (ret == 0) {
2794*2d543d20SAndroid Build Coastguard Worker if (higher_info->priority > modinfo->priority) {
2795*2d543d20SAndroid Build Coastguard Worker errno = 0;
2796*2d543d20SAndroid Build Coastguard Worker WARN(sh,
2797*2d543d20SAndroid Build Coastguard Worker "A higher priority %s module exists at priority %d and will override the module currently being installed at priority %d.",
2798*2d543d20SAndroid Build Coastguard Worker modinfo->name,
2799*2d543d20SAndroid Build Coastguard Worker higher_info->priority,
2800*2d543d20SAndroid Build Coastguard Worker modinfo->priority);
2801*2d543d20SAndroid Build Coastguard Worker }
2802*2d543d20SAndroid Build Coastguard Worker else if (higher_info->priority < modinfo->priority) {
2803*2d543d20SAndroid Build Coastguard Worker errno = 0;
2804*2d543d20SAndroid Build Coastguard Worker INFO(sh,
2805*2d543d20SAndroid Build Coastguard Worker "Overriding %s module at lower priority %d with module at priority %d.",
2806*2d543d20SAndroid Build Coastguard Worker modinfo->name,
2807*2d543d20SAndroid Build Coastguard Worker higher_info->priority,
2808*2d543d20SAndroid Build Coastguard Worker modinfo->priority);
2809*2d543d20SAndroid Build Coastguard Worker }
2810*2d543d20SAndroid Build Coastguard Worker
2811*2d543d20SAndroid Build Coastguard Worker if (higher_info->enabled == 0 && modinfo->enabled == -1) {
2812*2d543d20SAndroid Build Coastguard Worker errno = 0;
2813*2d543d20SAndroid Build Coastguard Worker WARN(sh,
2814*2d543d20SAndroid Build Coastguard Worker "%s module will be disabled after install as there is a disabled instance of this module present in the system.",
2815*2d543d20SAndroid Build Coastguard Worker modinfo->name);
2816*2d543d20SAndroid Build Coastguard Worker }
2817*2d543d20SAndroid Build Coastguard Worker }
2818*2d543d20SAndroid Build Coastguard Worker
2819*2d543d20SAndroid Build Coastguard Worker /* set module meta data */
2820*2d543d20SAndroid Build Coastguard Worker ret = semanage_direct_set_module_info(sh, modinfo);
2821*2d543d20SAndroid Build Coastguard Worker if (ret != 0) {
2822*2d543d20SAndroid Build Coastguard Worker status = -2;
2823*2d543d20SAndroid Build Coastguard Worker goto cleanup;
2824*2d543d20SAndroid Build Coastguard Worker }
2825*2d543d20SAndroid Build Coastguard Worker
2826*2d543d20SAndroid Build Coastguard Worker /* install module source file */
2827*2d543d20SAndroid Build Coastguard Worker if (!strcasecmp(modinfo->lang_ext, "cil")) {
2828*2d543d20SAndroid Build Coastguard Worker type = SEMANAGE_MODULE_PATH_CIL;
2829*2d543d20SAndroid Build Coastguard Worker } else {
2830*2d543d20SAndroid Build Coastguard Worker type = SEMANAGE_MODULE_PATH_HLL;
2831*2d543d20SAndroid Build Coastguard Worker }
2832*2d543d20SAndroid Build Coastguard Worker ret = semanage_module_get_path(
2833*2d543d20SAndroid Build Coastguard Worker sh,
2834*2d543d20SAndroid Build Coastguard Worker modinfo,
2835*2d543d20SAndroid Build Coastguard Worker type,
2836*2d543d20SAndroid Build Coastguard Worker path,
2837*2d543d20SAndroid Build Coastguard Worker sizeof(path));
2838*2d543d20SAndroid Build Coastguard Worker if (ret != 0) {
2839*2d543d20SAndroid Build Coastguard Worker status = -3;
2840*2d543d20SAndroid Build Coastguard Worker goto cleanup;
2841*2d543d20SAndroid Build Coastguard Worker }
2842*2d543d20SAndroid Build Coastguard Worker
2843*2d543d20SAndroid Build Coastguard Worker ret = write_compressed_file(sh, path, data, data_len);
2844*2d543d20SAndroid Build Coastguard Worker if (ret < 0) {
2845*2d543d20SAndroid Build Coastguard Worker ERR(sh, "Error while writing to %s.", path);
2846*2d543d20SAndroid Build Coastguard Worker status = -3;
2847*2d543d20SAndroid Build Coastguard Worker goto cleanup;
2848*2d543d20SAndroid Build Coastguard Worker }
2849*2d543d20SAndroid Build Coastguard Worker
2850*2d543d20SAndroid Build Coastguard Worker /* if this is an HLL, delete the CIL cache if it exists so it will get recompiled */
2851*2d543d20SAndroid Build Coastguard Worker if (type == SEMANAGE_MODULE_PATH_HLL) {
2852*2d543d20SAndroid Build Coastguard Worker ret = semanage_module_get_path(
2853*2d543d20SAndroid Build Coastguard Worker sh,
2854*2d543d20SAndroid Build Coastguard Worker modinfo,
2855*2d543d20SAndroid Build Coastguard Worker SEMANAGE_MODULE_PATH_CIL,
2856*2d543d20SAndroid Build Coastguard Worker path,
2857*2d543d20SAndroid Build Coastguard Worker sizeof(path));
2858*2d543d20SAndroid Build Coastguard Worker if (ret != 0) {
2859*2d543d20SAndroid Build Coastguard Worker status = -3;
2860*2d543d20SAndroid Build Coastguard Worker goto cleanup;
2861*2d543d20SAndroid Build Coastguard Worker }
2862*2d543d20SAndroid Build Coastguard Worker
2863*2d543d20SAndroid Build Coastguard Worker if (stat(path, &sb) == 0) {
2864*2d543d20SAndroid Build Coastguard Worker ret = unlink(path);
2865*2d543d20SAndroid Build Coastguard Worker if (ret != 0) {
2866*2d543d20SAndroid Build Coastguard Worker ERR(sh, "Error while removing cached CIL file %s: %s", path, strerror(errno));
2867*2d543d20SAndroid Build Coastguard Worker status = -3;
2868*2d543d20SAndroid Build Coastguard Worker goto cleanup;
2869*2d543d20SAndroid Build Coastguard Worker }
2870*2d543d20SAndroid Build Coastguard Worker }
2871*2d543d20SAndroid Build Coastguard Worker }
2872*2d543d20SAndroid Build Coastguard Worker
2873*2d543d20SAndroid Build Coastguard Worker cleanup:
2874*2d543d20SAndroid Build Coastguard Worker semanage_module_key_destroy(sh, &higher_key);
2875*2d543d20SAndroid Build Coastguard Worker semanage_module_info_destroy(sh, higher_info);
2876*2d543d20SAndroid Build Coastguard Worker free(higher_info);
2877*2d543d20SAndroid Build Coastguard Worker umask(mask);
2878*2d543d20SAndroid Build Coastguard Worker
2879*2d543d20SAndroid Build Coastguard Worker return status;
2880*2d543d20SAndroid Build Coastguard Worker }
2881*2d543d20SAndroid Build Coastguard Worker
semanage_direct_remove_key(semanage_handle_t * sh,const semanage_module_key_t * modkey)2882*2d543d20SAndroid Build Coastguard Worker static int semanage_direct_remove_key(semanage_handle_t *sh,
2883*2d543d20SAndroid Build Coastguard Worker const semanage_module_key_t *modkey)
2884*2d543d20SAndroid Build Coastguard Worker {
2885*2d543d20SAndroid Build Coastguard Worker assert(sh);
2886*2d543d20SAndroid Build Coastguard Worker assert(modkey);
2887*2d543d20SAndroid Build Coastguard Worker
2888*2d543d20SAndroid Build Coastguard Worker int status = 0;
2889*2d543d20SAndroid Build Coastguard Worker int ret = 0;
2890*2d543d20SAndroid Build Coastguard Worker
2891*2d543d20SAndroid Build Coastguard Worker char path[PATH_MAX];
2892*2d543d20SAndroid Build Coastguard Worker semanage_module_info_t *modinfo = NULL;
2893*2d543d20SAndroid Build Coastguard Worker
2894*2d543d20SAndroid Build Coastguard Worker semanage_module_key_t modkey_tmp;
2895*2d543d20SAndroid Build Coastguard Worker ret = semanage_module_key_init(sh, &modkey_tmp);
2896*2d543d20SAndroid Build Coastguard Worker if (ret != 0) {
2897*2d543d20SAndroid Build Coastguard Worker status = -1;
2898*2d543d20SAndroid Build Coastguard Worker goto cleanup;
2899*2d543d20SAndroid Build Coastguard Worker }
2900*2d543d20SAndroid Build Coastguard Worker
2901*2d543d20SAndroid Build Coastguard Worker /* validate module key */
2902*2d543d20SAndroid Build Coastguard Worker ret = semanage_module_validate_priority(modkey->priority);
2903*2d543d20SAndroid Build Coastguard Worker if (ret != 0) {
2904*2d543d20SAndroid Build Coastguard Worker errno = 0;
2905*2d543d20SAndroid Build Coastguard Worker ERR(sh, "Priority %d is invalid.", modkey->priority);
2906*2d543d20SAndroid Build Coastguard Worker status = -1;
2907*2d543d20SAndroid Build Coastguard Worker goto cleanup;
2908*2d543d20SAndroid Build Coastguard Worker }
2909*2d543d20SAndroid Build Coastguard Worker
2910*2d543d20SAndroid Build Coastguard Worker ret = semanage_module_validate_name(modkey->name);
2911*2d543d20SAndroid Build Coastguard Worker if (ret != 0) {
2912*2d543d20SAndroid Build Coastguard Worker errno = 0;
2913*2d543d20SAndroid Build Coastguard Worker ERR(sh, "Name %s is invalid.", modkey->name);
2914*2d543d20SAndroid Build Coastguard Worker status = -1;
2915*2d543d20SAndroid Build Coastguard Worker goto cleanup;
2916*2d543d20SAndroid Build Coastguard Worker }
2917*2d543d20SAndroid Build Coastguard Worker
2918*2d543d20SAndroid Build Coastguard Worker ret = semanage_module_key_set_name(sh, &modkey_tmp, modkey->name);
2919*2d543d20SAndroid Build Coastguard Worker if (ret != 0) {
2920*2d543d20SAndroid Build Coastguard Worker status = -1;
2921*2d543d20SAndroid Build Coastguard Worker goto cleanup;
2922*2d543d20SAndroid Build Coastguard Worker }
2923*2d543d20SAndroid Build Coastguard Worker
2924*2d543d20SAndroid Build Coastguard Worker /* get module path */
2925*2d543d20SAndroid Build Coastguard Worker ret = semanage_module_get_path(
2926*2d543d20SAndroid Build Coastguard Worker sh,
2927*2d543d20SAndroid Build Coastguard Worker (const semanage_module_info_t *)modkey,
2928*2d543d20SAndroid Build Coastguard Worker SEMANAGE_MODULE_PATH_NAME,
2929*2d543d20SAndroid Build Coastguard Worker path,
2930*2d543d20SAndroid Build Coastguard Worker sizeof(path));
2931*2d543d20SAndroid Build Coastguard Worker if (ret != 0) {
2932*2d543d20SAndroid Build Coastguard Worker status = -2;
2933*2d543d20SAndroid Build Coastguard Worker goto cleanup;
2934*2d543d20SAndroid Build Coastguard Worker }
2935*2d543d20SAndroid Build Coastguard Worker
2936*2d543d20SAndroid Build Coastguard Worker /* remove directory */
2937*2d543d20SAndroid Build Coastguard Worker ret = semanage_remove_directory(path);
2938*2d543d20SAndroid Build Coastguard Worker if (ret != 0) {
2939*2d543d20SAndroid Build Coastguard Worker ERR(sh, "Unable to remove module %s at priority %d.", modkey->name, modkey->priority);
2940*2d543d20SAndroid Build Coastguard Worker status = -2;
2941*2d543d20SAndroid Build Coastguard Worker goto cleanup;
2942*2d543d20SAndroid Build Coastguard Worker }
2943*2d543d20SAndroid Build Coastguard Worker
2944*2d543d20SAndroid Build Coastguard Worker /* check if its the last module at any priority */
2945*2d543d20SAndroid Build Coastguard Worker ret = semanage_module_get_module_info(sh, &modkey_tmp, &modinfo);
2946*2d543d20SAndroid Build Coastguard Worker if (ret != 0) {
2947*2d543d20SAndroid Build Coastguard Worker /* info that no other module will override */
2948*2d543d20SAndroid Build Coastguard Worker errno = 0;
2949*2d543d20SAndroid Build Coastguard Worker INFO(sh,
2950*2d543d20SAndroid Build Coastguard Worker "Removing last %s module (no other %s module exists at another priority).",
2951*2d543d20SAndroid Build Coastguard Worker modkey->name,
2952*2d543d20SAndroid Build Coastguard Worker modkey->name);
2953*2d543d20SAndroid Build Coastguard Worker
2954*2d543d20SAndroid Build Coastguard Worker /* remove disabled status file */
2955*2d543d20SAndroid Build Coastguard Worker ret = semanage_module_get_path(
2956*2d543d20SAndroid Build Coastguard Worker sh,
2957*2d543d20SAndroid Build Coastguard Worker (const semanage_module_info_t *)modkey,
2958*2d543d20SAndroid Build Coastguard Worker SEMANAGE_MODULE_PATH_DISABLED,
2959*2d543d20SAndroid Build Coastguard Worker path,
2960*2d543d20SAndroid Build Coastguard Worker sizeof(path));
2961*2d543d20SAndroid Build Coastguard Worker if (ret != 0) {
2962*2d543d20SAndroid Build Coastguard Worker status = -1;
2963*2d543d20SAndroid Build Coastguard Worker goto cleanup;
2964*2d543d20SAndroid Build Coastguard Worker }
2965*2d543d20SAndroid Build Coastguard Worker
2966*2d543d20SAndroid Build Coastguard Worker struct stat sb;
2967*2d543d20SAndroid Build Coastguard Worker if (stat(path, &sb) == 0) {
2968*2d543d20SAndroid Build Coastguard Worker ret = unlink(path);
2969*2d543d20SAndroid Build Coastguard Worker if (ret != 0) {
2970*2d543d20SAndroid Build Coastguard Worker status = -1;
2971*2d543d20SAndroid Build Coastguard Worker goto cleanup;
2972*2d543d20SAndroid Build Coastguard Worker }
2973*2d543d20SAndroid Build Coastguard Worker }
2974*2d543d20SAndroid Build Coastguard Worker }
2975*2d543d20SAndroid Build Coastguard Worker else {
2976*2d543d20SAndroid Build Coastguard Worker /* if a lower priority module is going to become active */
2977*2d543d20SAndroid Build Coastguard Worker if (modkey->priority > modinfo->priority) {
2978*2d543d20SAndroid Build Coastguard Worker /* inform what the new active module will be */
2979*2d543d20SAndroid Build Coastguard Worker errno = 0;
2980*2d543d20SAndroid Build Coastguard Worker INFO(sh,
2981*2d543d20SAndroid Build Coastguard Worker "%s module at priority %d is now active.",
2982*2d543d20SAndroid Build Coastguard Worker modinfo->name,
2983*2d543d20SAndroid Build Coastguard Worker modinfo->priority);
2984*2d543d20SAndroid Build Coastguard Worker }
2985*2d543d20SAndroid Build Coastguard Worker }
2986*2d543d20SAndroid Build Coastguard Worker
2987*2d543d20SAndroid Build Coastguard Worker cleanup:
2988*2d543d20SAndroid Build Coastguard Worker semanage_module_key_destroy(sh, &modkey_tmp);
2989*2d543d20SAndroid Build Coastguard Worker
2990*2d543d20SAndroid Build Coastguard Worker semanage_module_info_destroy(sh, modinfo);
2991*2d543d20SAndroid Build Coastguard Worker free(modinfo);
2992*2d543d20SAndroid Build Coastguard Worker
2993*2d543d20SAndroid Build Coastguard Worker return status;
2994*2d543d20SAndroid Build Coastguard Worker }
2995*2d543d20SAndroid Build Coastguard Worker
2996