From 52ef77c01469532dec059cc7d93af06882bbacd9 Mon Sep 17 00:00:00 2001 From: Gal Schlezinger Date: Sun, 2 Jun 2024 13:39:12 +0300 Subject: [PATCH] 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. --- src/commands/env.rs | 13 ++++++++++++- src/path_ext.rs | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/src/commands/env.rs b/src/commands/env.rs index e234660..a5652a7 100644 --- a/src/commands/env.rs +++ b/src/commands/env.rs @@ -35,7 +35,18 @@ fn generate_symlink_path() -> String { } fn make_symlink(config: &FnmConfig) -> Result { - 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() { diff --git a/src/path_ext.rs b/src/path_ext.rs index d87df44..67de47c 100644 --- a/src/path_ext.rs +++ b/src/path_ext.rs @@ -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(self, permissions: F) -> Self + where + F: FnOnce(&mut Permissions); } impl> 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> PathExt for T { } self } + + fn ensure_exists_silently_with_permissions(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 + } }