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