netsim_embed_machine/
namespace.rs1use std::fs::File;
2use std::io::{self, Write};
3use std::os::unix::io::AsRawFd;
4
5pub fn unshare_user() -> Result<(), io::Error> {
6 let uid = unsafe { libc::geteuid() };
7 let gid = unsafe { libc::getegid() };
8
9 unsafe { errno!(libc::unshare(libc::CLONE_NEWUSER))? };
10
11 let mut f = File::create("/proc/self/uid_map")?;
12 let s = format!("0 {uid} 1\n");
13 f.write_all(s.as_bytes())?;
14
15 let mut f = File::create("/proc/self/setgroups")?;
16 f.write_all(b"deny\n")?;
17
18 let mut f = File::create("/proc/self/gid_map")?;
19 let s = format!("0 {gid} 1\n");
20 f.write_all(s.as_bytes())?;
21
22 Ok(())
23}
24
25#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
26pub struct Namespace {
27 pid: i32,
28 tid: i64,
29}
30
31impl Namespace {
32 pub fn current() -> Result<Self, io::Error> {
33 unsafe {
34 let pid = errno!(libc::getpid())?;
35 let tid = errno!(libc::syscall(libc::SYS_gettid))?;
36 Ok(Self { pid, tid })
37 }
38 }
39
40 pub fn unshare() -> Result<Self, io::Error> {
41 unsafe {
42 errno!(libc::unshare(libc::CLONE_NEWNET | libc::CLONE_NEWUTS))?;
43 }
44 Self::current()
45 }
46
47 pub fn enter(&self) -> Result<(), io::Error> {
48 let fd = File::open(self.to_string())?;
49 unsafe {
50 errno!(libc::setns(fd.as_raw_fd(), libc::CLONE_NEWNET))?;
51 }
52 Ok(())
53 }
54}
55
56impl std::fmt::Display for Namespace {
57 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
58 write!(f, "/proc/{}/task/{}/ns/net", self.pid, self.tid)
59 }
60}