1#![feature(naked_functions)]
2#![feature(linkage)]
3#![feature(io_error_more)]
4#[warn(unused_variables)]
5use std::sync::Mutex;
6use std::{io::ErrorKind, path::PathBuf};
7
8use lazy_init::LazyTransform;
9use lazy_static::lazy_static;
10use naming_core::{GetFlags, NameSession, NameStore, NsNode, Result, PATH_MAX};
11use secgate::{
12 secure_gate,
13 util::{Descriptor, HandleMgr, SimpleBuffer},
14};
15use tracing::Level;
16use twizzler_abi::{
17 aux::KernelInitInfo,
18 object::{Protections, MAX_SIZE, NULLPAGE_SIZE},
19 syscall::{sys_object_create, BackingType, LifetimeType, ObjectCreate, ObjectCreateFlags},
20};
21use twizzler_rt_abi::{
22 error::{ArgumentError, ResourceError},
23 object::{MapFlags, ObjID},
24};
25
26struct NamespaceClient<'a> {
27 session: NameSession<'a>,
28 buffer: SimpleBuffer,
29}
30
31impl<'a> NamespaceClient<'a> {
32 fn new(session: NameSession<'a>) -> Option<Self> {
33 let id = sys_object_create(
35 ObjectCreate::new(
36 BackingType::Normal,
37 LifetimeType::Volatile,
38 None,
39 ObjectCreateFlags::empty(),
40 Protections::all(),
41 ),
42 &[],
43 &[],
44 )
45 .ok()?;
46 let handle =
47 twizzler_rt_abi::object::twz_rt_map_object(id, MapFlags::WRITE | MapFlags::READ)
48 .ok()?;
49 let buffer = SimpleBuffer::new(handle);
50 Some(Self { session, buffer })
51 }
52
53 fn sbid(&self) -> ObjID {
54 self.buffer.handle().id()
55 }
56
57 fn read_buffer(&self, name_len: usize) -> Result<PathBuf> {
58 if name_len >= PATH_MAX {
59 return Err(ArgumentError::InvalidArgument.into());
60 }
61 let mut buf = vec![0; name_len];
62 self.buffer.read(&mut buf);
63 Ok(PathBuf::from(
64 String::from_utf8(buf).map_err(|_| ErrorKind::InvalidFilename)?,
65 ))
66 }
67
68 fn read_buffer_at(&self, name_len: usize, off: usize) -> Result<PathBuf> {
69 if name_len >= PATH_MAX {
70 return Err(ArgumentError::InvalidArgument.into());
71 }
72 let mut buf = vec![0; name_len];
73 self.buffer.read_offset(&mut buf, off);
74 Ok(PathBuf::from(
75 String::from_utf8(buf).map_err(|_| ArgumentError::InvalidArgument)?,
76 ))
77 }
78}
79
80unsafe impl Send for Namer<'_> {}
81unsafe impl Sync for Namer<'_> {}
82
83struct Namer<'a> {
84 handles: Mutex<HandleMgr<NamespaceClient<'a>>>,
85 names: NameStore,
86}
87
88impl Namer<'_> {
89 fn new() -> Self {
90 Self {
91 handles: Mutex::new(HandleMgr::new(None)),
92 names: NameStore::new(),
93 }
94 }
95
96 fn new_with(id: ObjID) -> Result<Self> {
97 let names = NameStore::new_with(id)?;
98 Ok(Self {
99 handles: Mutex::new(HandleMgr::new(None)),
100 names,
101 })
102 }
103}
104
105lazy_static! {
106 static ref NAMINGSERVICE: LazyTransform<(), Namer<'static>> = LazyTransform::new(());
107}
108
109fn get_kernel_init_info() -> &'static KernelInitInfo {
110 unsafe {
111 (((twizzler_abi::slot::RESERVED_KERNEL_INIT * MAX_SIZE) + NULLPAGE_SIZE)
112 as *const KernelInitInfo)
113 .as_ref()
114 .unwrap()
115 }
116}
117
118#[secure_gate(options(info))]
120pub fn namer_start(_info: &secgate::GateCallInfo, bootstrap: ObjID) -> Result<ObjID> {
121 tracing::subscriber::set_global_default(
122 tracing_subscriber::fmt()
123 .with_max_level(Level::INFO)
124 .without_time()
125 .finish(),
126 )
127 .unwrap();
128
129 Ok(NAMINGSERVICE
130 .get_or_create(|_| {
131 let namer = Namer::new_with(bootstrap)
132 .or::<ErrorKind>(Ok(Namer::new()))
133 .unwrap();
134 namer.names.root_session().mkns("/initrd", false).unwrap();
135 for n in get_kernel_init_info().names() {
136 namer
137 .names
138 .root_session()
139 .put(&format!("/initrd/{}", n.name()), n.id())
140 .unwrap();
141 }
142
143 namer
144 })
145 .names
146 .id())
147}
148
149#[secure_gate(options(info))]
150pub fn open_handle(info: &secgate::GateCallInfo) -> Result<(Descriptor, ObjID)> {
151 let service = NAMINGSERVICE.get().ok_or(ResourceError::Unavailable)?;
152 let mut binding = service.handles.lock().unwrap();
153
154 let session = service.names.root_session();
155 let client = NamespaceClient::new(session).ok_or(ResourceError::Unavailable)?;
156 let id = client.sbid();
157
158 let desc = binding
159 .insert(info.source_context().unwrap_or(0.into()), client)
160 .ok_or(ResourceError::OutOfResources)?;
161
162 Ok((desc, id))
163}
164
165#[secure_gate(options(info))]
166pub fn close_handle(info: &secgate::GateCallInfo, desc: Descriptor) -> Result<()> {
167 let service = NAMINGSERVICE.get().unwrap();
168
169 let mut binding = service.handles.lock().unwrap();
170
171 binding.remove(info.source_context().unwrap_or(0.into()), desc);
172 Ok(())
173}
174
175#[secure_gate(options(info))]
176pub fn put(
177 info: &secgate::GateCallInfo,
178 desc: Descriptor,
179 name_len: usize,
180 id: ObjID,
181) -> Result<()> {
182 let service = NAMINGSERVICE.get().unwrap();
183 let mut binding = service.handles.lock().unwrap();
184 let client = binding
185 .lookup_mut(info.source_context().unwrap_or(0.into()), desc)
186 .ok_or(ArgumentError::BadHandle)?;
187
188 let path = client.read_buffer(name_len)?;
189
190 client.session.put(path, id)
191}
192
193#[secure_gate(options(info))]
194pub fn mkns(
195 info: &secgate::GateCallInfo,
196 desc: Descriptor,
197 name_len: usize,
198 persist: bool,
199) -> Result<()> {
200 let service = NAMINGSERVICE.get().unwrap();
201 let mut binding = service.handles.lock().unwrap();
202 let client = binding
203 .lookup_mut(info.source_context().unwrap_or(0.into()), desc)
204 .ok_or(ArgumentError::BadHandle)?;
205
206 let path = client.read_buffer(name_len)?;
207
208 client.session.mkns(path, persist)
209}
210
211#[secure_gate(options(info))]
212pub fn link(
213 info: &secgate::GateCallInfo,
214 desc: Descriptor,
215 name_len: usize,
216 link_len: usize,
217) -> Result<()> {
218 let service = NAMINGSERVICE.get().unwrap();
219 let mut binding = service.handles.lock().unwrap();
220 let client = binding
221 .lookup_mut(info.source_context().unwrap_or(0.into()), desc)
222 .ok_or(ErrorKind::Other)?;
223
224 let path = client.read_buffer(name_len)?;
225 let link = client.read_buffer_at(link_len, name_len)?;
226
227 client.session.link(path, link)
228}
229
230#[secure_gate(options(info))]
231pub fn get(
232 info: &secgate::GateCallInfo,
233 desc: Descriptor,
234 name_len: usize,
235 flags: GetFlags,
236) -> Result<NsNode> {
237 let service = NAMINGSERVICE.get().unwrap();
238 let mut binding = service.handles.lock().unwrap();
239 let client = binding
240 .lookup_mut(info.source_context().unwrap_or(0.into()), desc)
241 .ok_or(ErrorKind::Other)?;
242
243 let path = client.read_buffer(name_len)?;
244
245 client.session.get(path, flags)
246}
247
248#[secure_gate(options(info))]
249pub fn remove(info: &secgate::GateCallInfo, desc: Descriptor, name_len: usize) -> Result<()> {
250 let service = NAMINGSERVICE.get().unwrap();
251 let mut binding = service.handles.lock().unwrap();
252 let client = binding
253 .lookup_mut(info.source_context().unwrap_or(0.into()), desc)
254 .ok_or(ErrorKind::Other)?;
255
256 let path = client.read_buffer(name_len)?;
257
258 client.session.remove(path)?;
259
260 Ok(())
261}
262
263#[secure_gate(options(info))]
264pub fn enumerate_names(
265 info: &secgate::GateCallInfo,
266 desc: Descriptor,
267 name_len: usize,
268) -> Result<usize> {
269 let service = NAMINGSERVICE.get().unwrap();
270 let mut binding = service.handles.lock().unwrap();
271 let client = binding
272 .lookup_mut(info.source_context().unwrap_or(0.into()), desc)
273 .ok_or(ErrorKind::Other)?;
274
275 let path = client.read_buffer(name_len)?;
276
277 let vec1 = client.session.enumerate_namespace(path)?;
279 let len = vec1.len();
280
281 let mut buffer = SimpleBuffer::new(client.buffer.handle().clone());
282 let slice = unsafe {
283 std::slice::from_raw_parts(
284 vec1.as_ptr() as *const u8,
285 len * std::mem::size_of::<NsNode>(),
286 )
287 };
288 buffer.write(slice);
289
290 Ok(len)
291}
292
293#[secure_gate(options(info))]
294pub fn enumerate_names_nsid(
295 info: &secgate::GateCallInfo,
296 desc: Descriptor,
297 id: ObjID,
298) -> Result<usize> {
299 let service = NAMINGSERVICE.get().unwrap();
300 let mut binding = service.handles.lock().unwrap();
301 let client = binding
302 .lookup_mut(info.source_context().unwrap_or(0.into()), desc)
303 .ok_or(ErrorKind::Other)?;
304
305 let vec1 = client.session.enumerate_namespace_nsid(id)?;
307 let len = vec1.len();
308
309 let mut buffer = SimpleBuffer::new(client.buffer.handle().clone());
310 let slice = unsafe {
311 std::slice::from_raw_parts(
312 vec1.as_ptr() as *const u8,
313 len * std::mem::size_of::<NsNode>(),
314 )
315 };
316 buffer.write(slice);
317
318 Ok(len)
319}
320
321#[secure_gate(options(info))]
322pub fn change_namespace(
323 info: &secgate::GateCallInfo,
324 desc: Descriptor,
325 name_len: usize,
326) -> Result<()> {
327 let service = NAMINGSERVICE.get().unwrap();
328 let mut binding = service.handles.lock().unwrap();
329 let client = binding
330 .lookup_mut(info.source_context().unwrap_or(0.into()), desc)
331 .ok_or(ErrorKind::Other)?;
332
333 let path = client.read_buffer(name_len)?;
334
335 client.session.change_namespace(path)
336}