diff options
author | Ritesh Harjani <riteshh@codeaurora.org> | 2018-06-06 15:09:00 +0530 |
---|---|---|
committer | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2018-06-14 09:19:10 +0200 |
commit | f1feccec5ad848b4f763376480a006a9d58fa721 (patch) | |
tree | fa2d174cfe67d5ea706255afe5a84f78b10da942 /ubifs-utils/mkfs.ubifs/mkfs.ubifs.c | |
parent | 08cc6a2af66e62e3228e17bfa8e8aa918643d06e (diff) |
mkfs.ubifs: Implement selinux labelling support in mkfs.ubifs.
This implements/adds selinux labelling support to mkfs.ubifs
utility. It adds an extra option in configure to enable
selinux labelling support and then finally in mkfs.ubifs adds
an extra option to pass the file_contexts which is looked up
for filesystem file labels.
- Default behavior is kept without selinux so as to not break existing
support where selinux library/headers may not be present.
- If this is configured with --with-selinux then XATTR from the
file_contexts(passed with --selinux option while mkfs.ubifs)
will be taken and not from the host file's xattr.
This is done to avoid the problem where the host OS may have
selinux enabled and hence same xattr names will be present in both
host filesystem files and from the --selinux=file passed.
So the existing behavior is kept mutually exclusive and preference
is given to selinux xattrs (if configured with --with-selinux).
Signed-off-by: Ritesh Harjani <riteshh@codeaurora.org>
Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Diffstat (limited to 'ubifs-utils/mkfs.ubifs/mkfs.ubifs.c')
-rw-r--r-- | ubifs-utils/mkfs.ubifs/mkfs.ubifs.c | 117 |
1 files changed, 116 insertions, 1 deletions
diff --git a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c index 2333dde..f0518b9 100644 --- a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c +++ b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c @@ -30,6 +30,11 @@ #include <sys/xattr.h> #endif +#ifdef WITH_SELINUX +#include <selinux/selinux.h> +#include <selinux/label.h> +#endif + /* Size (prime number) of hash table for link counting */ #define HASH_TABLE_SIZE 10099 @@ -40,6 +45,13 @@ /* Default time granularity in nanoseconds */ #define DEFAULT_TIME_GRAN 1000000000 + +#ifdef WITH_SELINUX +#define XATTR_NAME_SELINUX "security.selinux" +static struct selabel_handle *sehnd; +static char *secontext; +#endif + /** * struct idx_entry - index entry. * @next: next index entry (NULL at end of list) @@ -116,6 +128,9 @@ static int out_fd; static int out_ubi; static int squash_owner; static int do_create_inum_attr; +static char *context; +static int context_len; +static struct stat context_st; /* The 'head' (position) which nodes are written */ static int head_lnum; @@ -163,6 +178,7 @@ static const struct option longopts[] = { {"orph-lebs", 1, NULL, 'p'}, {"squash-uids" , 0, NULL, 'U'}, {"set-inode-attr", 0, NULL, 'a'}, + {"selinux", 1, NULL, 's'}, {NULL, 0, NULL, 0} }; @@ -206,6 +222,7 @@ static const char *helptext = "-a, --set-inum-attr create user.image-inode-number extended attribute on files\n" " added to the image. The attribute will contain the inode\n" " number the file has in the generated image.\n" +"-s, --selinux=FILE Selinux context file\n" "-h, --help display this help text\n\n" "Note, SIZE is specified in bytes, but it may also be specified in Kilobytes,\n" "Megabytes, and Gigabytes if a KiB, MiB, or GiB suffix is used.\n\n" @@ -638,7 +655,18 @@ static int get_options(int argc, char**argv) case 'a': do_create_inum_attr = 1; break; - + case 's': + context_len = strlen(optarg); + context = (char *) xmalloc(context_len + 1); + if (!context) + return err_msg("xmalloc failed\n"); + memcpy(context, optarg, context_len); + + /* Make sure root directory exists */ + if (stat(context, &context_st)) + return sys_err_msg("bad file context %s\n", + context); + break; } } @@ -725,6 +753,7 @@ static int get_options(int argc, char**argv) printf("\tfanout: %d\n", c->fanout); printf("\torph_lebs: %d\n", c->orph_lebs); printf("\tspace_fixup: %d\n", c->space_fixup); + printf("\tselinux file: %s\n", context); } if (validate_options()) @@ -1202,6 +1231,70 @@ out_free: } #endif +#ifdef WITH_SELINUX +static int inode_add_selinux_xattr(struct ubifs_ino_node *host_ino, + const char *path_name, struct stat *st, ino_t inum) +{ + int ret; + char *sepath = NULL; + char *name; + struct qstr nm; + unsigned int con_size; + + if (!context || !sehnd) { + secontext = NULL; + con_size = 0; + return 0; + } + + if (path_name[strlen(root)] == '/') + sepath = strdup(&path_name[strlen(root)]); + + else if (asprintf(&sepath, "/%s", &path_name[strlen(root)]) < 0) + sepath = NULL; + + if (!sepath) + return sys_err_msg("could not get sepath\n"); + + if (selabel_lookup(sehnd, &secontext, sepath, st->st_mode) < 0) { + /* Failed to lookup context, assume unlabeled */ + secontext = strdup("system_u:object_r:unlabeled_t:s0"); + dbg_msg(2, "missing context: %s\t%s\t%d\n", secontext, sepath, + st->st_mode); + } + + dbg_msg(2, "appling selinux context on sepath=%s, secontext=%s\n", + sepath, secontext); + free(sepath); + con_size = strlen(secontext) + 1; + name = strdup(XATTR_NAME_SELINUX); + + nm.name = name; + nm.len = strlen(name); + host_ino->xattr_cnt++; + host_ino->xattr_size += CALC_DENT_SIZE(nm.len); + host_ino->xattr_size += CALC_XATTR_BYTES(con_size); + host_ino->xattr_names += nm.len; + + ret = add_xattr(st, inum, secontext, con_size, &nm); + if (ret < 0) + dbg_msg(2, "add_xattr failed %d\n", ret); + return ret; +} + +#else +static inline int inode_add_selinux_xattr(struct ubifs_ino_node *host_ino, + const char *path_name, struct stat *st, ino_t inum) +{ + (void)host_ino; + (void)path_name; + (void)st; + (void)inum; + + return 0; +} +#endif + /** * add_inode - write an inode. * @st: stat information of source inode @@ -1260,7 +1353,11 @@ static int add_inode(struct stat *st, ino_t inum, void *data, len = UBIFS_INO_NODE_SZ + data_len; if (xattr_path) { +#ifdef WITH_SELINUX + ret = inode_add_selinux_xattr(ino, xattr_path, st, inum); +#else ret = inode_add_xattr(ino, xattr_path, st, inum); +#endif if (ret < 0) return ret; } @@ -2415,6 +2512,18 @@ static int init(void) if (err) return err; +#ifdef WITH_SELINUX + if (context) { + struct selinux_opt seopts[] = { + { SELABEL_OPT_PATH, context } + }; + + sehnd = selabel_open(SELABEL_CTX_FILE, seopts, 1); + if (!sehnd) + return err_msg("could not open selinux context\n"); + } +#endif + return 0; } @@ -2439,6 +2548,12 @@ static void destroy_hash_table(void) */ static void deinit(void) { + +#ifdef WITH_SELINUX + if (sehnd) + selabel_close(sehnd); +#endif + free(c->lpt); free(c->ltab); free(leb_buf); |