From bf5667f21c8f983dcd04b1d1f477f00dc606a660 Mon Sep 17 00:00:00 2001 From: Lucas Fernandes Nogueira Date: Wed, 17 Nov 2021 14:38:10 -0300 Subject: [PATCH] fix(core): resolve symbolic links on `current_exe` calls [TRI-048] (#33) --- core/tauri-utils/src/lib.rs | 1 + core/tauri-utils/src/platform.rs | 14 +++++++++++++- core/tauri/src/api/process.rs | 9 +-------- core/tauri/src/api/process/command.rs | 4 ++-- core/tauri/src/updater/core.rs | 8 +++++--- 5 files changed, 22 insertions(+), 14 deletions(-) diff --git a/core/tauri-utils/src/lib.rs b/core/tauri-utils/src/lib.rs index 17314f535..19c72497e 100644 --- a/core/tauri-utils/src/lib.rs +++ b/core/tauri-utils/src/lib.rs @@ -64,6 +64,7 @@ impl Default for Env { // validate that we're actually running on an AppImage // an AppImage is mounted to `/tmp/.mount_${appPrefix}${hash}` // see https://github.com/AppImage/AppImageKit/blob/1681fd84dbe09c7d9b22e13cdb16ea601aa0ec47/src/runtime.c#L501 + // note that it is safe to use `std::env::current_exe` here since we just loaded an AppImage. if !std::env::current_exe() .map(|p| p.to_string_lossy().into_owned().starts_with("/tmp/.mount_")) .unwrap_or(true) diff --git a/core/tauri-utils/src/platform.rs b/core/tauri-utils/src/platform.rs index f6375518e..217271d76 100644 --- a/core/tauri-utils/src/platform.rs +++ b/core/tauri-utils/src/platform.rs @@ -8,6 +8,18 @@ use std::path::{PathBuf, MAIN_SEPARATOR}; use crate::{Env, PackageInfo}; +/// Gets the path to the current executable, resolving symbolic links for security reasons. +/// +/// See https://doc.rust-lang.org/std/env/fn.current_exe.html#security for +/// an example of what to be careful of when using `current_exe` output. +/// +/// We canonicalize the path we received from `current_exe` to resolve any +/// soft links. it avoids the usual issue of needing the file to exist at +/// the passed path because a valid `current_exe` result should always exist. +pub fn current_exe() -> std::io::Result { + std::env::current_exe().and_then(|path| path.canonicalize()) +} + /// Try to determine the current target triple. /// /// Returns a target triple (e.g. `x86_64-unknown-linux-gnu` or `i686-pc-windows-msvc`) or an @@ -75,7 +87,7 @@ pub fn target_triple() -> crate::Result { /// On MacOS, it's `${exe_dir}../Resources` (inside .app). #[allow(unused_variables)] pub fn resource_dir(package_info: &PackageInfo, env: &Env) -> crate::Result { - let exe = std::env::current_exe()?; + let exe = current_exe()?; let exe_dir = exe.parent().expect("failed to get exe directory"); let curr_dir = exe_dir.display().to_string(); diff --git a/core/tauri/src/api/process.rs b/core/tauri/src/api/process.rs index e650fae9b..575ee9b4c 100644 --- a/core/tauri/src/api/process.rs +++ b/core/tauri/src/api/process.rs @@ -84,14 +84,7 @@ pub fn current_binary(env: &Env) -> Option { return Some(PathBuf::from(app_image_path)); } - // see https://doc.rust-lang.org/std/env/fn.current_exe.html#security for - // an example of what to be careful of when using `current_exe` output. - std::env::current_exe() - .ok() - // we canonicalize the path we received from `current_exe` to resolve any - // soft links. it avoids the usual issue of needing the file to exist at - // the passed path because a valid `current_exe` result should always exist - .and_then(|path| path.canonicalize().ok()) + tauri_utils::platform::current_exe().ok() } /// Restarts the process. diff --git a/core/tauri/src/api/process/command.rs b/core/tauri/src/api/process/command.rs index 094003e43..ea9450d55 100644 --- a/core/tauri/src/api/process/command.rs +++ b/core/tauri/src/api/process/command.rs @@ -152,7 +152,7 @@ pub struct Output { #[cfg(not(windows))] fn relative_command_path(command: String) -> crate::Result { - match std::env::current_exe()?.parent() { + match platform::current_exe()?.parent() { Some(exe_dir) => Ok(format!("{}/{}", exe_dir.to_string_lossy(), command)), None => Err(crate::api::Error::Command("Could not evaluate executable dir".to_string()).into()), } @@ -160,7 +160,7 @@ fn relative_command_path(command: String) -> crate::Result { #[cfg(windows)] fn relative_command_path(command: String) -> crate::Result { - match std::env::current_exe()?.parent() { + match platform::current_exe()?.parent() { Some(exe_dir) => Ok(format!("{}/{}.exe", exe_dir.to_string_lossy(), command)), None => Err(crate::api::Error::Command("Could not evaluate executable dir".to_string()).into()), } diff --git a/core/tauri/src/updater/core.rs b/core/tauri/src/updater/core.rs index 16fb310b6..68c95f63b 100644 --- a/core/tauri/src/updater/core.rs +++ b/core/tauri/src/updater/core.rs @@ -10,6 +10,8 @@ use crate::{ use base64::decode; use http::StatusCode; use minisign_verify::{PublicKey, Signature}; +use tauri_utils::platform::current_exe; + use std::{ collections::HashMap, env, @@ -255,7 +257,7 @@ impl<'a> UpdateBuilder<'a> { } else { // we expect it to fail if we can't find the executable path // without this path we can't continue the update process. - env::current_exe()? + current_exe()? }; // Did the target is provided by the config? @@ -434,7 +436,7 @@ impl Update { .to_string(); // get the current app name - let bin_name = std::env::current_exe() + let bin_name = current_exe() .ok() .and_then(|pb| pb.file_name().map(|s| s.to_os_string())) .and_then(|s| s.into_string().ok()) @@ -585,7 +587,7 @@ fn copy_files_and_run( exit(0); } else if found_path.extension() == Some(OsStr::new("msi")) { if with_elevated_task { - if let Some(bin_name) = std::env::current_exe() + if let Some(bin_name) = current_exe() .ok() .and_then(|pb| pb.file_name().map(|s| s.to_os_string())) .and_then(|s| s.into_string().ok())