1*6a54128fSAndroid Build Coastguard Worker #ifndef _GNU_SOURCE
2*6a54128fSAndroid Build Coastguard Worker # define _GNU_SOURCE //asprintf
3*6a54128fSAndroid Build Coastguard Worker #endif
4*6a54128fSAndroid Build Coastguard Worker #include "config.h"
5*6a54128fSAndroid Build Coastguard Worker #include "perms.h"
6*6a54128fSAndroid Build Coastguard Worker #include "support/nls-enable.h"
7*6a54128fSAndroid Build Coastguard Worker #include <time.h>
8*6a54128fSAndroid Build Coastguard Worker #include <sys/stat.h>
9*6a54128fSAndroid Build Coastguard Worker
10*6a54128fSAndroid Build Coastguard Worker #ifndef XATTR_SELINUX_SUFFIX
11*6a54128fSAndroid Build Coastguard Worker # define XATTR_SELINUX_SUFFIX "selinux"
12*6a54128fSAndroid Build Coastguard Worker #endif
13*6a54128fSAndroid Build Coastguard Worker #ifndef XATTR_CAPS_SUFFIX
14*6a54128fSAndroid Build Coastguard Worker # define XATTR_CAPS_SUFFIX "capability"
15*6a54128fSAndroid Build Coastguard Worker #endif
16*6a54128fSAndroid Build Coastguard Worker
17*6a54128fSAndroid Build Coastguard Worker struct inode_params {
18*6a54128fSAndroid Build Coastguard Worker ext2_filsys fs;
19*6a54128fSAndroid Build Coastguard Worker char *path;
20*6a54128fSAndroid Build Coastguard Worker char *filename;
21*6a54128fSAndroid Build Coastguard Worker char *src_dir;
22*6a54128fSAndroid Build Coastguard Worker char *target_out;
23*6a54128fSAndroid Build Coastguard Worker char *mountpoint;
24*6a54128fSAndroid Build Coastguard Worker fs_config_f fs_config_func;
25*6a54128fSAndroid Build Coastguard Worker struct selabel_handle *sehnd;
26*6a54128fSAndroid Build Coastguard Worker time_t fixed_time;
27*6a54128fSAndroid Build Coastguard Worker const struct ugid_map* uid_map;
28*6a54128fSAndroid Build Coastguard Worker const struct ugid_map* gid_map;
29*6a54128fSAndroid Build Coastguard Worker errcode_t error;
30*6a54128fSAndroid Build Coastguard Worker };
31*6a54128fSAndroid Build Coastguard Worker
ino_add_xattr(ext2_filsys fs,ext2_ino_t ino,const char * name,const void * value,int value_len)32*6a54128fSAndroid Build Coastguard Worker static errcode_t ino_add_xattr(ext2_filsys fs, ext2_ino_t ino, const char *name,
33*6a54128fSAndroid Build Coastguard Worker const void *value, int value_len)
34*6a54128fSAndroid Build Coastguard Worker {
35*6a54128fSAndroid Build Coastguard Worker errcode_t retval, close_retval;
36*6a54128fSAndroid Build Coastguard Worker struct ext2_xattr_handle *xhandle;
37*6a54128fSAndroid Build Coastguard Worker
38*6a54128fSAndroid Build Coastguard Worker retval = ext2fs_xattrs_open(fs, ino, &xhandle);
39*6a54128fSAndroid Build Coastguard Worker if (retval) {
40*6a54128fSAndroid Build Coastguard Worker com_err(__func__, retval, _("while opening inode %u"), ino);
41*6a54128fSAndroid Build Coastguard Worker return retval;
42*6a54128fSAndroid Build Coastguard Worker }
43*6a54128fSAndroid Build Coastguard Worker retval = ext2fs_xattrs_read(xhandle);
44*6a54128fSAndroid Build Coastguard Worker if (retval) {
45*6a54128fSAndroid Build Coastguard Worker com_err(__func__, retval,
46*6a54128fSAndroid Build Coastguard Worker _("while reading xattrs of inode %u"), ino);
47*6a54128fSAndroid Build Coastguard Worker goto xattrs_close;
48*6a54128fSAndroid Build Coastguard Worker }
49*6a54128fSAndroid Build Coastguard Worker retval = ext2fs_xattr_set(xhandle, name, value, value_len);
50*6a54128fSAndroid Build Coastguard Worker if (retval) {
51*6a54128fSAndroid Build Coastguard Worker com_err(__func__, retval,
52*6a54128fSAndroid Build Coastguard Worker _("while setting xattrs of inode %u"), ino);
53*6a54128fSAndroid Build Coastguard Worker goto xattrs_close;
54*6a54128fSAndroid Build Coastguard Worker }
55*6a54128fSAndroid Build Coastguard Worker xattrs_close:
56*6a54128fSAndroid Build Coastguard Worker close_retval = ext2fs_xattrs_close(&xhandle);
57*6a54128fSAndroid Build Coastguard Worker if (close_retval) {
58*6a54128fSAndroid Build Coastguard Worker com_err(__func__, close_retval,
59*6a54128fSAndroid Build Coastguard Worker _("while closing xattrs of inode %u"), ino);
60*6a54128fSAndroid Build Coastguard Worker return retval ? retval : close_retval;
61*6a54128fSAndroid Build Coastguard Worker }
62*6a54128fSAndroid Build Coastguard Worker return retval;
63*6a54128fSAndroid Build Coastguard Worker }
64*6a54128fSAndroid Build Coastguard Worker
set_selinux_xattr(ext2_filsys fs,ext2_ino_t ino,struct inode_params * params)65*6a54128fSAndroid Build Coastguard Worker static errcode_t set_selinux_xattr(ext2_filsys fs, ext2_ino_t ino,
66*6a54128fSAndroid Build Coastguard Worker struct inode_params *params)
67*6a54128fSAndroid Build Coastguard Worker {
68*6a54128fSAndroid Build Coastguard Worker errcode_t retval;
69*6a54128fSAndroid Build Coastguard Worker char *secontext = NULL;
70*6a54128fSAndroid Build Coastguard Worker struct ext2_inode inode;
71*6a54128fSAndroid Build Coastguard Worker
72*6a54128fSAndroid Build Coastguard Worker if (params->sehnd == NULL)
73*6a54128fSAndroid Build Coastguard Worker return 0;
74*6a54128fSAndroid Build Coastguard Worker
75*6a54128fSAndroid Build Coastguard Worker retval = ext2fs_read_inode(fs, ino, &inode);
76*6a54128fSAndroid Build Coastguard Worker if (retval) {
77*6a54128fSAndroid Build Coastguard Worker com_err(__func__, retval,
78*6a54128fSAndroid Build Coastguard Worker _("while reading inode %u"), ino);
79*6a54128fSAndroid Build Coastguard Worker return retval;
80*6a54128fSAndroid Build Coastguard Worker }
81*6a54128fSAndroid Build Coastguard Worker
82*6a54128fSAndroid Build Coastguard Worker retval = selabel_lookup(params->sehnd, &secontext, params->filename,
83*6a54128fSAndroid Build Coastguard Worker inode.i_mode);
84*6a54128fSAndroid Build Coastguard Worker if (retval < 0) {
85*6a54128fSAndroid Build Coastguard Worker int saved_errno = errno;
86*6a54128fSAndroid Build Coastguard Worker com_err(__func__, errno,
87*6a54128fSAndroid Build Coastguard Worker _("searching for label \"%s\""), params->filename);
88*6a54128fSAndroid Build Coastguard Worker return saved_errno;
89*6a54128fSAndroid Build Coastguard Worker }
90*6a54128fSAndroid Build Coastguard Worker
91*6a54128fSAndroid Build Coastguard Worker retval = ino_add_xattr(fs, ino, "security." XATTR_SELINUX_SUFFIX,
92*6a54128fSAndroid Build Coastguard Worker secontext, strlen(secontext) + 1);
93*6a54128fSAndroid Build Coastguard Worker
94*6a54128fSAndroid Build Coastguard Worker freecon(secontext);
95*6a54128fSAndroid Build Coastguard Worker return retval;
96*6a54128fSAndroid Build Coastguard Worker }
97*6a54128fSAndroid Build Coastguard Worker
98*6a54128fSAndroid Build Coastguard Worker /*
99*6a54128fSAndroid Build Coastguard Worker * Returns mapped UID/GID if there is a corresponding entry in |mapping|.
100*6a54128fSAndroid Build Coastguard Worker * Otherwise |id| as is.
101*6a54128fSAndroid Build Coastguard Worker */
resolve_ugid(const struct ugid_map * mapping,unsigned int id)102*6a54128fSAndroid Build Coastguard Worker static unsigned int resolve_ugid(const struct ugid_map* mapping,
103*6a54128fSAndroid Build Coastguard Worker unsigned int id)
104*6a54128fSAndroid Build Coastguard Worker {
105*6a54128fSAndroid Build Coastguard Worker size_t i;
106*6a54128fSAndroid Build Coastguard Worker for (i = 0; i < mapping->size; ++i) {
107*6a54128fSAndroid Build Coastguard Worker const struct ugid_map_entry* entry = &mapping->entries[i];
108*6a54128fSAndroid Build Coastguard Worker if (entry->parent_id <= id &&
109*6a54128fSAndroid Build Coastguard Worker id < entry->parent_id + entry->length) {
110*6a54128fSAndroid Build Coastguard Worker return id + entry->child_id - entry->parent_id;
111*6a54128fSAndroid Build Coastguard Worker }
112*6a54128fSAndroid Build Coastguard Worker }
113*6a54128fSAndroid Build Coastguard Worker
114*6a54128fSAndroid Build Coastguard Worker /* No entry is found. */
115*6a54128fSAndroid Build Coastguard Worker return id;
116*6a54128fSAndroid Build Coastguard Worker }
117*6a54128fSAndroid Build Coastguard Worker
set_perms_and_caps(ext2_filsys fs,ext2_ino_t ino,struct inode_params * params)118*6a54128fSAndroid Build Coastguard Worker static errcode_t set_perms_and_caps(ext2_filsys fs, ext2_ino_t ino,
119*6a54128fSAndroid Build Coastguard Worker struct inode_params *params)
120*6a54128fSAndroid Build Coastguard Worker {
121*6a54128fSAndroid Build Coastguard Worker errcode_t retval;
122*6a54128fSAndroid Build Coastguard Worker uint64_t capabilities = 0;
123*6a54128fSAndroid Build Coastguard Worker struct ext2_inode inode;
124*6a54128fSAndroid Build Coastguard Worker struct vfs_cap_data cap_data;
125*6a54128fSAndroid Build Coastguard Worker unsigned int uid = 0, gid = 0, imode = 0;
126*6a54128fSAndroid Build Coastguard Worker
127*6a54128fSAndroid Build Coastguard Worker retval = ext2fs_read_inode(fs, ino, &inode);
128*6a54128fSAndroid Build Coastguard Worker if (retval) {
129*6a54128fSAndroid Build Coastguard Worker com_err(__func__, retval, _("while reading inode %u"), ino);
130*6a54128fSAndroid Build Coastguard Worker return retval;
131*6a54128fSAndroid Build Coastguard Worker }
132*6a54128fSAndroid Build Coastguard Worker
133*6a54128fSAndroid Build Coastguard Worker /* Permissions */
134*6a54128fSAndroid Build Coastguard Worker if (params->fs_config_func != NULL) {
135*6a54128fSAndroid Build Coastguard Worker const char *filename = params->filename;
136*6a54128fSAndroid Build Coastguard Worker if (strcmp(filename, params->mountpoint) == 0) {
137*6a54128fSAndroid Build Coastguard Worker /* The root of the filesystem needs to be an empty string. */
138*6a54128fSAndroid Build Coastguard Worker filename = "";
139*6a54128fSAndroid Build Coastguard Worker }
140*6a54128fSAndroid Build Coastguard Worker params->fs_config_func(filename, S_ISDIR(inode.i_mode),
141*6a54128fSAndroid Build Coastguard Worker params->target_out, &uid, &gid, &imode,
142*6a54128fSAndroid Build Coastguard Worker &capabilities);
143*6a54128fSAndroid Build Coastguard Worker uid = resolve_ugid(params->uid_map, uid);
144*6a54128fSAndroid Build Coastguard Worker gid = resolve_ugid(params->gid_map, gid);
145*6a54128fSAndroid Build Coastguard Worker inode.i_uid = (__u16) uid;
146*6a54128fSAndroid Build Coastguard Worker inode.i_gid = (__u16) gid;
147*6a54128fSAndroid Build Coastguard Worker ext2fs_set_i_uid_high(inode, (__u16) (uid >> 16));
148*6a54128fSAndroid Build Coastguard Worker ext2fs_set_i_gid_high(inode, (__u16) (gid >> 16));
149*6a54128fSAndroid Build Coastguard Worker inode.i_mode = (inode.i_mode & S_IFMT) | (imode & 0xffff);
150*6a54128fSAndroid Build Coastguard Worker retval = ext2fs_write_inode(fs, ino, &inode);
151*6a54128fSAndroid Build Coastguard Worker if (retval) {
152*6a54128fSAndroid Build Coastguard Worker com_err(__func__, retval,
153*6a54128fSAndroid Build Coastguard Worker _("while writing inode %u"), ino);
154*6a54128fSAndroid Build Coastguard Worker return retval;
155*6a54128fSAndroid Build Coastguard Worker }
156*6a54128fSAndroid Build Coastguard Worker }
157*6a54128fSAndroid Build Coastguard Worker
158*6a54128fSAndroid Build Coastguard Worker /* Capabilities */
159*6a54128fSAndroid Build Coastguard Worker if (!capabilities)
160*6a54128fSAndroid Build Coastguard Worker return 0;
161*6a54128fSAndroid Build Coastguard Worker memset(&cap_data, 0, sizeof(cap_data));
162*6a54128fSAndroid Build Coastguard Worker cap_data.magic_etc = VFS_CAP_REVISION_2 | VFS_CAP_FLAGS_EFFECTIVE;
163*6a54128fSAndroid Build Coastguard Worker cap_data.data[0].permitted = (uint32_t) (capabilities & 0xffffffff);
164*6a54128fSAndroid Build Coastguard Worker cap_data.data[1].permitted = (uint32_t) (capabilities >> 32);
165*6a54128fSAndroid Build Coastguard Worker return ino_add_xattr(fs, ino, "security." XATTR_CAPS_SUFFIX,
166*6a54128fSAndroid Build Coastguard Worker &cap_data, sizeof(cap_data));
167*6a54128fSAndroid Build Coastguard Worker }
168*6a54128fSAndroid Build Coastguard Worker
set_timestamp(ext2_filsys fs,ext2_ino_t ino,struct inode_params * params)169*6a54128fSAndroid Build Coastguard Worker static errcode_t set_timestamp(ext2_filsys fs, ext2_ino_t ino,
170*6a54128fSAndroid Build Coastguard Worker struct inode_params *params)
171*6a54128fSAndroid Build Coastguard Worker {
172*6a54128fSAndroid Build Coastguard Worker errcode_t retval;
173*6a54128fSAndroid Build Coastguard Worker struct ext2_inode inode;
174*6a54128fSAndroid Build Coastguard Worker struct stat stat;
175*6a54128fSAndroid Build Coastguard Worker char *src_filename = NULL;
176*6a54128fSAndroid Build Coastguard Worker
177*6a54128fSAndroid Build Coastguard Worker retval = ext2fs_read_inode(fs, ino, &inode);
178*6a54128fSAndroid Build Coastguard Worker if (retval) {
179*6a54128fSAndroid Build Coastguard Worker com_err(__func__, retval,
180*6a54128fSAndroid Build Coastguard Worker _("while reading inode %u"), ino);
181*6a54128fSAndroid Build Coastguard Worker return retval;
182*6a54128fSAndroid Build Coastguard Worker }
183*6a54128fSAndroid Build Coastguard Worker
184*6a54128fSAndroid Build Coastguard Worker if (params->fixed_time == -1 && params->src_dir) {
185*6a54128fSAndroid Build Coastguard Worker /* replace mountpoint from filename with src_dir */
186*6a54128fSAndroid Build Coastguard Worker if (asprintf(&src_filename, "%s/%s", params->src_dir,
187*6a54128fSAndroid Build Coastguard Worker params->filename + strlen(params->mountpoint)) < 0) {
188*6a54128fSAndroid Build Coastguard Worker return -ENOMEM;
189*6a54128fSAndroid Build Coastguard Worker }
190*6a54128fSAndroid Build Coastguard Worker retval = lstat(src_filename, &stat);
191*6a54128fSAndroid Build Coastguard Worker if (retval < 0) {
192*6a54128fSAndroid Build Coastguard Worker com_err(__func__, errno,
193*6a54128fSAndroid Build Coastguard Worker _("while lstat file %s"), src_filename);
194*6a54128fSAndroid Build Coastguard Worker goto end;
195*6a54128fSAndroid Build Coastguard Worker }
196*6a54128fSAndroid Build Coastguard Worker inode.i_atime = inode.i_ctime = inode.i_mtime = stat.st_mtime;
197*6a54128fSAndroid Build Coastguard Worker } else {
198*6a54128fSAndroid Build Coastguard Worker inode.i_atime = inode.i_ctime = inode.i_mtime = params->fixed_time;
199*6a54128fSAndroid Build Coastguard Worker }
200*6a54128fSAndroid Build Coastguard Worker
201*6a54128fSAndroid Build Coastguard Worker retval = ext2fs_write_inode(fs, ino, &inode);
202*6a54128fSAndroid Build Coastguard Worker if (retval) {
203*6a54128fSAndroid Build Coastguard Worker com_err(__func__, retval,
204*6a54128fSAndroid Build Coastguard Worker _("while writing inode %u"), ino);
205*6a54128fSAndroid Build Coastguard Worker goto end;
206*6a54128fSAndroid Build Coastguard Worker }
207*6a54128fSAndroid Build Coastguard Worker
208*6a54128fSAndroid Build Coastguard Worker end:
209*6a54128fSAndroid Build Coastguard Worker free(src_filename);
210*6a54128fSAndroid Build Coastguard Worker return retval;
211*6a54128fSAndroid Build Coastguard Worker }
212*6a54128fSAndroid Build Coastguard Worker
is_dir(ext2_filsys fs,ext2_ino_t ino)213*6a54128fSAndroid Build Coastguard Worker static int is_dir(ext2_filsys fs, ext2_ino_t ino)
214*6a54128fSAndroid Build Coastguard Worker {
215*6a54128fSAndroid Build Coastguard Worker struct ext2_inode inode;
216*6a54128fSAndroid Build Coastguard Worker
217*6a54128fSAndroid Build Coastguard Worker if (ext2fs_read_inode(fs, ino, &inode))
218*6a54128fSAndroid Build Coastguard Worker return 0;
219*6a54128fSAndroid Build Coastguard Worker return S_ISDIR(inode.i_mode);
220*6a54128fSAndroid Build Coastguard Worker }
221*6a54128fSAndroid Build Coastguard Worker
androidify_inode(ext2_filsys fs,ext2_ino_t ino,struct inode_params * params)222*6a54128fSAndroid Build Coastguard Worker static errcode_t androidify_inode(ext2_filsys fs, ext2_ino_t ino,
223*6a54128fSAndroid Build Coastguard Worker struct inode_params *params)
224*6a54128fSAndroid Build Coastguard Worker {
225*6a54128fSAndroid Build Coastguard Worker errcode_t retval;
226*6a54128fSAndroid Build Coastguard Worker
227*6a54128fSAndroid Build Coastguard Worker retval = set_timestamp(fs, ino, params);
228*6a54128fSAndroid Build Coastguard Worker if (retval)
229*6a54128fSAndroid Build Coastguard Worker return retval;
230*6a54128fSAndroid Build Coastguard Worker
231*6a54128fSAndroid Build Coastguard Worker retval = set_selinux_xattr(fs, ino, params);
232*6a54128fSAndroid Build Coastguard Worker if (retval)
233*6a54128fSAndroid Build Coastguard Worker return retval;
234*6a54128fSAndroid Build Coastguard Worker
235*6a54128fSAndroid Build Coastguard Worker return set_perms_and_caps(fs, ino, params);
236*6a54128fSAndroid Build Coastguard Worker }
237*6a54128fSAndroid Build Coastguard Worker
walk_dir(ext2_ino_t dir EXT2FS_ATTR ((unused)),int flags EXT2FS_ATTR ((unused)),struct ext2_dir_entry * de,int offset EXT2FS_ATTR ((unused)),int blocksize EXT2FS_ATTR ((unused)),char * buf EXT2FS_ATTR ((unused)),void * priv_data)238*6a54128fSAndroid Build Coastguard Worker static int walk_dir(ext2_ino_t dir EXT2FS_ATTR((unused)),
239*6a54128fSAndroid Build Coastguard Worker int flags EXT2FS_ATTR((unused)),
240*6a54128fSAndroid Build Coastguard Worker struct ext2_dir_entry *de,
241*6a54128fSAndroid Build Coastguard Worker int offset EXT2FS_ATTR((unused)),
242*6a54128fSAndroid Build Coastguard Worker int blocksize EXT2FS_ATTR((unused)),
243*6a54128fSAndroid Build Coastguard Worker char *buf EXT2FS_ATTR((unused)), void *priv_data)
244*6a54128fSAndroid Build Coastguard Worker {
245*6a54128fSAndroid Build Coastguard Worker __u16 name_len;
246*6a54128fSAndroid Build Coastguard Worker errcode_t retval;
247*6a54128fSAndroid Build Coastguard Worker struct inode_params *params = (struct inode_params *)priv_data;
248*6a54128fSAndroid Build Coastguard Worker
249*6a54128fSAndroid Build Coastguard Worker name_len = de->name_len & 0xff;
250*6a54128fSAndroid Build Coastguard Worker if (!strncmp(de->name, ".", name_len)
251*6a54128fSAndroid Build Coastguard Worker || (!strncmp(de->name, "..", name_len)))
252*6a54128fSAndroid Build Coastguard Worker return 0;
253*6a54128fSAndroid Build Coastguard Worker
254*6a54128fSAndroid Build Coastguard Worker if (asprintf(¶ms->filename, "%s/%.*s", params->path, name_len,
255*6a54128fSAndroid Build Coastguard Worker de->name) < 0) {
256*6a54128fSAndroid Build Coastguard Worker params->error = ENOMEM;
257*6a54128fSAndroid Build Coastguard Worker return -ENOMEM;
258*6a54128fSAndroid Build Coastguard Worker }
259*6a54128fSAndroid Build Coastguard Worker
260*6a54128fSAndroid Build Coastguard Worker if (!strncmp(de->name, "lost+found", 10)) {
261*6a54128fSAndroid Build Coastguard Worker retval = set_selinux_xattr(params->fs, de->inode, params);
262*6a54128fSAndroid Build Coastguard Worker if (retval)
263*6a54128fSAndroid Build Coastguard Worker goto end;
264*6a54128fSAndroid Build Coastguard Worker } else {
265*6a54128fSAndroid Build Coastguard Worker retval = androidify_inode(params->fs, de->inode, params);
266*6a54128fSAndroid Build Coastguard Worker if (retval)
267*6a54128fSAndroid Build Coastguard Worker goto end;
268*6a54128fSAndroid Build Coastguard Worker if (is_dir(params->fs, de->inode)) {
269*6a54128fSAndroid Build Coastguard Worker char *cur_path = params->path;
270*6a54128fSAndroid Build Coastguard Worker char *cur_filename = params->filename;
271*6a54128fSAndroid Build Coastguard Worker params->path = params->filename;
272*6a54128fSAndroid Build Coastguard Worker retval = ext2fs_dir_iterate2(params->fs, de->inode, 0, NULL,
273*6a54128fSAndroid Build Coastguard Worker walk_dir, params);
274*6a54128fSAndroid Build Coastguard Worker if (retval)
275*6a54128fSAndroid Build Coastguard Worker goto end;
276*6a54128fSAndroid Build Coastguard Worker params->path = cur_path;
277*6a54128fSAndroid Build Coastguard Worker params->filename = cur_filename;
278*6a54128fSAndroid Build Coastguard Worker }
279*6a54128fSAndroid Build Coastguard Worker }
280*6a54128fSAndroid Build Coastguard Worker
281*6a54128fSAndroid Build Coastguard Worker end:
282*6a54128fSAndroid Build Coastguard Worker free(params->filename);
283*6a54128fSAndroid Build Coastguard Worker params->error |= retval;
284*6a54128fSAndroid Build Coastguard Worker return retval;
285*6a54128fSAndroid Build Coastguard Worker }
286*6a54128fSAndroid Build Coastguard Worker
__android_configure_fs(ext2_filsys fs,char * src_dir,char * target_out,char * mountpoint,fs_config_f fs_config_func,struct selabel_handle * sehnd,time_t fixed_time,const struct ugid_map * uid_map,const struct ugid_map * gid_map)287*6a54128fSAndroid Build Coastguard Worker errcode_t __android_configure_fs(ext2_filsys fs, char *src_dir,
288*6a54128fSAndroid Build Coastguard Worker char *target_out,
289*6a54128fSAndroid Build Coastguard Worker char *mountpoint,
290*6a54128fSAndroid Build Coastguard Worker fs_config_f fs_config_func,
291*6a54128fSAndroid Build Coastguard Worker struct selabel_handle *sehnd,
292*6a54128fSAndroid Build Coastguard Worker time_t fixed_time,
293*6a54128fSAndroid Build Coastguard Worker const struct ugid_map* uid_map,
294*6a54128fSAndroid Build Coastguard Worker const struct ugid_map* gid_map)
295*6a54128fSAndroid Build Coastguard Worker {
296*6a54128fSAndroid Build Coastguard Worker errcode_t retval;
297*6a54128fSAndroid Build Coastguard Worker struct inode_params params = {
298*6a54128fSAndroid Build Coastguard Worker .fs = fs,
299*6a54128fSAndroid Build Coastguard Worker .src_dir = src_dir,
300*6a54128fSAndroid Build Coastguard Worker .target_out = target_out,
301*6a54128fSAndroid Build Coastguard Worker .fs_config_func = fs_config_func,
302*6a54128fSAndroid Build Coastguard Worker .sehnd = sehnd,
303*6a54128fSAndroid Build Coastguard Worker .fixed_time = fixed_time,
304*6a54128fSAndroid Build Coastguard Worker .path = mountpoint,
305*6a54128fSAndroid Build Coastguard Worker .filename = mountpoint,
306*6a54128fSAndroid Build Coastguard Worker .mountpoint = mountpoint,
307*6a54128fSAndroid Build Coastguard Worker .uid_map = uid_map,
308*6a54128fSAndroid Build Coastguard Worker .gid_map = gid_map,
309*6a54128fSAndroid Build Coastguard Worker .error = 0
310*6a54128fSAndroid Build Coastguard Worker };
311*6a54128fSAndroid Build Coastguard Worker
312*6a54128fSAndroid Build Coastguard Worker /* walk_dir will add the "/". Don't add it twice. */
313*6a54128fSAndroid Build Coastguard Worker if (strlen(mountpoint) == 1 && mountpoint[0] == '/')
314*6a54128fSAndroid Build Coastguard Worker params.path = "";
315*6a54128fSAndroid Build Coastguard Worker
316*6a54128fSAndroid Build Coastguard Worker retval = androidify_inode(fs, EXT2_ROOT_INO, ¶ms);
317*6a54128fSAndroid Build Coastguard Worker if (retval)
318*6a54128fSAndroid Build Coastguard Worker return retval;
319*6a54128fSAndroid Build Coastguard Worker
320*6a54128fSAndroid Build Coastguard Worker retval = ext2fs_dir_iterate2(fs, EXT2_ROOT_INO, 0, NULL, walk_dir,
321*6a54128fSAndroid Build Coastguard Worker ¶ms);
322*6a54128fSAndroid Build Coastguard Worker if (retval)
323*6a54128fSAndroid Build Coastguard Worker return retval;
324*6a54128fSAndroid Build Coastguard Worker return params.error;
325*6a54128fSAndroid Build Coastguard Worker }
326*6a54128fSAndroid Build Coastguard Worker
android_configure_fs(ext2_filsys fs,char * src_dir,char * target_out,char * mountpoint,struct selinux_opt * seopts EXT2FS_ATTR ((unused)),unsigned int nopt EXT2FS_ATTR ((unused)),char * fs_config_file,time_t fixed_time,const struct ugid_map * uid_map,const struct ugid_map * gid_map)327*6a54128fSAndroid Build Coastguard Worker errcode_t android_configure_fs(ext2_filsys fs, char *src_dir, char *target_out,
328*6a54128fSAndroid Build Coastguard Worker char *mountpoint,
329*6a54128fSAndroid Build Coastguard Worker struct selinux_opt *seopts EXT2FS_ATTR((unused)),
330*6a54128fSAndroid Build Coastguard Worker unsigned int nopt EXT2FS_ATTR((unused)),
331*6a54128fSAndroid Build Coastguard Worker char *fs_config_file, time_t fixed_time,
332*6a54128fSAndroid Build Coastguard Worker const struct ugid_map* uid_map,
333*6a54128fSAndroid Build Coastguard Worker const struct ugid_map* gid_map)
334*6a54128fSAndroid Build Coastguard Worker {
335*6a54128fSAndroid Build Coastguard Worker errcode_t retval;
336*6a54128fSAndroid Build Coastguard Worker fs_config_f fs_config_func = NULL;
337*6a54128fSAndroid Build Coastguard Worker struct selabel_handle *sehnd = NULL;
338*6a54128fSAndroid Build Coastguard Worker
339*6a54128fSAndroid Build Coastguard Worker /* Retrieve file contexts */
340*6a54128fSAndroid Build Coastguard Worker #if !defined(__ANDROID__)
341*6a54128fSAndroid Build Coastguard Worker if (nopt > 0) {
342*6a54128fSAndroid Build Coastguard Worker sehnd = selabel_open(SELABEL_CTX_FILE, seopts, nopt);
343*6a54128fSAndroid Build Coastguard Worker if (!sehnd) {
344*6a54128fSAndroid Build Coastguard Worker int saved_errno = errno;
345*6a54128fSAndroid Build Coastguard Worker com_err(__func__, errno,
346*6a54128fSAndroid Build Coastguard Worker _("while opening file contexts \"%s\""),
347*6a54128fSAndroid Build Coastguard Worker seopts[0].value);
348*6a54128fSAndroid Build Coastguard Worker return saved_errno;
349*6a54128fSAndroid Build Coastguard Worker }
350*6a54128fSAndroid Build Coastguard Worker }
351*6a54128fSAndroid Build Coastguard Worker #else
352*6a54128fSAndroid Build Coastguard Worker sehnd = selinux_android_file_context_handle();
353*6a54128fSAndroid Build Coastguard Worker if (!sehnd) {
354*6a54128fSAndroid Build Coastguard Worker com_err(__func__, EINVAL,
355*6a54128fSAndroid Build Coastguard Worker _("while opening android file_contexts"));
356*6a54128fSAndroid Build Coastguard Worker return EINVAL;
357*6a54128fSAndroid Build Coastguard Worker }
358*6a54128fSAndroid Build Coastguard Worker #endif
359*6a54128fSAndroid Build Coastguard Worker
360*6a54128fSAndroid Build Coastguard Worker /* Load the FS config */
361*6a54128fSAndroid Build Coastguard Worker if (fs_config_file) {
362*6a54128fSAndroid Build Coastguard Worker retval = load_canned_fs_config(fs_config_file);
363*6a54128fSAndroid Build Coastguard Worker if (retval < 0) {
364*6a54128fSAndroid Build Coastguard Worker com_err(__func__, retval,
365*6a54128fSAndroid Build Coastguard Worker _("while loading fs_config \"%s\""),
366*6a54128fSAndroid Build Coastguard Worker fs_config_file);
367*6a54128fSAndroid Build Coastguard Worker return retval;
368*6a54128fSAndroid Build Coastguard Worker }
369*6a54128fSAndroid Build Coastguard Worker fs_config_func = canned_fs_config;
370*6a54128fSAndroid Build Coastguard Worker } else if (mountpoint)
371*6a54128fSAndroid Build Coastguard Worker fs_config_func = fs_config;
372*6a54128fSAndroid Build Coastguard Worker
373*6a54128fSAndroid Build Coastguard Worker return __android_configure_fs(fs, src_dir, target_out, mountpoint,
374*6a54128fSAndroid Build Coastguard Worker fs_config_func, sehnd, fixed_time,
375*6a54128fSAndroid Build Coastguard Worker uid_map, gid_map);
376*6a54128fSAndroid Build Coastguard Worker }
377