From: Keno Fischer <keno@juliacomputing.com> To: linux-arm-kernel@lists.infradead.org Cc: Will Deacon <will@kernel.org>, Catalin Marinas <catalin.marinas@arm.com>, Oleg Nesterov <oleg@redhat.com>, Linux Kernel Mailing List <linux-kernel@vger.kernel.org>, Kyle Huey <khuey@pernos.co> Subject: arm64: Register modification during syscall entry/exit stop Date: Mon, 18 May 2020 21:05:30 -0400 [thread overview] Message-ID: <CABV8kRz0mKSc=u1LeonQSLroKJLOKWOWktCoGji2nvEBc=e7=w@mail.gmail.com> (raw) Continuing my theme of "weird things I encounter while trying to use ptrace on arm64", I ran into the effect of the following code in the syscall entry/exit reporting: ``` /* * A scratch register (ip(r12) on AArch32, x7 on AArch64) is * used to denote syscall entry/exit: */ regno = (is_compat_task() ? 12 : 7); saved_reg = regs->regs[regno]; regs->regs[regno] = dir; ``` This seems very weird to me. I can't think of any other architecture that does something similar (other than unicore32 apparently, but the ptrace support there seems like it might have just been copied from ARM). I'm able to work around this in my application, but it adds another stumbling block. Some examples of things that happen: - Writes to x7 during syscall exit stops are ignored, so if the ptracer tries to emulate a setjmp-type thing, it might miss this register (ptracers sometimes like to do this to manually serialize execution between different threads, puppeteering a single thread of execution between different register states). - Reads from x7 are incorrect, so if the ptracer saves a register state and later tries to set it back to the task, it may get x7 incorrect, but user space may be expecting the register to be preserved (when might this happen? - consider a ptracer that wants to modify some syscall arguments, it modifies the arguments, restarts the syscall but then incurs a signal, so it tries to restore the original registers to let userspace deal with the signal without being confused - expect signal traps don't ignore x7 modifications, so x7 may have been unexpectedly modified). - We now have seccomp traps, which kind of look and act like syscall-entry traps, but don't have this behavior, so it's not particularly reliable for ptracers to use. Furthermore, it seems unnecessary to me on modern kernels. We now have PTRACE_GET_SYSCALL_INFO, which exposes this information without lying to the ptracer about the tracee's registers. I understand, we can't just change this, since people may be relying on it, but I would like to propose adding a ptrace option (PTRACE_O_ARM_REGSGOOD?) that turns this behavior off. Now, I don't think we currently have any other arch-specific ptrace options, so maybe there is a different option that would be preferable (e.g. could be a different regset), but I do think it would be good to have a way to operate on the real x7 value. As I said, I can work around it, but hopefully I will be able to save a future implementer some headache. Keno
WARNING: multiple messages have this Message-ID (diff)
From: Keno Fischer <keno@juliacomputing.com> To: linux-arm-kernel@lists.infradead.org Cc: Catalin Marinas <catalin.marinas@arm.com>, Kyle Huey <khuey@pernos.co>, Will Deacon <will@kernel.org>, Oleg Nesterov <oleg@redhat.com>, Linux Kernel Mailing List <linux-kernel@vger.kernel.org> Subject: arm64: Register modification during syscall entry/exit stop Date: Mon, 18 May 2020 21:05:30 -0400 [thread overview] Message-ID: <CABV8kRz0mKSc=u1LeonQSLroKJLOKWOWktCoGji2nvEBc=e7=w@mail.gmail.com> (raw) Continuing my theme of "weird things I encounter while trying to use ptrace on arm64", I ran into the effect of the following code in the syscall entry/exit reporting: ``` /* * A scratch register (ip(r12) on AArch32, x7 on AArch64) is * used to denote syscall entry/exit: */ regno = (is_compat_task() ? 12 : 7); saved_reg = regs->regs[regno]; regs->regs[regno] = dir; ``` This seems very weird to me. I can't think of any other architecture that does something similar (other than unicore32 apparently, but the ptrace support there seems like it might have just been copied from ARM). I'm able to work around this in my application, but it adds another stumbling block. Some examples of things that happen: - Writes to x7 during syscall exit stops are ignored, so if the ptracer tries to emulate a setjmp-type thing, it might miss this register (ptracers sometimes like to do this to manually serialize execution between different threads, puppeteering a single thread of execution between different register states). - Reads from x7 are incorrect, so if the ptracer saves a register state and later tries to set it back to the task, it may get x7 incorrect, but user space may be expecting the register to be preserved (when might this happen? - consider a ptracer that wants to modify some syscall arguments, it modifies the arguments, restarts the syscall but then incurs a signal, so it tries to restore the original registers to let userspace deal with the signal without being confused - expect signal traps don't ignore x7 modifications, so x7 may have been unexpectedly modified). - We now have seccomp traps, which kind of look and act like syscall-entry traps, but don't have this behavior, so it's not particularly reliable for ptracers to use. Furthermore, it seems unnecessary to me on modern kernels. We now have PTRACE_GET_SYSCALL_INFO, which exposes this information without lying to the ptracer about the tracee's registers. I understand, we can't just change this, since people may be relying on it, but I would like to propose adding a ptrace option (PTRACE_O_ARM_REGSGOOD?) that turns this behavior off. Now, I don't think we currently have any other arch-specific ptrace options, so maybe there is a different option that would be preferable (e.g. could be a different regset), but I do think it would be good to have a way to operate on the real x7 value. As I said, I can work around it, but hopefully I will be able to save a future implementer some headache. Keno _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next reply other threads:[~2020-05-19 1:06 UTC|newest] Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top 2020-05-19 1:05 Keno Fischer [this message] 2020-05-19 1:05 ` arm64: Register modification during syscall entry/exit stop Keno Fischer 2020-05-19 8:15 ` Will Deacon 2020-05-19 8:15 ` Will Deacon 2020-05-19 8:37 ` Keno Fischer 2020-05-19 8:37 ` Keno Fischer 2020-05-20 17:41 ` Will Deacon 2020-05-20 17:41 ` Will Deacon 2020-05-23 5:35 ` Keno Fischer 2020-05-23 5:35 ` Keno Fischer 2020-05-24 6:56 ` Keno Fischer 2020-05-24 6:56 ` Keno Fischer 2020-05-27 9:55 ` Will Deacon 2020-05-27 9:55 ` Will Deacon 2020-05-27 10:19 ` Dave Martin 2020-05-27 10:19 ` Dave Martin 2020-05-31 9:33 ` Will Deacon 2020-05-31 9:33 ` Will Deacon 2020-05-31 16:13 ` Keno Fischer 2020-05-31 16:13 ` Keno Fischer 2020-06-01 9:14 ` Dave Martin 2020-06-01 9:14 ` Dave Martin 2020-06-01 9:23 ` Keno Fischer 2020-06-01 9:23 ` Keno Fischer 2020-06-01 9:52 ` Dave Martin 2020-06-01 9:52 ` Dave Martin 2020-05-31 16:20 ` Keno Fischer 2020-05-31 16:20 ` Keno Fischer 2020-06-01 9:23 ` Dave Martin 2020-06-01 9:23 ` Dave Martin 2020-06-01 9:40 ` Keno Fischer 2020-06-01 9:40 ` Keno Fischer 2020-06-01 9:59 ` Dave Martin 2020-06-01 9:59 ` Dave Martin
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to='CABV8kRz0mKSc=u1LeonQSLroKJLOKWOWktCoGji2nvEBc=e7=w@mail.gmail.com' \ --to=keno@juliacomputing.com \ --cc=catalin.marinas@arm.com \ --cc=khuey@pernos.co \ --cc=linux-arm-kernel@lists.infradead.org \ --cc=linux-kernel@vger.kernel.org \ --cc=oleg@redhat.com \ --cc=will@kernel.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.