This commit is contained in:
parent
d76eca5a7c
commit
9602c03c23
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user