aboutsummaryrefslogtreecommitdiff
path: root/src/platform/linux/native_image_sources.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/platform/linux/native_image_sources.rs')
-rw-r--r--src/platform/linux/native_image_sources.rs96
1 files changed, 0 insertions, 96 deletions
diff --git a/src/platform/linux/native_image_sources.rs b/src/platform/linux/native_image_sources.rs
deleted file mode 100644
index b4d3b073..00000000
--- a/src/platform/linux/native_image_sources.rs
+++ /dev/null
@@ -1,96 +0,0 @@
-//! Bounded kernel CoW snapshots. No read/write or whole-file clone fallback.
-use std::fs::File;
-use std::io;
-use std::os::fd::AsRawFd;
-
-#[repr(C)]
-struct CloneRange {
- src_fd: i64,
- src_offset: u64,
- src_length: u64,
- dest_offset: u64,
-}
-
-fn stat(fd: libc::c_int) -> io::Result<libc::stat> {
- let mut result = std::mem::MaybeUninit::<libc::stat>::uninit();
- // SAFETY: fstat initializes the supplied stat on success; fd remains borrowed.
- if unsafe { libc::fstat(fd, result.as_mut_ptr()) } != 0 {
- return Err(io::Error::last_os_error());
- }
- // SAFETY: successful fstat initialized the value.
- Ok(unsafe { result.assume_init() })
-}
-
-fn invalid() -> io::Error {
- io::Error::new(
- io::ErrorKind::InvalidInput,
- "invalid native snapshot source or destination",
- )
-}
-
-pub(crate) fn clone_native_image_source(
- source_fd: i64,
- destination: &File,
- expected_len: usize,
-) -> io::Result<()> {
- let fd = libc::c_int::try_from(source_fd).map_err(|_| invalid())?;
- if fd < 0
- || expected_len == 0
- || expected_len > 16 * 1024 * 1024
- || !expected_len.is_multiple_of(4)
- {
- return Err(invalid());
- }
- let source = stat(fd)?;
- let dest = stat(destination.as_raw_fd())?;
- // SAFETY: geteuid has no preconditions.
- let uid = unsafe { libc::geteuid() };
- let valid_source = |value: &libc::stat| {
- value.st_mode & libc::S_IFMT == libc::S_IFREG
- && value.st_uid == uid
- && value.st_size == expected_len as i64
- && value.st_dev == source.st_dev
- && value.st_ino == source.st_ino
- };
- if !valid_source(&source)
- || dest.st_mode & libc::S_IFMT != libc::S_IFREG
- || dest.st_mode & 0o777 != 0o600
- || dest.st_uid != uid
- || dest.st_nlink != 1
- || dest.st_size != 0
- || (dest.st_dev == source.st_dev && dest.st_ino == source.st_ino)
- {
- return Err(invalid());
- }
- let range = CloneRange {
- src_fd: source_fd,
- src_offset: 0,
- src_length: expected_len as u64,
- dest_offset: 0,
- };
- // Explicit nonzero length is essential: FICLONE (or a zero range length)
- // clones through EOF and source growth could exceed the reservation before
- // post-validation. This request cannot extend the destination past the
- // reservation even if the producer changes size concurrently. Filesystems
- // requiring block alignment may reject an EOF range after concurrent growth;
- // that is a normal fallback, never a reason to try an unbounded clone.
- // SAFETY: the request consumes a valid repr(C) range, both descriptors stay
- // open throughout the call, and the source descriptor is never owned here.
- if unsafe { libc::ioctl(destination.as_raw_fd(), libc::FICLONERANGE, &range) } != 0 {
- return Err(io::Error::last_os_error());
- }
- let after = stat(destination.as_raw_fd())?;
- if !valid_source(&stat(fd)?)
- || after.st_dev != dest.st_dev
- || after.st_ino != dest.st_ino
- || after.st_size != expected_len as i64
- || after.st_nlink != 1
- || after.st_uid != uid
- || after.st_mode & 0o777 != 0o600
- {
- return Err(invalid());
- }
- // The kernel serializes clone against writes. These stats establish exact
- // length at validation points, not producer quiescence or a content hash.
- Ok(())
-}