bin/commit: Add --selinux-policy option
authorColin Walters <walters@verbum.org>
Fri, 25 Aug 2017 14:30:44 +0000 (10:30 -0400)
committerAtomic Bot <atomic-devel@projectatomic.io>
Fri, 25 Aug 2017 16:39:53 +0000 (16:39 +0000)
This was really straightforward to implement, and is useful
for dev/test scenarios mainly like we have in rpm-ostree at least.

Closes: https://github.com/ostreedev/ostree/issues/1113
Closes: #1114
Approved by: jlebon

src/ostree/ot-builtin-commit.c
tests/installed/itest-label-selinux.sh [new file with mode: 0755]

index 6d1ce06020f9475487560388ed5f47bfcae431c6..9967f6dd3fc6bf52a80950629b257c60aa524385 100644 (file)
@@ -47,6 +47,7 @@ static gboolean opt_link_checkout_speedup;
 static gboolean opt_skip_if_unchanged;
 static gboolean opt_tar_autocreate_parents;
 static gboolean opt_no_xattrs;
+static char *opt_selinux_policy;
 static gboolean opt_canonical_permissions;
 static char **opt_trees;
 static gint opt_owner_uid = -1;
@@ -93,6 +94,7 @@ static GOptionEntry options[] = {
   { "owner-gid", 0, 0, G_OPTION_ARG_INT, &opt_owner_gid, "Set file ownership group id", "GID" },
   { "canonical-permissions", 0, 0, G_OPTION_ARG_NONE, &opt_canonical_permissions, "Canonicalize permissions in the same way bare-user does for hardlinked files", NULL },
   { "no-xattrs", 0, 0, G_OPTION_ARG_NONE, &opt_no_xattrs, "Do not import extended attributes", NULL },
+  { "selinux-policy", 0, 0, G_OPTION_ARG_FILENAME, &opt_selinux_policy, "Set SELinux labels based on policy in root filesystem PATH (may be /)", "PATH" },
   { "link-checkout-speedup", 0, 0, G_OPTION_ARG_NONE, &opt_link_checkout_speedup, "Optimize for commits of trees composed of hardlinks into the repository", NULL },
   { "tar-autocreate-parents", 0, 0, G_OPTION_ARG_NONE, &opt_tar_autocreate_parents, "When loading tar archives, automatically create parent directories as needed", NULL },
   { "skip-if-unchanged", 0, 0, G_OPTION_ARG_NONE, &opt_skip_if_unchanged, "If the contents are unchanged from previous commit, do nothing", NULL },
@@ -395,6 +397,7 @@ ostree_builtin_commit (int argc, char **argv, GCancellable *cancellable, GError
   g_autoptr(GHashTable) mode_overrides = NULL;
   g_autoptr(GHashTable) skip_list = NULL;
   OstreeRepoCommitModifierFlags flags = 0;
+  g_autoptr(OstreeSePolicy) policy = NULL;
   OstreeRepoCommitModifier *modifier = NULL;
   OstreeRepoTransactionStats stats;
   struct CommitFilterData filter_data = { 0, };
@@ -459,12 +462,26 @@ ostree_builtin_commit (int argc, char **argv, GCancellable *cancellable, GError
       || opt_owner_gid >= 0
       || opt_statoverride_file != NULL
       || opt_skiplist_file != NULL
-      || opt_no_xattrs)
+      || opt_no_xattrs
+      || opt_selinux_policy)
     {
       filter_data.mode_adds = mode_adds;
       filter_data.skip_list = skip_list;
       modifier = ostree_repo_commit_modifier_new (flags, commit_filter,
                                                   &filter_data, NULL);
+      if (opt_selinux_policy)
+        {
+          glnx_fd_close int rootfs_dfd = -1;
+          if (!glnx_opendirat (AT_FDCWD, opt_selinux_policy, TRUE, &rootfs_dfd, error))
+            {
+              g_prefix_error (error, "selinux-policy: ");
+              goto out;
+            }
+          policy = ostree_sepolicy_new_at (rootfs_dfd, cancellable, error);
+          if (!policy)
+            goto out;
+          ostree_repo_commit_modifier_set_sepolicy (modifier, policy);
+        }
     }
 
   if (opt_parent)
diff --git a/tests/installed/itest-label-selinux.sh b/tests/installed/itest-label-selinux.sh
new file mode 100755 (executable)
index 0000000..1a2b4aa
--- /dev/null
@@ -0,0 +1,29 @@
+#!/bin/bash
+
+# Test commit --selinux-policy
+
+set -xeuo pipefail
+
+dn=$(dirname $0)
+. ${dn}/libinsttest.sh
+
+cd /ostree/repo/tmp
+rm co -rf
+ostree checkout -H ${host_refspec} co
+testbin=co/usr/bin/foo-a-generic-binary
+assert_not_has_file "${testbin}"
+# Make a test binary that we label as shell_exec_t on disk, but should be
+# reset by --selinux-policy back to bin_t
+echo 'test foo' > ${testbin}
+chcon --reference co/usr/bin/true ${testbin}
+oldcon=$(getfattr --only-values -m security.selinux ${testbin})
+chcon --reference co/usr/bin/bash ${testbin}
+newcon=$(getfattr --only-values -m security.selinux ${testbin})
+assert_not_streq "${oldcon}" "${newcon}"
+ostree --repo=/ostree/repo commit -b testbranch --link-checkout-speedup \
+       --selinux-policy co --tree=dir=co
+ostree --repo=/ostree/repo ls -X testbranch /usr/bin/foo-a-generic-binary > ls.txt
+assert_file_has_content ls.txt ${oldcon}
+
+ostree --repo=/ostree/repo refs --delete testbranch
+rm co -rf