summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mkfs/Makemodule.am3
-rw-r--r--mkfs/dirscan.c26
-rw-r--r--mkfs/mkfs.c61
-rw-r--r--mkfs/mkfs.h11
-rw-r--r--mkfs/selinux.c55
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