unshare --map-root-user
shriphani opened this issue · 1 comments
Hi,
Thanks for this amazing library. I need to execute a binary using unshare. I am able to execute it in my shell using: unshare --map-root-user --net -- /path/to/binary
just fine.
I have this so far but I get errors:
let mut namespaces: Vec<unshare::Namespace> = Vec::new();
namespaces.push(unshare::Namespace::Net);
namespaces.push(unshare::Namespace::User);
let mut executor = unshare::Command::new(dest);
executor
.arg("job_id")
.arg(job_path1)
.arg("--verbose")
.unshare(&namespaces)
.uid(0)
.gid(0);
let executor_process_handle = executor
.spawn()
.map_err(|e| tonic::Status::internal(format!("Unable to spawn executor {}", e)))?;
And this gives me:
Unable to spawn executor error when forking: Operation not permitted (os error 1)
I also tried this:
let mut namespaces: Vec<unshare::Namespace> = Vec::new();
namespaces.push(unshare::Namespace::Net);
namespaces.push(unshare::Namespace::User);
namespaces.push(unshare::Namespace::Pid);
let uid_map = UidMap {
inside_uid: 0,
outside_uid: getuid().as_raw(),
count: 1,
};
let gid_map = GidMap {
inside_gid: 0,
outside_gid: getgid().as_raw(),
count: 0,
};
let mut executor = unshare::Command::new(dest);
executor
.arg("job_id")
.arg(job_path1)
.arg("--verbose")
.unshare(&namespaces)
.set_id_maps(vec![uid_map], vec![gid_map]);
let executor_process_handle = executor
.spawn()
.map_err(|e| tonic::Status::internal(format!("Unable to spawn executor {}", e)))?;
And this gives me: Unable to spawn executor error setting uid/gid mappings: Permission denied (os error 13)
.
Just not sure what I am missing. Any help would be appreciated.
Best,
Shriphani
Might be late but I encountered the same problem when I found this Cargo today to implement my containered network-less builder.
You need to call .set_id_map_commands()
method if you are not mapping a same ID pair between the child and your current process. The default behaviour when .set_id_map_commands()
is not called only applies to when you map your ID to itself.
A simple program to showcase how you should do to imitate the unshare --map-root-user
behaviour:
use unshare;
use libc;
fn main() {
let uidmap = unshare::UidMap {
inside_uid: 0,
outside_uid: unsafe {
libc::getuid()
},
count: 1,
};
let gidmap = unshare::GidMap {
inside_gid: 0,
outside_gid: unsafe {
libc::getgid()
},
count: 1,
};
unshare::Command::new("/bin/bash")
.arg("-c")
.arg("ip link set dev lo up; ping 127.0.0.1")
.unshare(&[unshare::Namespace::User, unshare::Namespace::Net])
.set_id_map_commands("/usr/bin/newuidmap", "/usr/bin/newgidmap")
.set_id_maps(vec![uidmap], vec![gidmap])
.spawn()
.unwrap()
.wait()
.unwrap();
}