Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

treefile: Add option to label /usr/etc as /etc #4640

Merged
merged 4 commits into from
Oct 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions ci/installdeps.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@
# we have the canonical spec file handy so just builddep from that
# XXX: use --allowerasing as a temporary hack to ease the migration to libmodulemd2
time dnf builddep --spec -y packaging/rpm-ostree.spec.in --allowerasing

osid="$(. /etc/os-release && echo $ID)"
if [ "${osid}" == centos ]; then
dnf -y update https://kojihub.stream.centos.org/kojifiles/packages/ostree/2023.7/2.el9/$(arch)/ostree-{,libs-,devel-}2023.7-2.el9.$(arch).rpm

Check warning

Code scanning / shellcheck

Quote this to prevent word splitting. Warning

Quote this to prevent word splitting.

Check warning

Code scanning / shellcheck

Quote this to prevent word splitting. Warning

Quote this to prevent word splitting.
fi
fi

mkdir -p target
Expand Down
2 changes: 1 addition & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ PKG_PROG_PKG_CONFIG
dnl Remember to update AM_CPPFLAGS in Makefile.am when bumping GIO req.
PKG_CHECK_MODULES(PKGDEP_GIO_UNIX, [gio-unix-2.0])
dnl These are the dependencies of the public librpmostree-1.0.0 shared library
PKG_CHECK_MODULES(PKGDEP_LIBRPMOSTREE, [gio-unix-2.0 >= 2.50.0 json-glib-1.0 ostree-1 >= 2023.6 rpm >= 4.16])
PKG_CHECK_MODULES(PKGDEP_LIBRPMOSTREE, [gio-unix-2.0 >= 2.50.0 json-glib-1.0 ostree-1 >= 2023.7 rpm >= 4.16])
dnl And these additional ones are used by for the rpmostreeinternals C/C++ library
PKG_CHECK_MODULES(PKGDEP_RPMOSTREE, [polkit-gobject-1 libarchive])

Expand Down
4 changes: 4 additions & 0 deletions docs/treefile.md
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,10 @@ It supports the following parameters:
to the UNIX epoch time to be used as the build timestamp. Currently only
fully supports the `bdb` backend. Somewhat experimental.

* `selinux-label-version`: integer, optional: When set to `1`, this will
turn on an ostree flag which labels files in `/usr/etc` as if they were in
`/etc`. This is important to aid in having a "transient" `/etc`.

* `cliwrap`: boolean, optional. Defaults to `false`. If enabled,
rpm-ostree will replace binaries such as `/usr/bin/rpm` with
wrappers that intercept unsafe operations, or adjust functionality.
Expand Down
10 changes: 10 additions & 0 deletions rpmostree-cxxrs.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -1748,6 +1748,7 @@ struct Treefile final : public ::rust::Opaque
bool get_documentation () const noexcept;
bool get_recommends () const noexcept;
bool get_selinux () const noexcept;
::std::uint32_t get_selinux_label_version () const noexcept;
::rust::String get_gpg_key () const noexcept;
::rust::String get_automatic_version_suffix () const noexcept;
bool get_container () const noexcept;
Expand Down Expand Up @@ -2588,6 +2589,9 @@ extern "C"

bool rpmostreecxx$cxxbridge1$Treefile$get_selinux (::rpmostreecxx::Treefile const &self) noexcept;

::std::uint32_t rpmostreecxx$cxxbridge1$Treefile$get_selinux_label_version (
::rpmostreecxx::Treefile const &self) noexcept;

void rpmostreecxx$cxxbridge1$Treefile$get_gpg_key (::rpmostreecxx::Treefile const &self,
::rust::String *return$) noexcept;

Expand Down Expand Up @@ -5133,6 +5137,12 @@ Treefile::get_selinux () const noexcept
return rpmostreecxx$cxxbridge1$Treefile$get_selinux (*this);
}

::std::uint32_t
Treefile::get_selinux_label_version () const noexcept
{
return rpmostreecxx$cxxbridge1$Treefile$get_selinux_label_version (*this);
}

::rust::String
Treefile::get_gpg_key () const noexcept
{
Expand Down
1 change: 1 addition & 0 deletions rpmostree-cxxrs.h
Original file line number Diff line number Diff line change
Expand Up @@ -1530,6 +1530,7 @@ struct Treefile final : public ::rust::Opaque
bool get_documentation () const noexcept;
bool get_recommends () const noexcept;
bool get_selinux () const noexcept;
::std::uint32_t get_selinux_label_version () const noexcept;
::rust::String get_gpg_key () const noexcept;
::rust::String get_automatic_version_suffix () const noexcept;
bool get_container () const noexcept;
Expand Down
14 changes: 7 additions & 7 deletions rust/src/composepost.rs
Original file line number Diff line number Diff line change
Expand Up @@ -267,15 +267,15 @@ fn postprocess_subs_dist(rootfs_dfd: &Dir) -> Result<()> {
for line in f.lines() {
let line = line?;
if line.starts_with("/var/home ") {
w.write_all(b"# https://github.com/projectatomic/rpm-ostree/pull/1754\n")?;
w.write_all(b"# ")?;
writeln!(w, "# https://github.com/projectatomic/rpm-ostree/pull/1754")?;
write!(w, "# ")?;
}
w.write_all(line.as_bytes())?;
w.write_all(b"\n")?;
writeln!(w, "{}", line)?;
}
w.write_all(b"# https://github.com/projectatomic/rpm-ostree/pull/1754\n")?;
w.write_all(b"/home /var/home")?;
w.write_all(b"\n")?;
writeln!(w, "# https://github.com/projectatomic/rpm-ostree/pull/1754")?;
writeln!(w, "/home /var/home")?;
writeln!(w, "# https://github.com/coreos/rpm-ostree/pull/4640")?;
writeln!(w, "/usr/etc /etc")?;
Ok(())
})?;
}
Expand Down
1 change: 1 addition & 0 deletions rust/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -607,6 +607,7 @@ pub mod ffi {
fn get_documentation(&self) -> bool;
fn get_recommends(&self) -> bool;
fn get_selinux(&self) -> bool;
fn get_selinux_label_version(&self) -> u32;
fn get_gpg_key(&self) -> String;
fn get_automatic_version_suffix(&self) -> String;
fn get_container(&self) -> bool;
Expand Down
11 changes: 11 additions & 0 deletions rust/src/treefile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,7 @@ fn treefile_merge(dest: &mut TreeComposeConfig, src: &mut TreeComposeConfig) {
basearch,
rojig,
selinux,
selinux_label_version,
ima,
gpg_key,
include,
Expand Down Expand Up @@ -1332,6 +1333,10 @@ impl Treefile {
self.parsed.base.selinux.unwrap_or(true)
}

pub(crate) fn get_selinux_label_version(&self) -> u32 {
self.parsed.base.selinux_label_version.unwrap_or_default()
}

pub(crate) fn get_gpg_key(&self) -> String {
self.parsed.base.gpg_key.clone().unwrap_or_default()
}
Expand Down Expand Up @@ -1480,6 +1485,10 @@ impl Treefile {
{
bail!(r#"Treefile repo var "basearch" invalid; it is automatically filled in"#);
}
match config.selinux_label_version.unwrap_or_default() {
0 | 1 => {}
o => anyhow::bail!("Invalid selinux-label-version: {o}"),
}
Ok(())
}

Expand Down Expand Up @@ -2473,6 +2482,8 @@ pub(crate) struct BaseComposeConfigFields {
#[serde(skip_serializing_if = "Option::is_none")]
pub(crate) selinux: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub(crate) selinux_label_version: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub(crate) ima: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub(crate) gpg_key: Option<String>,
Expand Down
14 changes: 12 additions & 2 deletions src/app/rpmostree-compose-builtin-tree.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -1135,7 +1135,6 @@ static gboolean
impl_commit_tree (RpmOstreeTreeComposeContext *self, GCancellable *cancellable, GError **error)
{
auto gpgkey = (*self->treefile_rs)->get_gpg_key ();
auto selinux = (*self->treefile_rs)->get_selinux ();

/* pick up any initramfs regeneration args to shove into the metadata */
JsonNode *initramfs_args = json_object_get_member (self->treefile, "initramfs-args");
Expand Down Expand Up @@ -1211,8 +1210,19 @@ impl_commit_tree (RpmOstreeTreeComposeContext *self, GCancellable *cancellable,
if (!gpgkey.empty ())
gpgkey_c = gpgkey.c_str ();
auto container = (*self->treefile_rs)->get_container ();
RpmOstreeSELinuxMode selinux_mode;
{
auto selinux = (*self->treefile_rs)->get_selinux ();
auto selinux_label_version = (*self->treefile_rs)->get_selinux_label_version ();
if (selinux && selinux_label_version == 1)
selinux_mode = RPMOSTREE_SELINUX_MODE_V1;
else if (selinux)
selinux_mode = RPMOSTREE_SELINUX_MODE_V0;
else
selinux_mode = RPMOSTREE_SELINUX_MODE_DISABLED;
}
if (!rpmostree_compose_commit (self->rootfs_dfd, self->build_repo, parent_revision, metadata,
detached_metadata, gpgkey_c, container, selinux,
detached_metadata, gpgkey_c, container, selinux_mode,
self->devino_cache, &new_revision, cancellable, error))
return glnx_prefix_error (error, "Writing commit");
g_assert (new_revision != NULL);
Expand Down
11 changes: 7 additions & 4 deletions src/libpriv/rpmostree-postprocess.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -761,16 +761,19 @@ on_progress_timeout (gpointer datap)
gboolean
rpmostree_compose_commit (int rootfs_fd, OstreeRepo *repo, const char *parent_revision,
GVariant *src_metadata, GVariant *detached_metadata,
const char *gpg_keyid, gboolean container, gboolean enable_selinux,
const char *gpg_keyid, gboolean container, RpmOstreeSELinuxMode selinux,
OstreeRepoDevInoCache *devino_cache, char **out_new_revision,
GCancellable *cancellable, GError **error)
{
int label_modifier_flags = 0;
g_autoptr (OstreeSePolicy) sepolicy = NULL;
if (enable_selinux)
if (selinux != RPMOSTREE_SELINUX_MODE_DISABLED)
{
sepolicy = ostree_sepolicy_new_at (rootfs_fd, cancellable, error);
if (!sepolicy)
return FALSE;
if (selinux == RPMOSTREE_SELINUX_MODE_V1)
label_modifier_flags |= OSTREE_REPO_COMMIT_MODIFIER_FLAGS_SELINUX_LABEL_V1;
}

g_autoptr (OstreeMutableTree) mtree = ostree_mutable_tree_new ();
Expand All @@ -783,7 +786,7 @@ rpmostree_compose_commit (int rootfs_fd, OstreeRepo *repo, const char *parent_re
*/
auto modifier_flags = static_cast<OstreeRepoCommitModifierFlags> (
OSTREE_REPO_COMMIT_MODIFIER_FLAGS_ERROR_ON_UNLABELED
| OSTREE_REPO_COMMIT_MODIFIER_FLAGS_CONSUME);
| OSTREE_REPO_COMMIT_MODIFIER_FLAGS_CONSUME | label_modifier_flags);
/* If changing this, also look at changing rpmostree-unpacker.c */
g_autoptr (OstreeRepoCommitModifier) commit_modifier
= ostree_repo_commit_modifier_new (modifier_flags, NULL, NULL, NULL);
Expand All @@ -794,7 +797,7 @@ rpmostree_compose_commit (int rootfs_fd, OstreeRepo *repo, const char *parent_re

if (sepolicy && ostree_sepolicy_get_name (sepolicy) != NULL)
ostree_repo_commit_modifier_set_sepolicy (commit_modifier, sepolicy);
else if (enable_selinux)
else if (selinux != RPMOSTREE_SELINUX_MODE_DISABLED)
return glnx_throw (error, "SELinux enabled, but no policy found");

if (devino_cache)
Expand Down
13 changes: 10 additions & 3 deletions src/libpriv/rpmostree-postprocess.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,19 @@ gboolean rpmostree_prepare_rootfs_get_sepolicy (int dfd, OstreeSePolicy **out_se
gboolean rpmostree_rootfs_fixup_selinux_store_root (int rootfs_dfd, GCancellable *cancellable,
GError **error);

typedef enum
{
RPMOSTREE_SELINUX_MODE_DISABLED,
RPMOSTREE_SELINUX_MODE_V0, // Enabled
RPMOSTREE_SELINUX_MODE_V1, // Label /usr/etc as /etc
} RpmOstreeSELinuxMode;

gboolean rpmostree_compose_commit (int rootfs_dfd, OstreeRepo *repo, const char *parent,
GVariant *metadata, GVariant *detached_metadata,
const char *gpg_keyid, gboolean container,
gboolean enable_selinux, OstreeRepoDevInoCache *devino_cache,
char **out_new_revision, GCancellable *cancellable,
GError **error);
RpmOstreeSELinuxMode selinux,
OstreeRepoDevInoCache *devino_cache, char **out_new_revision,
GCancellable *cancellable, GError **error);

G_END_DECLS

Expand Down
5 changes: 5 additions & 0 deletions tests/compose/test-misc-tweaks.sh
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ documentation: true
EOF
cat > config/other.yaml <<'EOF'
recommends: true
selinux-label-version: 1
cgwalters marked this conversation as resolved.
Show resolved Hide resolved
readonly-executables: true
container-cmd:
- /usr/bin/bash
Expand Down Expand Up @@ -135,6 +136,10 @@ export treefile=${new_treefile}
runcompose
echo "ok compose"

ostree --repo=${repo} ls -X ${treeref} /usr/etc/sysctl.conf > ls.txt
assert_file_has_content ls.txt ':system_conf_t:'
echo "ok selinux-label-version"

# Tests for docs
ostree --repo=${repo} ls -R ${treeref} /usr/share/man > manpages.txt
assert_file_has_content manpages.txt man5/ostree.repo.5
Expand Down