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 | |
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>
-rw-r--r-- | Makefile.am | 4 | ||||
-rw-r--r-- | configure.ac | 27 | ||||
-rw-r--r-- | ubifs-utils/Makemodule.am | 4 | ||||
-rw-r--r-- | ubifs-utils/mkfs.ubifs/mkfs.ubifs.c | 117 |
4 files changed, 149 insertions, 3 deletions
diff --git a/Makefile.am b/Makefile.am index 5a6e77c..391edef 100644 --- a/Makefile.am +++ b/Makefile.am @@ -10,6 +10,10 @@ if WITHOUT_LZO AM_CPPFLAGS += -DWITHOUT_LZO endif +if WITH_SELINUX +AM_CPPFLAGS += -DWITH_SELINUX +endif + sbin_PROGRAMS = sbin_SCRIPTS = check_PROGRAMS = diff --git a/configure.ac b/configure.ac index f5538a0..c05d362 100644 --- a/configure.ac +++ b/configure.ac @@ -68,6 +68,7 @@ need_zlib="no" need_lzo="no" need_xattr="no" need_cmocka="no" +need_selinux="no" AM_COND_IF([UNIT_TESTS], [ @@ -153,6 +154,15 @@ AC_ARG_WITH([lzo], *) AC_MSG_ERROR([bad value ${withval} for --without-lzo]) ;; esac]) +AC_ARG_WITH([selinux], + [AS_HELP_STRING([--with-selinux], + [Enable support for selinux extended attributes])], + [case "${withval}" in + yes) need_selinux="yes";; + no) ;; + *) AC_MSG_ERROR([bad value ${withval} for --with-selinux]) ;; + esac]) + ##### search for dependencies ##### clock_gettime_missing="no" @@ -162,11 +172,16 @@ zlib_missing="no" lzo_missing="no" xattr_missing="no" cmocka_missing="no" +selinux_missing="no" if test "x$need_zlib" = "xyes"; then PKG_CHECK_MODULES(ZLIB, [zlib], [], [zlib_missing="yes"]) fi +if test "x$need_selinux" = "xyes"; then + PKG_CHECK_MODULES(LIBSELINUX, [libselinux], [], [selinux_missing="yes"]) +fi + if test "x$need_uuid" = "xyes"; then PKG_CHECK_MODULES(UUID, [uuid], [], [uuid_missing="yes"]) fi @@ -195,6 +210,11 @@ if test "x$need_xattr" = "xyes"; then AC_CHECK_HEADERS([sys/acl.h], [], [xattr_missing="yes"]) fi +if test "x$need_selinux" = "xyes"; then + AC_CHECK_HEADERS([selinux/selinux.h], [], [selinux_missing="yes"]) + AC_CHECK_HEADERS([selinux/label.h], [], [selinux_missing="yes"]) +fi + if test "x$need_cmocka" = "xyes"; then PKG_CHECK_MODULES(CMOCKA, [cmocka], [], [cmocka_missing="yes"]) fi @@ -244,6 +264,12 @@ if test "x$xattr_missing" = "xyes"; then need_xattr="no" fi +if test "x$selinux_missing" = "xyes"; then + AC_MSG_WARN([cannot find headers for selinux library]) + AC_MSG_WARN([disabling SELINUX support]) + need_selinux="no" +fi + if test "x$cmocka_missing" = "xyes"; then AC_MSG_WARN([cannot find CMocka library required for unit tests]) AC_MSG_NOTICE([unit tests can optionally be disabled]) @@ -258,6 +284,7 @@ fi AM_CONDITIONAL([WITHOUT_LZO], [test "x$need_lzo" != "xyes"]) AM_CONDITIONAL([WITHOUT_XATTR], [test "x$need_xattr" != "xyes"]) +AM_CONDITIONAL([WITH_SELINUX], [test "x$need_selinux" == "xyes"]) AC_CHECK_SIZEOF([off_t]) AC_CHECK_SIZEOF([loff_t]) diff --git a/ubifs-utils/Makemodule.am b/ubifs-utils/Makemodule.am index 5862afb..879f91a 100644 --- a/ubifs-utils/Makemodule.am +++ b/ubifs-utils/Makemodule.am @@ -16,8 +16,8 @@ mkfs_ubifs_SOURCES = \ ubifs-utils/mkfs.ubifs/hashtable/hashtable.c \ ubifs-utils/mkfs.ubifs/hashtable/hashtable_itr.c \ ubifs-utils/mkfs.ubifs/devtable.c -mkfs_ubifs_LDADD = libmtd.a libubi.a $(ZLIB_LIBS) $(LZO_LIBS) $(UUID_LIBS) -lm -mkfs_ubifs_CPPFLAGS = $(AM_CPPFLAGS) $(ZLIB_CFLAGS) $(LZO_CFLAGS) $(UUID_CFLAGS) \ +mkfs_ubifs_LDADD = libmtd.a libubi.a $(ZLIB_LIBS) $(LZO_LIBS) $(UUID_LIBS) $(LIBSELINUX_LIBS) -lm +mkfs_ubifs_CPPFLAGS = $(AM_CPPFLAGS) $(ZLIB_CFLAGS) $(LZO_CFLAGS) $(UUID_CFLAGS) $(LIBSELINUX_CFLAGS)\ -I$(top_srcdir)/ubi-utils/include -I$(top_srcdir)/ubifs-utils/mkfs.ubifs/ UBIFS_BINS = \ 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); |