about summary refs log tree commit diff
diff options
context:
space:
mode:
authoronur-ozkan <work@onurozkan.dev>2023-09-25 01:55:12 +0300
committeronur-ozkan <work@onurozkan.dev>2023-09-25 01:59:51 +0300
commit350ead872058a8be5fc45d27dad59f3bd7e00b6f (patch)
tree0232c567b01ec13d6fa51f59b521efa3938ef9ff
parentbf982631df866498a295528ff0047207e881d55d (diff)
downloadrust-350ead872058a8be5fc45d27dad59f3bd7e00b6f.tar.gz
rust-350ead872058a8be5fc45d27dad59f3bd7e00b6f.zip
add sanity checks for user write access on `x install`
Signed-off-by: onur-ozkan <work@onurozkan.dev>
-rw-r--r--src/bootstrap/install.rs31
1 files changed, 31 insertions, 0 deletions
diff --git a/src/bootstrap/install.rs b/src/bootstrap/install.rs
index b62aa999246..85cd8abb995 100644
--- a/src/bootstrap/install.rs
+++ b/src/bootstrap/install.rs
@@ -45,6 +45,23 @@ fn sanitize_sh(path: &Path) -> String {
     }
 }
 
+fn is_dir_writable_for_user(dir: &PathBuf) -> bool {
+    let tmp_file = dir.join(".tmp");
+    match fs::File::create(&tmp_file) {
+        Ok(_) => {
+            fs::remove_file(tmp_file).unwrap();
+            true
+        }
+        Err(e) => {
+            if e.kind() == std::io::ErrorKind::PermissionDenied {
+                false
+            } else {
+                panic!("Failed the write access check for the current user. {}", e);
+            }
+        }
+    }
+}
+
 fn install_sh(
     builder: &Builder<'_>,
     package: &str,
@@ -56,6 +73,17 @@ fn install_sh(
 
     let prefix = default_path(&builder.config.prefix, "/usr/local");
     let sysconfdir = prefix.join(default_path(&builder.config.sysconfdir, "/etc"));
+
+    // Sanity check for the user write access on prefix and sysconfdir
+    assert!(
+        is_dir_writable_for_user(&prefix),
+        "User doesn't have write access on `install.prefix` path in the `config.toml`.",
+    );
+    assert!(
+        is_dir_writable_for_user(&sysconfdir),
+        "User doesn't have write access on `install.sysconfdir` path in `config.toml`."
+    );
+
     let datadir = prefix.join(default_path(&builder.config.datadir, "share"));
     let docdir = prefix.join(default_path(&builder.config.docdir, "share/doc/rust"));
     let mandir = prefix.join(default_path(&builder.config.mandir, "share/man"));
@@ -92,6 +120,9 @@ fn prepare_dir(mut path: PathBuf) -> String {
     // More information on the environment variable is available here:
     // https://www.gnu.org/prep/standards/html_node/DESTDIR.html
     if let Some(destdir) = env::var_os("DESTDIR").map(PathBuf::from) {
+        // Sanity check for the user write access on DESTDIR
+        assert!(is_dir_writable_for_user(&destdir), "User doesn't have write access on DESTDIR.");
+
         let without_destdir = path.clone();
         path = destdir;
         // Custom .join() which ignores disk roots.