Browse Source

fix 'insecure world writable dir' error from gem

fixes #1158, hopefully.
when we create the multishell path, we will ensure only the owner can read and write to it.
remotes/origin/fix-insecure-world-writable-dir
Gal Schlezinger 8 months ago
parent
commit
52ef77c014
  1. 13
      src/commands/env.rs
  2. 34
      src/path_ext.rs

13
src/commands/env.rs

@ -35,7 +35,18 @@ fn generate_symlink_path() -> String { @@ -35,7 +35,18 @@ fn generate_symlink_path() -> String {
}
fn make_symlink(config: &FnmConfig) -> Result<std::path::PathBuf, Error> {
let base_dir = config.multishell_storage().ensure_exists_silently();
let base_dir = if cfg!(windows) {
config.multishell_storage().ensure_exists_silently()
} else {
config
.multishell_storage()
.ensure_exists_silently_with_permissions(|permissions| {
use std::os::unix::fs::PermissionsExt;
// r/w only for owner
permissions.set_mode(0o700);
})
};
let mut temp_dir = base_dir.join(generate_symlink_path());
while temp_dir.exists() {

34
src/path_ext.rs

@ -1,10 +1,19 @@ @@ -1,10 +1,19 @@
use log::warn;
use std::fs::Permissions;
pub trait PathExt {
fn exists(&self) -> bool;
fn ensure_exists_silently(self) -> Self;
fn ensure_exists_silently_with_permissions<F>(self, permissions: F) -> Self
where
F: FnOnce(&mut Permissions);
}
impl<T: AsRef<std::path::Path>> PathExt for T {
fn exists(&self) -> bool {
std::path::Path::exists(self.as_ref())
}
/// Ensures a path is existing by creating it recursively
/// if it is missing. No error is emitted if the creation has failed.
fn ensure_exists_silently(self) -> Self {
@ -13,4 +22,29 @@ impl<T: AsRef<std::path::Path>> PathExt for T { @@ -13,4 +22,29 @@ impl<T: AsRef<std::path::Path>> PathExt for T {
}
self
}
fn ensure_exists_silently_with_permissions<F>(self, modify_permissions: F) -> Self
where
F: FnOnce(&mut Permissions),
{
if self.exists() {
return self;
}
if let Err(err) = std::fs::create_dir_all(self.as_ref()) {
warn!("Failed to create directory {:?}: {err}", self.as_ref());
}
let modified = self.as_ref().metadata().and_then(|x| {
let mut permissions = x.permissions();
modify_permissions(&mut permissions);
std::fs::set_permissions(self.as_ref(), permissions)
});
if let Err(err) = modified {
warn!("Failed to set permissions {:?}: {err}", self.as_ref());
}
self
}
}

Loading…
Cancel
Save