diff --git a/Makefile-libostree.am b/Makefile-libostree.am index dd39697406..d40de48d13 100644 --- a/Makefile-libostree.am +++ b/Makefile-libostree.am @@ -173,9 +173,9 @@ endif # USE_GPGME symbol_files = $(top_srcdir)/src/libostree/libostree-released.sym # Uncomment this include when adding new development symbols. -#if BUILDOPT_IS_DEVEL_BUILD -#symbol_files += $(top_srcdir)/src/libostree/libostree-devel.sym -#endif +if BUILDOPT_IS_DEVEL_BUILD +symbol_files += $(top_srcdir)/src/libostree/libostree-devel.sym +endif # http://blog.jgc.org/2007/06/escaping-comma-and-space-in-gnu-make.html wl_versionscript_arg = -Wl,--version-script= diff --git a/apidoc/ostree-sections.txt b/apidoc/ostree-sections.txt index f0901f214c..ae8abe81ae 100644 --- a/apidoc/ostree-sections.txt +++ b/apidoc/ostree-sections.txt @@ -522,6 +522,7 @@ ostree_repo_file_get_type OstreeSePolicy ostree_sepolicy_new ostree_sepolicy_new_at +ostree_sepolicy_new_from_commit ostree_sepolicy_get_path ostree_sepolicy_get_name ostree_sepolicy_get_label diff --git a/src/libostree/libostree-devel.sym b/src/libostree/libostree-devel.sym index e3cd14a4af..35d5395678 100644 --- a/src/libostree/libostree-devel.sym +++ b/src/libostree/libostree-devel.sym @@ -22,6 +22,11 @@ - uncomment the include in Makefile-libostree.am */ +LIBOSTREE_2021.5 { +global: + ostree_sepolicy_new_from_commit; +} LIBOSTREE_2021.4; + /* Stub section for the stable release *after* this development one; don't * edit this other than to update the year. This is just a copy/paste * source. Replace $LASTSTABLE with the last stable version, and $NEWVERSION diff --git a/src/libostree/ostree-repo-commit.c b/src/libostree/ostree-repo-commit.c index 8dc2355e9e..c87e8de892 100644 --- a/src/libostree/ostree-repo-commit.c +++ b/src/libostree/ostree-repo-commit.c @@ -4314,7 +4314,6 @@ ostree_repo_commit_modifier_unref (OstreeRepoCommitModifier *modifier) 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); return; @@ -4386,38 +4385,10 @@ ostree_repo_commit_modifier_set_sepolicy_from_commit (OstreeRepoCommitModifier 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); + g_autoptr(OstreeSePolicy) policy = ostree_sepolicy_new_from_commit (repo, rev, cancellable, error); if (!policy) - return glnx_prefix_error (error, "reading policy"); - + return FALSE; ostree_repo_commit_modifier_set_sepolicy (modifier, policy); - /* Transfer ownership */ - modifier->sepolicy_tmpdir = tmpdir; - tmpdir.initialized = FALSE; - return TRUE; } diff --git a/src/libostree/ostree-sepolicy.c b/src/libostree/ostree-sepolicy.c index e6b9a0e1d6..390c3d38b5 100644 --- a/src/libostree/ostree-sepolicy.c +++ b/src/libostree/ostree-sepolicy.c @@ -29,6 +29,7 @@ #include "otutil.h" #include "ostree-sepolicy.h" +#include "ostree-repo.h" #include "ostree-sepolicy-private.h" #include "ostree-bootloader-uboot.h" #include "ostree-bootloader-syslinux.h" @@ -47,6 +48,7 @@ struct OstreeSePolicy { int rootfs_dfd; int rootfs_dfd_owned; GFile *path; + GLnxTmpDir tmpdir; #ifdef HAVE_SELINUX GFile *selinux_policy_root; @@ -77,6 +79,8 @@ ostree_sepolicy_finalize (GObject *object) { OstreeSePolicy *self = OSTREE_SEPOLICY (object); + (void) glnx_tmpdir_delete (&self->tmpdir, NULL, NULL); + g_clear_object (&self->path); if (self->rootfs_dfd_owned != -1) (void) close (self->rootfs_dfd_owned); @@ -266,6 +270,56 @@ get_policy_checksum (char **out_csum, #endif +/** + * ostree_sepolicy_new_from_commit: + * @repo: The repo + * @commit: SHA-256 commit checksum + * @error: Error + * + * Extract the SELinux policy from a commit object via a partial checkout. This is useful + * for labeling derived content as separate commits. + * + * This function is the backend of `ostree_repo_commit_modifier_set_sepolicy_from_commit()`. + * + * Returns: (transfer full): A new policy + */ +OstreeSePolicy* +ostree_sepolicy_new_from_commit (OstreeRepo *repo, + const char *commit, + GCancellable *cancellable, + GError **error) +{ + GLNX_AUTO_PREFIX_ERROR ("setting sepolicy from commit", error); + g_autoptr(GFile) root = NULL; + if (!ostree_repo_read_commit (repo, commit, &root, NULL, cancellable, error)) + return NULL; + const char policypath[] = "usr/etc/selinux"; + g_autoptr(GFile) policyroot = g_file_get_child (root, policypath); + + 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; + + if (g_file_query_exists (policyroot, NULL)) + { + 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_null (error, "policy checkout"), NULL; + } + + OstreeSePolicy *ret = ostree_sepolicy_new_at (tmpdir.fd, cancellable, error); + if (!ret) + return NULL; + /* Transfer ownership of tmpdir */ + ret->tmpdir = tmpdir; + tmpdir.initialized = FALSE; + return ret; +} /* Workaround for http://marc.info/?l=selinux&m=149323809332417&w=2 */ #ifdef HAVE_SELINUX diff --git a/src/libostree/ostree-sepolicy.h b/src/libostree/ostree-sepolicy.h index 7e90527fc6..d5904099c5 100644 --- a/src/libostree/ostree-sepolicy.h +++ b/src/libostree/ostree-sepolicy.h @@ -44,6 +44,11 @@ OstreeSePolicy* ostree_sepolicy_new_at (int rootfs_dfd, GCancellable *cancellable, GError **error); +_OSTREE_PUBLIC +OstreeSePolicy* ostree_sepolicy_new_from_commit (OstreeRepo *repo, + const char *commit, + GCancellable *cancellable, + GError **error); _OSTREE_PUBLIC GFile * ostree_sepolicy_get_path (OstreeSePolicy *self);