summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am4
-rw-r--r--configure.ac27
-rw-r--r--ubifs-utils/Makemodule.am4
-rw-r--r--ubifs-utils/mkfs.ubifs/mkfs.ubifs.c117
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);