Skip to content

Commit

Permalink
repo: Add an API to init OstreeSePolicy from commit directly
Browse files Browse the repository at this point in the history
This is part of `OstreeCommitModifier`, but I'm not using
that in some of the ostree-ext Rust code.

It just makes more sense as a direct policy API, where it should
have been in the first place.  There's already support for
setting a policy object on a commit modifier, so that's all the
old API needs to do now.
  • Loading branch information
cgwalters committed Sep 29, 2021
1 parent e8394c7 commit 8907e13
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 34 deletions.
6 changes: 3 additions & 3 deletions Makefile-libostree.am
Original file line number Diff line number Diff line change
Expand Up @@ -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=
Expand Down
1 change: 1 addition & 0 deletions apidoc/ostree-sections.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 5 additions & 0 deletions src/libostree/libostree-devel.sym
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
33 changes: 2 additions & 31 deletions src/libostree/ostree-repo-commit.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}

Expand Down
55 changes: 55 additions & 0 deletions src/libostree/ostree-sepolicy.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -47,6 +48,7 @@ struct OstreeSePolicy {
int rootfs_dfd;
int rootfs_dfd_owned;
GFile *path;
GLnxTmpDir tmpdir;

#ifdef HAVE_SELINUX
GFile *selinux_policy_root;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -266,6 +270,57 @@ get_policy_checksum (char **out_csum,

#endif

/**
* ostree_sepolicy_new_from_commit:
* @repo: The repo
* @commit: SHA-256 commit 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 *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
Expand Down
5 changes: 5 additions & 0 deletions src/libostree/ostree-sepolicy.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit 8907e13

Please sign in to comment.