@@ -22,6 +22,9 @@ pub type AddressType = *mut ::libc::c_void;
22
22
) ) ]
23
23
use libc:: user_regs_struct;
24
24
25
+ #[ cfg( all( target_os = "linux" , target_env = "gnu" ) ) ]
26
+ use libc:: ptrace_syscall_info;
27
+
25
28
cfg_if ! {
26
29
if #[ cfg( any( all( target_os = "linux" , target_arch = "s390x" ) ,
27
30
all( target_os = "linux" , target_env = "gnu" ) ,
@@ -121,6 +124,10 @@ libc_enum! {
121
124
#[ cfg( all( target_os = "linux" , target_env = "gnu" ,
122
125
any( target_arch = "x86" , target_arch = "x86_64" ) ) ) ]
123
126
PTRACE_SYSEMU_SINGLESTEP ,
127
+ #[ cfg( all( target_os = "linux" , target_env = "gnu" ) ) ]
128
+ PTRACE_GET_SYSCALL_INFO ,
129
+ PTRACE_GETSIGMASK ,
130
+ PTRACE_SETSIGMASK ,
124
131
}
125
132
}
126
133
@@ -152,6 +159,80 @@ libc_enum! {
152
159
}
153
160
}
154
161
162
+ #[ cfg( all( target_os = "linux" , target_env = "gnu" ) ) ]
163
+ #[ cfg_attr( docsrs, doc( cfg( all( ) ) ) ) ]
164
+ #[ derive( Clone , Copy , Debug , Eq , Hash , PartialEq ) ]
165
+ pub struct SyscallInfo {
166
+ /// Type of system call stop
167
+ pub op : SyscallInfoOp ,
168
+ /// AUDIT_ARCH_* value; see seccomp(2)
169
+ pub arch : u32 ,
170
+ /// CPU instruction pointer
171
+ pub instruction_pointer : u64 ,
172
+ /// CPU stack pointer
173
+ pub stack_pointer : u64 ,
174
+ }
175
+
176
+ #[ cfg( all( target_os = "linux" , target_env = "gnu" ) ) ]
177
+ #[ cfg_attr( docsrs, doc( cfg( all( ) ) ) ) ]
178
+ #[ derive( Clone , Copy , Debug , Eq , Hash , PartialEq ) ]
179
+ pub enum SyscallInfoOp {
180
+ None ,
181
+ /// System call entry.
182
+ Entry {
183
+ /// System call number.
184
+ nr : i64 ,
185
+ /// System call arguments.
186
+ args : [ u64 ; 6 ] ,
187
+ } ,
188
+ /// System call exit.
189
+ Exit {
190
+ /// System call return value.
191
+ ret_val : i64 ,
192
+ /// System call error flag.
193
+ is_error : u8 ,
194
+ } ,
195
+ /// PTRACE_EVENT_SECCOMP stop.
196
+ Seccomp {
197
+ /// System call number.
198
+ nr : i64 ,
199
+ /// System call arguments.
200
+ args : [ u64 ; 6 ] ,
201
+ /// SECCOMP_RET_DATA portion of SECCOMP_RET_TRACE return value.
202
+ ret_data : u32 ,
203
+ } ,
204
+ }
205
+
206
+ #[ cfg( all( target_os = "linux" , target_env = "gnu" ) ) ]
207
+ impl SyscallInfo {
208
+ pub fn from_raw ( raw : ptrace_syscall_info ) -> Result < SyscallInfo > {
209
+ let op = match raw. op {
210
+ libc:: PTRACE_SYSCALL_INFO_NONE => Ok ( SyscallInfoOp :: None ) ,
211
+ libc:: PTRACE_SYSCALL_INFO_ENTRY => Ok ( SyscallInfoOp :: Entry {
212
+ nr : unsafe { raw. u . entry . nr as _ } ,
213
+ args : unsafe { raw. u . entry . args } ,
214
+ } ) ,
215
+ libc:: PTRACE_SYSCALL_INFO_EXIT => Ok ( SyscallInfoOp :: Exit {
216
+ ret_val : unsafe { raw. u . exit . sval } ,
217
+ is_error : unsafe { raw. u . exit . is_error } ,
218
+ } ) ,
219
+ libc:: PTRACE_SYSCALL_INFO_SECCOMP => Ok ( SyscallInfoOp :: Seccomp {
220
+ nr : unsafe { raw. u . seccomp . nr as _ } ,
221
+ args : unsafe { raw. u . seccomp . args } ,
222
+ ret_data : unsafe { raw. u . seccomp . ret_data } ,
223
+ } ) ,
224
+ _ => Err ( Errno :: ENOSYS ) ,
225
+ } ?;
226
+
227
+ Ok ( SyscallInfo {
228
+ op,
229
+ arch : raw. arch ,
230
+ instruction_pointer : raw. instruction_pointer ,
231
+ stack_pointer : raw. stack_pointer ,
232
+ } )
233
+ }
234
+ }
235
+
155
236
libc_bitflags ! {
156
237
/// Ptrace options used in conjunction with the PTRACE_SETOPTIONS request.
157
238
/// See `man ptrace` for more details.
@@ -292,6 +373,22 @@ pub fn getsiginfo(pid: Pid) -> Result<siginfo_t> {
292
373
ptrace_get_data :: < siginfo_t > ( Request :: PTRACE_GETSIGINFO , pid)
293
374
}
294
375
376
+ /// Get ptrace syscall info as with `ptrace(PTRACE_GET_SYSCALL_INFO,...)`
377
+ /// Only available on Linux 5.3+
378
+ #[ cfg( all( target_os = "linux" , target_env = "gnu" ) ) ]
379
+ pub fn getsyscallinfo ( pid : Pid ) -> Result < SyscallInfo > {
380
+ let mut data = mem:: MaybeUninit :: uninit ( ) ;
381
+ unsafe {
382
+ ptrace_other (
383
+ Request :: PTRACE_GET_SYSCALL_INFO ,
384
+ pid,
385
+ mem:: size_of :: < ptrace_syscall_info > ( ) as * mut c_void ,
386
+ data. as_mut_ptr ( ) as * mut _ as * mut c_void ,
387
+ ) ?;
388
+ }
389
+ SyscallInfo :: from_raw ( unsafe { data. assume_init ( ) } )
390
+ }
391
+
295
392
/// Set siginfo as with `ptrace(PTRACE_SETSIGINFO,...)`
296
393
pub fn setsiginfo ( pid : Pid , sig : & siginfo_t ) -> Result < ( ) > {
297
394
let ret = unsafe {
0 commit comments