shadow_rs/host/syscall/handler/
prctl.rs
1use linux_api::errno::Errno;
2use linux_api::prctl::PrctlOp;
3use linux_api::sched::SuidDump;
4use shadow_shim_helper_rs::syscall_types::ForeignPtr;
5
6use crate::host::syscall::handler::{SyscallContext, SyscallHandler};
7use crate::host::syscall::types::SyscallError;
8
9impl SyscallHandler {
10 log_syscall!(
11 prctl,
12 std::ffi::c_int,
13 PrctlOp,
14 std::ffi::c_ulong,
15 std::ffi::c_ulong,
16 std::ffi::c_ulong,
17 std::ffi::c_ulong,
18 );
19 pub fn prctl(
20 ctx: &mut SyscallContext,
21 option: PrctlOp,
22 arg2: std::ffi::c_ulong,
23 _arg3: std::ffi::c_ulong,
24 _arg4: std::ffi::c_ulong,
25 _arg5: std::ffi::c_ulong,
26 ) -> Result<std::ffi::c_int, SyscallError> {
27 match option {
28 PrctlOp::PR_CAP_AMBIENT
29 | PrctlOp::PR_CAPBSET_READ
30 | PrctlOp::PR_CAPBSET_DROP
31 | PrctlOp::PR_SET_CHILD_SUBREAPER
32 | PrctlOp::PR_GET_CHILD_SUBREAPER
33 | PrctlOp::PR_SET_ENDIAN
34 | PrctlOp::PR_GET_ENDIAN
35 | PrctlOp::PR_SET_FP_MODE
36 | PrctlOp::PR_GET_FP_MODE
37 | PrctlOp::PR_SET_FPEMU
38 | PrctlOp::PR_GET_FPEMU
39 | PrctlOp::PR_SET_FPEXC
40 | PrctlOp::PR_GET_FPEXC
41 | PrctlOp::PR_SET_KEEPCAPS
42 | PrctlOp::PR_GET_KEEPCAPS
43 | PrctlOp::PR_MCE_KILL
44 | PrctlOp::PR_MCE_KILL_GET
45 | PrctlOp::PR_MPX_ENABLE_MANAGEMENT
46 | PrctlOp::PR_MPX_DISABLE_MANAGEMENT
47 | PrctlOp::PR_SET_NAME
48 | PrctlOp::PR_GET_NAME
49 | PrctlOp::PR_SET_NO_NEW_PRIVS
50 | PrctlOp::PR_GET_NO_NEW_PRIVS
51 | PrctlOp::PR_SET_MM
52 | PrctlOp::PR_SET_PTRACER
53 | PrctlOp::PR_SET_SECUREBITS
54 | PrctlOp::PR_GET_SECUREBITS
55 | PrctlOp::PR_GET_SPECULATION_CTRL
56 | PrctlOp::PR_SET_THP_DISABLE
57 | PrctlOp::PR_TASK_PERF_EVENTS_DISABLE
58 | PrctlOp::PR_TASK_PERF_EVENTS_ENABLE
59 | PrctlOp::PR_GET_THP_DISABLE
60 | PrctlOp::PR_GET_TIMERSLACK
61 | PrctlOp::PR_SET_TIMING
62 | PrctlOp::PR_GET_TIMING
63 | PrctlOp::PR_GET_TSC
64 | PrctlOp::PR_GET_UNALIGN => {
65 log::trace!("prctl {option} executing natively");
66 Err(SyscallError::Native)
67 }
68 PrctlOp::PR_SET_SECCOMP | PrctlOp::PR_GET_SECCOMP => {
69 log::warn!("Not allowing seccomp prctl {option}");
70 Err(Errno::EINVAL.into())
71 }
72 PrctlOp::PR_SET_UNALIGN
74 | PrctlOp::PR_SET_TSC
77 | PrctlOp::PR_SET_TIMERSLACK
80 | PrctlOp::PR_SET_SPECULATION_CTRL
82 | PrctlOp::PR_SET_PDEATHSIG => {
86 log::warn!("Not allowing unimplemented prctl {option}");
87 Err(Errno::EINVAL.into())
88 }
89 PrctlOp::PR_GET_TID_ADDRESS => {
90 let out_ptr = ForeignPtr::from(arg2)
91 .cast::<ForeignPtr<linux_api::posix_types::kernel_pid_t>>();
92 let tid_addr = ctx.objs.thread.get_tid_address();
93 ctx.objs.process.memory_borrow_mut().write(out_ptr, &tid_addr)?;
94 Ok(0)
95 }
96 PrctlOp::PR_SET_DUMPABLE => {
97 let dumpable = SuidDump::new(arg2.try_into().or(Err(Errno::EINVAL))?);
98 if [SuidDump::SUID_DUMP_DISABLE, SuidDump::SUID_DUMP_USER].contains(&dumpable) {
99 ctx.objs.process.set_dumpable(dumpable);
100 Ok(0)
101 } else {
102 Err(Errno::EINVAL.into())
103 }
104 }
105 PrctlOp::PR_GET_DUMPABLE => {
106 Ok(ctx.objs.process.dumpable().val())
107 }
108 _ => {
109 log::warn!("Unknown prctl operation {option}");
110 Err(Errno::EINVAL.into())
111 }
112 }
113 }
114}