Skip to content

Commit a9e8556

Browse files
committed
Check ownership during Cargo.toml discovery.
This adds a check for file ownership when locating Cargo.toml files.
1 parent a31c16f commit a9e8556

File tree

4 files changed

+33
-5
lines changed

4 files changed

+33
-5
lines changed

src/cargo/core/workspace.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ use crate::core::{EitherManifest, Package, SourceId, VirtualManifest};
2121
use crate::ops;
2222
use crate::sources::{PathSource, CRATES_IO_INDEX, CRATES_IO_REGISTRY};
2323
use crate::util::errors::{CargoResult, ManifestError};
24+
use crate::util::important_paths;
2425
use crate::util::interning::InternedString;
2526
use crate::util::lev_distance;
2627
use crate::util::toml::{read_manifest, InheritableFields, TomlDependency, TomlProfiles};
@@ -1707,7 +1708,9 @@ fn find_workspace_root_with_loader(
17071708
config: &Config,
17081709
mut loader: impl FnMut(&Path) -> CargoResult<Option<PathBuf>>,
17091710
) -> CargoResult<Option<PathBuf>> {
1711+
let safe_directories = config.safe_directories()?;
17101712
for ances_manifest_path in find_root_iter(manifest_path, config) {
1713+
important_paths::check_safe_manifest_path(config, &safe_directories, &ances_manifest_path)?;
17111714
debug!("find_root - trying {}", ances_manifest_path.display());
17121715
if let Some(ws_root_path) = loader(&ances_manifest_path)? {
17131716
return Ok(Some(ws_root_path));

src/cargo/ops/registry.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -830,7 +830,7 @@ pub fn modify_owners(config: &Config, opts: &OwnersOptions) -> CargoResult<()> {
830830
let name = match opts.krate {
831831
Some(ref name) => name.clone(),
832832
None => {
833-
let manifest_path = find_root_manifest_for_wd(config.cwd())?;
833+
let manifest_path = find_root_manifest_for_wd(config)?;
834834
let ws = Workspace::new(&manifest_path, config)?;
835835
ws.current()?.package_id().name().to_string()
836836
}
@@ -905,7 +905,7 @@ pub fn yank(
905905
let name = match krate {
906906
Some(name) => name,
907907
None => {
908-
let manifest_path = find_root_manifest_for_wd(config.cwd())?;
908+
let manifest_path = find_root_manifest_for_wd(config)?;
909909
let ws = Workspace::new(&manifest_path, config)?;
910910
ws.current()?.package_id().name().to_string()
911911
}

src/cargo/util/command_prelude.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,7 @@ pub trait ArgMatchesExt {
344344
}
345345
return Ok(path);
346346
}
347-
find_root_manifest_for_wd(config.cwd())
347+
find_root_manifest_for_wd(config)
348348
}
349349

350350
fn workspace<'a>(&self, config: &'a Config) -> CargoResult<Workspace<'a>> {

src/cargo/util/important_paths.rs

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,21 @@
1-
use crate::util::errors::CargoResult;
1+
use crate::util::errors::{self, CargoResult};
2+
use crate::util::Config;
23
use cargo_util::paths;
4+
use std::collections::HashSet;
35
use std::path::{Path, PathBuf};
46

57
/// Finds the root `Cargo.toml`.
6-
pub fn find_root_manifest_for_wd(cwd: &Path) -> CargoResult<PathBuf> {
8+
pub fn find_root_manifest_for_wd(config: &Config) -> CargoResult<PathBuf> {
79
let valid_cargo_toml_file_name = "Cargo.toml";
810
let invalid_cargo_toml_file_name = "cargo.toml";
911
let mut invalid_cargo_toml_path_exists = false;
12+
let safe_directories = config.safe_directories()?;
13+
let cwd = config.cwd();
1014

1115
for current in paths::ancestors(cwd, None) {
1216
let manifest = current.join(valid_cargo_toml_file_name);
1317
if manifest.exists() {
18+
check_safe_manifest_path(config, &safe_directories, &manifest)?;
1419
return Ok(manifest);
1520
}
1621
if current.join(invalid_cargo_toml_file_name).exists() {
@@ -43,3 +48,23 @@ pub fn find_project_manifest_exact(pwd: &Path, file: &str) -> CargoResult<PathBu
4348
anyhow::bail!("Could not find `{}` in `{}`", file, pwd.display())
4449
}
4550
}
51+
52+
/// Checks whether or not the given manifest path is owned by a different user.
53+
pub fn check_safe_manifest_path(
54+
config: &Config,
55+
safe_directories: &HashSet<PathBuf>,
56+
path: &Path,
57+
) -> CargoResult<()> {
58+
if !config.safe_directories_enabled() {
59+
return Ok(());
60+
}
61+
paths::validate_ownership(path, safe_directories).map_err(|e| {
62+
match e.downcast_ref::<paths::OwnershipError>() {
63+
Some(e) => {
64+
let to_add = e.path.parent().unwrap();
65+
errors::ownership_error(e, "manifests", to_add, config)
66+
}
67+
None => e,
68+
}
69+
})
70+
}

0 commit comments

Comments
 (0)