Skip to content

Commit

Permalink
bin/checkout: add --selinux-policy switch
Browse files Browse the repository at this point in the history
This was already supported by the underlying API. Expose it so that we
can test it.

Closes: #1442
Approved by: cgwalters
  • Loading branch information
jlebon authored and rh-atomic-bot committed Feb 2, 2018
1 parent 6b95d51 commit 8174885
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 8 deletions.
39 changes: 35 additions & 4 deletions src/ostree/ot-builtin-checkout.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ static gboolean opt_disable_fsync;
static gboolean opt_require_hardlinks;
static gboolean opt_force_copy;
static gboolean opt_bareuseronly_dirs;
static char *opt_selinux_policy;
static char *opt_selinux_prefix;

static gboolean
parse_fsync_cb (const char *option_name,
Expand All @@ -57,7 +59,7 @@ parse_fsync_cb (const char *option_name,

if (!ot_parse_boolean (value, &val, error))
return FALSE;

opt_disable_fsync = !val;

return TRUE;
Expand All @@ -83,6 +85,8 @@ static GOptionEntry options[] = {
{ "require-hardlinks", 'H', 0, G_OPTION_ARG_NONE, &opt_require_hardlinks, "Do not fall back to full copies if hardlinking fails", NULL },
{ "force-copy", 'C', 0, G_OPTION_ARG_NONE, &opt_force_copy, "Never hardlink (but may reflink if available)", NULL },
{ "bareuseronly-dirs", 'M', 0, G_OPTION_ARG_NONE, &opt_bareuseronly_dirs, "Suppress mode bits outside of 0775 for directories (suid, world writable, etc.)", NULL },
{ "selinux-policy", 0, 0, G_OPTION_ARG_FILENAME, &opt_selinux_policy, "Set SELinux labels based on policy in root filesystem PATH (may be /); implies --force-copy", "PATH" },
{ "selinux-prefix", 0, 0, G_OPTION_ARG_STRING, &opt_selinux_prefix, "When setting SELinux labels, prefix all paths by PREFIX", "PREFIX" },
{ NULL }
};

Expand All @@ -102,10 +106,15 @@ process_one_checkout (OstreeRepo *repo,
* convenient infrastructure for testing C APIs with data.
*/
if (opt_disable_cache || opt_whiteouts || opt_require_hardlinks ||
opt_union_add || opt_force_copy || opt_bareuseronly_dirs || opt_union_identical)
opt_union_add || opt_force_copy || opt_bareuseronly_dirs || opt_union_identical ||
opt_selinux_policy || opt_selinux_prefix)
{
OstreeRepoCheckoutAtOptions options = { 0, };

/* do this early so option checking also catches force copy conflicts */
if (opt_selinux_policy)
opt_force_copy = TRUE;

if (opt_user_mode)
options.mode = OSTREE_REPO_CHECKOUT_MODE_USER;
/* Can't union these */
Expand All @@ -132,6 +141,11 @@ process_one_checkout (OstreeRepo *repo,
glnx_throw (error, "Cannot specify both --require-hardlinks and --force-copy");
goto out;
}
if (opt_selinux_prefix && !opt_selinux_policy)
{
glnx_throw (error, "Cannot specify --selinux-prefix without --selinux-policy");
goto out;
}
else if (opt_union)
options.overwrite_mode = OSTREE_REPO_CHECKOUT_OVERWRITE_UNION_FILES;
else if (opt_union_add)
Expand All @@ -150,6 +164,23 @@ process_one_checkout (OstreeRepo *repo,
options.process_whiteouts = TRUE;
if (subpath)
options.subpath = subpath;

g_autoptr(OstreeSePolicy) policy = NULL;
if (opt_selinux_policy)
{
glnx_autofd 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;
options.sepolicy = policy;
options.sepolicy_prefix = opt_selinux_prefix;
}

options.no_copy_fallback = opt_require_hardlinks;
options.force_copy = opt_force_copy;
options.bareuseronly_dirs = opt_bareuseronly_dirs;
Expand Down Expand Up @@ -201,7 +232,7 @@ process_one_checkout (OstreeRepo *repo,
cancellable, error))
goto out;
}

ret = TRUE;
out:
return ret;
Expand Down Expand Up @@ -234,7 +265,7 @@ process_many_checkouts (OstreeRepo *repo,
if (!instream)
goto out;
}

datastream = g_data_input_stream_new (instream);

while ((revision = g_data_input_stream_read_upto (datastream, "", 1, &len,
Expand Down
53 changes: 49 additions & 4 deletions tests/installed/itest-label-selinux.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,56 @@ 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 \
ostree 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
ostree ls -X testbranch /usr/bin/foo-a-generic-binary > ls.txt
assert_file_has_content ls.txt ${oldcon}
ostree --repo=/ostree/repo fsck
ostree fsck

ostree --repo=/ostree/repo refs --delete testbranch
ostree refs --delete testbranch
rm co -rf
echo "ok commit with sepolicy"

# Now let's check that selinux policy labels can be applied on checkout

rm rootfs -rf
if ostree checkout -H \
--selinux-policy / ${host_refspec} co; then
assert_not_reached "checked out with -H and --selinux-policy"
fi
# recommit just two binaries into a new branch with selinux labels stripped
mkdir -p rootfs/usr/bin
oldcon=$(getfattr --only-values -m security.selinux /usr/bin/bash)
cp /usr/bin/{true,bash} rootfs/usr/bin
newcon=$(getfattr --only-values -m security.selinux rootfs/usr/bin/bash)
assert_not_streq "${oldcon}" "${newcon}"
echo "ok checkout with sepolicy setup"

ostree commit -b testbranch rootfs
ostree checkout testbranch --selinux-policy / co
newcon=$(getfattr --only-values -m security.selinux co/usr/bin/bash)
assert_streq "${oldcon}" "${newcon}"
rm co -rf
echo "ok checkout with sepolicy"
ostree checkout testbranch --selinux-policy / --subpath /usr/bin co
newcon=$(getfattr --only-values -m security.selinux co/bash)
assert_streq "${oldcon}" "${newcon}"
rm co -rf
echo "ok checkout with sepolicy and subpath"

# now commit tree with mismatched leading dirs
mkdir -p rootfs/subdir
mv rootfs/{usr,subdir}
ostree commit -b testbranch rootfs
ostree checkout testbranch --selinux-policy / co
newcon=$(getfattr --only-values -m security.selinux co/subdir/usr/bin/bash)
assert_not_streq "${oldcon}" "${newcon}"
rm co -rf
ostree checkout testbranch --selinux-policy / \
--subpath subdir --selinux-prefix / co
newcon=$(getfattr --only-values -m security.selinux co/usr/bin/bash)
assert_streq "${oldcon}" "${newcon}"

ostree refs --delete testbranch
rm co -rf
echo "ok checkout with sepolicy and selinux-prefix"

0 comments on commit 8174885

Please sign in to comment.