diff options
Diffstat (limited to 'mkfs')
| -rw-r--r-- | mkfs/Makemodule.am | 3 | ||||
| -rw-r--r-- | mkfs/dirscan.c | 26 | ||||
| -rw-r--r-- | mkfs/mkfs.c | 61 | ||||
| -rw-r--r-- | mkfs/mkfs.h | 11 | ||||
| -rw-r--r-- | mkfs/selinux.c | 55 | 
5 files changed, 114 insertions, 42 deletions
| diff --git a/mkfs/Makemodule.am b/mkfs/Makemodule.am index 75fc3a4..cb37698 100644 --- a/mkfs/Makemodule.am +++ b/mkfs/Makemodule.am @@ -1,5 +1,5 @@  gensquashfs_SOURCES = mkfs/mkfs.c mkfs/mkfs.h mkfs/options.c -gensquashfs_SOURCES += mkfs/dirscan.c +gensquashfs_SOURCES += mkfs/dirscan.c mkfs/selinux.c  gensquashfs_LDADD = libsqfshelper.a libsquashfs.la libfstree.a libutil.la  gensquashfs_LDADD += $(LIBSELINUX_LIBS)  gensquashfs_CPPFLAGS = $(AM_CPPFLAGS) @@ -7,7 +7,6 @@ gensquashfs_CFLAGS = $(AM_CFLAGS) $(LIBSELINUX_CFLAGS)  if WITH_SELINUX  gensquashfs_CPPFLAGS += -DWITH_SELINUX -gensquashfs_SOURCES += mkfs/selinux.c  endif  bin_PROGRAMS += gensquashfs diff --git a/mkfs/dirscan.c b/mkfs/dirscan.c index 5cb955a..160fbc3 100644 --- a/mkfs/dirscan.c +++ b/mkfs/dirscan.c @@ -109,9 +109,9 @@ fail:  #endif  static int populate_dir(fstree_t *fs, tree_node_t *root, dev_t devstart, -			unsigned int flags) +			void *selinux_handle, unsigned int flags)  { -	char *extra = NULL; +	char *extra = NULL, *path;  	struct dirent *ent;  	struct stat sb;  	tree_node_t *n; @@ -177,6 +177,21 @@ static int populate_dir(fstree_t *fs, tree_node_t *root, dev_t devstart,  				goto fail;  		}  #endif +		if (selinux_handle != NULL) { +			path = fstree_get_path(n); +			if (path == NULL) { +				perror("getting full path for " +				       "SELinux relabeling"); +				goto fail; +			} + +			if (selinux_relable_node(selinux_handle, fs, n, path)) { +				free(path); +				goto fail; +			} + +			free(path); +		}  		free(extra);  		extra = NULL; @@ -189,7 +204,7 @@ static int populate_dir(fstree_t *fs, tree_node_t *root, dev_t devstart,  			if (pushd(n->name))  				return -1; -			if (populate_dir(fs, n, devstart, flags)) +			if (populate_dir(fs, n, devstart, selinux_handle, flags))  				return -1;  			if (popd()) @@ -206,7 +221,8 @@ fail:  	return -1;  } -int fstree_from_dir(fstree_t *fs, const char *path, unsigned int flags) +int fstree_from_dir(fstree_t *fs, const char *path, void *selinux_handle, +		    unsigned int flags)  {  	struct stat sb;  	int ret; @@ -219,7 +235,7 @@ int fstree_from_dir(fstree_t *fs, const char *path, unsigned int flags)  	if (pushd(path))  		return -1; -	ret = populate_dir(fs, fs->root, sb.st_dev, flags); +	ret = populate_dir(fs, fs->root, sb.st_dev, selinux_handle, flags);  	if (popd())  		ret = -1; diff --git a/mkfs/mkfs.c b/mkfs/mkfs.c index 5746c69..c3a4e73 100644 --- a/mkfs/mkfs.c +++ b/mkfs/mkfs.c @@ -89,13 +89,41 @@ static int pack_files(sqfs_data_writer_t *data, fstree_t *fs,  	return restore_working_dir(opt);  } -static int read_fstree(fstree_t *fs, options_t *opt) +static int relabel_tree_dfs(fstree_t *fs, tree_node_t *n, void *selinux_handle) +{ +	char *path = fstree_get_path(n); + +	if (path == NULL) { +		perror("getting absolute node path for SELinux relabeling"); +		return -1; +	} + +	if (selinux_relable_node(selinux_handle, fs, n, path)) { +		free(path); +		return -1; +	} + +	free(path); + +	if (S_ISDIR(n->mode)) { +		for (n = n->data.dir.children; n != NULL; n = n->next) { +			if (relabel_tree_dfs(fs, n, selinux_handle)) +				return -1; +		} +	} + +	return 0; +} + +static int read_fstree(fstree_t *fs, options_t *opt, void *selinux_handle)  {  	FILE *fp;  	int ret; -	if (opt->infile == NULL) -		return fstree_from_dir(fs, opt->packdir, opt->dirscan_flags); +	if (opt->infile == NULL) { +		return fstree_from_dir(fs, opt->packdir, selinux_handle, +				       opt->dirscan_flags); +	}  	fp = fopen(opt->infile, "rb");  	if (fp == NULL) { @@ -115,6 +143,9 @@ static int read_fstree(fstree_t *fs, options_t *opt)  	if (restore_working_dir(opt))  		return -1; +	if (ret == 0 && selinux_handle != NULL) +		ret = relabel_tree_dfs(fs, fs->root, selinux_handle); +  	return ret;  } @@ -127,6 +158,7 @@ int main(int argc, char **argv)  	sqfs_compressor_t *cmp;  	sqfs_id_table_t *idtbl;  	sqfs_file_t *outfile; +	void *sehnd = NULL;  	sqfs_super_t super;  	options_t opt;  	fstree_t fs; @@ -159,8 +191,22 @@ int main(int argc, char **argv)  	if (sqfs_super_write(&super, outfile))  		goto out_outfile; -	if (read_fstree(&fs, &opt)) +	if (opt.selinux != NULL) { +		sehnd = selinux_open_context_file(opt.selinux); +		if (sehnd == NULL) +			goto out_outfile; +	} + +	if (read_fstree(&fs, &opt, sehnd)) { +		if (sehnd != NULL) +			selinux_close_context_file(sehnd);  		goto out_outfile; +	} + +	if (sehnd != NULL) { +		selinux_close_context_file(sehnd); +		sehnd = NULL; +	}  	tree_node_sort_recursive(fs.root); @@ -171,13 +217,6 @@ int main(int argc, char **argv)  	super.inode_count = fs.inode_tbl_size - 2; -#ifdef WITH_SELINUX -	if (opt.selinux != NULL) { -		if (fstree_relabel_selinux(&fs, opt.selinux)) -			goto out_outfile; -	} -#endif -  	fstree_xattr_deduplicate(&fs);  	cmp = sqfs_compressor_create(&cfg); diff --git a/mkfs/mkfs.h b/mkfs/mkfs.h index f00898b..3a139a7 100644 --- a/mkfs/mkfs.h +++ b/mkfs/mkfs.h @@ -68,8 +68,15 @@ enum {  void process_command_line(options_t *opt, int argc, char **argv); -int fstree_from_dir(fstree_t *fs, const char *path, unsigned int flags); +int fstree_from_dir(fstree_t *fs, const char *path, void *selinux_handle, +		    unsigned int flags); -int fstree_relabel_selinux(fstree_t *fs, const char *filename); + +void *selinux_open_context_file(const char *filename); + +int selinux_relable_node(void *sehnd, fstree_t *fs, +			 tree_node_t *node, const char *path); + +void selinux_close_context_file(void *sehnd);  #endif /* MKFS_H */ diff --git a/mkfs/selinux.c b/mkfs/selinux.c index 5fc4f52..a4cda71 100644 --- a/mkfs/selinux.c +++ b/mkfs/selinux.c @@ -9,16 +9,13 @@  #define XATTR_NAME_SELINUX "security.selinux"  #define XATTR_VALUE_SELINUX "system_u:object_r:unlabeled_t:s0" -static int relable_node(fstree_t *fs, struct selabel_handle *sehnd, -			tree_node_t *node) +#ifdef WITH_SELINUX +int selinux_relable_node(void *sehnd, fstree_t *fs, +			 tree_node_t *node, const char *path)  { -	char *context = NULL, *path; +	char *context = NULL;  	int ret; -	path = fstree_get_path(node); -	if (path == NULL) -		goto fail; -  	if (selabel_lookup(sehnd, &context, path, node->mode) < 0) {  		context = strdup(XATTR_VALUE_SELINUX);  		if (context == NULL) @@ -27,36 +24,50 @@ static int relable_node(fstree_t *fs, struct selabel_handle *sehnd,  	ret = fstree_add_xattr(fs, node, XATTR_NAME_SELINUX, context);  	free(context); -	free(path);  	return ret;  fail:  	perror("relabeling files"); -	free(path);  	return -1;  } -int fstree_relabel_selinux(fstree_t *fs, const char *filename) +void *selinux_open_context_file(const char *filename)  {  	struct selabel_handle *sehnd;  	struct selinux_opt seopts[] = {  		{ SELABEL_OPT_PATH, filename },  	}; -	size_t i; -	int ret = 0;  	sehnd = selabel_open(SELABEL_CTX_FILE, seopts, 1); - -	if (sehnd == NULL) { +	if (sehnd == NULL)  		perror(filename); -		return -1; -	} -	for (i = 2; i < fs->inode_tbl_size; ++i) { -		ret = relable_node(fs, sehnd, fs->inode_table[i]); -		if (ret) -			break; -	} +	return sehnd; +} +void selinux_close_context_file(void *sehnd) +{  	selabel_close(sehnd); -	return ret;  } +#else +int selinux_relable_node(void *sehnd, fstree_t *fs, +			 tree_node_t *node, const char *path) +{ +	(void)sehnd; (void)fs; (void)node; (void)path; +	fputs("Built without SELinux support, cannot add SELinux labels\n", +	      stderr); +	return -1; +} + +void *selinux_open_context_file(const char *filename) +{ +	(void)filename; +	fputs("Built without SELinux support, cannot open contexts file\n", +	      stderr); +	return NULL; +} + +void selinux_close_context_file(void *sehnd) +{ +	(void)sehnd; +} +#endif | 
