Merge pull request #2041 from cgwalters/auto-sepolicy
repo/commit: Add support for --selinux-policy-from-base
This commit is contained in:
commit
7a95929867
|
|
@ -379,6 +379,7 @@ ostree_repo_commit_modifier_new
|
||||||
OstreeRepoCommitModifierXattrCallback
|
OstreeRepoCommitModifierXattrCallback
|
||||||
ostree_repo_commit_modifier_set_xattr_callback
|
ostree_repo_commit_modifier_set_xattr_callback
|
||||||
ostree_repo_commit_modifier_set_sepolicy
|
ostree_repo_commit_modifier_set_sepolicy
|
||||||
|
ostree_repo_commit_modifier_set_sepolicy_from_commit
|
||||||
ostree_repo_commit_modifier_set_devino_cache
|
ostree_repo_commit_modifier_set_devino_cache
|
||||||
ostree_repo_commit_modifier_ref
|
ostree_repo_commit_modifier_ref
|
||||||
ostree_repo_commit_modifier_unref
|
ostree_repo_commit_modifier_unref
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@
|
||||||
/* Add new symbols here. Release commits should copy this section into -released.sym. */
|
/* Add new symbols here. Release commits should copy this section into -released.sym. */
|
||||||
LIBOSTREE_2020.2 {
|
LIBOSTREE_2020.2 {
|
||||||
global:
|
global:
|
||||||
someostree_symbol_deleteme;
|
ostree_repo_commit_modifier_set_sepolicy_from_commit;
|
||||||
} LIBOSTREE_2020.1;
|
} LIBOSTREE_2020.1;
|
||||||
|
|
||||||
/* Stub section for the stable release *after* this development one; don't
|
/* Stub section for the stable release *after* this development one; don't
|
||||||
|
|
|
||||||
|
|
@ -4227,9 +4227,11 @@ ostree_repo_commit_modifier_unref (OstreeRepoCommitModifier *modifier)
|
||||||
if (modifier->xattr_destroy)
|
if (modifier->xattr_destroy)
|
||||||
modifier->xattr_destroy (modifier->xattr_user_data);
|
modifier->xattr_destroy (modifier->xattr_user_data);
|
||||||
|
|
||||||
g_clear_object (&modifier->sepolicy);
|
|
||||||
g_clear_pointer (&modifier->devino_cache, (GDestroyNotify)g_hash_table_unref);
|
g_clear_pointer (&modifier->devino_cache, (GDestroyNotify)g_hash_table_unref);
|
||||||
|
|
||||||
|
g_clear_object (&modifier->sepolicy);
|
||||||
|
(void) glnx_tmpdir_delete (&modifier->sepolicy_tmpdir, NULL, NULL);
|
||||||
|
|
||||||
g_free (modifier);
|
g_free (modifier);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -4279,6 +4281,60 @@ ostree_repo_commit_modifier_set_sepolicy (OstreeRepoCommitModifier
|
||||||
modifier->sepolicy = sepolicy ? g_object_ref (sepolicy) : NULL;
|
modifier->sepolicy = sepolicy ? g_object_ref (sepolicy) : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ostree_repo_commit_modifier_set_sepolicy_from_commit:
|
||||||
|
* @modifier: Commit modifier
|
||||||
|
* @repo: OSTree repo containing @rev
|
||||||
|
* @rev: Find SELinux policy from this base commit
|
||||||
|
* @cancellable:
|
||||||
|
* @error:
|
||||||
|
*
|
||||||
|
* In many cases, one wants to create a "derived" commit from base commit.
|
||||||
|
* SELinux policy labels are part of that base commit. This API allows
|
||||||
|
* one to easily set up SELinux labeling from a base commit.
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
ostree_repo_commit_modifier_set_sepolicy_from_commit (OstreeRepoCommitModifier *modifier,
|
||||||
|
OstreeRepo *repo,
|
||||||
|
const char *rev,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
GLNX_AUTO_PREFIX_ERROR ("setting sepolicy from commit", error);
|
||||||
|
g_autofree char *commit = NULL;
|
||||||
|
g_autoptr(GFile) root = NULL;
|
||||||
|
if (!ostree_repo_read_commit (repo, rev, &root, &commit, cancellable, error))
|
||||||
|
return FALSE;
|
||||||
|
const char policypath[] = "usr/etc/selinux";
|
||||||
|
g_autoptr(GFile) policyroot = g_file_get_child (root, policypath);
|
||||||
|
if (!g_file_query_exists (policyroot, NULL))
|
||||||
|
return TRUE; /* No policy, nothing to do */
|
||||||
|
|
||||||
|
GLnxTmpDir tmpdir = {0,};
|
||||||
|
if (!glnx_mkdtemp ("ostree-commit-sepolicy-XXXXXX", 0700, &tmpdir, error))
|
||||||
|
return FALSE;
|
||||||
|
if (!glnx_shutil_mkdir_p_at (tmpdir.fd, "usr/etc", 0755, cancellable, error))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
OstreeRepoCheckoutAtOptions coopts = {0,};
|
||||||
|
coopts.mode = OSTREE_REPO_CHECKOUT_MODE_USER;
|
||||||
|
coopts.subpath = glnx_strjoina ("/", policypath);
|
||||||
|
|
||||||
|
if (!ostree_repo_checkout_at (repo, &coopts, tmpdir.fd, policypath, commit, cancellable, error))
|
||||||
|
return glnx_prefix_error (error, "policy checkout");
|
||||||
|
|
||||||
|
g_autoptr(OstreeSePolicy) policy = ostree_sepolicy_new_at (tmpdir.fd, cancellable, error);
|
||||||
|
if (!policy)
|
||||||
|
return glnx_prefix_error (error, "reading policy");
|
||||||
|
|
||||||
|
ostree_repo_commit_modifier_set_sepolicy (modifier, policy);
|
||||||
|
/* Transfer ownership */
|
||||||
|
modifier->sepolicy_tmpdir = tmpdir;
|
||||||
|
tmpdir.initialized = FALSE;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ostree_repo_commit_modifier_set_devino_cache:
|
* ostree_repo_commit_modifier_set_devino_cache:
|
||||||
* @modifier: Modifier
|
* @modifier: Modifier
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,7 @@ struct OstreeRepoCommitModifier {
|
||||||
GDestroyNotify xattr_destroy;
|
GDestroyNotify xattr_destroy;
|
||||||
gpointer xattr_user_data;
|
gpointer xattr_user_data;
|
||||||
|
|
||||||
|
GLnxTmpDir sepolicy_tmpdir;
|
||||||
OstreeSePolicy *sepolicy;
|
OstreeSePolicy *sepolicy;
|
||||||
GHashTable *devino_cache;
|
GHashTable *devino_cache;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -691,6 +691,13 @@ _OSTREE_PUBLIC
|
||||||
void ostree_repo_commit_modifier_set_sepolicy (OstreeRepoCommitModifier *modifier,
|
void ostree_repo_commit_modifier_set_sepolicy (OstreeRepoCommitModifier *modifier,
|
||||||
OstreeSePolicy *sepolicy);
|
OstreeSePolicy *sepolicy);
|
||||||
|
|
||||||
|
_OSTREE_PUBLIC
|
||||||
|
gboolean ostree_repo_commit_modifier_set_sepolicy_from_commit (OstreeRepoCommitModifier *modifier,
|
||||||
|
OstreeRepo *repo,
|
||||||
|
const char *commit,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GError **error);
|
||||||
|
|
||||||
_OSTREE_PUBLIC
|
_OSTREE_PUBLIC
|
||||||
void ostree_repo_commit_modifier_set_devino_cache (OstreeRepoCommitModifier *modifier,
|
void ostree_repo_commit_modifier_set_devino_cache (OstreeRepoCommitModifier *modifier,
|
||||||
OstreeRepoDevInoCache *cache);
|
OstreeRepoDevInoCache *cache);
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,7 @@ static gboolean opt_tar_autocreate_parents;
|
||||||
static char *opt_tar_pathname_filter;
|
static char *opt_tar_pathname_filter;
|
||||||
static gboolean opt_no_xattrs;
|
static gboolean opt_no_xattrs;
|
||||||
static char *opt_selinux_policy;
|
static char *opt_selinux_policy;
|
||||||
|
static gboolean opt_selinux_policy_from_base;
|
||||||
static gboolean opt_canonical_permissions;
|
static gboolean opt_canonical_permissions;
|
||||||
static gboolean opt_consume;
|
static gboolean opt_consume;
|
||||||
static gboolean opt_devino_canonical;
|
static gboolean opt_devino_canonical;
|
||||||
|
|
@ -107,6 +108,7 @@ static GOptionEntry options[] = {
|
||||||
{ "canonical-permissions", 0, 0, G_OPTION_ARG_NONE, &opt_canonical_permissions, "Canonicalize permissions in the same way bare-user does for hardlinked files", NULL },
|
{ "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 },
|
{ "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" },
|
{ "selinux-policy", 0, 0, G_OPTION_ARG_FILENAME, &opt_selinux_policy, "Set SELinux labels based on policy in root filesystem PATH (may be /)", "PATH" },
|
||||||
|
{ "selinux-policy-from-base", 'P', 0, G_OPTION_ARG_NONE, &opt_selinux_policy_from_base, "Set SELinux labels based on first --tree argument", NULL },
|
||||||
{ "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 },
|
{ "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 },
|
||||||
{ "devino-canonical", 'I', 0, G_OPTION_ARG_NONE, &opt_devino_canonical, "Assume hardlinked objects are unmodified. Implies --link-checkout-speedup", NULL },
|
{ "devino-canonical", 'I', 0, G_OPTION_ARG_NONE, &opt_devino_canonical, "Assume hardlinked objects are unmodified. Implies --link-checkout-speedup", 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 },
|
{ "tar-autocreate-parents", 0, 0, G_OPTION_ARG_NONE, &opt_tar_autocreate_parents, "When loading tar archives, automatically create parent directories as needed", NULL },
|
||||||
|
|
@ -550,6 +552,11 @@ ostree_builtin_commit (int argc, char **argv, OstreeCommandInvocation *invocatio
|
||||||
flags |= OSTREE_REPO_COMMIT_MODIFIER_FLAGS_GENERATE_SIZES;
|
flags |= OSTREE_REPO_COMMIT_MODIFIER_FLAGS_GENERATE_SIZES;
|
||||||
if (opt_disable_fsync)
|
if (opt_disable_fsync)
|
||||||
ostree_repo_set_disable_fsync (repo, TRUE);
|
ostree_repo_set_disable_fsync (repo, TRUE);
|
||||||
|
if (opt_selinux_policy && opt_selinux_policy_from_base)
|
||||||
|
{
|
||||||
|
glnx_throw (error, "Cannot specify both --selinux-policy and --selinux-policy-from-base");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
if (flags != 0
|
if (flags != 0
|
||||||
|| opt_owner_uid >= 0
|
|| opt_owner_uid >= 0
|
||||||
|
|
@ -557,25 +564,13 @@ ostree_builtin_commit (int argc, char **argv, OstreeCommandInvocation *invocatio
|
||||||
|| opt_statoverride_file != NULL
|
|| opt_statoverride_file != NULL
|
||||||
|| opt_skiplist_file != NULL
|
|| opt_skiplist_file != NULL
|
||||||
|| opt_no_xattrs
|
|| opt_no_xattrs
|
||||||
|| opt_selinux_policy)
|
|| opt_selinux_policy
|
||||||
|
|| opt_selinux_policy_from_base)
|
||||||
{
|
{
|
||||||
filter_data.mode_adds = mode_adds;
|
filter_data.mode_adds = mode_adds;
|
||||||
filter_data.skip_list = skip_list;
|
filter_data.skip_list = skip_list;
|
||||||
modifier = ostree_repo_commit_modifier_new (flags, commit_filter,
|
modifier = ostree_repo_commit_modifier_new (flags, commit_filter,
|
||||||
&filter_data, NULL);
|
&filter_data, 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;
|
|
||||||
ostree_repo_commit_modifier_set_sepolicy (modifier, policy);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opt_editor)
|
if (opt_editor)
|
||||||
|
|
@ -621,6 +616,7 @@ ostree_builtin_commit (int argc, char **argv, OstreeCommandInvocation *invocatio
|
||||||
g_assert (opt_trees && *opt_trees);
|
g_assert (opt_trees && *opt_trees);
|
||||||
for (tree_iter = (const char *const*)opt_trees; *tree_iter; tree_iter++)
|
for (tree_iter = (const char *const*)opt_trees; *tree_iter; tree_iter++)
|
||||||
{
|
{
|
||||||
|
const gboolean first = (tree_iter == (const char *const*)opt_trees);
|
||||||
tree = *tree_iter;
|
tree = *tree_iter;
|
||||||
|
|
||||||
eq = strchr (tree, '=');
|
eq = strchr (tree, '=');
|
||||||
|
|
@ -637,12 +633,33 @@ ostree_builtin_commit (int argc, char **argv, OstreeCommandInvocation *invocatio
|
||||||
g_clear_object (&object_to_commit);
|
g_clear_object (&object_to_commit);
|
||||||
if (strcmp (tree_type, "dir") == 0)
|
if (strcmp (tree_type, "dir") == 0)
|
||||||
{
|
{
|
||||||
|
if (first && opt_selinux_policy_from_base)
|
||||||
|
{
|
||||||
|
opt_selinux_policy = g_strdup (tree);
|
||||||
|
opt_selinux_policy_from_base = FALSE;
|
||||||
|
}
|
||||||
|
if (first && opt_selinux_policy)
|
||||||
|
{
|
||||||
|
g_assert (modifier);
|
||||||
|
glnx_autofd int rootfs_dfd = -1;
|
||||||
|
if (!glnx_opendirat (AT_FDCWD, opt_selinux_policy, TRUE, &rootfs_dfd, error))
|
||||||
|
goto out;
|
||||||
|
policy = ostree_sepolicy_new_at (rootfs_dfd, cancellable, error);
|
||||||
|
if (!policy)
|
||||||
|
goto out;
|
||||||
|
ostree_repo_commit_modifier_set_sepolicy (modifier, policy);
|
||||||
|
}
|
||||||
if (!ostree_repo_write_dfd_to_mtree (repo, AT_FDCWD, tree, mtree, modifier,
|
if (!ostree_repo_write_dfd_to_mtree (repo, AT_FDCWD, tree, mtree, modifier,
|
||||||
cancellable, error))
|
cancellable, error))
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
else if (strcmp (tree_type, "tar") == 0)
|
else if (strcmp (tree_type, "tar") == 0)
|
||||||
{
|
{
|
||||||
|
if (first && opt_selinux_policy_from_base)
|
||||||
|
{
|
||||||
|
glnx_throw (error, "Cannot use --selinux-policy-from-base with tar");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
if (!opt_tar_pathname_filter)
|
if (!opt_tar_pathname_filter)
|
||||||
{
|
{
|
||||||
if (strcmp (tree, "-") == 0)
|
if (strcmp (tree, "-") == 0)
|
||||||
|
|
@ -707,6 +724,12 @@ ostree_builtin_commit (int argc, char **argv, OstreeCommandInvocation *invocatio
|
||||||
}
|
}
|
||||||
else if (strcmp (tree_type, "ref") == 0)
|
else if (strcmp (tree_type, "ref") == 0)
|
||||||
{
|
{
|
||||||
|
if (first && opt_selinux_policy_from_base)
|
||||||
|
{
|
||||||
|
g_assert (modifier);
|
||||||
|
if (!ostree_repo_commit_modifier_set_sepolicy_from_commit (modifier, repo, tree, cancellable, error))
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
if (!ostree_repo_read_commit (repo, tree, &object_to_commit, NULL, cancellable, error))
|
if (!ostree_repo_read_commit (repo, tree, &object_to_commit, NULL, cancellable, error))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ set -xeuo pipefail
|
||||||
|
|
||||||
. ${KOLA_EXT_DATA}/libinsttest.sh
|
. ${KOLA_EXT_DATA}/libinsttest.sh
|
||||||
require_writable_sysroot
|
require_writable_sysroot
|
||||||
|
prepare_tmpdir /var/tmp
|
||||||
|
|
||||||
date
|
date
|
||||||
cd /ostree/repo/tmp
|
cd /ostree/repo/tmp
|
||||||
|
|
@ -87,3 +88,19 @@ rm co -rf
|
||||||
ostree refs --delete testbranch
|
ostree refs --delete testbranch
|
||||||
echo "ok checkout selinux and skip-list"
|
echo "ok checkout selinux and skip-list"
|
||||||
date
|
date
|
||||||
|
|
||||||
|
mkdir -p usr/{bin,lib,etc}
|
||||||
|
echo 'somebinary' > usr/bin/somebinary
|
||||||
|
ls -Z usr/bin/somebinary > lsz.txt
|
||||||
|
assert_not_file_has_content lsz.txt ':bin_t:'
|
||||||
|
rm -f lsz.txt
|
||||||
|
echo 'somelib' > usr/lib/somelib.so
|
||||||
|
echo 'someconf' > usr/etc/some.conf
|
||||||
|
ostree commit -b newbase --selinux-policy-from-base --tree=ref=${host_refspec} --tree=dir=$(pwd)
|
||||||
|
ostree ls -X newbase /usr/bin/somebinary > newls.txt
|
||||||
|
assert_file_has_content newls.txt ':bin_t:'
|
||||||
|
ostree ls -X newbase /usr/lib/somelib.so > newls.txt
|
||||||
|
assert_file_has_content newls.txt ':lib_t:'
|
||||||
|
ostree ls -X newbase /usr/etc/some.conf > newls.txt
|
||||||
|
assert_file_has_content newls.txt ':etc_t:'
|
||||||
|
echo "ok commit --selinux-policy-from-base"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue