shadow_rs/host/syscall/handler/
shadow.rs1use std::ffi::CString;
2
3use linux_api::errno::Errno;
4use shadow_shim_helper_rs::syscall_types::ForeignPtr;
5
6use crate::core::worker::Worker;
7use crate::host::syscall::handler::{SyscallContext, SyscallHandler};
8use crate::host::syscall::type_formatting::{SyscallBufferArg, SyscallSockAddrArg};
9use crate::host::syscall::types::ForeignArrayPtr;
10use crate::utility::case_insensitive_eq;
11
12impl SyscallHandler {
13 log_syscall!(shadow_yield, std::ffi::c_int);
14 pub fn shadow_yield(_ctx: &mut SyscallContext) -> Result<(), Errno> {
15 Ok(())
16 }
17
18 log_syscall!(
19 shadow_hostname_to_addr_ipv4,
20 std::ffi::c_int,
21 SyscallBufferArg<1>,
22 u64,
23 SyscallSockAddrArg<3>,
24 u64,
25 );
26 pub fn shadow_hostname_to_addr_ipv4(
27 ctx: &mut SyscallContext,
28 name_ptr: ForeignPtr<std::ffi::c_char>,
29 name_len: u64,
30 addr_ptr: ForeignPtr<()>,
31 addr_len: u64,
32 ) -> Result<(), Errno> {
33 log::trace!("Handling custom syscall shadow_hostname_to_addr_ipv4");
34
35 let name_len: usize = name_len.try_into().unwrap();
36 let addr_len: usize = addr_len.try_into().unwrap();
37
38 if addr_len < std::mem::size_of::<u32>() {
39 log::trace!("Invalid addr_len {addr_len}, returning EINVAL");
40 return Err(Errno::EINVAL);
41 }
42
43 let name_ptr = name_ptr.cast::<u8>();
44 let name_ptr = ForeignArrayPtr::new(name_ptr, name_len);
45 let addr_ptr = addr_ptr.cast::<u32>();
46
47 let mut mem = ctx.objs.process.memory_borrow_mut();
48
49 let name = mem.read_vec(name_ptr)?;
50 let Ok(name) = CString::new(name) else {
51 return Err(Errno::EFAULT);
56 };
57
58 let addr = if case_insensitive_eq(name.as_bytes(), &b"localhost"[..]) {
59 log::trace!("Returning loopback address for localhost");
60 std::net::Ipv4Addr::LOCALHOST
61 } else if case_insensitive_eq(name.as_bytes(), ctx.objs.host.info().name.as_bytes()) {
62 log::trace!("Using default address for my own hostname {name:?}");
63 ctx.objs.host.default_ip()
64 } else if let Some(addr) = Worker::resolve_name_to_ip(&name) {
65 addr
66 } else {
67 log::trace!("Unable to find address for name {name:?}");
68 return Err(Errno::EFAULT);
70 };
71
72 log::trace!("Found address {addr} for name {name:?}");
73
74 let addr = u32::from(addr);
75 mem.write(addr_ptr, &addr.to_be())?;
76
77 Ok(())
78 }
79}