* [PATCH 5/6] ptrace: introduce PTRACE_SET_SYSCALL_INFO request [not found] <20250107230153.GA30560@strace.io> @ 2025-01-07 23:04 ` Dmitry V. Levin 2025-01-09 1:37 ` kernel test robot ` (4 more replies) 0 siblings, 5 replies; 7+ messages in thread From: Dmitry V. Levin @ 2025-01-07 23:04 UTC (permalink / raw) To: Oleg Nesterov Cc: Eugene Syromyatnikov, Mike Frysinger, Renzo Davoli, Davide Berardi, strace-devel, linux-kernel, linux-api 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. 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)). Link: https://lore.kernel.org/all/59505464-c84a-403d-972f-d4b2055eeaac@gmail.com/ Signed-off-by: Dmitry V. Levin <ldv@strace.io> --- include/linux/ptrace.h | 3 ++ include/uapi/linux/ptrace.h | 3 +- kernel/ptrace.c | 102 ++++++++++++++++++++++++++++++++++++ 3 files changed, 107 insertions(+), 1 deletion(-) diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h index 90507d4afcd6..c8dbf1e498bf 100644 --- a/include/linux/ptrace.h +++ b/include/linux/ptrace.h @@ -17,6 +17,9 @@ struct syscall_info { struct seccomp_data data; }; +/* sizeof() the first published struct ptrace_syscall_info */ +#define PTRACE_SYSCALL_INFO_SIZE_VER0 84 + extern int ptrace_access_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, unsigned int gup_flags); diff --git a/include/uapi/linux/ptrace.h b/include/uapi/linux/ptrace.h index 72c038fc71d0..231b8bf7eeff 100644 --- a/include/uapi/linux/ptrace.h +++ b/include/uapi/linux/ptrace.h @@ -74,6 +74,7 @@ struct seccomp_metadata { }; #define PTRACE_GET_SYSCALL_INFO 0x420e +#define PTRACE_SET_SYSCALL_INFO 0x4212 #define PTRACE_SYSCALL_INFO_NONE 0 #define PTRACE_SYSCALL_INFO_ENTRY 1 #define PTRACE_SYSCALL_INFO_EXIT 2 @@ -81,7 +82,7 @@ struct seccomp_metadata { struct ptrace_syscall_info { __u8 op; /* PTRACE_SYSCALL_INFO_* */ - __u8 pad[3]; + __u8 reserved[3]; __u32 arch; __u64 instruction_pointer; __u64 stack_pointer; diff --git a/kernel/ptrace.c b/kernel/ptrace.c index e7e0003cc8e0..52377653743d 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c @@ -1018,6 +1018,104 @@ ptrace_get_syscall_info(struct task_struct *child, unsigned long user_size, write_size = min(actual_size, user_size); return copy_to_user(datavp, &info, write_size) ? -EFAULT : actual_size; } + +static unsigned long +ptrace_set_syscall_info_entry(struct task_struct *child, struct pt_regs *regs, + struct ptrace_syscall_info *info) +{ + unsigned long args[ARRAY_SIZE(info->entry.args)]; + int nr = info->entry.nr; + int i; + + if (nr != info->entry.nr) + return -ERANGE; + + for (i = 0; i < ARRAY_SIZE(args); i++) { + args[i] = info->entry.args[i]; + if (args[i] != info->entry.args[i]) + return -ERANGE; + } + + syscall_set_nr(child, regs, nr); + syscall_set_arguments(child, regs, args); + if (nr == -1) { + /* + * When the syscall number is set to -1, the syscall will be + * skipped. In this case also set the syscall return value to + * -ENOSYS, otherwise on some architectures the corresponding + * struct pt_regs field will remain unchanged. + * + * Note that on some architectures syscall_set_return_value() + * modifies one of the struct pt_regs fields also modified by + * syscall_set_arguments(), so the former should be called + * after the latter. + */ + syscall_set_return_value(child, regs, -ENOSYS, 0); + } + + return 0; +} + +static unsigned long +ptrace_set_syscall_info_seccomp(struct task_struct *child, struct pt_regs *regs, + struct ptrace_syscall_info *info) +{ + /* + * info->entry is currently a subset of info->seccomp, + * info->seccomp.ret_data is currently ignored. + */ + return ptrace_set_syscall_info_entry(child, regs, info); +} + +static unsigned long +ptrace_set_syscall_info_exit(struct task_struct *child, struct pt_regs *regs, + struct ptrace_syscall_info *info) +{ + if (info->exit.is_error) + syscall_set_return_value(child, regs, info->exit.rval, 0); + else + syscall_set_return_value(child, regs, 0, info->exit.rval); + + return 0; +} + +static int +ptrace_set_syscall_info(struct task_struct *child, unsigned long user_size, + void __user *datavp) +{ + struct pt_regs *regs = task_pt_regs(child); + struct ptrace_syscall_info info; + int error; + + BUILD_BUG_ON(sizeof(struct ptrace_syscall_info) < PTRACE_SYSCALL_INFO_SIZE_VER0); + + if (user_size < PTRACE_SYSCALL_INFO_SIZE_VER0 || user_size > PAGE_SIZE) + return -EINVAL; + + error = copy_struct_from_user(&info, sizeof(info), datavp, user_size); + if (error) + return error; + + /* Reserved for future use. */ + if (memchr_inv(info.reserved, 0, sizeof(info.reserved))) + return -EINVAL; + + /* Changing the type of the system call stop is not supported. */ + if (ptrace_get_syscall_info_op(child) != info.op) + return -EINVAL; + + switch (info.op) { + case PTRACE_SYSCALL_INFO_ENTRY: + return ptrace_set_syscall_info_entry(child, regs, &info); + case PTRACE_SYSCALL_INFO_EXIT: + return ptrace_set_syscall_info_exit(child, regs, &info); + case PTRACE_SYSCALL_INFO_SECCOMP: + return ptrace_set_syscall_info_seccomp(child, regs, &info); + default: + /* Other types of system call stops are not supported. */ + return -EINVAL; + } +} #endif /* CONFIG_HAVE_ARCH_TRACEHOOK */ int ptrace_request(struct task_struct *child, long request, @@ -1236,6 +1334,10 @@ int ptrace_request(struct task_struct *child, long request, case PTRACE_GET_SYSCALL_INFO: ret = ptrace_get_syscall_info(child, addr, datavp); break; + + case PTRACE_SET_SYSCALL_INFO: + ret = ptrace_set_syscall_info(child, addr, datavp); + break; #endif case PTRACE_SECCOMP_GET_FILTER: -- ldv ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH 5/6] ptrace: introduce PTRACE_SET_SYSCALL_INFO request 2025-01-07 23:04 ` [PATCH 5/6] ptrace: introduce PTRACE_SET_SYSCALL_INFO request Dmitry V. Levin @ 2025-01-09 1:37 ` kernel test robot 2025-01-09 2:21 ` kernel test robot ` (3 subsequent siblings) 4 siblings, 0 replies; 7+ messages in thread From: kernel test robot @ 2025-01-09 1:37 UTC (permalink / raw) To: Dmitry V. Levin, Oleg Nesterov Cc: llvm, oe-kbuild-all, Eugene Syromyatnikov, Mike Frysinger, Renzo Davoli, Davide Berardi, strace-devel, linux-kernel, linux-api Hi Dmitry, kernel test robot noticed the following build errors: [auto build test ERROR on openrisc/for-next] [also build test ERROR on powerpc/next powerpc/fixes s390/features uml/next jcmvbkbc-xtensa/xtensa-for-next arnd-asm-generic/master vgupta-arc/for-curr arm64/for-next/core linus/master uml/fixes tip/x86/core vgupta-arc/for-next v6.13-rc6 next-20250108] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Dmitry-V-Levin/Revert-arch-remove-unused-function-syscall_set_arguments/20250108-070658 base: https://github.com/openrisc/linux.git for-next patch link: https://lore.kernel.org/r/20250107230456.GE30633%40strace.io patch subject: [PATCH 5/6] ptrace: introduce PTRACE_SET_SYSCALL_INFO request config: hexagon-allnoconfig (https://download.01.org/0day-ci/archive/20250109/202501090919.TiLTOhaq-lkp@intel.com/config) compiler: clang version 20.0.0git (https://github.com/llvm/llvm-project 096551537b2a747a3387726ca618ceeb3950e9bc) reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250109/202501090919.TiLTOhaq-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202501090919.TiLTOhaq-lkp@intel.com/ All errors (new ones prefixed by >>): >> kernel/ptrace.c:1053:3: error: call to undeclared function 'syscall_set_return_value'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration] 1053 | syscall_set_return_value(child, regs, -ENOSYS, 0); | ^ kernel/ptrace.c:1053:3: note: did you mean 'syscall_get_return_value'? arch/hexagon/include/asm/syscall.h:56:20: note: 'syscall_get_return_value' declared here 56 | static inline long syscall_get_return_value(struct task_struct *task, | ^ kernel/ptrace.c:1075:3: error: call to undeclared function 'syscall_set_return_value'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration] 1075 | syscall_set_return_value(child, regs, info->exit.rval, 0); | ^ 2 errors generated. vim +/syscall_set_return_value +1053 kernel/ptrace.c 1021 1022 static unsigned long 1023 ptrace_set_syscall_info_entry(struct task_struct *child, struct pt_regs *regs, 1024 struct ptrace_syscall_info *info) 1025 { 1026 unsigned long args[ARRAY_SIZE(info->entry.args)]; 1027 int nr = info->entry.nr; 1028 int i; 1029 1030 if (nr != info->entry.nr) 1031 return -ERANGE; 1032 1033 for (i = 0; i < ARRAY_SIZE(args); i++) { 1034 args[i] = info->entry.args[i]; 1035 if (args[i] != info->entry.args[i]) 1036 return -ERANGE; 1037 } 1038 1039 syscall_set_nr(child, regs, nr); 1040 syscall_set_arguments(child, regs, args); 1041 if (nr == -1) { 1042 /* 1043 * When the syscall number is set to -1, the syscall will be 1044 * skipped. In this case also set the syscall return value to 1045 * -ENOSYS, otherwise on some architectures the corresponding 1046 * struct pt_regs field will remain unchanged. 1047 * 1048 * Note that on some architectures syscall_set_return_value() 1049 * modifies one of the struct pt_regs fields also modified by 1050 * syscall_set_arguments(), so the former should be called 1051 * after the latter. 1052 */ > 1053 syscall_set_return_value(child, regs, -ENOSYS, 0); 1054 } 1055 1056 return 0; 1057 } 1058 -- 0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 5/6] ptrace: introduce PTRACE_SET_SYSCALL_INFO request 2025-01-07 23:04 ` [PATCH 5/6] ptrace: introduce PTRACE_SET_SYSCALL_INFO request Dmitry V. Levin 2025-01-09 1:37 ` kernel test robot @ 2025-01-09 2:21 ` kernel test robot 2025-01-09 14:03 ` kernel test robot ` (2 subsequent siblings) 4 siblings, 0 replies; 7+ messages in thread From: kernel test robot @ 2025-01-09 2:21 UTC (permalink / raw) To: Dmitry V. Levin, Oleg Nesterov Cc: llvm, oe-kbuild-all, Eugene Syromyatnikov, Mike Frysinger, Renzo Davoli, Davide Berardi, strace-devel, linux-kernel, linux-api Hi Dmitry, kernel test robot noticed the following build errors: [auto build test ERROR on openrisc/for-next] [also build test ERROR on powerpc/next powerpc/fixes s390/features uml/next jcmvbkbc-xtensa/xtensa-for-next arnd-asm-generic/master vgupta-arc/for-curr arm64/for-next/core linus/master uml/fixes tip/x86/core vgupta-arc/for-next v6.13-rc6 next-20250108] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Dmitry-V-Levin/Revert-arch-remove-unused-function-syscall_set_arguments/20250108-070658 base: https://github.com/openrisc/linux.git for-next patch link: https://lore.kernel.org/r/20250107230456.GE30633%40strace.io patch subject: [PATCH 5/6] ptrace: introduce PTRACE_SET_SYSCALL_INFO request config: hexagon-randconfig-001-20250109 (https://download.01.org/0day-ci/archive/20250109/202501090954.gYTxI9sY-lkp@intel.com/config) compiler: clang version 14.0.6 (https://github.com/llvm/llvm-project f28c006a5895fc0e329fe15fead81e37457cb1d1) reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250109/202501090954.gYTxI9sY-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202501090954.gYTxI9sY-lkp@intel.com/ All errors (new ones prefixed by >>): >> kernel/ptrace.c:1053:3: error: implicit declaration of function 'syscall_set_return_value' is invalid in C99 [-Werror,-Wimplicit-function-declaration] syscall_set_return_value(child, regs, -ENOSYS, 0); ^ kernel/ptrace.c:1053:3: note: did you mean 'syscall_get_return_value'? arch/hexagon/include/asm/syscall.h:56:20: note: 'syscall_get_return_value' declared here static inline long syscall_get_return_value(struct task_struct *task, ^ kernel/ptrace.c:1075:3: error: implicit declaration of function 'syscall_set_return_value' is invalid in C99 [-Werror,-Wimplicit-function-declaration] syscall_set_return_value(child, regs, info->exit.rval, 0); ^ 2 errors generated. vim +/syscall_set_return_value +1053 kernel/ptrace.c 1021 1022 static unsigned long 1023 ptrace_set_syscall_info_entry(struct task_struct *child, struct pt_regs *regs, 1024 struct ptrace_syscall_info *info) 1025 { 1026 unsigned long args[ARRAY_SIZE(info->entry.args)]; 1027 int nr = info->entry.nr; 1028 int i; 1029 1030 if (nr != info->entry.nr) 1031 return -ERANGE; 1032 1033 for (i = 0; i < ARRAY_SIZE(args); i++) { 1034 args[i] = info->entry.args[i]; 1035 if (args[i] != info->entry.args[i]) 1036 return -ERANGE; 1037 } 1038 1039 syscall_set_nr(child, regs, nr); 1040 syscall_set_arguments(child, regs, args); 1041 if (nr == -1) { 1042 /* 1043 * When the syscall number is set to -1, the syscall will be 1044 * skipped. In this case also set the syscall return value to 1045 * -ENOSYS, otherwise on some architectures the corresponding 1046 * struct pt_regs field will remain unchanged. 1047 * 1048 * Note that on some architectures syscall_set_return_value() 1049 * modifies one of the struct pt_regs fields also modified by 1050 * syscall_set_arguments(), so the former should be called 1051 * after the latter. 1052 */ > 1053 syscall_set_return_value(child, regs, -ENOSYS, 0); 1054 } 1055 1056 return 0; 1057 } 1058 -- 0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 5/6] ptrace: introduce PTRACE_SET_SYSCALL_INFO request 2025-01-07 23:04 ` [PATCH 5/6] ptrace: introduce PTRACE_SET_SYSCALL_INFO request Dmitry V. Levin 2025-01-09 1:37 ` kernel test robot 2025-01-09 2:21 ` kernel test robot @ 2025-01-09 14:03 ` kernel test robot 2025-01-09 15:17 ` Eugene Syromiatnikov 2025-01-09 15:21 ` Oleg Nesterov 4 siblings, 0 replies; 7+ messages in thread From: kernel test robot @ 2025-01-09 14:03 UTC (permalink / raw) To: Dmitry V. Levin, Oleg Nesterov Cc: oe-kbuild-all, Eugene Syromyatnikov, Mike Frysinger, Renzo Davoli, Davide Berardi, strace-devel, linux-kernel, linux-api Hi Dmitry, kernel test robot noticed the following build warnings: [auto build test WARNING on openrisc/for-next] [also build test WARNING on powerpc/next powerpc/fixes s390/features uml/next jcmvbkbc-xtensa/xtensa-for-next arnd-asm-generic/master vgupta-arc/for-curr arm64/for-next/core linus/master uml/fixes tip/x86/core vgupta-arc/for-next v6.13-rc6 next-20250109] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Dmitry-V-Levin/Revert-arch-remove-unused-function-syscall_set_arguments/20250108-070658 base: https://github.com/openrisc/linux.git for-next patch link: https://lore.kernel.org/r/20250107230456.GE30633%40strace.io patch subject: [PATCH 5/6] ptrace: introduce PTRACE_SET_SYSCALL_INFO request config: mips-randconfig-r122-20250109 (https://download.01.org/0day-ci/archive/20250109/202501092150.9BH2s9AO-lkp@intel.com/config) compiler: mips64-linux-gcc (GCC) 14.2.0 reproduce: (https://download.01.org/0day-ci/archive/20250109/202501092150.9BH2s9AO-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202501092150.9BH2s9AO-lkp@intel.com/ sparse warnings: (new ones prefixed by >>) kernel/ptrace.c:55:22: sparse: sparse: incompatible types in comparison expression (different address spaces): kernel/ptrace.c:55:22: sparse: struct task_struct * kernel/ptrace.c:55:22: sparse: struct task_struct [noderef] __rcu * kernel/ptrace.c:74:23: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct task_struct [noderef] __rcu *parent @@ got struct task_struct *new_parent @@ kernel/ptrace.c:74:23: sparse: expected struct task_struct [noderef] __rcu *parent kernel/ptrace.c:74:23: sparse: got struct task_struct *new_parent kernel/ptrace.c:75:29: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct cred const [noderef] __rcu *ptracer_cred @@ got struct cred const * @@ kernel/ptrace.c:75:29: sparse: expected struct cred const [noderef] __rcu *ptracer_cred kernel/ptrace.c:75:29: sparse: got struct cred const * kernel/ptrace.c:129:18: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct cred const *old_cred @@ got struct cred const [noderef] __rcu *ptracer_cred @@ kernel/ptrace.c:129:18: sparse: expected struct cred const *old_cred kernel/ptrace.c:129:18: sparse: got struct cred const [noderef] __rcu *ptracer_cred kernel/ptrace.c:133:25: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct spinlock [usertype] *lock @@ got struct spinlock [noderef] __rcu * @@ kernel/ptrace.c:133:25: sparse: expected struct spinlock [usertype] *lock kernel/ptrace.c:133:25: sparse: got struct spinlock [noderef] __rcu * kernel/ptrace.c:160:27: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct spinlock [usertype] *lock @@ got struct spinlock [noderef] __rcu * @@ kernel/ptrace.c:160:27: sparse: expected struct spinlock [usertype] *lock kernel/ptrace.c:160:27: sparse: got struct spinlock [noderef] __rcu * kernel/ptrace.c:192:28: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct spinlock [usertype] *lock @@ got struct spinlock [noderef] __rcu * @@ kernel/ptrace.c:192:28: sparse: expected struct spinlock [usertype] *lock kernel/ptrace.c:192:28: sparse: got struct spinlock [noderef] __rcu * kernel/ptrace.c:198:30: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct spinlock [usertype] *lock @@ got struct spinlock [noderef] __rcu * @@ kernel/ptrace.c:198:30: sparse: expected struct spinlock [usertype] *lock kernel/ptrace.c:198:30: sparse: got struct spinlock [noderef] __rcu * kernel/ptrace.c:251:44: sparse: sparse: incompatible types in comparison expression (different address spaces): kernel/ptrace.c:251:44: sparse: struct task_struct [noderef] __rcu * kernel/ptrace.c:251:44: sparse: struct task_struct * kernel/ptrace.c:494:54: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct task_struct *parent @@ got struct task_struct [noderef] __rcu *parent @@ kernel/ptrace.c:494:54: sparse: expected struct task_struct *parent kernel/ptrace.c:494:54: sparse: got struct task_struct [noderef] __rcu *parent kernel/ptrace.c:502:53: sparse: sparse: incorrect type in argument 2 (different address spaces) @@ expected struct task_struct *new_parent @@ got struct task_struct [noderef] __rcu *real_parent @@ kernel/ptrace.c:502:53: sparse: expected struct task_struct *new_parent kernel/ptrace.c:502:53: sparse: got struct task_struct [noderef] __rcu *real_parent kernel/ptrace.c:550:41: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct task_struct *p1 @@ got struct task_struct [noderef] __rcu *real_parent @@ kernel/ptrace.c:550:41: sparse: expected struct task_struct *p1 kernel/ptrace.c:550:41: sparse: got struct task_struct [noderef] __rcu *real_parent kernel/ptrace.c:552:50: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct sighand_struct *sigh @@ got struct sighand_struct [noderef] __rcu *sighand @@ kernel/ptrace.c:552:50: sparse: expected struct sighand_struct *sigh kernel/ptrace.c:552:50: sparse: got struct sighand_struct [noderef] __rcu *sighand kernel/ptrace.c:743:37: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct spinlock [usertype] *lock @@ got struct spinlock [noderef] __rcu * @@ kernel/ptrace.c:743:37: sparse: expected struct spinlock [usertype] *lock kernel/ptrace.c:743:37: sparse: got struct spinlock [noderef] __rcu * kernel/ptrace.c:751:39: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct spinlock [usertype] *lock @@ got struct spinlock [noderef] __rcu * @@ kernel/ptrace.c:751:39: sparse: expected struct spinlock [usertype] *lock kernel/ptrace.c:751:39: sparse: got struct spinlock [noderef] __rcu * kernel/ptrace.c:862:29: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct spinlock [usertype] *lock @@ got struct spinlock [noderef] __rcu * @@ kernel/ptrace.c:862:29: sparse: expected struct spinlock [usertype] *lock kernel/ptrace.c:862:29: sparse: got struct spinlock [noderef] __rcu * kernel/ptrace.c:866:31: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct spinlock [usertype] *lock @@ got struct spinlock [noderef] __rcu * @@ kernel/ptrace.c:866:31: sparse: expected struct spinlock [usertype] *lock kernel/ptrace.c:866:31: sparse: got struct spinlock [noderef] __rcu * kernel/ptrace.c:1206:37: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct spinlock [usertype] *lock @@ got struct spinlock [noderef] __rcu * @@ kernel/ptrace.c:1206:37: sparse: expected struct spinlock [usertype] *lock kernel/ptrace.c:1206:37: sparse: got struct spinlock [noderef] __rcu * kernel/ptrace.c:1208:39: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct spinlock [usertype] *lock @@ got struct spinlock [noderef] __rcu * @@ kernel/ptrace.c:1208:39: sparse: expected struct spinlock [usertype] *lock kernel/ptrace.c:1208:39: sparse: got struct spinlock [noderef] __rcu * kernel/ptrace.c: note: in included file (through include/linux/fwnode.h, include/linux/logic_pio.h, include/asm-generic/io.h, ...): include/linux/list.h:83:21: sparse: sparse: self-comparison always evaluates to true kernel/ptrace.c: note: in included file (through include/linux/rcuwait.h, include/linux/percpu-rwsem.h, include/linux/fs.h, ...): include/linux/sched/signal.h:751:37: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct spinlock [usertype] *lock @@ got struct spinlock [noderef] __rcu * @@ include/linux/sched/signal.h:751:37: sparse: expected struct spinlock [usertype] *lock include/linux/sched/signal.h:751:37: sparse: got struct spinlock [noderef] __rcu * kernel/ptrace.c:380:30: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct spinlock [usertype] *l @@ got struct spinlock [noderef] __rcu * @@ kernel/ptrace.c:380:30: sparse: expected struct spinlock [usertype] *l kernel/ptrace.c:380:30: sparse: got struct spinlock [noderef] __rcu * kernel/ptrace.c:409:12: sparse: sparse: context imbalance in 'ptrace_attach' - different lock contexts for basic block kernel/ptrace.c:500:38: sparse: sparse: dereference of noderef expression kernel/ptrace.c: note: in included file (through include/linux/fwnode.h, include/linux/logic_pio.h, include/asm-generic/io.h, ...): include/linux/list.h:83:21: sparse: sparse: self-comparison always evaluates to true kernel/ptrace.c: note: in included file (through include/linux/rcuwait.h, include/linux/percpu-rwsem.h, include/linux/fs.h, ...): include/linux/sched/signal.h:751:37: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct spinlock [usertype] *lock @@ got struct spinlock [noderef] __rcu * @@ include/linux/sched/signal.h:751:37: sparse: expected struct spinlock [usertype] *lock include/linux/sched/signal.h:751:37: sparse: got struct spinlock [noderef] __rcu * kernel/ptrace.c:690:9: sparse: sparse: context imbalance in 'ptrace_getsiginfo' - different lock contexts for basic block include/linux/sched/signal.h:751:37: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct spinlock [usertype] *lock @@ got struct spinlock [noderef] __rcu * @@ include/linux/sched/signal.h:751:37: sparse: expected struct spinlock [usertype] *lock include/linux/sched/signal.h:751:37: sparse: got struct spinlock [noderef] __rcu * kernel/ptrace.c:706:9: sparse: sparse: context imbalance in 'ptrace_setsiginfo' - different lock contexts for basic block kernel/ptrace.c: note: in included file: arch/mips/include/asm/syscall.h:85:25: sparse: sparse: incorrect type in initializer (different address spaces) @@ expected int const [noderef] __user *__p @@ got int * @@ arch/mips/include/asm/syscall.h:85:25: sparse: expected int const [noderef] __user *__p arch/mips/include/asm/syscall.h:85:25: sparse: got int * >> arch/mips/include/asm/syscall.h:121:25: sparse: sparse: incorrect type in initializer (different address spaces) @@ expected int [noderef] __user *__p @@ got int * @@ arch/mips/include/asm/syscall.h:121:25: sparse: expected int [noderef] __user *__p arch/mips/include/asm/syscall.h:121:25: sparse: got int * kernel/ptrace.c: note: in included file (through include/linux/rcuwait.h, include/linux/percpu-rwsem.h, include/linux/fs.h, ...): include/linux/sched/signal.h:751:37: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct spinlock [usertype] *lock @@ got struct spinlock [noderef] __rcu * @@ include/linux/sched/signal.h:751:37: sparse: expected struct spinlock [usertype] *lock include/linux/sched/signal.h:751:37: sparse: got struct spinlock [noderef] __rcu * include/linux/sched/signal.h:751:37: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct spinlock [usertype] *lock @@ got struct spinlock [noderef] __rcu * @@ include/linux/sched/signal.h:751:37: sparse: expected struct spinlock [usertype] *lock include/linux/sched/signal.h:751:37: sparse: got struct spinlock [noderef] __rcu * kernel/ptrace.c:1369:9: sparse: sparse: context imbalance in 'ptrace_request' - different lock contexts for basic block vim +121 arch/mips/include/asm/syscall.h 307e4cb2957c2f Dmitry V. Levin 2025-01-08 116 307e4cb2957c2f Dmitry V. Levin 2025-01-08 117 #ifdef CONFIG_64BIT 307e4cb2957c2f Dmitry V. Levin 2025-01-08 118 case 4: case 5: case 6: case 7: 307e4cb2957c2f Dmitry V. Levin 2025-01-08 119 #ifdef CONFIG_MIPS32_O32 307e4cb2957c2f Dmitry V. Levin 2025-01-08 120 if (test_tsk_thread_flag(task, TIF_32BIT_REGS)) 307e4cb2957c2f Dmitry V. Levin 2025-01-08 @121 put_user(*arg, (int *)usp + n); 307e4cb2957c2f Dmitry V. Levin 2025-01-08 122 else 307e4cb2957c2f Dmitry V. Levin 2025-01-08 123 #endif 307e4cb2957c2f Dmitry V. Levin 2025-01-08 124 regs->regs[4 + n] = *arg; 307e4cb2957c2f Dmitry V. Levin 2025-01-08 125 307e4cb2957c2f Dmitry V. Levin 2025-01-08 126 return; 307e4cb2957c2f Dmitry V. Levin 2025-01-08 127 #endif 307e4cb2957c2f Dmitry V. Levin 2025-01-08 128 } 307e4cb2957c2f Dmitry V. Levin 2025-01-08 129 } 307e4cb2957c2f Dmitry V. Levin 2025-01-08 130 -- 0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 5/6] ptrace: introduce PTRACE_SET_SYSCALL_INFO request 2025-01-07 23:04 ` [PATCH 5/6] ptrace: introduce PTRACE_SET_SYSCALL_INFO request Dmitry V. Levin ` (2 preceding siblings ...) 2025-01-09 14:03 ` kernel test robot @ 2025-01-09 15:17 ` Eugene Syromiatnikov 2025-01-09 15:21 ` Oleg Nesterov 4 siblings, 0 replies; 7+ messages in thread From: Eugene Syromiatnikov @ 2025-01-09 15:17 UTC (permalink / raw) To: Dmitry V. Levin Cc: Oleg Nesterov, Eugene Syromyatnikov, Mike Frysinger, Renzo Davoli, Davide Berardi, strace-devel, linux-kernel, linux-api On Wed, Jan 08, 2025 at 01:04:56AM +0200, 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. > index 72c038fc71d0..231b8bf7eeff 100644 > --- a/include/uapi/linux/ptrace.h > +++ b/include/uapi/linux/ptrace.h > @@ -74,6 +74,7 @@ struct seccomp_metadata { > }; > > #define PTRACE_GET_SYSCALL_INFO 0x420e > +#define PTRACE_SET_SYSCALL_INFO 0x4212 It seems prudent to also add a comment about 0x4212 being taken right after "#define PTRACE_GET_SYSCALL_USER_DISPATCH_CONFIG 0x4211", or the usage of this ptrace request number may be overlooked on the next update. > struct ptrace_syscall_info { > __u8 op; /* PTRACE_SYSCALL_INFO_* */ > - __u8 pad[3]; > + __u8 reserved[3]; > __u32 arch; > __u64 instruction_pointer; > __u64 stack_pointer; I would like to suggest adding flags for changing scno and args right away; while it is possibly of limited use and seems like an unnecessary overcomplication, at least changing arguments only seems natural to me, to avoid possible interaction with scno-related shenanigans that might present/appear on some kernels and/or architectures. Also, it makes the aforementioned possible extensions of the interface (changing of ip/sp) more natural (as in those cases users might definitely want to avoid touching syscall number/arguments). ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 5/6] ptrace: introduce PTRACE_SET_SYSCALL_INFO request 2025-01-07 23:04 ` [PATCH 5/6] ptrace: introduce PTRACE_SET_SYSCALL_INFO request Dmitry V. Levin ` (3 preceding siblings ...) 2025-01-09 15:17 ` Eugene Syromiatnikov @ 2025-01-09 15:21 ` Oleg Nesterov 2025-01-11 11:49 ` Dmitry V. Levin 4 siblings, 1 reply; 7+ messages in thread From: Oleg Nesterov @ 2025-01-09 15:21 UTC (permalink / raw) To: Dmitry V. Levin Cc: Eugene Syromyatnikov, Mike Frysinger, Renzo Davoli, Davide Berardi, strace-devel, linux-kernel, linux-api On 01/08, Dmitry V. Levin wrote: > > +ptrace_set_syscall_info_entry(struct task_struct *child, struct pt_regs *regs, > + struct ptrace_syscall_info *info) > +{ ... > + syscall_set_nr(child, regs, nr); > + syscall_set_arguments(child, regs, args); > + if (nr == -1) { > + /* > + * When the syscall number is set to -1, the syscall will be > + * skipped. In this case also set the syscall return value to > + * -ENOSYS, otherwise on some architectures the corresponding > + * struct pt_regs field will remain unchanged. > + * > + * Note that on some architectures syscall_set_return_value() > + * modifies one of the struct pt_regs fields also modified by > + * syscall_set_arguments(), so the former should be called > + * after the latter. > + */ > + syscall_set_return_value(child, regs, -ENOSYS, 0); > + } This doesn't look nice to me... We don't need this syscall_set_return_value(ENOSYS) on x86, right? So perhaps we should move this "if (nr == -1) code into syscall_set_nr/syscall_set_arguments on those "some architectures" which actually need it ? Oleg. ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 5/6] ptrace: introduce PTRACE_SET_SYSCALL_INFO request 2025-01-09 15:21 ` Oleg Nesterov @ 2025-01-11 11:49 ` Dmitry V. Levin 0 siblings, 0 replies; 7+ messages in thread From: Dmitry V. Levin @ 2025-01-11 11:49 UTC (permalink / raw) To: Oleg Nesterov Cc: Eugene Syromyatnikov, Mike Frysinger, Renzo Davoli, Davide Berardi, strace-devel, linux-kernel, linux-api On Thu, Jan 09, 2025 at 04:21:39PM +0100, Oleg Nesterov wrote: > On 01/08, Dmitry V. Levin wrote: > > > > +ptrace_set_syscall_info_entry(struct task_struct *child, struct pt_regs *regs, > > + struct ptrace_syscall_info *info) > > +{ > ... > > + syscall_set_nr(child, regs, nr); > > + syscall_set_arguments(child, regs, args); > > + if (nr == -1) { > > + /* > > + * When the syscall number is set to -1, the syscall will be > > + * skipped. In this case also set the syscall return value to > > + * -ENOSYS, otherwise on some architectures the corresponding > > + * struct pt_regs field will remain unchanged. > > + * > > + * Note that on some architectures syscall_set_return_value() > > + * modifies one of the struct pt_regs fields also modified by > > + * syscall_set_arguments(), so the former should be called > > + * after the latter. > > + */ > > + syscall_set_return_value(child, regs, -ENOSYS, 0); > > + } > > This doesn't look nice to me... > > We don't need this syscall_set_return_value(ENOSYS) on x86, right? No, we don't need this on x86. > So perhaps we should move this "if (nr == -1) code into > syscall_set_nr/syscall_set_arguments on those "some architectures" which > actually need it ? Thanks for the suggestion. I think the best option is to skip syscall_set_arguments() invocation in case of nr == -1. It's not just pointless, but also it would clobber the syscall return value on those architectures like arm64 that share the same register both for the first argument of syscall and its return value. This is what I'm going to implement for the next iteration of the series: syscall_set_nr(child, regs, nr); /* * If the syscall number is set to -1, setting syscall arguments is not * just pointless, it would also clobber the syscall return value on * those architectures that share the same register both for the first * argument of syscall and its return value. */ if (nr != -1) syscall_set_arguments(child, regs, args); -- ldv ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2025-01-11 11:49 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- [not found] <20250107230153.GA30560@strace.io> 2025-01-07 23:04 ` [PATCH 5/6] ptrace: introduce PTRACE_SET_SYSCALL_INFO request Dmitry V. Levin 2025-01-09 1:37 ` kernel test robot 2025-01-09 2:21 ` kernel test robot 2025-01-09 14:03 ` kernel test robot 2025-01-09 15:17 ` Eugene Syromiatnikov 2025-01-09 15:21 ` Oleg Nesterov 2025-01-11 11:49 ` Dmitry V. Levin
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).