Colin Walters 2022-07-11 15:15:23 -04:00
parent d76eca5a7c
commit 9602c03c23
2 changed files with 5 additions and 151 deletions

View File

@ -1,147 +0,0 @@
From 5626e776d89a3c3900b504e867aaf83a7efcb269 Mon Sep 17 00:00:00 2001
From: Colin Walters <walters@verbum.org>
Date: Thu, 16 Jun 2022 12:32:37 -0400
Subject: [PATCH] composepost: Add and use helpers for reading/writing absolute
symlinks
See https://pagure.io/releng/failed-composes/issue/3660
The port to cap-std regressed only the *non-unified* core case
for tmpfiles.d translation. Here cap-std's `read_link()` API correctly
checks for relative paths for the link name, but it *also* bombs
out if the link *target* is absolute, even if we're not going to
follow it.
I think this is arguably buggy behavior. But, that's a debate
for a future time.
Now, this bug was masked in our CI because it doesn't occur in
unified core mode where we handle tmpfiles.d translation as part
of package imports.
Add and use internal helpers for reading (and writing, for tests)
absolute symlinks.
---
rust/src/capstdext.rs | 55 ++++++++++++++++++++++++++++++++++++++++-
rust/src/composepost.rs | 19 ++++++++++----
2 files changed, 68 insertions(+), 6 deletions(-)
diff --git a/rust/src/capstdext.rs b/rust/src/capstdext.rs
index 99c30967..15b8f51a 100644
--- a/rust/src/capstdext.rs
+++ b/rust/src/capstdext.rs
@@ -6,9 +6,11 @@
use cap_std::fs::DirBuilder;
use cap_std_ext::cap_std;
use cap_std_ext::cap_std::fs::Dir;
-use std::ffi::OsStr;
+use cap_std_ext::rustix;
+use std::ffi::{OsStr, OsString};
use std::io::Result;
use std::os::unix::fs::DirBuilderExt;
+use std::os::unix::prelude::OsStringExt;
use std::path::Path;
pub(crate) fn dirbuilder_from_mode(m: u32) -> DirBuilder {
@@ -35,3 +37,54 @@ pub(crate) fn open_dir_of(
})?;
Ok((parent, filename))
}
+
+pub(crate) fn read_link_contents_impl(dir: &Dir, path: &Path) -> Result<OsString> {
+ let parent = path
+ .parent()
+ .filter(|v| !v.as_os_str().is_empty())
+ .unwrap_or_else(|| Path::new("."));
+ let dir = dir.open_dir(parent)?;
+ let filename = path.file_name().ok_or_else(|| {
+ std::io::Error::new(
+ std::io::ErrorKind::InvalidInput,
+ "the source path does not name a file",
+ )
+ })?;
+ let l = rustix::fs::readlinkat(&dir, filename, Vec::new())?;
+ Ok(OsString::from_vec(l.into_bytes()))
+}
+
+// Today cap-std's read_link *also* verifies that the link target doesn't lead outside
+// the filesystem. I think this is arguably incorrect behavior, but for now let's
+// add an API that does this.
+pub(crate) fn read_link_contents(dir: &Dir, path: impl AsRef<Path>) -> Result<OsString> {
+ read_link_contents_impl(dir, path.as_ref())
+}
+
+#[cfg(test)]
+pub(crate) fn write_link_contents_impl(dir: &Dir, contents: &OsStr, path: &Path) -> Result<()> {
+ let parent = path
+ .parent()
+ .filter(|v| !v.as_os_str().is_empty())
+ .unwrap_or_else(|| Path::new("."));
+ let dir = dir.open_dir(parent)?;
+ let filename = path.file_name().ok_or_else(|| {
+ std::io::Error::new(
+ std::io::ErrorKind::InvalidInput,
+ "the source path does not name a file",
+ )
+ })?;
+ rustix::fs::symlinkat(contents, &dir, filename).map_err(Into::into)
+}
+
+// Today cap-std's read_link *also* verifies that the link target doesn't lead outside
+// the filesystem. I think this is arguably incorrect behavior, but for now let's
+// add an API that does this.
+#[cfg(test)]
+pub(crate) fn write_read_link_contents(
+ dir: &Dir,
+ original: impl AsRef<OsStr>,
+ path: impl AsRef<Path>,
+) -> Result<()> {
+ write_link_contents_impl(dir, original.as_ref(), path.as_ref())
+}
diff --git a/rust/src/composepost.rs b/rust/src/composepost.rs
index c486607a..3ddcda49 100644
--- a/rust/src/composepost.rs
+++ b/rust/src/composepost.rs
@@ -791,11 +791,13 @@ fn convert_path_to_tmpfiles_d_recurse(
file_info.set_file_type(FileType::Directory);
} else if meta.is_symlink() {
file_info.set_file_type(FileType::SymbolicLink);
- let link_target = rootfs.read_link(&full_path).context("Reading symlink")?;
- let target_path = Utf8Path::from_path(&link_target).ok_or_else(|| {
- format_err!("non UTF-8 symlink target '{}'", &link_target.display())
- })?;
- file_info.set_symlink_target(target_path.as_str());
+ let link_target =
+ crate::capstdext::read_link_contents(rootfs, full_path.as_std_path())
+ .context("Reading symlink")?;
+ let link_target = link_target
+ .to_str()
+ .ok_or_else(|| format_err!("non UTF-8 symlink target '{:?}'", link_target))?;
+ file_info.set_symlink_target(link_target);
} else if meta.is_file() {
file_info.set_file_type(FileType::Regular);
} else {
@@ -1344,6 +1346,12 @@ OSTREE_VERSION='33.4'
rootfs
.symlink("../", "var/lib/test/nested/symlink")
.unwrap();
+ crate::capstdext::write_read_link_contents(
+ &rootfs,
+ "/var/lib/foo",
+ "var/lib/test/absolute-symlink",
+ )
+ .unwrap();
// Also make this a sanity test for our directory size API
let cancellable = gio::Cancellable::new();
@@ -1364,6 +1372,7 @@ OSTREE_VERSION='33.4'
.map(|s| s.to_owned())
.collect();
let expected = &[
+ "L /var/lib/test/absolute-symlink - - - - /var/lib/foo",
"L /var/lib/test/nested/symlink - - - - ../",
"d /var/lib 0755 test-user test-group - -",
"d /var/lib/nfs 0755 test-user test-group - -",
--
2.35.1

View File

@ -3,15 +3,13 @@
Summary: Hybrid image/package system
Name: rpm-ostree
Version: 2022.10
Release: 3%{?dist}
Version: 2022.11
Release: 2%{?dist}
License: LGPLv2+
URL: https://github.com/coreos/rpm-ostree
# This tarball is generated via "cd packaging && make -f Makefile.dist-packaging dist-snapshot"
# in the upstream git. It also contains vendored Rust sources.
Source0: https://github.com/coreos/rpm-ostree/releases/download/v%{version}/rpm-ostree-%{version}.tar.xz
# Backport https://github.com/coreos/rpm-ostree/pull/3771
Patch0: 0001-composepost-Add-and-use-helpers-for-reading-writing-.patch
ExclusiveArch: %{rust_arches}
@ -237,6 +235,9 @@ $PYTHON autofiles.py > files.devel \
%files devel -f files.devel
%changelog
* Mon Jul 11 2022 Colin Walters <walters@verbum.org> - 2022.11-2
- https://github.com/coreos/rpm-ostree/releases/tag/v2022.11
* Thu Jun 16 2022 Colin Walters <walters@verbum.org> - 2022.10-3
- Backport https://github.com/coreos/rpm-ostree/pull/3771