PTRACE_SET_SYSCALL_INFO is a generic ptrace API that complements PTRACE_GET_SYSCALL_INFO by letting the ptracer modify details of system calls the tracee is blocked in. This API allows ptracers to obtain and modify system call details in a straightforward and architecture-agnostic way, providing a consistent way of manipulating the system call number and arguments across architectures. As in case of PTRACE_GET_SYSCALL_INFO, PTRACE_SET_SYSCALL_INFO also does not aim to address numerous architecture-specific system call ABI peculiarities, like differences in the number of system call arguments for such system calls as pread64 and preadv. The current implementation supports changing only those bits of system call information that are used by strace system call tampering, namely, syscall number, syscall arguments, and syscall return value. Support of changing additional details returned by PTRACE_GET_SYSCALL_INFO, such as instruction pointer and stack pointer, could be added later if needed, by using struct ptrace_syscall_info.flags to specify the additional details that should be set. Currently, "flags" and "reserved" fields of struct ptrace_syscall_info must be initialized with zeroes; "arch", "instruction_pointer", and "stack_pointer" fields are currently ignored. PTRACE_SET_SYSCALL_INFO currently supports only PTRACE_SYSCALL_INFO_ENTRY, PTRACE_SYSCALL_INFO_EXIT, and PTRACE_SYSCALL_INFO_SECCOMP operations. Other operations could be added later if needed. Ideally, PTRACE_SET_SYSCALL_INFO should have been introduced along with PTRACE_GET_SYSCALL_INFO, but it didn't happen. The last straw that convinced me to implement PTRACE_SET_SYSCALL_INFO was apparent failure to provide an API of changing the first system call argument on riscv architecture. ptrace(2) man page: long ptrace(enum __ptrace_request request, pid_t pid, void *addr, void *data); ... PTRACE_SET_SYSCALL_INFO Modify information about the system call that caused the stop. The "data" argument is a pointer to struct ptrace_syscall_info that specifies the system call information to be set. The "addr" argument should be set to sizeof(struct ptrace_syscall_info)).
Showing the changes to include/uapi (1 of 2 files). Show all
Unified · Split
| @@ -74,6 +74,7 @@ struct seccomp_metadata { · 73 unmodified lines | ||
| 74 | 74 | }; |
| 75 | 75 | |
| 76 | 76 | #define PTRACE_GET_SYSCALL_INFO 0x420e |
| 77 | +#define PTRACE_SET_SYSCALL_INFO 0x4212 | |
| 77 | 78 | #define PTRACE_SYSCALL_INFO_NONE 0 |
| 78 | 79 | #define PTRACE_SYSCALL_INFO_ENTRY 1 |
| 79 | 80 | #define PTRACE_SYSCALL_INFO_EXIT 2 |
| @@ -81,7 +82,8 @@ struct seccomp_metadata { · 1 unmodified line | ||
| 81 | 82 | |
| 82 | 83 | struct ptrace_syscall_info { |
| 83 | 84 | __u8 op; /* PTRACE_SYSCALL_INFO_* */ |
| 84 | − __u8 pad[3]; | |
| 85 | + __u8 reserved; | |
| 86 | + __u16 flags; | |
| 85 | 87 | __u32 arch; |
| 86 | 88 | __u64 instruction_pointer; |
| 87 | 89 | __u64 stack_pointer; |
| @@ -98,6 +100,7 @@ struct ptrace_syscall_info { · 10 unmodified lines | ||
| 98 | 100 | __u64 nr; |
| 99 | 101 | __u64 args[6]; |
| 100 | 102 | __u32 ret_data; |
| 103 | + __u32 reserved2; | |
| 101 | 104 | } seccomp; |
| 102 | 105 | }; |
| 103 | 106 | }; |
| @@ -142,6 +145,8 @@ struct ptrace_sud_config { · 38 unmodified lines | ||
| 142 | 145 | __u64 len; |
| 143 | 146 | }; |
| 144 | 147 | |
| 148 | +/* 0x4212 is PTRACE_SET_SYSCALL_INFO */ | |
| 149 | + | |
| 145 | 150 | /* |
| 146 | 151 | * These values are stored in task->ptrace_message |
| 147 | 152 | * by ptrace_stop to describe the current syscall-stop. |