Sha256: 07f77d7fdd8494e3a0dbf05767b69e45e9405234114bf533c453caedfeba2e43

Contents?: true

Size: 1.81 KB

Versions: 27

Compression:

Stored size: 1.81 KB

Contents

use crate::fs::{open, OpenOptions, Permissions};
use rustix::fs::{fchmod, Mode};
use rustix::io::Errno;
#[cfg(unix)]
use std::os::unix::fs::PermissionsExt;
use std::path::Path;
use std::{fs, io};

/// This sounds like it should be a job for `fchmodat`, however `fchmodat`
/// handles symlinks in an incompatible way. It either follows symlinks
/// without guaranteeing to stay in the sandbox, or with `AT_SYMLINK_NOFOLLOW`
/// it attempts to change the permissions of symlinks themselves. What we'd
/// need is for it to fail if it encounters a symlink, like `O_NOFOLLOW` does.
pub(crate) fn set_permissions_impl(
    start: &fs::File,
    path: &Path,
    perm: Permissions,
) -> io::Result<()> {
    let std_perm = perm.into_std(start)?;

    // Try `fchmod` with a normal handle. Normal handles need some kind of
    // access, so first try read.
    match open(start, path, OpenOptions::new().read(true)) {
        Ok(file) => return set_file_permissions(&file, std_perm),
        Err(err) => match Errno::from_io_error(&err) {
            Some(Errno::ACCESS) => (),
            _ => return Err(err),
        },
    }

    // Next try write.
    match open(start, path, OpenOptions::new().write(true)) {
        Ok(file) => return set_file_permissions(&file, std_perm),
        Err(err) => match Errno::from_io_error(&err) {
            Some(Errno::ACCESS) | Some(Errno::ISDIR) => (),
            _ => return Err(err),
        },
    }

    // If neither of those worked, we're out of luck.
    Err(Errno::NOTSUP.into())
}

pub(crate) fn set_file_permissions(file: &fs::File, perm: fs::Permissions) -> io::Result<()> {
    // Use `from_bits_truncate` for compatibility with std, which allows
    // non-permission bits to propagate through.
    let mode = Mode::from_bits_truncate(perm.mode().try_into().unwrap());
    Ok(fchmod(file, mode)?)
}

Version data entries

27 entries across 27 versions & 1 rubygems

Version Path
wasmtime-30.0.2 ./ext/cargo-vendor/cap-primitives-3.4.2/src/rustix/fs/set_permissions_impl.rs
wasmtime-29.0.0 ./ext/cargo-vendor/cap-primitives-3.4.2/src/rustix/fs/set_permissions_impl.rs
wasmtime-28.0.0 ./ext/cargo-vendor/cap-primitives-3.4.2/src/rustix/fs/set_permissions_impl.rs
wasmtime-27.0.0 ./ext/cargo-vendor/cap-primitives-3.4.1/src/rustix/fs/set_permissions_impl.rs
wasmtime-26.0.0 ./ext/cargo-vendor/cap-primitives-3.3.0/src/rustix/fs/set_permissions_impl.rs
wasmtime-25.0.2 ./ext/cargo-vendor/cap-primitives-3.2.0/src/rustix/fs/set_permissions_impl.rs
wasmtime-25.0.1 ./ext/cargo-vendor/cap-primitives-3.2.0/src/rustix/fs/set_permissions_impl.rs
wasmtime-25.0.0 ./ext/cargo-vendor/cap-primitives-3.2.0/src/rustix/fs/set_permissions_impl.rs
wasmtime-24.0.0 ./ext/cargo-vendor/cap-primitives-3.2.0/src/rustix/fs/set_permissions_impl.rs
wasmtime-23.0.2 ./ext/cargo-vendor/cap-primitives-3.1.0/src/rustix/fs/set_permissions_impl.rs
wasmtime-22.0.0 ./ext/cargo-vendor/cap-primitives-3.1.0/src/rustix/fs/set_permissions_impl.rs
wasmtime-21.0.1 ./ext/cargo-vendor/cap-primitives-3.1.0/src/rustix/fs/set_permissions_impl.rs
wasmtime-20.0.2 ./ext/cargo-vendor/cap-primitives-3.1.0/src/rustix/fs/set_permissions_impl.rs
wasmtime-20.0.0 ./ext/cargo-vendor/cap-primitives-3.0.0/src/rustix/fs/set_permissions_impl.rs
wasmtime-18.0.3 ./ext/cargo-vendor/cap-primitives-2.0.1/src/rustix/fs/set_permissions_impl.rs
wasmtime-17.0.1 ./ext/cargo-vendor/cap-primitives-2.0.1/src/rustix/fs/set_permissions_impl.rs
wasmtime-17.0.0 ./ext/cargo-vendor/cap-primitives-2.0.1/src/rustix/fs/set_permissions_impl.rs
wasmtime-16.0.0 ./ext/cargo-vendor/cap-primitives-2.0.1/src/rustix/fs/set_permissions_impl.rs
wasmtime-15.0.1 ./ext/cargo-vendor/cap-primitives-2.0.1/src/rustix/fs/set_permissions_impl.rs
wasmtime-15.0.0 ./ext/cargo-vendor/cap-primitives-2.0.1/src/rustix/fs/set_permissions_impl.rs