std::process::Command does not work properly with less privileged children accessing stdin/stdout/stderr file descriptors
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 119k
- Forks
- 16.2k
- PR merge metrics
- PR metrics pending
Description
I tried this code:
use std::io::Write;
use std::os::unix::process::CommandExt;
use std::process::{Command, Stdio};
fn main() {
let mut command = Command::new("/bin/cat");
command.arg("/dev/fd/0")
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.uid(35565)
.gid(35565);
let mut child = command.spawn().unwrap();
child.stdin.take().unwrap().write_all("foo".as_ref()).unwrap();
}
Tokio version:
use std::process::Stdio;
use tokio::io::{AsyncReadExt, AsyncWriteExt};
use tokio::process::Command;
#[tokio::main]
async fn main() {
tokio::task::spawn(async move {
let mut command = Command::new("/bin/cat");
command.arg("/dev/fd/0")
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.uid(35565)
.gid(35565);
let mut child = command.spawn().unwrap();
child.stdin.take().unwrap().write_all("foo".as_ref()).await.unwrap();
});
}
I expected to see this happen:
The child process opens and reads it's stdin.
Instead, this happened:
The child process was unable to read it's stdin fd.
Meta
I've asked around about this issue in other places and it seems that it's Linux quirk that the Rust standard library does not handle. Neither does there seem to be a proper way to handle it (nor do I know how to safely work around stdlib).
- https://superuser.com/a/1699427
- https://github.com/tokio-rs/tokio/issues/6193
- https://users.rust-lang.org/t/letting-child-process-read-stdin-after-dropping-privileges/90860
rustc --version --verbose:
rustc 1.74.1 (a28077b28 2023-12-04)
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the std::process::Command example and the Unix CommandExt uid/gid configuration, then reproduce the behavior on Linux with /bin/cat and /dev/fd/0. Read the linked Tokio issue and referenced discussions to understand the platform limitation. Done means establishing whether the standard library can safely support the child process reading its redirected standard input.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- operating-systems
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 35/100