Major update to SELinux handling
We use the new unified OSTree API (OstreeSePolicy) to perform labeling, rather than having our own here. Also create a new rpm-ostree-relabeling-helper that is run to label any leftover files such as /etc/fstab that we create offline, and also to relabel the entire disk.
This commit is contained in:
parent
9be80f1775
commit
39a7c458ef
@ -17,6 +17,11 @@
|
||||
|
||||
privlib_SCRIPTS = src/rpmqa-sorted src/repoquery-sorted
|
||||
|
||||
privlib_PROGRAMS = rpm-ostree-relabeling-helper
|
||||
rpm_ostree_relabeling_helper_SOURCES = src/rpm-ostree-relabeling-helper.c
|
||||
rpm_ostree_relabeling_helper_CFLAGS = $(AM_CFLAGS) $(PKGDEP_RPMOSTREE_CFLAGS)
|
||||
rpm_ostree_relabeling_helper_LDADD = $(AM_LDFLAGS) $(PKGDEP_RPMOSTREE_LIBS)
|
||||
|
||||
bin_PROGRAMS += rpm-ostree
|
||||
|
||||
rpm_ostree_SOURCES = src/rpm-ostree.c \
|
||||
|
@ -29,9 +29,9 @@ srpm: dist-snapshot
|
||||
sed -e "s,^Version:.*,Version: $(GITREV_FOR_PKG)," $(srcdir)/packaging/$(PACKAGE).spec.in > $(PACKAGE).spec
|
||||
$(srcdir)/packaging/rpmbuild-cwd -bs $(PACKAGE).spec
|
||||
|
||||
rpm: srpm
|
||||
$(srcdir)/packaging/rpmbuild-cwd --rebuild $(PKG_VER)*.src.rpm
|
||||
local-rpm: srpm
|
||||
$(srcdir)/packaging/rpmbuild-cwd --rebuild packaging/$(PKG_VER)*.src.rpm
|
||||
|
||||
buildinstall: rpm
|
||||
mock: srpm
|
||||
sudo yum localinstall $(PKG_VER)*.src.rpm
|
||||
|
||||
|
@ -32,7 +32,7 @@ LT_INIT([disable-static])
|
||||
PKG_PROG_PKG_CONFIG
|
||||
|
||||
PKG_CHECK_MODULES(PKGDEP_GIO_UNIX, [gio-unix-2.0])
|
||||
PKG_CHECK_MODULES(PKGDEP_RPMOSTREE, [gio-unix-2.0 json-glib-1.0 ostree-1 libgsystem libselinux])
|
||||
PKG_CHECK_MODULES(PKGDEP_RPMOSTREE, [gio-unix-2.0 json-glib-1.0 ostree-1 libgsystem])
|
||||
AC_PATH_PROG([XSLTPROC], [xsltproc])
|
||||
|
||||
GOBJECT_INTROSPECTION_REQUIRE([1.34.0])
|
||||
|
@ -172,6 +172,10 @@ function createDisk(diskpath, cancellable, params) {
|
||||
if (bootPartitionOffset > 0)
|
||||
gfHandle.mount("/dev/sda" + bootPartitionOffset, "/boot");
|
||||
gfHandle.extlinux("/boot");
|
||||
// It's understandable that extlinux wants the loader to be
|
||||
// immutable...except that later breaks our ability to set SELinux
|
||||
// security contexts on it.
|
||||
gfHandle.set_e2attrs("/boot/ldlinux.sys", "i", new Guestfs.SetE2attrs({ clear: Guestfs.Tristate.TRUE }));
|
||||
gfHandle.umount_all();
|
||||
_installSyslinux(gfHandle, cancellable);
|
||||
gfHandle.part_set_bootable("/dev/sda", 1, true);
|
||||
@ -406,11 +410,26 @@ function pullDeploy(mntdir, srcrepo, osname, target, revision, originRepoUrl, ca
|
||||
ProcUtil.runSync(adminCmd, cancellable,
|
||||
{logInitiation: true, env: adminEnv});
|
||||
|
||||
let sysroot = OSTree.Sysroot.new(mntdir);
|
||||
sysroot.load(null);
|
||||
let deployments = sysroot.get_deployments();
|
||||
let newDeployment = deployments[0];
|
||||
let newDeploymentDirectory = sysroot.get_deployment_directory(newDeployment);
|
||||
|
||||
let defaultFstab = 'UUID=' + ROOT_UUID + ' / ext4 defaults 1 1\n\
|
||||
UUID=' + BOOT_UUID + ' /boot ext4 defaults 1 2\n\
|
||||
UUID=' + SWAP_UUID + ' swap swap defaults 0 0\n';
|
||||
let fstabPath = ostreeOsdir.resolve_relative_path('current/etc/fstab');
|
||||
let fstabPath = newDeploymentDirectory.resolve_relative_path('etc/fstab');
|
||||
fstabPath.replace_contents(defaultFstab, null, false, Gio.FileCreateFlags.REPLACE_DESTINATION, cancellable);
|
||||
|
||||
print("Labeling deployment root");
|
||||
let libdir = Gio.File.new_for_path(GLib.getenv('OSTBUILD_LIBDIR'));
|
||||
ProcUtil.runSync([libdir.get_child('rpm-ostree-relabeling-helper').get_path(),
|
||||
newDeploymentDirectory.get_path(),
|
||||
newDeploymentDirectory.get_path(),
|
||||
""],
|
||||
cancellable,
|
||||
{ logInitiation: true });
|
||||
};
|
||||
|
||||
function requestSnapshotForTree(task, resultdir, refname, revision) {
|
||||
|
@ -19,6 +19,7 @@
|
||||
const GLib = imports.gi.GLib;
|
||||
const Gio = imports.gi.Gio;
|
||||
const Lang = imports.lang;
|
||||
const OSTree = imports.gi.OSTree;
|
||||
const Format = imports.format;
|
||||
|
||||
const GSystem = imports.gi.GSystem;
|
||||
@ -72,6 +73,18 @@ const TaskEnsureDiskCaches = new Lang.Class({
|
||||
if (!addKernelArgs) addKernelArgs = [];
|
||||
LibQA.pullDeploy(mntdir, this.repo, osname, ref, revision, originRepoUrl,
|
||||
cancellable, { addKernelArgs: addKernelArgs });
|
||||
print("Doing initial labeling");
|
||||
let sysroot = OSTree.Sysroot.new(mntdir);
|
||||
sysroot.load(null);
|
||||
let deployments = sysroot.get_deployments();
|
||||
let newDeployment = deployments[0];
|
||||
let newDeploymentDirectory = sysroot.get_deployment_directory(newDeployment);
|
||||
ProcUtil.runSync([this.libdir.get_child('rpm-ostree-relabeling-helper').get_path(),
|
||||
newDeploymentDirectory.get_path(),
|
||||
mntdir.get_path(),
|
||||
""],
|
||||
cancellable,
|
||||
{ logInitiation: true });
|
||||
} finally {
|
||||
gfmnt.umount(cancellable);
|
||||
}
|
||||
|
236
src/rpm-ostree-relabeling-helper.c
Normal file
236
src/rpm-ostree-relabeling-helper.c
Normal file
@ -0,0 +1,236 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* Copyright (C) 2014 Colin Walters <walters@verbum.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published
|
||||
* by the Free Software Foundation; either version 2 of the licence or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <glib-unix.h>
|
||||
#include <ostree.h>
|
||||
|
||||
#include "libgsystem.h"
|
||||
|
||||
#define OSTREE_GIO_FAST_QUERYINFO ("standard::name,standard::type,standard::size,standard::is-symlink,standard::symlink-target," \
|
||||
"unix::device,unix::inode,unix::mode,unix::uid,unix::gid,unix::rdev")
|
||||
|
||||
static char *
|
||||
ptrarray_path_join (GPtrArray *path)
|
||||
{
|
||||
GString *path_buf;
|
||||
|
||||
path_buf = g_string_new ("");
|
||||
|
||||
if (path->len == 0)
|
||||
g_string_append_c (path_buf, '/');
|
||||
else
|
||||
{
|
||||
guint i;
|
||||
for (i = 0; i < path->len; i++)
|
||||
{
|
||||
const char *elt = path->pdata[i];
|
||||
|
||||
g_string_append_c (path_buf, '/');
|
||||
g_string_append (path_buf, elt);
|
||||
}
|
||||
}
|
||||
|
||||
return g_string_free (path_buf, FALSE);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
relabel_one_path (OstreeSePolicy *sepolicy,
|
||||
GFile *path,
|
||||
GFileInfo *info,
|
||||
GPtrArray *path_parts,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
gs_free char *relpath = NULL;
|
||||
gs_free char *new_label = NULL;
|
||||
|
||||
relpath = ptrarray_path_join (path_parts);
|
||||
if (!ostree_sepolicy_restorecon (sepolicy, relpath,
|
||||
info, path,
|
||||
OSTREE_SEPOLICY_RESTORECON_FLAGS_ALLOW_NOLABEL |
|
||||
OSTREE_SEPOLICY_RESTORECON_FLAGS_KEEP_EXISTING,
|
||||
&new_label,
|
||||
cancellable, error))
|
||||
{
|
||||
g_prefix_error (error, "Setting context of %s: ", gs_file_get_path_cached (path));
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (new_label)
|
||||
g_print ("Set label of '%s' (as '%s') to '%s'\n",
|
||||
gs_file_get_path_cached (path),
|
||||
relpath,
|
||||
new_label);
|
||||
|
||||
ret = TRUE;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
relabel_recursively (OstreeSePolicy *sepolicy,
|
||||
GFile *dir,
|
||||
GFileInfo *dir_info,
|
||||
GPtrArray *path_parts,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
gs_unref_object GFileEnumerator *direnum = NULL;
|
||||
|
||||
if (!relabel_one_path (sepolicy, dir, dir_info, path_parts,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
|
||||
direnum = g_file_enumerate_children (dir, OSTREE_GIO_FAST_QUERYINFO,
|
||||
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
|
||||
cancellable, error);
|
||||
if (!direnum)
|
||||
goto out;
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
GFileInfo *file_info;
|
||||
GFile *child;
|
||||
GFileType ftype;
|
||||
|
||||
if (!gs_file_enumerator_iterate (direnum, &file_info, &child,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
if (file_info == NULL)
|
||||
break;
|
||||
|
||||
g_ptr_array_add (path_parts, (char*)gs_file_get_basename_cached (child));
|
||||
|
||||
ftype = g_file_info_get_file_type (file_info);
|
||||
if (ftype == G_FILE_TYPE_DIRECTORY)
|
||||
{
|
||||
if (!relabel_recursively (sepolicy, child, file_info, path_parts,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!relabel_one_path (sepolicy, child, file_info, path_parts,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
|
||||
g_ptr_array_remove_index (path_parts, path_parts->len - 1);
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
selinux_relabel_dir (OstreeSePolicy *sepolicy,
|
||||
GFile *dir,
|
||||
const char *prefix,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
gs_unref_ptrarray GPtrArray *path_parts = g_ptr_array_new ();
|
||||
gs_unref_object GFileInfo *root_info = NULL;
|
||||
|
||||
root_info = g_file_query_info (dir, OSTREE_GIO_FAST_QUERYINFO,
|
||||
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
|
||||
cancellable, error);
|
||||
if (!root_info)
|
||||
goto out;
|
||||
|
||||
g_ptr_array_add (path_parts, (char*)prefix);
|
||||
if (!relabel_recursively (sepolicy, dir, root_info, path_parts,
|
||||
cancellable, error))
|
||||
{
|
||||
g_prefix_error (error, "Relabeling /%s: ", prefix);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc,
|
||||
char **argv)
|
||||
{
|
||||
GError *local_error = NULL;
|
||||
GError **error = &local_error;
|
||||
GCancellable *cancellable = NULL;
|
||||
const char *policy_name;
|
||||
gs_unref_object GFile *subpath = NULL;
|
||||
const char *prefix;
|
||||
gs_unref_object OstreeSePolicy *sepolicy = NULL;
|
||||
gs_unref_object GFile *root = NULL;
|
||||
|
||||
if (argc <= 3)
|
||||
{
|
||||
g_printerr ("usage: %s ROOTFS SUBPATH PREFIX\n", argv[0]);
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"Option processing failed");
|
||||
goto out;
|
||||
}
|
||||
|
||||
root = g_file_new_for_path (argv[1]);
|
||||
subpath = g_file_new_for_path (argv[2]);
|
||||
prefix = argv[3];
|
||||
|
||||
sepolicy = ostree_sepolicy_new (root, cancellable, error);
|
||||
if (!sepolicy)
|
||||
goto out;
|
||||
|
||||
policy_name = ostree_sepolicy_get_name (sepolicy);
|
||||
if (policy_name)
|
||||
{
|
||||
g_print ("Relabeling using policy '%s'\n", policy_name);
|
||||
if (!selinux_relabel_dir (sepolicy, subpath, prefix,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
else
|
||||
g_print ("No SELinux policy found in root '%s'\n",
|
||||
gs_file_get_path_cached (root));
|
||||
|
||||
out:
|
||||
if (local_error != NULL)
|
||||
{
|
||||
int is_tty = isatty (1);
|
||||
const char *prefix = "";
|
||||
const char *suffix = "";
|
||||
if (is_tty)
|
||||
{
|
||||
prefix = "\x1b[31m\x1b[1m"; /* red, bold */
|
||||
suffix = "\x1b[22m\x1b[0m"; /* bold off, color reset */
|
||||
}
|
||||
g_printerr ("%serror: %s%s\n", prefix, suffix, local_error->message);
|
||||
g_error_free (local_error);
|
||||
return 2;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
@ -27,8 +27,6 @@
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <selinux/selinux.h>
|
||||
#include <selinux/label.h>
|
||||
#include "libgsystem.h"
|
||||
|
||||
static gboolean
|
||||
@ -661,97 +659,6 @@ create_rootfs_from_yumroot_content (GFile *targetroot,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static GVariant *
|
||||
xattr_cb (OstreeRepo *repo,
|
||||
const char *path,
|
||||
GFileInfo *file_info,
|
||||
gpointer user_data)
|
||||
{
|
||||
guint32 mode;
|
||||
char *con;
|
||||
int res;
|
||||
GVariantBuilder builder;
|
||||
GVariant *ret;
|
||||
struct selabel_handle *hnd = user_data;
|
||||
|
||||
mode = g_file_info_get_attribute_uint32 (file_info, "unix::mode");
|
||||
|
||||
res = selabel_lookup_raw (hnd, &con, path, mode);
|
||||
if (res != 0)
|
||||
{
|
||||
if (strcmp (path, "/") == 0)
|
||||
{
|
||||
g_printerr ("error: selabel_lookup_raw(/) failed: %s", strerror (errno));
|
||||
exit (1);
|
||||
}
|
||||
else
|
||||
g_printerr ("warning: selabel_lookup_raw(%s): %s\n", path, strerror (errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(ayay)"));
|
||||
g_variant_builder_add (&builder, "(@ay@ay)",
|
||||
g_variant_new_bytestring ("security.selinux"),
|
||||
g_variant_new_bytestring (con));
|
||||
|
||||
freecon (con);
|
||||
|
||||
ret = g_variant_builder_end (&builder);
|
||||
g_variant_ref_sink (ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static char *
|
||||
selinux_type_from_config (GFile *config_path,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
gboolean success = FALSE;
|
||||
gs_unref_object GFileInputStream *filein = NULL;
|
||||
gs_unref_object GDataInputStream *datain = NULL;
|
||||
char *ret = NULL;
|
||||
const char *selinuxtype_prefix = "SELINUXTYPE=";
|
||||
|
||||
filein = g_file_read (config_path, cancellable, error);
|
||||
if (!filein)
|
||||
goto out;
|
||||
|
||||
datain = g_data_input_stream_new ((GInputStream*)filein);
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
gsize len;
|
||||
GError *temp_error = NULL;
|
||||
gs_free char *line = g_data_input_stream_read_line_utf8 (datain, &len,
|
||||
cancellable, &temp_error);
|
||||
|
||||
if (temp_error)
|
||||
{
|
||||
g_propagate_error (error, temp_error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!line)
|
||||
break;
|
||||
|
||||
|
||||
if (!g_str_has_prefix (line, selinuxtype_prefix))
|
||||
continue;
|
||||
|
||||
ret = g_strstrip (g_strdup (line + strlen (selinuxtype_prefix)));
|
||||
break;
|
||||
}
|
||||
|
||||
success = TRUE;
|
||||
out:
|
||||
if (!success)
|
||||
{
|
||||
g_free (ret);
|
||||
return NULL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
rpmostree_postprocess (GFile *rootfs,
|
||||
GCancellable *cancellable,
|
||||
@ -780,106 +687,6 @@ rpmostree_postprocess (GFile *rootfs,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
workaround_selinux_pcre_version_mismatch (GFile *dir,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
gs_unref_object GFile *contexts_files = g_file_resolve_relative_path (dir, "contexts/files");
|
||||
gs_unref_object GFileEnumerator *direnum = NULL;
|
||||
|
||||
direnum = g_file_enumerate_children (contexts_files, "standard::name,standard::type",
|
||||
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
|
||||
cancellable, error);
|
||||
if (!direnum)
|
||||
goto out;
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
GFileInfo *file_info;
|
||||
GFile *child;
|
||||
const char *name;
|
||||
|
||||
if (!gs_file_enumerator_iterate (direnum, &file_info, &child,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
if (!file_info)
|
||||
break;
|
||||
|
||||
name = g_file_info_get_name (file_info);
|
||||
|
||||
if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_REGULAR
|
||||
&& g_str_has_suffix (name, ".bin"))
|
||||
{
|
||||
gs_free char *bintmp_name = g_strconcat (name, ".tmp", NULL);
|
||||
gs_unref_object GFile *bin_tmp = g_file_get_child (contexts_files, bintmp_name);
|
||||
|
||||
g_print ("Saving '%s' as '%s'\n", gs_file_get_path_cached (child),
|
||||
gs_file_get_path_cached (bin_tmp));
|
||||
if (!gs_file_rename (child, bin_tmp, cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
undo_workaround_selinux_pcre_version_mismatch (GFile *dir,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
gs_unref_object GFile *contexts_files = g_file_resolve_relative_path (dir, "contexts/files");
|
||||
gs_unref_object GFileEnumerator *direnum = NULL;
|
||||
|
||||
direnum = g_file_enumerate_children (contexts_files, "standard::name,standard::type",
|
||||
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
|
||||
cancellable, error);
|
||||
if (!direnum)
|
||||
goto out;
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
GFileInfo *file_info;
|
||||
GFile *child;
|
||||
const char *name;
|
||||
|
||||
if (!gs_file_enumerator_iterate (direnum, &file_info, &child,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
if (!file_info)
|
||||
break;
|
||||
|
||||
name = g_file_info_get_name (file_info);
|
||||
|
||||
if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_REGULAR
|
||||
&& g_str_has_suffix (name, ".bin.tmp"))
|
||||
{
|
||||
const char *lastdot = strrchr (name, '.');
|
||||
gs_free char *bin_name = NULL;
|
||||
gs_unref_object GFile *bin_tmp = NULL;
|
||||
|
||||
g_assert (lastdot);
|
||||
|
||||
bin_name = g_strndup (name, lastdot - name);
|
||||
bin_tmp = g_file_get_child (contexts_files, bin_name);
|
||||
|
||||
g_print ("Moving '%s' back to '%s'\n", gs_file_get_path_cached (child),
|
||||
gs_file_get_path_cached (bin_tmp));
|
||||
if (!gs_file_rename (child, bin_tmp, cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
rpmostree_commit (GFile *rootfs,
|
||||
OstreeRepo *repo,
|
||||
@ -895,52 +702,14 @@ rpmostree_commit (GFile *rootfs,
|
||||
gs_free char *parent_revision = NULL;
|
||||
gs_free char *new_revision = NULL;
|
||||
gs_unref_object GFile *root_tree = NULL;
|
||||
gs_unref_object GFile *selinux_root = NULL;
|
||||
gs_unref_object OstreeSePolicy *sepolicy = NULL;
|
||||
|
||||
/* hardcode targeted policy for now */
|
||||
if (enable_selinux)
|
||||
{
|
||||
gs_unref_object GFile *usr_etc_selinux = g_file_resolve_relative_path (rootfs, "usr/etc/selinux");
|
||||
gs_unref_object GFile *usr_etc_selinux_config = g_file_resolve_relative_path (usr_etc_selinux, "config");
|
||||
gs_free char *selinux_config_type = NULL;
|
||||
|
||||
if (g_file_query_exists (usr_etc_selinux_config, NULL))
|
||||
{
|
||||
selinux_config_type = selinux_type_from_config (usr_etc_selinux_config,
|
||||
cancellable, error);
|
||||
if (!selinux_config_type)
|
||||
{
|
||||
g_prefix_error (error, "Failed to read SELINUXTYPE= from '%s': ",
|
||||
gs_file_get_path_cached (usr_etc_selinux_config));
|
||||
goto out;
|
||||
}
|
||||
|
||||
g_print ("Detected SELINUXTYPE=%s\n", selinux_config_type);
|
||||
selinux_root = g_file_get_child (usr_etc_selinux, selinux_config_type);
|
||||
}
|
||||
|
||||
if (selinux_root)
|
||||
{
|
||||
g_print ("Setting policy root: %s\n",
|
||||
gs_file_get_path_cached (selinux_root));
|
||||
if (selinux_set_policy_root (gs_file_get_path_cached (selinux_root)) != 0)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"selinux_set_policy_root(%s): %s",
|
||||
gs_file_get_path_cached (selinux_root),
|
||||
strerror (errno));
|
||||
goto out;
|
||||
}
|
||||
|
||||
g_print ("Enabling workaround for SELinux pcre versioning\n");
|
||||
if (!workaround_selinux_pcre_version_mismatch (selinux_root, cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_print ("Note: SELinux enabled but no policy found in this tree\n");
|
||||
enable_selinux = FALSE;
|
||||
}
|
||||
sepolicy = ostree_sepolicy_new (rootfs, cancellable, error);
|
||||
if (!sepolicy)
|
||||
goto out;
|
||||
}
|
||||
|
||||
g_print ("Committing '%s' ...\n", gs_file_get_path_cached (rootfs));
|
||||
@ -948,30 +717,20 @@ rpmostree_commit (GFile *rootfs,
|
||||
goto out;
|
||||
|
||||
mtree = ostree_mutable_tree_new ();
|
||||
commit_modifier = ostree_repo_commit_modifier_new (enable_selinux ? 0 : OSTREE_REPO_COMMIT_MODIFIER_FLAGS_SKIP_XATTRS, NULL, NULL, NULL);
|
||||
if (enable_selinux)
|
||||
/* For now skip ACLs */
|
||||
commit_modifier = ostree_repo_commit_modifier_new (OSTREE_REPO_COMMIT_MODIFIER_FLAGS_SKIP_XATTRS, NULL, NULL, NULL);
|
||||
if (sepolicy)
|
||||
{
|
||||
struct selabel_handle *hnd = selabel_open (SELABEL_CTX_FILE, NULL, 0);
|
||||
if (!hnd)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"Failed selabel_open(): %s", strerror (errno));
|
||||
goto out;
|
||||
}
|
||||
ostree_repo_commit_modifier_set_xattr_callback (commit_modifier, xattr_cb, NULL, hnd);
|
||||
const char *policy_name = ostree_sepolicy_get_name (sepolicy);
|
||||
g_print ("Labeling with SELinux policy '%s'\n", policy_name);
|
||||
ostree_repo_commit_modifier_set_sepolicy (commit_modifier, sepolicy);
|
||||
}
|
||||
|
||||
if (!ostree_repo_write_directory_to_mtree (repo, rootfs, mtree, commit_modifier, cancellable, error))
|
||||
goto out;
|
||||
if (!ostree_repo_write_mtree (repo, mtree, &root_tree, cancellable, error))
|
||||
goto out;
|
||||
|
||||
if (enable_selinux)
|
||||
{
|
||||
g_print ("Undoing workaround for SELinux pcre versioning\n");
|
||||
if (!undo_workaround_selinux_pcre_version_mismatch (selinux_root, cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!ostree_repo_resolve_rev (repo, refname, TRUE, &parent_revision, error))
|
||||
goto out;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user