Skip to content

Commit

Permalink
libpriv/scripts: inject pkgname in scriptlets environment
Browse files Browse the repository at this point in the history
This introduces a new `RPMOSTREE_SCRIPT_PKG_NAME` environment
variable which gets propagated through `bwrap` into the context
of scripts. It allows sandboxed logic to introspect the package name.
  • Loading branch information
lucab committed Aug 1, 2022
1 parent bfa1fc2 commit fcc7809
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 6 deletions.
24 changes: 18 additions & 6 deletions rust/src/builtins/scriptlet_intercept/groupadd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// SPDX-License-Identifier: Apache-2.0 OR MIT

use anyhow::{anyhow, Result};
use anyhow::{anyhow, Context, Result};
use cap_std::fs::{Dir, Permissions};
use cap_std_ext::prelude::CapStdExtDirExt;
use clap::{Arg, Command};
Expand All @@ -13,6 +13,13 @@ use std::os::unix::prelude::PermissionsExt;
pub(crate) fn entrypoint(args: &[&str]) -> Result<()> {
fail::fail_point!("intercept_groupadd_ok", |_| Ok(()));

// Extract the package name from rpm-ostree/bwrap environment.
// This also works as a sanity check to ensure we are running in
// the context of a scriptlet.
static SCRIPT_PKG_VAR: &str = "RPMOSTREE_SCRIPT_PKG_NAME";
let pkgname = std::env::var(SCRIPT_PKG_VAR)
.with_context(|| format!("Failed to access {SCRIPT_PKG_VAR} environment variable"))?;

// This parses the same CLI surface as the real `groupadd`,
// but in the end we only extract the group name and (if
// present) the static GID.
Expand All @@ -29,7 +36,7 @@ pub(crate) fn entrypoint(args: &[&str]) -> Result<()> {
}

let rootdir = Dir::open_ambient_dir("/", cap_std::ambient_authority())?;
generate_sysusers_fragment(&rootdir, groupname, gid)?;
generate_sysusers_fragment(&rootdir, &pkgname, groupname, gid)?;

Ok(())
}
Expand Down Expand Up @@ -77,12 +84,17 @@ fn cli_cmd() -> Command<'static> {
///
/// This returns whether a new fragment has been actually written
/// to disk.
fn generate_sysusers_fragment(rootdir: &Dir, groupname: &str, gid: Option<u32>) -> Result<bool> {
fn generate_sysusers_fragment(
rootdir: &Dir,
pkgname: &str,
groupname: &str,
gid: Option<u32>,
) -> Result<bool> {
static SYSUSERS_DIR: &str = "usr/lib/sysusers.d";

// The filename of the configuration fragment is in fact a public
// API, because users may have masked it in /etc. Do not change this.
let filename = format!("30-pkg-group-{groupname}.conf");
let filename = format!("30-pkg-{pkgname}-group-{groupname}.conf");

rootdir.create_dir_all(SYSUSERS_DIR)?;
let conf_dir = rootdir.open_dir(SYSUSERS_DIR)?;
Expand Down Expand Up @@ -146,10 +158,10 @@ mod test {
("bar", None, true, "-"),
];
for entry in groups {
let generated = generate_sysusers_fragment(&tmpdir, entry.0, entry.1).unwrap();
let generated = generate_sysusers_fragment(&tmpdir, "foo", entry.0, entry.1).unwrap();
assert_eq!(generated, entry.2, "{:?}", entry);

let path = format!("usr/lib/sysusers.d/30-pkg-group-{}.conf", entry.0);
let path = format!("usr/lib/sysusers.d/30-pkg-foo-group-{}.conf", entry.0);
assert!(tmpdir.is_file(&path));

let mut fragment = tmpdir.open(&path).unwrap();
Expand Down
5 changes: 5 additions & 0 deletions src/libpriv/rpmostree-scripts.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,9 @@ rpmostree_run_script_in_bwrap_container (int rootfs_fd, GLnxTmpDir *var_lib_rpm_
int provided_stdin_fd, GCancellable *cancellable,
GError **error)
{
g_assert (name != NULL);
g_assert (name[0] != '\0');

const char *pkg_script = scriptdesc ? glnx_strjoina (name, ".", scriptdesc + 1) : name;

// A dance just to pass a well-known fd for /dev/null to bwrap as fd 3
Expand Down Expand Up @@ -370,6 +373,8 @@ rpmostree_run_script_in_bwrap_container (int rootfs_fd, GLnxTmpDir *var_lib_rpm_
if (bridge_sysusers != NULL)
bwrap->setenv ("RPMOSTREE_EXP_BRIDGE_SYSUSERS", rust::String (bridge_sysusers));

bwrap->setenv ("RPMOSTREE_SCRIPT_PKG_NAME", name);

/* https://github.com/systemd/systemd/pull/7631 AKA
* "systemctl,verbs: Introduce SYSTEMD_OFFLINE environment variable"
* https://github.com/systemd/systemd/commit/f38951a62837a00a0b1ff42d007e9396b347742d
Expand Down

0 comments on commit fcc7809

Please sign in to comment.