Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Set permissions on log directory #5398

Merged
merged 1 commit into from
Nov 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions mullvad-nsis/include/mullvad-nsis.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,6 @@ extern "C" {
/// the final null terminator.
Status get_system_local_appdata(uint16_t *buffer, uintptr_t *buffer_size);

Status create_privileged_directory(const uint16_t* path);

} // extern "C"
39 changes: 37 additions & 2 deletions mullvad-nsis/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
#![cfg(all(target_arch = "x86", target_os = "windows"))]

use std::{os::windows::ffi::OsStrExt, panic::UnwindSafe, ptr};
use std::{
ffi::OsString,
os::windows::ffi::{OsStrExt, OsStringExt},
panic::UnwindSafe,
path::Path,
ptr,
};

#[repr(C)]
pub enum Status {
Expand All @@ -11,6 +17,35 @@ pub enum Status {
Panic,
}

/// Max path size allowed
const MAX_PATH_SIZE: isize = 32_767;

/// SAFETY: path needs to be a windows path encoded as a string of u16 that terminates in 0 (two nul-bytes).
/// The string is also not allowed to be greater than `MAX_PATH_SIZE`.
#[no_mangle]
pub unsafe extern "C" fn create_privileged_directory(path: *const u16) -> Status {
catch_and_log_unwind(|| {
let mut i = 0;
// Calculate the length of the path by checking when the first u16 == 0
let len = loop {
if *(path.offset(i)) == 0 {
break i;
} else if i >= MAX_PATH_SIZE {
return Status::InvalidArguments;
}
i += 1;
};
let path = std::slice::from_raw_parts(path, len as usize);
let path = OsString::from_wide(path);
let path = Path::new(&path);

match mullvad_paths::windows::create_privileged_directory(path) {
Ok(()) => Status::Ok,
Err(_) => Status::OsError,
}
})
}

/// Writes the system's app data path into `buffer` when `Status::Ok` is returned.
/// If `buffer` is `null`, or if the buffer is too small, `InsufficientBufferSize`
/// is returned, and the required buffer size (in chars) is returned in `buffer_size`.
Expand Down Expand Up @@ -53,6 +88,6 @@ pub unsafe extern "C" fn get_system_local_appdata(
fn catch_and_log_unwind(func: impl FnOnce() -> Status + UnwindSafe) -> Status {
match std::panic::catch_unwind(func) {
Ok(status) => status,
Err(_error) => Status::Panic,
Err(_) => Status::Panic,
}
}
2 changes: 2 additions & 0 deletions mullvad-paths/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,12 @@ workspace = true
features = [
"Win32_Foundation",
"Win32_Security",
"Win32_Security_Authorization",
"Win32_Storage_FileSystem",
"Win32_System_Com",
"Win32_System_ProcessStatus",
"Win32_System_SystemServices",
"Win32_System_Threading",
"Win32_UI_Shell",
"Win32_System_Memory",
]
4 changes: 3 additions & 1 deletion mullvad-paths/src/cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ use std::{env, path::PathBuf};
/// Creates and returns the cache directory pointed to by `MULLVAD_CACHE_DIR`, or the default
/// one if that variable is unset.
pub fn cache_dir() -> Result<PathBuf> {
#[cfg(not(target_os = "macos"))]
#[cfg(not(any(target_os = "macos", target_os = "windows")))]
let permissions = None;
#[cfg(target_os = "macos")]
let permissions = Some(std::os::unix::fs::PermissionsExt::from_mode(0o755));
#[cfg(target_os = "windows")]
let permissions = true;
crate::create_and_return(get_cache_dir, permissions)
}

Expand Down
22 changes: 21 additions & 1 deletion mullvad-paths/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
#![deny(rust_2018_idioms)]

use std::{fs, io, path::PathBuf};
#[cfg(not(target_os = "windows"))]
use std::fs;
use std::{io, path::PathBuf};

#[cfg(windows)]
use crate::windows::create_dir_recursive;

pub type Result<T> = std::result::Result<T, Error>;

Expand All @@ -20,6 +25,10 @@ pub enum Error {
#[error(display = "Missing %ALLUSERSPROFILE% environment variable")]
NoProgramDataDir,

#[cfg(windows)]
#[error(display = "Failed to create security attributes")]
GetSecurityAttributes(#[error(source)] io::Error),

#[cfg(all(windows, feature = "deduce-system-service"))]
#[error(display = "Failed to deduce system service directory")]
FailedToFindSystemServiceDir(#[error(source)] io::Error),
Expand All @@ -42,6 +51,7 @@ fn get_allusersprofile_dir() -> Result<PathBuf> {
}
}

#[cfg(not(target_os = "windows"))]
fn create_and_return(
dir_fn: fn() -> Result<PathBuf>,
permissions: Option<fs::Permissions>,
Expand All @@ -55,6 +65,16 @@ fn create_and_return(
Ok(dir)
}

#[cfg(windows)]
fn create_and_return(
dir_fn: fn() -> Result<PathBuf>,
set_security_permissions: bool,
) -> Result<PathBuf> {
let dir = dir_fn()?;
create_dir_recursive(&dir, set_security_permissions)?;
Ok(dir)
}

mod cache;
pub use crate::cache::{cache_dir, get_cache_dir, get_default_cache_dir};

Expand Down
12 changes: 8 additions & 4 deletions mullvad-paths/src/logs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,14 @@ use std::{env, path::PathBuf};
/// one if that variable is unset.
pub fn log_dir() -> Result<PathBuf> {
#[cfg(unix)]
let permissions = Some(PermissionsExt::from_mode(0o755));
#[cfg(not(unix))]
let permissions = None;
crate::create_and_return(get_log_dir, permissions)
{
let permissions = Some(PermissionsExt::from_mode(0o755));
crate::create_and_return(get_log_dir, permissions)
}
#[cfg(target_os = "windows")]
{
crate::create_and_return(get_log_dir, true)
}
}

/// Get the logging directory, but don't try to create it.
Expand Down
10 changes: 9 additions & 1 deletion mullvad-paths/src/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,15 @@ use std::{env, path::PathBuf};
/// Creates and returns the settings directory pointed to by `MULLVAD_SETTINGS_DIR`, or the default
/// one if that variable is unset.
pub fn settings_dir() -> Result<PathBuf> {
crate::create_and_return(get_settings_dir, None)
#[cfg(not(target_os = "windows"))]
{
crate::create_and_return(get_settings_dir, None)
}

#[cfg(target_os = "windows")]
{
crate::create_and_return(get_settings_dir, false)
}
}

fn get_settings_dir() -> Result<PathBuf> {
Expand Down
Loading
Loading