ptrace_syscalls/types/
dst.rs

1use std::{alloc::Layout, sync::Arc};
2
3use crate::{read_remote_memory, AddressType, InspectDynSizedFromPid, InspectError, InspectResult, Pid};
4use nix::{
5  errno::Errno,
6  libc::{c_char, c_int, c_long, c_uint},
7};
8use slice_dst::{SliceDst, TryAllocSliceDst};
9
10macro_rules! impl_slice_dst {
11  ($($t:ty => $other:expr, $a:expr),*) => {
12    $(
13      unsafe impl SliceDst for $t {
14        fn layout_for(len: usize) -> std::alloc::Layout {
15          Layout::from_size_align(len + $other, $a).unwrap()
16        }
17
18        fn retype(ptr: std::ptr::NonNull<[()]>) -> std::ptr::NonNull<Self> {
19          unsafe { std::ptr::NonNull::new_unchecked(ptr.as_ptr() as *mut _) }
20        }
21      }
22
23      impl InspectDynSizedFromPid for InspectResult<Arc<$t>> {
24        fn inspect_from(pid: Pid, address: AddressType, size: usize) -> Self {
25          let arc = unsafe {
26            Arc::<$t>::try_new_slice_dst(size - $other, |ptr| {
27              let read = read_remote_memory(pid, address, size, ptr.as_ptr() as AddressType)?;
28              if read != size {
29                return Err(Errno::EIO);
30              } else {
31                Ok(())
32              }
33            })
34          }
35          .map_err(|e| InspectError::ReadFailure {
36            errno: e,
37            incomplete: None,
38          })?;
39          Ok(arc)
40        }
41      }
42    )*
43  };
44}
45
46impl_slice_dst! {
47  rseq => 28, 32,
48  statmount => 520, 8,
49  msgbuf => std::mem::size_of::<c_long>(), std::mem::align_of::<c_long>(),
50  file_handle => 8, 4,
51  xattr_args => 16, 8,
52  mount_attr => 32, 8
53}
54
55#[derive(Debug, PartialEq)]
56#[repr(C, align(32))]
57// aligned(4 * sizeof(__u64))
58pub struct rseq {
59  pub cpu_id_start: u32,
60  pub cpu_id: u32,
61  pub rseq_cs: u64,
62  pub flags: u32,
63  pub node_id: u32,
64  pub mm_cid: u32,
65  pub end: [c_char],
66}
67
68#[derive(Debug, PartialEq)]
69#[repr(C)]
70pub struct statmount {
71  pub size: u32,
72  pub __spare1: u32,
73  pub mask: u64,
74  pub sb_dev_major: u32,
75  pub sb_dev_minor: u32,
76  pub sb_magic: u64,
77  pub sb_flags: u32,
78  pub fs_type: u32,
79  pub mnt_id: u64,
80  pub mnt_parent_id: u64,
81  pub mnt_id_old: u64,
82  pub mnt_parent_id_old: u64,
83  pub mnt_attr: u64,
84  pub mnt_propagation: u64,
85  pub mnt_peer_group: u64,
86  pub mnt_master: u64,
87  pub propagate_from: u64,
88  pub mnt_root: u32,
89  pub mnt_point: u32,
90  pub __spare2: [u64; 50],
91  pub str: [c_char],
92}
93
94#[derive(Debug, PartialEq)]
95#[repr(C)]
96pub struct msgbuf {
97  pub mtype: c_long,
98  pub mtext: [c_char],
99}
100
101#[derive(Debug, PartialEq)]
102#[repr(C)]
103pub struct file_handle {
104  pub handle_bytes: c_uint,
105  pub handle_type: c_int,
106  pub f_handle: [c_char],
107}
108
109#[derive(Debug, PartialEq)]
110#[repr(C)]
111pub struct xattr_args {
112  pub value: u64,
113  pub size: u32,
114  pub flags: u32,
115  pub __trailer: [c_char],
116}
117
118#[derive(Debug, PartialEq)]
119#[repr(C)]
120pub struct mount_attr {
121  pub attr_set: u64,
122  pub attr_clr: u64,
123  pub propagation: u64,
124  pub userns_fd: u64,
125  pub __trailer: [c_char],
126}