shadow_rs/host/syscall/handler/
resource.rs1use linux_api::errno::Errno;
2use shadow_shim_helper_rs::syscall_types::ForeignPtr;
3
4use crate::host::process::ProcessId;
5use crate::host::syscall::handler::{SyscallContext, SyscallHandler};
6use crate::host::syscall::types::SyscallError;
7
8impl SyscallHandler {
9 fn prlimit64_impl(
10 ctx: &mut SyscallContext,
11 pid: linux_api::posix_types::kernel_pid_t,
12 resource: std::ffi::c_uint,
13 new_rlim: Option<&linux_api::resource::rlimit64>,
14 old_rlim: Option<&mut linux_api::resource::rlimit64>,
15 ) -> Result<(), SyscallError> {
16 let Ok(resource) = linux_api::resource::Resource::try_from(resource) else {
17 return Err(Errno::EINVAL.into());
18 };
19
20 if pid == 0 {
21 ctx.objs.process.prlimit64(resource, new_rlim, old_rlim)?;
23 } else {
24 let Ok(id) = ProcessId::try_from(pid) else {
26 return Err(Errno::ESRCH.into());
27 };
28 let Some(process) = ctx.objs.host.process_borrow(id) else {
29 return Err(Errno::ESRCH.into());
30 };
31 process
32 .borrow(ctx.objs.host.root())
33 .prlimit64(resource, new_rlim, old_rlim)?;
34 }
35 Ok(())
36 }
37
38 log_syscall!(
39 prlimit64,
40 std::ffi::c_int,
41 linux_api::posix_types::kernel_pid_t,
42 linux_api::resource::Resource,
43 *const linux_api::resource::rlimit64,
44 *const linux_api::resource::rlimit64,
45 );
46 pub fn prlimit64(
47 ctx: &mut SyscallContext,
48 pid: linux_api::posix_types::kernel_pid_t,
49 resource: std::ffi::c_uint,
50 new_rlim_ptr: ForeignPtr<linux_api::resource::rlimit64>,
51 old_rlim_ptr: ForeignPtr<linux_api::resource::rlimit64>,
52 ) -> Result<(), SyscallError> {
53 let new_rlim = if new_rlim_ptr.is_null() {
54 None
55 } else {
56 Some(&ctx.objs.process.memory_borrow().read(new_rlim_ptr)?)
57 };
58
59 let mut old_rlim = if old_rlim_ptr.is_null() {
60 None
61 } else {
62 Some(&mut linux_api::resource::rlimit64 {
63 rlim_cur: 0,
64 rlim_max: 0,
65 })
66 };
67
68 SyscallHandler::prlimit64_impl(ctx, pid, resource, new_rlim, old_rlim.as_deref_mut())?;
69
70 if !old_rlim_ptr.is_null() {
71 ctx.objs
72 .process
73 .memory_borrow_mut()
74 .write(old_rlim_ptr, old_rlim.unwrap())?;
75 }
76
77 Ok(())
78 }
79
80 log_syscall!(
81 getrlimit,
82 std::ffi::c_int,
83 linux_api::resource::Resource,
84 *const linux_api::resource::rlimit,
85 );
86 pub fn getrlimit(
87 ctx: &mut SyscallContext,
88 resource: std::ffi::c_uint,
89 rlimit_ptr: ForeignPtr<linux_api::resource::rlimit>,
90 ) -> Result<(), SyscallError> {
91 let mut rlim_val64 = linux_api::resource::rlimit64 {
92 rlim_cur: 0,
93 rlim_max: 0,
94 };
95 SyscallHandler::prlimit64_impl(ctx, 0, resource, None, Some(&mut rlim_val64))?;
96 let rlim_val = linux_api::resource::rlimit {
97 rlim_cur: rlim_val64.rlim_cur,
98 rlim_max: rlim_val64.rlim_max,
99 };
100 ctx.objs
101 .process
102 .memory_borrow_mut()
103 .write(rlimit_ptr, &rlim_val)?;
104 Ok(())
105 }
106
107 log_syscall!(
108 setrlimit,
109 std::ffi::c_int,
110 linux_api::resource::Resource,
111 *const linux_api::resource::rlimit,
112 );
113 pub fn setrlimit(
114 ctx: &mut SyscallContext,
115 resource: std::ffi::c_uint,
116 rlimit: ForeignPtr<linux_api::resource::rlimit>,
117 ) -> Result<(), SyscallError> {
118 let rlim_val = ctx.objs.process.memory_borrow().read(rlimit)?;
119 let rlim_val = linux_api::resource::rlimit64 {
120 rlim_cur: rlim_val.rlim_cur,
121 rlim_max: rlim_val.rlim_max,
122 };
123 SyscallHandler::prlimit64_impl(ctx, 0, resource, Some(&rlim_val), None)?;
124 Ok(())
125 }
126}