Skip to content

Commit a9bf1f6

Browse files
committed
bundle: enhance security by using the safe-path crate
Use the safe-path crate to protect from possible path related attacks. Signed-off-by: Jiang Liu <[email protected]>
1 parent 89292d9 commit a9bf1f6

File tree

3 files changed

+21
-13
lines changed

3 files changed

+21
-13
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ nix = "0.23.0"
1717
oci-distribution = { git = "https://github.com/arronwy/oci-distribution", branch = "export_pull_layer" }
1818
oci-spec = { git = "https://github.com/containers/oci-spec-rs" }
1919
ocicrypt-rs = { git = "https://github.com/arronwy/ocicrypt-rs", branch = "oci_distribution" }
20+
safe-path = "0.1"
2021
serde = { version = ">=1.0.27", features = ["serde_derive", "rc"] }
2122
serde_json = ">=1.0.9"
2223
sha2 = ">=0.10"

src/bundle.rs

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@
22
//
33
// SPDX-License-Identifier: Apache-2.0
44

5-
use anyhow::Result;
65
use std::collections::HashMap;
7-
use std::path::{Path, PathBuf};
6+
use std::path::PathBuf;
87

8+
use anyhow::{Context, Result};
99
use oci_spec::image::ImageConfiguration;
1010
use oci_spec::runtime::{Mount, Process, Spec};
11+
use safe_path::PinnedPathBuf;
1112

1213
pub const BUNDLE_CONFIG: &str = "config.json";
1314
pub const BUNDLE_ROOTFS: &str = "rootfs";
@@ -35,8 +36,8 @@ const ANNOTATION_EXPOSED_PORTS: &str = "org.opencontainers.image.exposedPorts";
3536
/// runtime configuration".
3637
pub fn create_runtime_config(
3738
image_config: &ImageConfiguration,
38-
bundle_path: &Path,
39-
) -> Result<PathBuf> {
39+
bundle_path: &PinnedPathBuf,
40+
) -> Result<PinnedPathBuf> {
4041
let mut spec = Spec::default();
4142
let mut annotations: HashMap<String, String> = HashMap::new();
4243
let mut labels = HashMap::new();
@@ -203,10 +204,12 @@ pub fn create_runtime_config(
203204
}
204205

205206
spec.set_annotations(Some(annotations));
207+
// TODO
206208
let bundle_config = bundle_path.join(BUNDLE_CONFIG);
207209
spec.save(&bundle_config)?;
208210

209-
Ok(bundle_config)
211+
PinnedPathBuf::new(bundle_path, BUNDLE_CONFIG)
212+
.context("The path of generated config.json file has changed, possible attack!")
210213
}
211214

212215
#[cfg(test)]
@@ -217,13 +220,14 @@ mod tests {
217220
#[test]
218221
fn test_bundle_create_config() {
219222
let image_config = ImageConfiguration::default();
220-
221223
let tempdir = tempfile::tempdir().unwrap();
222-
let filename = tempdir.path().join(BUNDLE_CONFIG);
224+
let tempdir = PinnedPathBuf::new("/", tempdir.path()).unwrap();
225+
let config_file = create_runtime_config(&image_config, &tempdir).unwrap();
223226

224-
assert!(!filename.exists());
227+
assert!(config_file.target().exists());
228+
assert!(config_file.target().is_file());
225229

226-
assert!(create_runtime_config(&image_config, tempdir.path()).is_ok());
227-
assert!(filename.exists());
230+
let spec = Spec::load(&config_file).unwrap();
231+
assert_eq!(spec.hostname().as_ref().unwrap(), BUNDLE_HOSTNAME);
228232
}
229233
}

src/image.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use anyhow::{anyhow, Result};
66
use oci_spec::image::{ImageConfiguration, Os};
7+
use safe_path::PinnedPathBuf;
78
use serde::Deserialize;
89
use std::collections::HashMap;
910
use std::convert::TryFrom;
@@ -113,7 +114,7 @@ impl ImageClient {
113114
pub async fn pull_image(
114115
&mut self,
115116
image_url: &str,
116-
bundle_dir: &Path,
117+
bundle_dir: &PinnedPathBuf,
117118
auth_info: &Option<&str>,
118119
decrypt_config: &Option<&str>,
119120
) -> Result<String> {
@@ -222,10 +223,12 @@ mod tests {
222223

223224
let mut image_client = ImageClient::default();
224225
for image in oci_images.iter() {
225-
let bundle_dir = tempfile::tempdir().unwrap();
226+
let tempdir = tempfile::tempdir().unwrap();
227+
let temp_path = tempdir.path().canonicalize().unwrap();
228+
let bundle_dir = PinnedPathBuf::from_path(temp_path).unwrap();
226229

227230
assert!(image_client
228-
.pull_image(image, bundle_dir.path(), &None, &None)
231+
.pull_image(image, &bundle_dir, &None, &None)
229232
.await
230233
.is_ok());
231234
}

0 commit comments

Comments
 (0)