diff options
Diffstat (limited to 'ubifs-utils/mkfs.ubifs')
-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); |