diff --git a/src/agent/Cargo.lock b/src/agent/Cargo.lock index 3b0c3efc87..d5a0dcbe79 100644 --- a/src/agent/Cargo.lock +++ b/src/agent/Cargo.lock @@ -882,6 +882,7 @@ dependencies = [ "num_cpus", "oci", "regex", + "safe-path", "serde", "serde_json", "slog", @@ -1767,6 +1768,13 @@ version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695" +[[package]] +name = "safe-path" +version = "0.1.0" +dependencies = [ + "libc", +] + [[package]] name = "scan_fmt" version = "0.2.6" diff --git a/src/libs/Cargo.lock b/src/libs/Cargo.lock index 2f03109f8a..6415f8d1e0 100644 --- a/src/libs/Cargo.lock +++ b/src/libs/Cargo.lock @@ -519,6 +519,7 @@ dependencies = [ "num_cpus", "oci", "regex", + "safe-path", "serde", "serde_json", "slog", diff --git a/src/libs/kata-types/Cargo.toml b/src/libs/kata-types/Cargo.toml index 598cde6202..f0a0f4471e 100644 --- a/src/libs/kata-types/Cargo.toml +++ b/src/libs/kata-types/Cargo.toml @@ -27,6 +27,7 @@ thiserror = "1.0" toml = "0.5.8" oci = { path = "../oci" } +safe-path = { path = "../safe-path" } [dev-dependencies] tempfile = "3" diff --git a/src/libs/kata-types/src/mount.rs b/src/libs/kata-types/src/mount.rs index f66e828bd1..00a2409b11 100644 --- a/src/libs/kata-types/src/mount.rs +++ b/src/libs/kata-types/src/mount.rs @@ -5,7 +5,7 @@ // use anyhow::{anyhow, Context, Result}; -use std::{collections::HashMap, path::PathBuf}; +use std::{collections::HashMap, fs, path::PathBuf}; /// Prefix to mark a volume as Kata special. pub const KATA_VOLUME_TYPE_PREFIX: &str = "kata:"; @@ -71,6 +71,27 @@ pub struct DirectVolumeMountInfo { pub options: Vec, } +/// join_path joins user provided volumepath with kata direct-volume root path +/// the volume_path is base64-encoded and then safely joined to the end of path prefix +pub fn join_path(prefix: &str, volume_path: &str) -> Result { + if volume_path.is_empty() { + return Err(anyhow!("volume path must not be empty")); + } + let b64_encoded_path = base64::encode(volume_path.as_bytes()); + + Ok(safe_path::scoped_join(prefix, b64_encoded_path)?) +} + +/// get DirectVolume mountInfo from mountinfo.json. +pub fn get_volume_mount_info(volume_path: &str) -> Result { + let mount_info_file_path = + join_path(KATA_DIRECT_VOLUME_ROOT_PATH, volume_path)?.join(KATA_MOUNT_INFO_FILE_NAME); + let mount_info_file = fs::read_to_string(mount_info_file_path)?; + let mount_info: DirectVolumeMountInfo = serde_json::from_str(&mount_info_file)?; + + Ok(mount_info) +} + /// Check whether a mount type is a marker for Kata specific volume. pub fn is_kata_special_volume(ty: &str) -> bool { ty.len() > KATA_VOLUME_TYPE_PREFIX.len() && ty.starts_with(KATA_VOLUME_TYPE_PREFIX) diff --git a/src/runtime-rs/Cargo.lock b/src/runtime-rs/Cargo.lock index 276facdbb1..df550eccb5 100644 --- a/src/runtime-rs/Cargo.lock +++ b/src/runtime-rs/Cargo.lock @@ -1481,6 +1481,7 @@ dependencies = [ "num_cpus", "oci", "regex", + "safe-path 0.1.0", "serde", "serde_json", "slog", diff --git a/src/tools/kata-ctl/Cargo.lock b/src/tools/kata-ctl/Cargo.lock index ed90e1117f..3056071bee 100644 --- a/src/tools/kata-ctl/Cargo.lock +++ b/src/tools/kata-ctl/Cargo.lock @@ -764,7 +764,9 @@ dependencies = [ "lazy_static", "num_cpus", "oci", + "proc-mounts", "regex", + "safe-path", "serde", "serde_json", "slog", @@ -1045,6 +1047,15 @@ dependencies = [ "winapi", ] +[[package]] +name = "partition-identity" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa925f9becb532d758b0014b472c576869910929cf4c3f8054b386f19ab9e21" +dependencies = [ + "thiserror", +] + [[package]] name = "percent-encoding" version = "2.2.0" @@ -1118,6 +1129,15 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "proc-mounts" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d652f8435d0ab70bf4f3590a6a851d59604831a458086541b95238cc51ffcf2" +dependencies = [ + "partition-identity", +] + [[package]] name = "prost" version = "0.8.0" diff --git a/src/tools/kata-ctl/src/ops/volume_ops.rs b/src/tools/kata-ctl/src/ops/volume_ops.rs index 1027dcb72b..0b037bf812 100644 --- a/src/tools/kata-ctl/src/ops/volume_ops.rs +++ b/src/tools/kata-ctl/src/ops/volume_ops.rs @@ -8,12 +8,12 @@ use crate::args::{DirectVolSubcommand, DirectVolumeCommand}; use anyhow::{anyhow, Ok, Result}; use futures::executor; use kata_types::mount::{ - DirectVolumeMountInfo, KATA_DIRECT_VOLUME_ROOT_PATH, KATA_MOUNT_INFO_FILE_NAME, + get_volume_mount_info, join_path, DirectVolumeMountInfo, KATA_DIRECT_VOLUME_ROOT_PATH, + KATA_MOUNT_INFO_FILE_NAME, }; use nix; use reqwest::StatusCode; -use safe_path; -use std::{fs, path::PathBuf, time::Duration}; +use std::{fs, time::Duration}; use url; use agent::ResizeVolumeRequest; @@ -90,17 +90,6 @@ async fn stats(volume_path: &str) -> Result> { Ok(Some(body)) } -// join_path joins user provided volumepath with kata direct-volume root path -// the volume_path is base64-encoded and then safely joined to the end of path prefix -fn join_path(prefix: &str, volume_path: &str) -> Result { - if volume_path.is_empty() { - return Err(anyhow!("volume path must not be empty")); - } - let b64_encoded_path = base64::encode(volume_path.as_bytes()); - - Ok(safe_path::scoped_join(prefix, b64_encoded_path)?) -} - // add writes the mount info (json string) of a direct volume into a filesystem path known to Kata Containers. pub fn add(volume_path: &str, mount_info: &str) -> Result> { let mount_info_dir_path = join_path(KATA_DIRECT_VOLUME_ROOT_PATH, volume_path)?; @@ -129,15 +118,6 @@ pub fn remove(volume_path: &str) -> Result> { Ok(None) } -pub fn get_volume_mount_info(volume_path: &str) -> Result { - let mount_info_file_path = - join_path(KATA_DIRECT_VOLUME_ROOT_PATH, volume_path)?.join(KATA_MOUNT_INFO_FILE_NAME); - let mount_info_file = fs::read_to_string(mount_info_file_path)?; - let mount_info: DirectVolumeMountInfo = serde_json::from_str(&mount_info_file)?; - - Ok(mount_info) -} - // get_sandbox_id_for_volume finds the id of the first sandbox found in the dir. // We expect a direct-assigned volume is associated with only a sandbox at a time. pub fn get_sandbox_id_for_volume(volume_path: &str) -> Result { @@ -170,7 +150,7 @@ mod tests { use super::*; use kata_types::mount::DirectVolumeMountInfo; use serial_test::serial; - use std::{collections::HashMap, fs}; + use std::{collections::HashMap, fs, path::PathBuf}; use tempfile::tempdir; use test_utils::skip_if_not_root;