Message ID | 20250107230153.GA30560@strace.io (mailing list archive) |
---|---|
Headers | show |
Series | ptrace: introduce PTRACE_SET_SYSCALL_INFO API | expand |
This would seem like a very good idea. However, it is perhaps important to realize that it doesn't fully eliminate the problems with 64-bit arguments on 32-bit ABIs being handled differently (never mind inconsistencies in system call ABIs etc.) There isn't all that much that can be done about that directly, though. -hpa On 1/7/25 15:01, Dmitry V. Levin wrote: > 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. > > Current implementation supports changing only those bits of system call > information that are used by strace, 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 re-using struct ptrace_syscall_info.reserved to specify > the additional details that should be set. Currently, the reserved > field of struct ptrace_syscall_info must be initialized with zeroes; > arch, instruction_pointer, and stack_pointer fields are 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 [1]. > > 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)). > > [1] https://lore.kernel.org/all/59505464-c84a-403d-972f-d4b2055eeaac@gmail.com/ > > Dmitry V. Levin (6): > Revert "arch: remove unused function syscall_set_arguments()" > syscall.h: add syscall_set_arguments() on remaining > HAVE_ARCH_TRACEHOOK arches > syscall.h: introduce syscall_set_nr() > ptrace_get_syscall_info: factor out ptrace_get_syscall_info_op > ptrace: introduce PTRACE_SET_SYSCALL_INFO request > selftests/ptrace: add a test case for PTRACE_SET_SYSCALL_INFO > > arch/arc/include/asm/syscall.h | 20 + > arch/arm/include/asm/syscall.h | 25 + > arch/arm64/include/asm/syscall.h | 20 + > arch/csky/include/asm/syscall.h | 13 + > arch/hexagon/include/asm/syscall.h | 14 + > arch/loongarch/include/asm/syscall.h | 15 + > arch/m68k/include/asm/syscall.h | 7 + > arch/microblaze/include/asm/syscall.h | 7 + > arch/mips/include/asm/syscall.h | 53 +++ > arch/nios2/include/asm/syscall.h | 16 + > arch/openrisc/include/asm/syscall.h | 13 + > arch/parisc/include/asm/syscall.h | 19 + > arch/powerpc/include/asm/syscall.h | 15 + > arch/riscv/include/asm/syscall.h | 16 + > arch/s390/include/asm/syscall.h | 19 + > arch/sh/include/asm/syscall_32.h | 19 + > arch/sparc/include/asm/syscall.h | 17 + > arch/um/include/asm/syscall-generic.h | 19 + > arch/x86/include/asm/syscall.h | 43 ++ > arch/xtensa/include/asm/syscall.h | 18 + > include/asm-generic/syscall.h | 30 ++ > include/linux/ptrace.h | 3 + > include/uapi/linux/ptrace.h | 3 +- > kernel/ptrace.c | 154 ++++++- > tools/testing/selftests/ptrace/Makefile | 2 +- > .../selftests/ptrace/set_syscall_info.c | 436 ++++++++++++++++++ > 26 files changed, 994 insertions(+), 22 deletions(-) > create mode 100644 tools/testing/selftests/ptrace/set_syscall_info.c >