Create new base directories with mode 0700

If base directories (e.g. $HOME/.config/fish) need to be created,
create them with mode 0700 (i.e. restricted to the owner).
This both keeps the behavior of old fish versions (e.g. 3.7.1) and is
compliant with the XDG Base Directory Specification.

See: https://specifications.freedesktop.org/basedir-spec/0.8/#referencing
This commit is contained in:
Joan Bruguera Micó 2024-12-28 12:05:58 +00:00 committed by Peter Ammon
parent f75912d205
commit c0a2b55efd
No known key found for this signature in database
2 changed files with 26 additions and 1 deletions

View file

@ -667,7 +667,7 @@ fn make_base_directory(xdg_var: &wstr, non_xdg_homepath: &wstr) -> BaseDirectory
let mut remoteness = DirRemoteness::unknown;
if path.is_empty() {
err = ENOENT;
} else if let Err(io_error) = std::fs::create_dir_all(wcs2osstring(&path)) {
} else if let Err(io_error) = create_dir_all_with_mode(wcs2osstring(&path), 0o700) {
err = io_error.raw_os_error().unwrap_or_default();
} else {
err = 0;
@ -685,6 +685,15 @@ fn make_base_directory(xdg_var: &wstr, non_xdg_homepath: &wstr) -> BaseDirectory
}
}
// Like std::fs::create_dir_all, but new directories are created using the given mode (e.g. 0o700).
fn create_dir_all_with_mode<P: AsRef<std::path::Path>>(path: P, mode: u32) -> std::io::Result<()> {
use std::os::unix::fs::DirBuilderExt;
std::fs::DirBuilder::new()
.recursive(true)
.mode(mode)
.create(path.as_ref())
}
/// Return whether the given path is on a remote filesystem.
fn path_remoteness(path: &wstr) -> DirRemoteness {
let narrow = wcs2zstring(path);

View file

@ -0,0 +1,16 @@
#RUN: %fish -C 'set -l fish %fish' %s
# Set a XDG_CONFIG_HOME with both pre-existing and non-existing directories.
set -l dir (mktemp -d)
mkdir -m 0755 $dir/old
set -gx XDG_CONFIG_HOME $dir/old/new
# Launch fish so it will create all missing directories.
$fish -c ''
# Check that existing directories kept their permissions, and new directories
# have the right permissions according to the XDG Base Directory Specification.
ls -ld $dir/old $dir/old/new $dir/old/new/fish | awk '{print $1}'
# CHECK: drwxr-xr-x
# CHECK: drwx------
# CHECK: drwx------