Merge pull request #2447 from cgwalters/sepolicy-for-commit
repo: Add an API to init `OstreeSePolicy` from commit directly
This commit is contained in:
commit
5bf4b1dabc
|
|
@ -173,9 +173,9 @@ endif # USE_GPGME
|
||||||
symbol_files = $(top_srcdir)/src/libostree/libostree-released.sym
|
symbol_files = $(top_srcdir)/src/libostree/libostree-released.sym
|
||||||
|
|
||||||
# Uncomment this include when adding new development symbols.
|
# Uncomment this include when adding new development symbols.
|
||||||
#if BUILDOPT_IS_DEVEL_BUILD
|
if BUILDOPT_IS_DEVEL_BUILD
|
||||||
#symbol_files += $(top_srcdir)/src/libostree/libostree-devel.sym
|
symbol_files += $(top_srcdir)/src/libostree/libostree-devel.sym
|
||||||
#endif
|
endif
|
||||||
|
|
||||||
# http://blog.jgc.org/2007/06/escaping-comma-and-space-in-gnu-make.html
|
# http://blog.jgc.org/2007/06/escaping-comma-and-space-in-gnu-make.html
|
||||||
wl_versionscript_arg = -Wl,--version-script=
|
wl_versionscript_arg = -Wl,--version-script=
|
||||||
|
|
|
||||||
|
|
@ -522,6 +522,7 @@ ostree_repo_file_get_type
|
||||||
OstreeSePolicy
|
OstreeSePolicy
|
||||||
ostree_sepolicy_new
|
ostree_sepolicy_new
|
||||||
ostree_sepolicy_new_at
|
ostree_sepolicy_new_at
|
||||||
|
ostree_sepolicy_new_from_commit
|
||||||
ostree_sepolicy_get_path
|
ostree_sepolicy_get_path
|
||||||
ostree_sepolicy_get_name
|
ostree_sepolicy_get_name
|
||||||
ostree_sepolicy_get_label
|
ostree_sepolicy_get_label
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,11 @@
|
||||||
- uncomment the include in Makefile-libostree.am
|
- 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
|
/* 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
|
* edit this other than to update the year. This is just a copy/paste
|
||||||
* source. Replace $LASTSTABLE with the last stable version, and $NEWVERSION
|
* source. Replace $LASTSTABLE with the last stable version, and $NEWVERSION
|
||||||
|
|
|
||||||
|
|
@ -4314,7 +4314,6 @@ ostree_repo_commit_modifier_unref (OstreeRepoCommitModifier *modifier)
|
||||||
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);
|
g_clear_object (&modifier->sepolicy);
|
||||||
(void) glnx_tmpdir_delete (&modifier->sepolicy_tmpdir, NULL, NULL);
|
|
||||||
|
|
||||||
g_free (modifier);
|
g_free (modifier);
|
||||||
return;
|
return;
|
||||||
|
|
@ -4386,38 +4385,10 @@ ostree_repo_commit_modifier_set_sepolicy_from_commit (OstreeRepoCommitModifier
|
||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
GLNX_AUTO_PREFIX_ERROR ("setting sepolicy from commit", error);
|
g_autoptr(OstreeSePolicy) policy = ostree_sepolicy_new_from_commit (repo, rev, cancellable, 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)
|
if (!policy)
|
||||||
return glnx_prefix_error (error, "reading policy");
|
return FALSE;
|
||||||
|
|
||||||
ostree_repo_commit_modifier_set_sepolicy (modifier, policy);
|
ostree_repo_commit_modifier_set_sepolicy (modifier, policy);
|
||||||
/* Transfer ownership */
|
|
||||||
modifier->sepolicy_tmpdir = tmpdir;
|
|
||||||
tmpdir.initialized = FALSE;
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@
|
||||||
#include "otutil.h"
|
#include "otutil.h"
|
||||||
|
|
||||||
#include "ostree-sepolicy.h"
|
#include "ostree-sepolicy.h"
|
||||||
|
#include "ostree-repo.h"
|
||||||
#include "ostree-sepolicy-private.h"
|
#include "ostree-sepolicy-private.h"
|
||||||
#include "ostree-bootloader-uboot.h"
|
#include "ostree-bootloader-uboot.h"
|
||||||
#include "ostree-bootloader-syslinux.h"
|
#include "ostree-bootloader-syslinux.h"
|
||||||
|
|
@ -47,6 +48,7 @@ struct OstreeSePolicy {
|
||||||
int rootfs_dfd;
|
int rootfs_dfd;
|
||||||
int rootfs_dfd_owned;
|
int rootfs_dfd_owned;
|
||||||
GFile *path;
|
GFile *path;
|
||||||
|
GLnxTmpDir tmpdir;
|
||||||
|
|
||||||
#ifdef HAVE_SELINUX
|
#ifdef HAVE_SELINUX
|
||||||
GFile *selinux_policy_root;
|
GFile *selinux_policy_root;
|
||||||
|
|
@ -77,6 +79,8 @@ ostree_sepolicy_finalize (GObject *object)
|
||||||
{
|
{
|
||||||
OstreeSePolicy *self = OSTREE_SEPOLICY (object);
|
OstreeSePolicy *self = OSTREE_SEPOLICY (object);
|
||||||
|
|
||||||
|
(void) glnx_tmpdir_delete (&self->tmpdir, NULL, NULL);
|
||||||
|
|
||||||
g_clear_object (&self->path);
|
g_clear_object (&self->path);
|
||||||
if (self->rootfs_dfd_owned != -1)
|
if (self->rootfs_dfd_owned != -1)
|
||||||
(void) close (self->rootfs_dfd_owned);
|
(void) close (self->rootfs_dfd_owned);
|
||||||
|
|
@ -266,6 +270,58 @@ get_policy_checksum (char **out_csum,
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ostree_sepolicy_new_from_commit:
|
||||||
|
* @repo: The repo
|
||||||
|
* @rev: ostree ref or checksum
|
||||||
|
* @cancellable: Cancellable
|
||||||
|
* @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 *rev,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
GLNX_AUTO_PREFIX_ERROR ("setting sepolicy from commit", error);
|
||||||
|
g_autoptr(GFile) root = NULL;
|
||||||
|
g_autofree char *commit = NULL;
|
||||||
|
if (!ostree_repo_read_commit (repo, rev, &root, &commit, 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");
|
||||||
|
}
|
||||||
|
|
||||||
|
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 */
|
/* Workaround for http://marc.info/?l=selinux&m=149323809332417&w=2 */
|
||||||
#ifdef HAVE_SELINUX
|
#ifdef HAVE_SELINUX
|
||||||
|
|
@ -443,7 +499,11 @@ ostree_sepolicy_new_at (int rootfs_dfd,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ostree_sepolicy_get_path:
|
* ostree_sepolicy_get_path:
|
||||||
* @self:
|
* @self: A SePolicy object
|
||||||
|
*
|
||||||
|
* This API should be considered deprecated, because it's supported for
|
||||||
|
* policy objects to be created from file-descriptor relative paths, which
|
||||||
|
* may not be globally accessible.
|
||||||
*
|
*
|
||||||
* Returns: (transfer none): Path to rootfs
|
* Returns: (transfer none): Path to rootfs
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,11 @@ OstreeSePolicy* ostree_sepolicy_new_at (int rootfs_dfd,
|
||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
|
_OSTREE_PUBLIC
|
||||||
|
OstreeSePolicy* ostree_sepolicy_new_from_commit (OstreeRepo *repo,
|
||||||
|
const char *rev,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GError **error);
|
||||||
|
|
||||||
_OSTREE_PUBLIC
|
_OSTREE_PUBLIC
|
||||||
GFile * ostree_sepolicy_get_path (OstreeSePolicy *self);
|
GFile * ostree_sepolicy_get_path (OstreeSePolicy *self);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue