Add more documentation for chroot, including an example and a manpage link - #163180
joshtriplett wants to merge 1 commit into
Conversation
|
r? @JohnTitor rustbot has assigned @JohnTitor. Use Why was this reviewer chosen?The reviewer was selected based on:
|
|
The job Click to see the possible cause of the failure (guessed by this bot) |
| /// Set the root of the child process. This calls `chroot` in the child process before executing | ||
| /// the command. | ||
| /// | ||
| /// This happens before changing to the directory specified with | ||
| /// [`process::Command::current_dir`], and that directory will be relative to the new root. | ||
| /// | ||
| /// If no directory has been specified with [`process::Command::current_dir`], this will set the | ||
| /// directory to `/`, to avoid leaving the current directory outside the chroot. (This is an | ||
| /// intentional difference from the underlying `chroot` system call.) | ||
| /// | ||
| /// This typically requires privileges, such as root or a specific capability. | ||
| /// | ||
| /// Note that according to the POSIX standard, `chroot` is not required to be async-signal-safe, | ||
| /// and functions called between `fork` and `exec` must be async-signal-safe. However, in | ||
| /// practice, the ability to `fork` then `chroot` then `exec` is a capability widely provided by | ||
| /// Rust targets and relied upon by numerous programs. | ||
| /// | ||
| /// See the [`chroot`] manual page for more details. | ||
| /// | ||
| /// [`chroot`]: https://man7.org/linux/man-pages/man2/chroot.2.html | ||
| /// | ||
| /// # Examples | ||
| /// | ||
| #[cfg_attr(target_family = "unix", doc = "```no_run")] | ||
| #[cfg_attr(not(target_family = "unix"), doc = "```ignore (needs unix)")] | ||
| /// use std::process::Command; | ||
| /// use std::os::unix::process::CommandExt; | ||
| /// | ||
| /// Command::new("contained") | ||
| /// .chroot("/sandbox") | ||
| /// .spawn()? | ||
| /// .wait()?; | ||
| #[doc = "```"] |
There was a problem hiding this comment.
We should probably also document this important bit of the manpage:
In particular, it is not intended to be used for any kind of security purpose, neither to fully sandbox a process nor to restrict filesystem system calls.
So maybe also "other_root" rather than "sandbox" in the example
| /// Command::new("contained") | ||
| /// .chroot("/sandbox") | ||
| /// .spawn()? | ||
| /// .wait()?; |
There was a problem hiding this comment.
Needs # Ok::<_, Box<dyn std::error::Error>>(()) at the end like the others
| /// Note that according to the POSIX standard, `chroot` is not required to be async-signal-safe, | ||
| /// and functions called between `fork` and `exec` must be async-signal-safe. However, in | ||
| /// practice, the ability to `fork` then `chroot` then `exec` is a capability widely provided by | ||
| /// Rust targets and relied upon by numerous programs. |
There was a problem hiding this comment.
Maybe not worth mentioning posix specifically? Since chroot hasn't been defined there since 2001
|
r? me |
As requested in #163067 .
This adds an example, adds a manpage link, adds a mention that it requires
privileges, and adds an explanation that POSIX doesn't require it to be
async-signal-safe but it's safe in practice on our targets.