• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #![allow(unsafe_code)]
2 
3 use bitflags::bitflags;
4 use linux_raw_sys::general::{
5     CLONE_FILES, CLONE_FS, CLONE_NEWCGROUP, CLONE_NEWIPC, CLONE_NEWNET, CLONE_NEWNS, CLONE_NEWPID,
6     CLONE_NEWTIME, CLONE_NEWUSER, CLONE_NEWUTS, CLONE_SYSVSEM,
7 };
8 
9 use crate::backend::c::c_int;
10 use crate::backend::thread::syscalls;
11 use crate::fd::BorrowedFd;
12 use crate::io;
13 
14 bitflags! {
15     /// Thread name space type.
16     pub struct ThreadNameSpaceType: u32 {
17         /// Time name space.
18         const TIME = CLONE_NEWTIME;
19         /// Mount name space.
20         const MOUNT = CLONE_NEWNS;
21         /// Control group (CGroup) name space.
22         const CONTROL_GROUP = CLONE_NEWCGROUP;
23         /// `Host name` and `NIS domain name` (UTS) name space.
24         const HOST_NAME_AND_NIS_DOMAIN_NAME = CLONE_NEWUTS;
25         /// Inter-process communication (IPC) name space.
26         const INTER_PROCESS_COMMUNICATION = CLONE_NEWIPC;
27         /// User name space.
28         const USER = CLONE_NEWUSER;
29         /// Process ID name space.
30         const PROCESS_ID = CLONE_NEWPID;
31         /// Network name space.
32         const NETWORK = CLONE_NEWNET;
33     }
34 }
35 
36 /// Type of name space referred to by a link.
37 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
38 #[repr(u32)]
39 pub enum LinkNameSpaceType {
40     /// Time name space.
41     Time = CLONE_NEWTIME,
42     /// Mount name space.
43     Mount = CLONE_NEWNS,
44     /// Control group (CGroup) name space.
45     ControlGroup = CLONE_NEWCGROUP,
46     /// `Host name` and `NIS domain name` (UTS) name space.
47     HostNameAndNISDomainName = CLONE_NEWUTS,
48     /// Inter-process communication (IPC) name space.
49     InterProcessCommunication = CLONE_NEWIPC,
50     /// User name space.
51     User = CLONE_NEWUSER,
52     /// Process ID name space.
53     ProcessID = CLONE_NEWPID,
54     /// Network name space.
55     Network = CLONE_NEWNET,
56 }
57 
58 bitflags! {
59     /// `CLONE_*` for use with [`unshare`].
60     pub struct UnshareFlags: u32 {
61         /// `CLONE_FILES`.
62         const FILES = CLONE_FILES;
63         /// `CLONE_FS`.
64         const FS = CLONE_FS;
65         /// `CLONE_NEWCGROUP`.
66         const NWCGROUP = CLONE_NEWCGROUP;
67         /// `CLONE_NEWIPC`.
68         const NEWIPC = CLONE_NEWIPC;
69         /// `CLONE_NEWNET`.
70         const NEWNET = CLONE_NEWNET;
71         /// `CLONE_NEWNS`.
72         const NEWNS = CLONE_NEWNS;
73         /// `CLONE_NEWPID`.
74         const NEWPID = CLONE_NEWPID;
75         /// `CLONE_NEWTIME`.
76         const NEWTIME = CLONE_NEWTIME;
77         /// `CLONE_NEWUSER`.
78         const NEWUSER = CLONE_NEWUSER;
79         /// `CLONE_SYSVSEM`.
80         const SYSVSEM = CLONE_SYSVSEM;
81     }
82 }
83 
84 /// Reassociate the calling thread with the namespace associated with link referred to by `fd`.
85 ///
86 /// `fd` must refer to one of the magic links in a `/proc/[pid]/ns/` directory, or a bind mount
87 /// to such a link.
88 ///
89 /// # References
90 /// - [`setns`]
91 ///
92 /// [`setns`]: https://man7.org/linux/man-pages/man2/setns.2.html
move_into_link_name_space( fd: BorrowedFd, allowed_type: Option<LinkNameSpaceType>, ) -> io::Result<()>93 pub fn move_into_link_name_space(
94     fd: BorrowedFd,
95     allowed_type: Option<LinkNameSpaceType>,
96 ) -> io::Result<()> {
97     let allowed_type = allowed_type.map_or(0, |t| t as c_int);
98     syscalls::setns(fd, allowed_type).map(|_r| ())
99 }
100 
101 /// Atomically move the calling thread into one or more of the same namespaces as the thread
102 /// referred to by `fd`.
103 ///
104 /// `fd` must refer to a thread ID. See: `pidfd_open` and `clone`.
105 ///
106 /// # References
107 /// - [`setns`]
108 ///
109 /// [`setns`]: https://man7.org/linux/man-pages/man2/setns.2.html
move_into_thread_name_spaces( fd: BorrowedFd, allowed_types: ThreadNameSpaceType, ) -> io::Result<()>110 pub fn move_into_thread_name_spaces(
111     fd: BorrowedFd,
112     allowed_types: ThreadNameSpaceType,
113 ) -> io::Result<()> {
114     syscalls::setns(fd, allowed_types.bits() as c_int).map(|_r| ())
115 }
116 
117 /// `unshare(flags)`—Disassociate parts of the current thread's execution
118 /// context with other threads.
119 ///
120 /// # References
121 /// - [`unshare`]
122 ///
123 /// [`unshare`]: https://man7.org/linux/man-pages/man2/unshare.2.html
unshare(flags: UnshareFlags) -> io::Result<()>124 pub fn unshare(flags: UnshareFlags) -> io::Result<()> {
125     syscalls::unshare(flags)
126 }
127