From: Dmitry V. L. <ld...@al...> - 2012-11-29 15:50:48
|
Hi, On Wed, Nov 28, 2012 at 01:14:33PM +0000, James Hogan wrote: > While implementing regset support in strace for the metag architecture, > I think I've noticed a problem in util.c. > > For SPARC/SPARC64, arg_setup and arg_finish_change are defined to use > PTRACE_GETREGS and PTRACE_SETREGS. However change_syscall also does a > read-modify-write using PTRACE_GETREGS and PTRACE_SETREGS. > > These are then combined in a bad way in setbpt: > > if (arg_setup(tcp, &state) < 0 > /* reads the registers into state */ > || get_arg0(tcp, &state, &tcp->inst[0]) < 0 > || get_arg1(tcp, &state, &tcp->inst[1]) < 0 > /* reads arguments from state */ > || change_syscall(tcp, clone_scno[current_personality]) < 0 > /* reads registers again, and changes one of them */ > || set_arg0(tcp, &state, CLONE_PTRACE|SIGCHLD) < 0 > || set_arg1(tcp, &state, 0) < 0 > /* sets argument registers in state */ > || arg_finish_change(tcp, &state) < 0) > /* writes back state, presumably undoing change_syscall's hard work. */ > > Looking at a "git diff v4.7..master util.c", it looks like clearbpt is > doing something similar too. > > Is that analysis correct or have I missed something important that would > make it work? Yes, there seems to be a bug on SPARC/SPARC64 where change_syscall is effectively disabled due to the way how it is implemented. -- ldv |