//! Utilities for working with `/proc`, where Linux's `procfs` is typically
//! mounted.
//!
//! `/proc` serves as an adjunct to Linux's main syscall surface area,
//! providing additional features with an awkward interface.
//!
//! This module does a considerable amount of work to determine whether `/proc`
//! is mounted, with actual `procfs`, and without any additional mount points
//! on top of the paths we open.
//!
//! Why all the effort to detect bind mount points? People are doing all kinds
//! of things with Linux containers these days, with many different privilege
//! schemes, and we want to avoid making any unnecessary assumptions. Rustix
//! and its users will sometimes use procfs *implicitly* (when Linux gives them
//! no better options), in ways that aren't obvious from their public APIs.
//! These filesystem accesses might not be visible to someone auditing the main
//! code of an application for places which may be influenced by the filesystem
//! namespace. So with the checking here, they may fail, but they won't be able
//! to succeed with bogus results.

use crate::fd::{AsFd, BorrowedFd, OwnedFd};
use crate::ffi::CStr;
use crate::fs::{
    fstat, fstatfs, major, openat, renameat, seek, FileType, FsWord, Mode, OFlags, RawDir,
    SeekFrom, Stat, CWD, PROC_SUPER_MAGIC,
};
use crate::io;
use crate::path::DecInt;
#[cfg(feature = "rustc-dep-of-std")]
use core::lazy::OnceCell;
use core::mem::MaybeUninit;
#[cfg(not(feature = "rustc-dep-of-std"))]
use once_cell::sync::OnceCell;

/// Linux's procfs always uses inode 1 for its root directory.
const PROC_ROOT_INO: u64 = 1;

// Identify an entry within "/proc", to determine which anomalies to check for.
#[derive(Copy, Clone, Debug)]
enum Kind {
    Proc,
    Pid,
    Fd,
    File,
    Symlink,
}

/// Check a subdirectory of "/proc" for anomalies.
fn check_proc_entry(
    kind: Kind,
    entry: BorrowedFd<'_>,
    proc_stat: Option<&Stat>,
) -> io::Result<Stat> {
    let entry_stat = fstat(entry)?;
    check_proc_entry_with_stat(kind, entry, entry_stat, proc_stat)
}

/// Check a subdirectory of "/proc" for anomalies, using the provided `Stat`.
fn check_proc_entry_with_stat(
    kind: Kind,
    entry: BorrowedFd<'_>,
    entry_stat: Stat,
    proc_stat: Option<&Stat>,
) -> io::Result<Stat> {
    // Check the filesystem magic.
    check_procfs(entry)?;

    match kind {
        Kind::Proc => check_proc_root(entry, &entry_stat)?,
        Kind::Pid | Kind::Fd => check_proc_subdir(entry, &entry_stat, proc_stat)?,
        Kind::File => check_proc_file(&entry_stat, proc_stat)?,
        Kind::Symlink => check_proc_symlink(&entry_stat, proc_stat)?,
    }

    // "/proc" directories are typically mounted r-xr-xr-x.
    // "/proc/self/fd" is r-x------. Allow them to have fewer permissions, but
    // not more.
    match kind {
        Kind::Symlink => {
            // On Linux, symlinks don't have their own permissions.
        }
        _ => {
            let expected_mode = if let Kind::Fd = kind { 0o500 } else { 0o555 };
            if entry_stat.st_mode & 0o777 & !expected_mode != 0 {
                return Err(io::Errno::NOTSUP);
            }
        }
    }

    match kind {
        Kind::Fd => {
            // Check that the "/proc/self/fd" directory doesn't have any
            // extraneous links into it (which might include unexpected
            // subdirectories).
            if entry_stat.st_nlink != 2 {
                return Err(io::Errno::NOTSUP);
            }
        }
        Kind::Pid | Kind::Proc => {
            // Check that the "/proc" and "/proc/self" directories aren't
            // empty.
            if entry_stat.st_nlink <= 2 {
                return Err(io::Errno::NOTSUP);
            }
        }
        Kind::File => {
            // Check that files in procfs don't have extraneous hard links to
            // them (which might indicate hard links to other things).
            if entry_stat.st_nlink != 1 {
                return Err(io::Errno::NOTSUP);
            }
        }
        Kind::Symlink => {
            // Check that symlinks in procfs don't have extraneous hard links
            // to them (which might indicate hard links to other things).
            if entry_stat.st_nlink != 1 {
                return Err(io::Errno::NOTSUP);
            }
        }
    }

    Ok(entry_stat)
}

fn check_proc_root(entry: BorrowedFd<'_>, stat: &Stat) -> io::Result<()> {
    // We use `O_DIRECTORY` for proc directories, so open should fail if we
    // don't get a directory when we expect one.
    assert_eq!(FileType::from_raw_mode(stat.st_mode), FileType::Directory);

    // Check the root inode number.
    if stat.st_ino != PROC_ROOT_INO {
        return Err(io::Errno::NOTSUP);
    }

    // Proc is a non-device filesystem, so check for major number 0.
    // <https://www.kernel.org/doc/Documentation/admin-guide/devices.txt>
    if major(stat.st_dev) != 0 {
        return Err(io::Errno::NOTSUP);
    }

    // Check that "/proc" is a mountpoint.
    if !is_mountpoint(entry) {
        return Err(io::Errno::NOTSUP);
    }

    Ok(())
}

fn check_proc_subdir(
    entry: BorrowedFd<'_>,
    stat: &Stat,
    proc_stat: Option<&Stat>,
) -> io::Result<()> {
    // We use `O_DIRECTORY` for proc directories, so open should fail if we
    // don't get a directory when we expect one.
    assert_eq!(FileType::from_raw_mode(stat.st_mode), FileType::Directory);

    check_proc_nonroot(stat, proc_stat)?;

    // Check that subdirectories of "/proc" are not mount points.
    if is_mountpoint(entry) {
        return Err(io::Errno::NOTSUP);
    }

    Ok(())
}

fn check_proc_file(stat: &Stat, proc_stat: Option<&Stat>) -> io::Result<()> {
    // Check that we have a regular file.
    if FileType::from_raw_mode(stat.st_mode) != FileType::RegularFile {
        return Err(io::Errno::NOTSUP);
    }

    check_proc_nonroot(stat, proc_stat)?;

    Ok(())
}

fn check_proc_symlink(stat: &Stat, proc_stat: Option<&Stat>) -> io::Result<()> {
    // Check that we have a symbolic link.
    if FileType::from_raw_mode(stat.st_mode) != FileType::Symlink {
        return Err(io::Errno::NOTSUP);
    }

    check_proc_nonroot(stat, proc_stat)?;

    Ok(())
}

fn check_proc_nonroot(stat: &Stat, proc_stat: Option<&Stat>) -> io::Result<()> {
    // Check that we haven't been linked back to the root of "/proc".
    if stat.st_ino == PROC_ROOT_INO {
        return Err(io::Errno::NOTSUP);
    }

    // Check that we're still in procfs.
    if stat.st_dev != proc_stat.unwrap().st_dev {
        return Err(io::Errno::NOTSUP);
    }

    Ok(())
}

/// Check that `file` is opened on a `procfs` filesystem.
fn check_procfs(file: BorrowedFd<'_>) -> io::Result<()> {
    let statfs = fstatfs(file)?;
    let f_type = statfs.f_type;
    if f_type != FsWord::from(PROC_SUPER_MAGIC) {
        return Err(io::Errno::NOTSUP);
    }

    Ok(())
}

/// Check whether the given directory handle is a mount point.
fn is_mountpoint(file: BorrowedFd<'_>) -> bool {
    // We use a `renameat` call that would otherwise fail, but which fails with
    // `XDEV` first if it would cross a mount point.
    let err = renameat(file, cstr!("../."), file, cstr!(".")).unwrap_err();
    match err {
        io::Errno::XDEV => true,  // the rename failed due to crossing a mount point
        io::Errno::BUSY => false, // the rename failed normally
        _ => panic!("Unexpected error from `renameat`: {:?}", err),
    }
}

/// Open a directory in `/proc`, mapping all errors to `io::Errno::NOTSUP`.
fn proc_opendirat<P: crate::path::Arg, Fd: AsFd>(dirfd: Fd, path: P) -> io::Result<OwnedFd> {
    // We don't add `PATH` here because that disables `DIRECTORY`. And we don't
    // add `NOATIME` for the same reason as the comment in `open_and_check_file`.
    let oflags = OFlags::NOFOLLOW | OFlags::DIRECTORY | OFlags::CLOEXEC | OFlags::NOCTTY;
    openat(dirfd, path, oflags, Mode::empty()).map_err(|_err| io::Errno::NOTSUP)
}

/// Returns a handle to Linux's `/proc` directory.
///
/// This ensures that `/proc` is procfs, that nothing is mounted on top of it,
/// and that it looks normal. It also returns the `Stat` of `/proc`.
///
/// # References
///  - [Linux]
///
/// [Linux]: https://man7.org/linux/man-pages/man5/proc.5.html
fn proc() -> io::Result<(BorrowedFd<'static>, &'static Stat)> {
    static PROC: StaticFd = StaticFd::new();

    // `OnceBox` is "racey" in that the initialization function may run
    // multiple times. We're ok with that, since the initialization function
    // has no side effects.
    PROC.get_or_try_init(|| {
        // Open "/proc".
        let proc = proc_opendirat(CWD, cstr!("/proc"))?;
        let proc_stat =
            check_proc_entry(Kind::Proc, proc.as_fd(), None).map_err(|_err| io::Errno::NOTSUP)?;

        Ok(new_static_fd(proc, proc_stat))
    })
    .map(|(fd, stat)| (fd.as_fd(), stat))
}

/// Returns a handle to Linux's `/proc/self` directory.
///
/// This ensures that `/proc/self` is procfs, that nothing is mounted on top of
/// it, and that it looks normal. It also returns the `Stat` of `/proc/self`.
///
/// # References
///  - [Linux]
///
/// [Linux]: https://man7.org/linux/man-pages/man5/proc.5.html
#[allow(unsafe_code)]
fn proc_self() -> io::Result<(BorrowedFd<'static>, &'static Stat)> {
    static PROC_SELF: StaticFd = StaticFd::new();

    // The init function here may run multiple times; see above.
    PROC_SELF
        .get_or_try_init(|| {
            let (proc, proc_stat) = proc()?;

            // `getpid` would return our pid in our own pid namespace, so
            // instead use `readlink` on the `self` symlink to learn our pid in
            // the procfs namespace.
            let self_symlink = open_and_check_file(proc, proc_stat, cstr!("self"), Kind::Symlink)?;
            let mut buf = [MaybeUninit::<u8>::uninit(); 20];
            let len = crate::backend::fs::syscalls::readlinkat(
                self_symlink.as_fd(),
                cstr!(""),
                &mut buf,
            )?;
            let pid: &[u8] = unsafe { core::mem::transmute(&buf[..len]) };

            // Open "/proc/self". Use our pid to compute the name rather than
            // literally using "self", as "self" is a symlink.
            let proc_self = proc_opendirat(proc, pid)?;
            let proc_self_stat = check_proc_entry(Kind::Pid, proc_self.as_fd(), Some(proc_stat))
                .map_err(|_err| io::Errno::NOTSUP)?;

            Ok(new_static_fd(proc_self, proc_self_stat))
        })
        .map(|(owned, stat)| (owned.as_fd(), stat))
}

/// Returns a handle to Linux's `/proc/self/fd` directory.
///
/// This ensures that `/proc/self/fd` is `procfs`, that nothing is mounted on
/// top of it, and that it looks normal.
///
/// # References
///  - [Linux]
///
/// [Linux]: https://man7.org/linux/man-pages/man5/proc.5.html
#[cfg_attr(doc_cfg, doc(cfg(feature = "procfs")))]
pub fn proc_self_fd() -> io::Result<BorrowedFd<'static>> {
    static PROC_SELF_FD: StaticFd = StaticFd::new();

    // The init function here may run multiple times; see above.
    PROC_SELF_FD
        .get_or_try_init(|| {
            let (_, proc_stat) = proc()?;

            let (proc_self, _proc_self_stat) = proc_self()?;

            // Open "/proc/self/fd".
            let proc_self_fd = proc_opendirat(proc_self, cstr!("fd"))?;
            let proc_self_fd_stat =
                check_proc_entry(Kind::Fd, proc_self_fd.as_fd(), Some(proc_stat))
                    .map_err(|_err| io::Errno::NOTSUP)?;

            Ok(new_static_fd(proc_self_fd, proc_self_fd_stat))
        })
        .map(|(owned, _stat)| owned.as_fd())
}

type StaticFd = OnceCell<(OwnedFd, Stat)>;

#[inline]
fn new_static_fd(fd: OwnedFd, stat: Stat) -> (OwnedFd, Stat) {
    (fd, stat)
}

/// Returns a handle to Linux's `/proc/self/fdinfo` directory.
///
/// This ensures that `/proc/self/fdinfo` is `procfs`, that nothing is mounted
/// on top of it, and that it looks normal. It also returns the `Stat` of
/// `/proc/self/fd`.
///
/// # References
///  - [Linux]
///
/// [Linux]: https://man7.org/linux/man-pages/man5/proc.5.html
fn proc_self_fdinfo() -> io::Result<(BorrowedFd<'static>, &'static Stat)> {
    static PROC_SELF_FDINFO: StaticFd = StaticFd::new();

    PROC_SELF_FDINFO
        .get_or_try_init(|| {
            let (_, proc_stat) = proc()?;

            let (proc_self, _proc_self_stat) = proc_self()?;

            // Open "/proc/self/fdinfo".
            let proc_self_fdinfo = proc_opendirat(proc_self, cstr!("fdinfo"))?;
            let proc_self_fdinfo_stat =
                check_proc_entry(Kind::Fd, proc_self_fdinfo.as_fd(), Some(proc_stat))
                    .map_err(|_err| io::Errno::NOTSUP)?;

            Ok((proc_self_fdinfo, proc_self_fdinfo_stat))
        })
        .map(|(owned, stat)| (owned.as_fd(), stat))
}

/// Returns a handle to a Linux `/proc/self/fdinfo/<fd>` file.
///
/// This ensures that `/proc/self/fdinfo/<fd>` is `procfs`, that nothing is
/// mounted on top of it, and that it looks normal.
///
/// # References
///  - [Linux]
///
/// [Linux]: https://man7.org/linux/man-pages/man5/proc.5.html
#[inline]
#[cfg_attr(doc_cfg, doc(cfg(feature = "procfs")))]
pub fn proc_self_fdinfo_fd<Fd: AsFd>(fd: Fd) -> io::Result<OwnedFd> {
    _proc_self_fdinfo(fd.as_fd())
}

fn _proc_self_fdinfo(fd: BorrowedFd<'_>) -> io::Result<OwnedFd> {
    let (proc_self_fdinfo, proc_self_fdinfo_stat) = proc_self_fdinfo()?;
    let fd_str = DecInt::from_fd(fd);
    open_and_check_file(
        proc_self_fdinfo,
        proc_self_fdinfo_stat,
        fd_str.as_c_str(),
        Kind::File,
    )
}

/// Returns a handle to a Linux `/proc/self/pagemap` file.
///
/// This ensures that `/proc/self/pagemap` is `procfs`, that nothing is
/// mounted on top of it, and that it looks normal.
///
/// # References
///  - [Linux]
///  - [Linux pagemap]
///
/// [Linux]: https://man7.org/linux/man-pages/man5/proc.5.html
/// [Linux pagemap]: https://www.kernel.org/doc/Documentation/vm/pagemap.txt
#[inline]
#[cfg_attr(doc_cfg, doc(cfg(feature = "procfs")))]
pub fn proc_self_pagemap() -> io::Result<OwnedFd> {
    proc_self_file(cstr!("pagemap"))
}

/// Returns a handle to a Linux `/proc/self/maps` file.
///
/// This ensures that `/proc/self/maps` is `procfs`, that nothing is
/// mounted on top of it, and that it looks normal.
///
/// # References
///  - [Linux]
///
/// [Linux]: https://man7.org/linux/man-pages/man5/proc.5.html
#[inline]
#[cfg_attr(doc_cfg, doc(cfg(feature = "procfs")))]
pub fn proc_self_maps() -> io::Result<OwnedFd> {
    proc_self_file(cstr!("maps"))
}

/// Returns a handle to a Linux `/proc/self/status` file.
///
/// This ensures that `/proc/self/status` is `procfs`, that nothing is
/// mounted on top of it, and that it looks normal.
///
/// # References
///  - [Linux]
///
/// [Linux]: https://man7.org/linux/man-pages/man5/proc.5.html
#[inline]
#[cfg_attr(doc_cfg, doc(cfg(feature = "procfs")))]
pub fn proc_self_status() -> io::Result<OwnedFd> {
    proc_self_file(cstr!("status"))
}

/// Open a file under `/proc/self`.
fn proc_self_file(name: &CStr) -> io::Result<OwnedFd> {
    let (proc_self, proc_self_stat) = proc_self()?;
    open_and_check_file(proc_self, proc_self_stat, name, Kind::File)
}

/// Open a procfs file within in `dir` and check it for bind mounts.
fn open_and_check_file(
    dir: BorrowedFd<'_>,
    dir_stat: &Stat,
    name: &CStr,
    kind: Kind,
) -> io::Result<OwnedFd> {
    let (_, proc_stat) = proc()?;

    // Don't use `NOATIME`, because it [requires us to own the file], and when
    // a process sets itself non-dumpable Linux changes the user:group of its
    // `/proc/<pid>` files [to root:root].
    //
    // [requires us to own the file]: https://man7.org/linux/man-pages/man2/openat.2.html
    // [to root:root]: https://man7.org/linux/man-pages/man5/proc.5.html
    let mut oflags = OFlags::RDONLY | OFlags::CLOEXEC | OFlags::NOFOLLOW | OFlags::NOCTTY;
    if let Kind::Symlink = kind {
        // Open symlinks with `O_PATH`.
        oflags |= OFlags::PATH;
    }
    let file = openat(dir, name, oflags, Mode::empty()).map_err(|_err| io::Errno::NOTSUP)?;
    let file_stat = fstat(&file)?;

    // `is_mountpoint` only works on directory mount points, not file mount
    // points. To detect file mount points, scan the parent directory to see if
    // we can find a regular file with an inode and name that matches the file
    // we just opened. If we can't find it, there could be a file bind mount on
    // top of the file we want.
    //
    // TODO: With Linux 5.8 we might be able to use `statx` and
    // `STATX_ATTR_MOUNT_ROOT` to detect mountpoints directly instead of doing
    // this scanning.

    let expected_type = match kind {
        Kind::File => FileType::RegularFile,
        Kind::Symlink => FileType::Symlink,
        _ => unreachable!(),
    };

    let mut found_file = false;
    let mut found_dot = false;

    // Position the directory iteration at the start.
    seek(dir, SeekFrom::Start(0))?;

    let mut buf = [MaybeUninit::uninit(); 2048];
    let mut iter = RawDir::new(dir, &mut buf);
    while let Some(entry) = iter.next() {
        let entry = entry.map_err(|_err| io::Errno::NOTSUP)?;
        if entry.ino() == file_stat.st_ino
            && entry.file_type() == expected_type
            && entry.file_name() == name
        {
            // We found the file. Proceed to check the file handle.
            let _ = check_proc_entry_with_stat(kind, file.as_fd(), file_stat, Some(proc_stat))?;

            found_file = true;
        } else if entry.ino() == dir_stat.st_ino
            && entry.file_type() == FileType::Directory
            && entry.file_name() == cstr!(".")
        {
            // We found ".", and it's the right ".".
            found_dot = true;
        }
    }

    if found_file && found_dot {
        Ok(file)
    } else {
        Err(io::Errno::NOTSUP)
    }
}
