naming_srv/
lib.rs

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