xref: /aosp_15_r20/external/selinux/restorecond/restore.c (revision 2d543d20722ada2425b5bdab9d0d1d29470e7bba)
1*2d543d20SAndroid Build Coastguard Worker #include "restore.h"
2*2d543d20SAndroid Build Coastguard Worker #include <glob.h>
3*2d543d20SAndroid Build Coastguard Worker 
4*2d543d20SAndroid Build Coastguard Worker #ifndef GLOB_TILDE
5*2d543d20SAndroid Build Coastguard Worker #define GLOB_TILDE 0
6*2d543d20SAndroid Build Coastguard Worker #endif
7*2d543d20SAndroid Build Coastguard Worker 
8*2d543d20SAndroid Build Coastguard Worker #ifndef GLOB_BRACE
9*2d543d20SAndroid Build Coastguard Worker #define GLOB_BRACE 0
10*2d543d20SAndroid Build Coastguard Worker #endif
11*2d543d20SAndroid Build Coastguard Worker 
12*2d543d20SAndroid Build Coastguard Worker char **exclude_list;
13*2d543d20SAndroid Build Coastguard Worker int exclude_count;
14*2d543d20SAndroid Build Coastguard Worker 
restore_init(struct restore_opts * opts)15*2d543d20SAndroid Build Coastguard Worker void restore_init(struct restore_opts *opts)
16*2d543d20SAndroid Build Coastguard Worker {
17*2d543d20SAndroid Build Coastguard Worker 	int rc;
18*2d543d20SAndroid Build Coastguard Worker 
19*2d543d20SAndroid Build Coastguard Worker 	struct selinux_opt selinux_opts[] = {
20*2d543d20SAndroid Build Coastguard Worker 		{ SELABEL_OPT_VALIDATE, opts->selabel_opt_validate },
21*2d543d20SAndroid Build Coastguard Worker 		{ SELABEL_OPT_PATH, opts->selabel_opt_path },
22*2d543d20SAndroid Build Coastguard Worker 		{ SELABEL_OPT_DIGEST, opts->selabel_opt_digest }
23*2d543d20SAndroid Build Coastguard Worker 	};
24*2d543d20SAndroid Build Coastguard Worker 
25*2d543d20SAndroid Build Coastguard Worker 	opts->hnd = selabel_open(SELABEL_CTX_FILE, selinux_opts, 3);
26*2d543d20SAndroid Build Coastguard Worker 	if (!opts->hnd) {
27*2d543d20SAndroid Build Coastguard Worker 		perror(opts->selabel_opt_path);
28*2d543d20SAndroid Build Coastguard Worker 		exit(1);
29*2d543d20SAndroid Build Coastguard Worker 	}
30*2d543d20SAndroid Build Coastguard Worker 
31*2d543d20SAndroid Build Coastguard Worker 	opts->restorecon_flags = 0;
32*2d543d20SAndroid Build Coastguard Worker 	opts->restorecon_flags = opts->nochange | opts->verbose |
33*2d543d20SAndroid Build Coastguard Worker 			   opts->progress | opts->set_specctx  |
34*2d543d20SAndroid Build Coastguard Worker 			   opts->add_assoc | opts->ignore_digest |
35*2d543d20SAndroid Build Coastguard Worker 			   opts->recurse | opts->userealpath |
36*2d543d20SAndroid Build Coastguard Worker 			   opts->xdev | opts->abort_on_error |
37*2d543d20SAndroid Build Coastguard Worker 			   opts->syslog_changes | opts->log_matches |
38*2d543d20SAndroid Build Coastguard Worker 			   opts->ignore_noent | opts->ignore_mounts;
39*2d543d20SAndroid Build Coastguard Worker 
40*2d543d20SAndroid Build Coastguard Worker 	/* Use setfiles, restorecon and restorecond own handles */
41*2d543d20SAndroid Build Coastguard Worker 	selinux_restorecon_set_sehandle(opts->hnd);
42*2d543d20SAndroid Build Coastguard Worker 
43*2d543d20SAndroid Build Coastguard Worker 	if (opts->rootpath) {
44*2d543d20SAndroid Build Coastguard Worker 		rc = selinux_restorecon_set_alt_rootpath(opts->rootpath);
45*2d543d20SAndroid Build Coastguard Worker 		if (rc) {
46*2d543d20SAndroid Build Coastguard Worker 			fprintf(stderr,
47*2d543d20SAndroid Build Coastguard Worker 				"selinux_restorecon_set_alt_rootpath error: %s.\n",
48*2d543d20SAndroid Build Coastguard Worker 				strerror(errno));
49*2d543d20SAndroid Build Coastguard Worker 			exit(-1);
50*2d543d20SAndroid Build Coastguard Worker 		}
51*2d543d20SAndroid Build Coastguard Worker 	}
52*2d543d20SAndroid Build Coastguard Worker 
53*2d543d20SAndroid Build Coastguard Worker 	if (exclude_list)
54*2d543d20SAndroid Build Coastguard Worker 		selinux_restorecon_set_exclude_list
55*2d543d20SAndroid Build Coastguard Worker 						 ((const char **)exclude_list);
56*2d543d20SAndroid Build Coastguard Worker }
57*2d543d20SAndroid Build Coastguard Worker 
restore_finish(void)58*2d543d20SAndroid Build Coastguard Worker void restore_finish(void)
59*2d543d20SAndroid Build Coastguard Worker {
60*2d543d20SAndroid Build Coastguard Worker 	int i;
61*2d543d20SAndroid Build Coastguard Worker 
62*2d543d20SAndroid Build Coastguard Worker 	if (exclude_list) {
63*2d543d20SAndroid Build Coastguard Worker 		for (i = 0; exclude_list[i]; i++)
64*2d543d20SAndroid Build Coastguard Worker 			free(exclude_list[i]);
65*2d543d20SAndroid Build Coastguard Worker 		free(exclude_list);
66*2d543d20SAndroid Build Coastguard Worker 	}
67*2d543d20SAndroid Build Coastguard Worker }
68*2d543d20SAndroid Build Coastguard Worker 
process_glob(char * name,struct restore_opts * opts)69*2d543d20SAndroid Build Coastguard Worker int process_glob(char *name, struct restore_opts *opts)
70*2d543d20SAndroid Build Coastguard Worker {
71*2d543d20SAndroid Build Coastguard Worker 	glob_t globbuf;
72*2d543d20SAndroid Build Coastguard Worker 	size_t i = 0;
73*2d543d20SAndroid Build Coastguard Worker 	int len, rc, errors;
74*2d543d20SAndroid Build Coastguard Worker 
75*2d543d20SAndroid Build Coastguard Worker 	memset(&globbuf, 0, sizeof(globbuf));
76*2d543d20SAndroid Build Coastguard Worker 
77*2d543d20SAndroid Build Coastguard Worker 	errors = glob(name, GLOB_TILDE | GLOB_PERIOD |
78*2d543d20SAndroid Build Coastguard Worker 			  GLOB_NOCHECK | GLOB_BRACE, NULL, &globbuf);
79*2d543d20SAndroid Build Coastguard Worker 	if (errors)
80*2d543d20SAndroid Build Coastguard Worker 		return errors;
81*2d543d20SAndroid Build Coastguard Worker 
82*2d543d20SAndroid Build Coastguard Worker 	for (i = 0; i < globbuf.gl_pathc; i++) {
83*2d543d20SAndroid Build Coastguard Worker 		len = strlen(globbuf.gl_pathv[i]) - 2;
84*2d543d20SAndroid Build Coastguard Worker 		if (len > 0 && strcmp(&globbuf.gl_pathv[i][len--], "/.") == 0)
85*2d543d20SAndroid Build Coastguard Worker 			continue;
86*2d543d20SAndroid Build Coastguard Worker 		if (len > 0 && strcmp(&globbuf.gl_pathv[i][len], "/..") == 0)
87*2d543d20SAndroid Build Coastguard Worker 			continue;
88*2d543d20SAndroid Build Coastguard Worker 		rc = selinux_restorecon(globbuf.gl_pathv[i],
89*2d543d20SAndroid Build Coastguard Worker 					opts->restorecon_flags);
90*2d543d20SAndroid Build Coastguard Worker 		if (rc < 0)
91*2d543d20SAndroid Build Coastguard Worker 			errors = rc;
92*2d543d20SAndroid Build Coastguard Worker 	}
93*2d543d20SAndroid Build Coastguard Worker 
94*2d543d20SAndroid Build Coastguard Worker 	globfree(&globbuf);
95*2d543d20SAndroid Build Coastguard Worker 
96*2d543d20SAndroid Build Coastguard Worker 	return errors;
97*2d543d20SAndroid Build Coastguard Worker }
98*2d543d20SAndroid Build Coastguard Worker 
add_exclude(const char * directory)99*2d543d20SAndroid Build Coastguard Worker void add_exclude(const char *directory)
100*2d543d20SAndroid Build Coastguard Worker {
101*2d543d20SAndroid Build Coastguard Worker 	char **tmp_list;
102*2d543d20SAndroid Build Coastguard Worker 
103*2d543d20SAndroid Build Coastguard Worker 	if (directory == NULL || directory[0] != '/') {
104*2d543d20SAndroid Build Coastguard Worker 		fprintf(stderr, "Full path required for exclude: %s.\n",
105*2d543d20SAndroid Build Coastguard Worker 			    directory);
106*2d543d20SAndroid Build Coastguard Worker 		exit(-1);
107*2d543d20SAndroid Build Coastguard Worker 	}
108*2d543d20SAndroid Build Coastguard Worker 
109*2d543d20SAndroid Build Coastguard Worker 	/* Add another two entries, one for directory, and the other to
110*2d543d20SAndroid Build Coastguard Worker 	 * terminate the list.
111*2d543d20SAndroid Build Coastguard Worker 	 */
112*2d543d20SAndroid Build Coastguard Worker 	tmp_list = realloc(exclude_list, sizeof(char *) * (exclude_count + 2));
113*2d543d20SAndroid Build Coastguard Worker 	if (!tmp_list) {
114*2d543d20SAndroid Build Coastguard Worker 		fprintf(stderr, "realloc failed while excluding %s.\n",
115*2d543d20SAndroid Build Coastguard Worker 			    directory);
116*2d543d20SAndroid Build Coastguard Worker 		exit(-1);
117*2d543d20SAndroid Build Coastguard Worker 	}
118*2d543d20SAndroid Build Coastguard Worker 	exclude_list = tmp_list;
119*2d543d20SAndroid Build Coastguard Worker 
120*2d543d20SAndroid Build Coastguard Worker 	exclude_list[exclude_count] = strdup(directory);
121*2d543d20SAndroid Build Coastguard Worker 	if (!exclude_list[exclude_count]) {
122*2d543d20SAndroid Build Coastguard Worker 		fprintf(stderr, "strdup failed while excluding %s.\n",
123*2d543d20SAndroid Build Coastguard Worker 			    directory);
124*2d543d20SAndroid Build Coastguard Worker 		exit(-1);
125*2d543d20SAndroid Build Coastguard Worker 	}
126*2d543d20SAndroid Build Coastguard Worker 	exclude_count++;
127*2d543d20SAndroid Build Coastguard Worker 	exclude_list[exclude_count] = NULL;
128*2d543d20SAndroid Build Coastguard Worker }
129